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、下限値、上限値を定義します。 レジスタ空間を指定するために、1 つの追加のトークンが出力されます。 範囲の追加のプロパティを伝達するために他のトークンが出力される場合もあります。たとえば、cbuffer または構造化バッファー宣言命令は、cbuffer または構造体のサイズを出力します。 エンコードの詳細は、d3d12TokenizedProgramFormat.h および D3D10ShaderBinary::CShaderCodeParser で確認できます。
SM5.1 命令では、(SM5.0 の場合のように) 命令の一部として追加のリソース オペランド情報を出力しません。 この情報は、宣言命令に移動されました。 SM5.0 では、インデックスの作成により宣言との関連付けがわかりにくくなったため、リソースにインデックスを作成する命令では、拡張オペコード トークンにリソースの属性を記述する必要がありました。 SM5.1 では、各 ID ('t1' など) は、必要なリソース情報を記述する 1 つの宣言に明確に関連付けられています。 したがって、リソース情報を記述するための命令で使用されていた拡張オペコード トークンは出力されなくなりました。
宣言以外の命令では、サンプラー、SRV、および UAV のリソース オペランドは 2D オペランドです。 最初のインデックスは、範囲 ID を指定するリテラル定数です。 2 番目のインデックスは、インデックスの線形化された値を表します。 この値は、ルート署名との相関性を高め、インデックスを調整するドライバー コンパイラの負担を軽減するために、(論理的な範囲の先頭ではなく) 対応するレジスタ空間の先頭を基準に計算されます。
CBV のリソース オペランドは、3D オペランドです。範囲のリテラル ID、cbuffer のインデックス、cbuffer の特定のインスタンスへのオフセット。
関連トピック