HLSL 5.0 float1x3 против постоянного правила упаковки буфера float3x1 - PullRequest
0 голосов
/ 17 ноября 2018

В настоящее время я пытаюсь разобраться с правилами постоянной буферизации в HLSL 5.0 и D3D11.Поэтому я немного поиграл с fxc.exe:

// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.18773
//
//
// Buffer Definitions:
//
// cbuffer testbuffer
// {
//
//   float foo;                         // Offset:    0 Size:     4
//   float3x1 bar;                      // Offset:    4 Size:    12 [unused]
//
// }
//
//
// Resource Bindings:
//
// Name                                 Type  Format         Dim Slot Elements
// ------------------------------ ---------- ------- ----------- ---- --------
// testbuffer                        cbuffer      NA          NA    0        1

Пока что все ведет себя так, как я этого ожидаю.float3x1 имеет размер 12 байтов и поэтому может быть помещен в первый 16-байтовый слот, поскольку переменная before имеет размер 4 байта.После изменения float3x1 на float1x3 вывод компилятора теперь выглядит следующим образом:

// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.18773
//
//
// Buffer Definitions:
//
// cbuffer testbuffer
// {
//
//   float foo;                         // Offset:    0 Size:     4
//   float1x3 bar;                      // Offset:   16 Size:    36 [unused]
//
// }
//
//
// Resource Bindings:
//
// Name                                 Type  Format         Dim Slot Elements
// ------------------------------ ---------- ------- ----------- ---- --------
// testbuffer                        cbuffer      NA          NA    0        1

Таким образом, кажется, что компилятор HLSL внезапно дает каждому float в float1x3 свой собственный 16-байтовый слот, которыйдовольно расточительно.Я много гуглил, чтобы понять это поведение, но ничего не смог найти.Я надеюсь, что некоторые из вас, ребята, могут объяснить это мне, так как это поведение действительно смущает меня.

1 Ответ

0 голосов
/ 17 ноября 2018

Этот ответ является гипотезой, основанной на моем понимании HLSL, который по умолчанию использует основную матрицу упаковки столбцов. Регистры в HLSL состоят из наборов из четырех 4-байтовых секций, всего 16 байтов на регистр. Каждый регистр действует как одна строка с четырьмя столбцами.

Когда вы объявляете float3x1, вы объявляете матрицу с 3 столбцами и одной строкой. Это хорошо вписывается в метод упаковки регистров HLSL, где одна строка может содержать 16 байтов.

Когда вы объявляете float1x3, вы объявляете матрицу с одним столбцом и тремя строками. Из-за способа, которым HLSL обрабатывает упаковку регистров, он должен распределять данные по 3 наборам регистров и резервировать пространство матрицы 3x3.

Если вам нужна матрица 1xX, лучше вместо этого объявить вектор, который будет автоматически помещаться в один регистр и может использоваться в любой ситуации, может быть матрица 1x3 или 3x1.

...