Поделиться через


Изменения байт-кода в 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.

Функции шейдера HLSL Model 5.1 для Direct3D 12

Модель шейдера 5.1