Na seção 6.4 Buffers Constantes do livro Renderização e Computação Prática com Direct3D 11 (páginas 325, 326), é mencionado:
Por padrão, o compilador HLSL tentará alinhar constantes para que não abranjam vários registros float4. [...] A compactação para um buffer constante HLSL também pode ser especificada manualmente através da palavra-chave packoffset.
Suponho que uma regra semelhante se aplique ao equivalente ao OpenGL, Objetos de Buffer Uniformes, pois eles mapeiam para o mesmo recurso de hardware.
Mas e uniformes de baunilha? Quais são as regras que se aplicam ao declarar uniformes?
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?
Se o compilador pode fazer essas otimizações, quão boas elas são? Podemos dizer explicitamente ao compilador para empacotar ou não e quando deveríamos?
s_buffer_load_dword
instruções - elas estão lendo os uniformes de entrada e o último número em hexadecimal é o deslocamento para leitura. Isso mostra que, no primeiro caso,xy
está no deslocamento 0 ezw
no deslocamento 16. No segundo caso, você temxy
no deslocamento 0,z
no deslocamento 16 ezw
no deslocamento 32. Parece que todos os uniformes são individualmente alinhados por 16 bytes e não empacotados juntos ou reordenados.