SM5.1 中的字节码更改

SM5.1 更改了如何在说明中声明和引用资源寄存器。

SM5.1 将朝着声明寄存器“变量”的方向移动,这类似于对组共享内存寄存器执行的作,如以下示例所示:

Texture2D<float4> tex0          : register(t5,  space0);
Texture2D<float4> tex1[][5][3]  : register(t10, space0);
Texture2D<float4> tex2[8]       : register(t0,  space1);
SamplerState samp0              : register(s5, space0);

float4 main(float4 coord : COORD) : SV_TARGET
{
    float4 r = coord;
    r += tex0.Sample(samp0, r.xy);
    r += tex2[r.x].Sample(samp0, r.xy);
    r += tex1[r.x][r.y][r.z].Sample(samp0, r.xy);
    return r;
}

此示例的反汇编如下:

// Resource Bindings:
//
// Name                                 Type  Format         Dim Space Slot  Elements
// ------------------------------ ---------- ------- ----------- ----- ---- ---------
// samp0                             sampler      NA          NA     0    5         1
// tex0                              texture  float4          2d     0    5         1
// tex1[0][5][3]                     texture  float4          2d     0   10 unbounded
// tex2[8]                           texture  float4          2d     1    0         8
//
//
//
// Input signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// COORD                    0   xyzw        0     NONE   float   xyzw
//
//
// Output signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
//
ps_5_1
dcl_globalFlags refactoringAllowed
dcl_sampler s0[5:5], mode_default, space=0
dcl_resource_texture2d (float,float,float,float) t0[5:5], space=0
dcl_resource_texture2d (float,float,float,float) t1[10:*], space=0
dcl_resource_texture2d (float,float,float,float) t2[0:7], space=1
dcl_input_ps linear v0.xyzw
dcl_output o0.xyzw
dcl_temps 2
sample r0.xyzw, v0.xyxx, t0[0].xyzw, s0[5]
add r0.xyzw, r0.xyzw, v0.xyzw
ftou r1.x, r0.x
sample r1.xyzw, r0.xyxx, t2[r1.x + 0].xyzw, s0[5]
add r0.xyzw, r0.xyzw, r1.xyzw
ftou r1.xyz, r0.zyxz
imul null, r1.yz, r1.zzyz, l(0, 15, 3, 0)
iadd r1.y, r1.z, r1.y
iadd r1.x, r1.x, r1.y
sample r1.xyzw, r0.xyxx, t1[r1.x + 10].xyzw, s0[5]
add o0.xyzw, r0.xyzw, r1.xyzw
ret
// Approximately 12 instruction slots used

每个着色器资源范围现在在着色器字节码中都有一个 ID(名称)。 例如,tex1 纹理数组在着色器字节代码中变为“t1”。 为每个资源范围提供唯一 ID 允许以下两项作:

  • 明确标识指令中正在编制索引的资源范围(dcl_resource_texture2d 请参阅示例指令)。
  • 将属性集附加到声明,例如元素类型、步幅大小、光栅作模式等。

请注意,范围的 ID 与 HLSL 下限声明无关。

反射资源绑定和着色器声明指令的顺序相同,有助于识别 HLSL 变量和字节码 ID 之间的对应关系。

SM5.1 中的每个声明指令都使用 3D作数来定义:范围 ID、下限和上限。 发出其他令牌以指定寄存器空间。 还可以发出其他令牌来传达范围的其他属性,例如 cbuffer 或结构化缓冲区声明指令发出 cbuffer 或结构的大小。 可在 d3d12TokenizedProgramFormat.h 和 D3D10ShaderBinary::CShaderCodeParser 中找到编码的确切详细信息。

SM5.1 指令不会作为指令的一部分发出其他资源作数信息(如 SM5.0 中)。 此信息现已移至声明说明。 在 SM5.0 中,说明索引资源所需的资源属性在扩展作代码令牌中描述,因为索引混淆了与声明的关联。 在 SM5.1 中,每个 ID(如“t1”)明确与描述所需资源信息的单个声明相关联。 因此,不再发出用于描述资源信息的指令的扩展作码令牌。

在非声明指令中,采样器、SRV 和 UAV 的资源作数是 2D作数。 第一个索引是指定范围 ID 的文本常量。 第二个索引表示索引的线性化值。 该值相对于相应寄存器空间的开头(而不是逻辑范围的开头)进行计算,以便更好地与根签名关联,并减少调整索引的驱动程序编译器负担。

CBV 的资源作数是一个 3D作数:范围的文本 ID、cbuffer 索引、偏移量到 cbuffer 的特定实例中。

direct3D 12 HLSL 着色器模型 5.1 功能

着色器模型 5.1