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 功能

Shader Model 5.1(着色器模型 5.1)