Common-Shader Core
在着色器模型 4 中,所有着色器阶段都使用通用着色器核心实现相同的基本功能。 此外,三个着色器阶段 (顶点、几何图形和像素) 提供每个阶段独有的功能,例如从几何着色器阶段生成新基元或放弃像素着色器阶段中的特定像素的功能。 下图显示了数据如何流经着色器阶段,以及公共着色器核心与着色器内存资源的关系。
- 输入数据:顶点着色器从输入装配器阶段接收其输入;geometry 和像素着色器从上一个着色器阶段接收其输入。 其他输入包括 系统值语义,这些语义由管道中适用的第一个单元使用。
- 输出数据:着色器生成要传递到管道中后续阶段的输出结果。 对于几何着色器,单个调用输出的数据量可能会有所不同。 某些输出由通用着色器核心 (解释,例如顶点位置和呈现目标数组索引) ,其他输出设计为由应用程序解释。
- 着色器代码:着色器可以从内存中读取、执行矢量浮点和整数算术运算或流控制操作。 可以在着色器中实现的语句数量没有限制。
- 取样器:采样器定义如何对纹理进行采样和筛选。 可以同时将多达 16 个采样器绑定到一个着色器。
- 纹理:可以使用采样器筛选纹理,或者直接使用 load 内部函数按纹素读取纹理。
- 缓冲区:从不筛选缓冲区,但可以直接使用 load 内部函数按元素从内存中读取缓冲区。 组合 (多达 128 个纹理和缓冲区资源,) 可以同时绑定到着色器。
- 常量缓冲区:常量缓冲区针对着色器常量变量进行优化。 可以同时将多达 16 个常量缓冲区绑定到着色器阶段。 它们旨在更频繁地从 CPU 更新;因此,它们具有额外的大小、布局和访问限制。
Direct3D 9 与 Direct3D 10 之间的差异:
- 在 Direct3D 9 中,每个着色器单元都有一个小型常量寄存器文件,用于存储所有常量着色器变量。 要容纳具有此有限常量空间的所有着色器,CPU 需要频繁回收常量。
- 在 Direct3D 10 中,常量存储在内存中的不可变缓冲区中,并像管理任何其他资源一样。 应用程序可以创建的常量缓冲区数没有限制。 通过按更新频率和使用将常量组织到缓冲区中,可以显著减少更新常量以适应所有着色器所需的带宽量。
整数和位支持
通用着色器核心提供一整套符合 IEEE 标准的 32 位整数和按位运算。 这些操作支持图形硬件示例中的一类新算法,包括压缩和打包技术、FFT 和位域程序流控制。
Direct3D 10 HLSL 中的 int 和 uint 数据类型映射到硬件中的 32 位整数。
Direct3D 9 与 Direct3D 10 之间的差异: 在 Direct3D 9 中,HLSL 中标记为整数的流输入被解释为浮点。 在 Direct3D 10 中,标记为整数的流输入被解释为 32 位整数。 此外,布尔值现在是设置的所有位或所有未设置的位。 如果值不等于 0.0f,则转换为 布尔 的数据将被解释为 true, (正零和负零都允许为 false) ,否则为 false。 |
位运算符
通用着色器核心支持以下按位运算符:
运算符 | 函数 |
---|---|
~ | 逻辑非 |
<< | 左 Shift 键 |
>> | 右移 |
& | 逻辑与 |
| | 逻辑或 |
^ | 逻辑 Xor |
<<= | 左移等于 |
>>= | 右移等于 |
&= | 和等于 |
|= | 或等于 |
^= | Xor Equal |
按位运算符定义为仅对 int 和 uint 数据类型进行操作。 尝试对 float 或 struct 数据类型使用按位运算符将导致错误。 对于其他运算符,按位运算符的优先级与 C 相同。
二进制强制转换
整数和浮点类型之间的强制转换将按照 C 截断规则转换数值。 将值从 float 强制转换为 int,再转换回 float 是一种有损转换,具体取决于目标数据类型的精度。 下面是一些转换函数: asfloat (DirectX HLSL) 、 asint (DirectX HLSL) 、 asuint (DirectX HLSL) 。
也可以使用 HLSL 内部函数执行二进制强制转换。 这会导致编译器将数字的位表示形式重新解释为目标数据类型。