В разделе 6.4 Буферы констант книги Практический рендеринг и вычисления с Direct3D 11 (страницы 325, 326) упоминается:
По умолчанию компилятор HLSL пытается выровнять константы так, чтобы они не охватывали несколько регистров float4. [...] Упаковка для постоянного буфера HLSL также может быть указана вручную через ключевое слово packoffset.
Я предполагаю, что подобное правило будет применяться к эквивалентным OpenGL объектам Uniform Buffer, поскольку они отображаются на одну и ту же аппаратную функцию.
А как насчет ванильной формы? Какие правила применяются при объявлении униформы?
uniform vec2 xy; // Can we expect the compiler to pack xy
uniform vec2 zw; // into a same four component register?
uniform vec2 rg;
uniform float foo; // Will this prevent from packing rg and ba?
uniform vec2 ba; // If so, will foo eat up a full four components register?
Если компилятор может делать такие оптимизации, насколько они хороши? Можем ли мы явно указать компилятору упаковывать или нет, и когда мы должны?
s_buffer_load_dword
инструкции - они читают входную форму, а последнее число в шестнадцатеричном формате - это смещение, с которого нужно читать. Это показывает, что в первом случаеxy
это смещение 0 иzw
смещение 16. Во втором случае вы имеетеxy
смещение 0,z
смещение 16 иzw
смещение 32. Похоже, что все формы по отдельности выровнены по 16 байтов и не упакованы. вместе или переупорядочены.