第3章-图形处理单元-3.3-可编程着色器阶段
3.3 可编程着色器阶段
现代着色器程序使用统一的着色器设计。这意味着顶点、像素、几何和曲面细分相关的着色器共享一个通用的编程模型。在内部,它们具有相同的指令集架构(ISA)。实现此模型的处理器在DirectX中称为通用着色器内核,具有此类内核的 GPU被称为具有统一着色器架构。这种架构背后的想法是着色器处理器可用于各种角色,GPU可以根据需要分配这些角色。例如,与由两个三角形组成的大正方形相比,具有小三角形的一组网格需要更多的顶点着色器处理。具有单独的顶点和像素着色器核心池的GPU意味着保持所有核心忙碌的理想工作分配是严格预先确定的。使用统一的着色器核心,GPU可以决定如何平衡此负载。
描述整个着色器编程模型远远超出了本书的范围,并且有许多文档、书籍和网站已经这样做了。着色器使用类似C的着色语言进行编程,例如DirectX的高级着色语言(HLSL)和OpenGL着色语言 (GLSL)。DirectX的HLSL可以编译为虚拟机字节码,也称为中间语言(IL或DXIL),以提供硬件独立性。"中间"表示还可以允许离线编译和存储着色器程序。该中间语言由驱动程序转换为特定GPU的ISA。控制台编程通常会避免中间语言步骤,因为系统只有一个ISA。
基本数据类型是32位单精度浮点标量和向量,尽管向量只是着色器代码的一部分,并且如上所述不受硬件支持。在现代 GPU上,本机也支持32位整数和64位浮点数。浮点向量通常包含位置(xyzw)、法线、矩阵行、颜色(rgba)或纹理坐标 (uvwq)等数据。整数最常用于表示计数器、索引或位掩码。还支持聚合数据类型,例如结构体、数组和矩阵。
绘制命令调用图形API来绘制一组图元,从而使得图形管线执行并运行其着色器。每个可编程着色器阶段都有两种类型的输入:统一(uniform)输入,其值在整个绘制调用期间保持不变(但可以在绘制调用之间更改),以及变化(varying)的输入,来自三角形顶点或光栅化的数据。例如,像素着色器可以将光源的颜色作为统一(uniform)值提供,并且三角形表面的位置每个像素都会发生变化,因此也会发生变化。纹理是一种特殊的统一(uniform)输入,曾经是应用于表面的彩色图像,但现在可以将其视为任何大型数据数组。
底层虚拟机为不同类型的输入和输出提供特殊寄存器。用于uniform的可用常量寄存器的数量远大于可用于varying输入或输出的那些寄存器。发生这种情况是因为需要为每个顶点或像素单独存储不同的输入和输出,因此需要多少个自然是有限制的。uniform输入存储一次,并在绘制调用中的所有顶点或像素中重复使用。虚拟机还具有通用临时寄存器,用于暂存空间。所有类型的寄存器都可以使用临时寄存器中的整数值进行数组索引。着色器虚拟机的输入和输出如图3.3所示。