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에서 인덱싱은 선언에 대한 연결을 난독 처리했기 때문에 리소스 인덱싱 리소스를 인덱싱하려면 확장된 opcode 토큰에서 리소스 특성을 설명해야 했습니다. SM5.1에서 각 ID(예: 't1')는 필요한 리소스 정보를 설명하는 단일 선언과 명확하게 연결됩니다. 따라서 리소스 정보를 설명하는 지침에 사용되는 확장된 opcode 토큰은 더 이상 내보내지지 않습니다.
선언이 아닌 명령에서 샘플러, SRV 및 UAV에 대한 리소스 피연산자는 2D 피연산자입니다. 첫 번째 인덱스는 범위 ID를 지정하는 리터럴 상수입니다. 두 번째 인덱스는 인덱스의 선형화된 값을 나타냅니다. 값은 루트 서명과 더 잘 상관 관계를 지정하고 인덱스 조정의 드라이버 컴파일러 부담을 줄이기 위해 해당 레지스터 공간의 시작 부분(논리 범위의 시작 부분을 기준으로 하지 않음)을 기준으로 계산됩니다.
CBV에 대한 리소스 피연산자는 3D 피연산자입니다. 범위의 리터럴 ID, cbuffer의 인덱스, cbuffer의 특정 인스턴스로 오프셋됩니다.
관련 항목
-
Direct3D 12용 HLSL 셰이더 모델 5.1 기능