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 を割り当てると、次の 2 つのことが可能になります。
- 命令でインデックスが作成されているリソース範囲 (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' など) は、必要なリソース情報を記述する 1 つの宣言に明確に関連付けられています。 そのため、リソース情報を記述する命令で使用される拡張オペコード トークンは出力されなくなります。
非宣言命令では、サンプラー、SRV、および UAV のリソース オペランドは 2D オペランドです。 最初のインデックスは、範囲 ID を指定するリテラル定数です。 2 番目のインデックスは、インデックスの線形化された値を表します。 値は、(論理範囲の先頭ではなく) 対応するレジスタ領域の先頭を基準にして計算され、ルート署名との相関関係が向上し、インデックスを調整するドライバー コンパイラの負担が軽減されます。
CBV のリソース オペランドは、範囲のリテラル ID、cbuffer のインデックス、cbuffer の特定のインスタンスへのオフセットという 3D オペランドです。
関連トピック
-
Direct3D 12 の HLSL シェーダー モデル 5.1 機能の