Изменения байт-кода в 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
Каждый диапазон ресурсов шейдера теперь имеет идентификатор (имя) в байт-коде шейдера. Например, массив текстур tex1 становится "t1" в коде байтов шейдера. Предоставление уникальных идентификаторов каждому диапазону ресурсов позволяет выполнять две задачи:
- Однозначно определите, какой диапазон ресурсов (см. dcl_resource_texture2d) индексируется в инструкции (см. пример инструкции).
- Прикрепите к объявлению набор атрибутов, например тип элемента, размер шага, режим работы растра и т. д.
Обратите внимание, что идентификатор диапазона не связан с объявлением нижней границы HLSL.
Порядок привязок ресурсов отражения и инструкций по объявлению шейдера одинаков, чтобы помочь определить соответствие между переменными HLSL и идентификаторами байт-кода.
Каждая инструкция объявления в SM5.1 использует трехмерный операнд для определения идентификатора диапазона, нижней и верхней границ. Для указания регистрового пространства создается дополнительный маркер. Для передачи дополнительных свойств диапазона также могут быть выданы другие маркеры, например cbuffer или инструкция объявления структурированного буфера выдает размер cbuffer или структуры. Точные сведения о кодировке можно найти в d3d12TokenizedProgramFormat.h и D3D10ShaderBinary::CShaderCodeParser.
Инструкции SM5.1 не будут выдавать дополнительные сведения об операнде ресурсов в рамках инструкции (как в SM5.0). Теперь эти сведения перемещаются в инструкции по объявлению. В SM5.0 инструкции индексирования ресурсов требовали, чтобы атрибуты ресурсов описывались в расширенных маркерах кода операций, так как индексирование маскировало связь с объявлением. В SM5.1 каждый идентификатор (например, t1) однозначно связан с одним объявлением, описывающим необходимые сведения о ресурсе. Таким образом, маркеры расширенного кода операций, используемые в инструкциях для описания сведений о ресурсах, больше не создаются.
В инструкциях, не являющихся объявлениями, операнд ресурсов для образцов, SRV и БПЛА является двухмерным операндом. Первый индекс является литеральной константой, указывающей идентификатор диапазона. Второй индекс представляет линейное значение индекса. Значение вычисляется относительно начала соответствующего регистрового пространства (не относительно начала логического диапазона), чтобы лучше соотносить с корневой сигнатурой и уменьшить нагрузку компилятора драйвера при настройке индекса.
Операнд ресурсов для CBV — это трехмерный операнд: литеральный идентификатор диапазона, индекс cbuffer, смещение в конкретный экземпляр cbuffer.
Связанные темы