Ist die Ausrichtung und Deklaration der Uniformen von Bedeutung?

10

In Abschnitt 6.4 Konstante Puffer des Buches Praktisches Rendern und Rechnen mit Direct3D 11 (Seiten 325, 326) wird Folgendes erwähnt:

Standardmäßig versucht der HLSL-Compiler, Konstanten so auszurichten, dass sie nicht mehrere float4-Register umfassen. [...] Das Packen für einen HLSL-Konstantenpuffer kann auch manuell über das Schlüsselwort packoffset angegeben werden.

Ich gehe davon aus, dass eine ähnliche Regel für das OpenGL-Äquivalent Uniform Buffer Objects gilt, da sie derselben Hardwarefunktion zugeordnet sind.

Was ist mit Vanilleuniformen? Welche Regeln gelten für die Erklärung von Uniformen?

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?

Wenn der Compiler solche Optimierungen durchführen kann, wie gut sind sie? Können wir den Compiler explizit anweisen, zu packen oder nicht, und wann sollten wir?

Julien Guertault
quelle

Antworten:

4

Ich suchte nach einer Antwort und lud den Shader-Analysator von AMD herunter, um die Baugruppe anzuzeigen, die beim Kompilieren für GCN erstellt wurde. In der folgenden Anordnung sind Vektorregister v # und Skalarregister sind s #.

Es scheint, dass die Uniformen sogar Vektoruniformen als separate Skalare an den Shader übergeben werden, so dass ein vec3 3 Skalarregister verwenden würde. Das Bit, das ich verwirrend fand, war v0 bis v4. Ich bin mir nicht sicher, ob v0 ein vollständiges 4-Float-Register oder ein einzelnes Float in einem Register ist, wobei ein vollständiges Vektorregister von v0 bis v3 reicht. Auf die eine oder andere Weise schien sich zwischen den beiden Versionen nichts zu ändern, sodass ich davon ausgehen kann, dass die Definitionsreihenfolge keinen Einfluss auf die Assembly hatte.

http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/07/AMD_GCN3_Instruction_Set_Architecture.pdf

#version 450

uniform vec2 xy; 
uniform vec2 zw;

out vec4 v;

void main(){ 
    v.xy = xy; 
    v.zw = zw; 
}

shader 
  asic(VI)
  type(VS)

  v_cndmask_b32  v0, s0, v0, vcc               
  v_mov_b32     v0, 0                          
  v_mov_b32     v1, 1.0                        
  exp           pos0, v0, v0, v0, v1 done      
  s_andn2_b32   s0, s5, 0x3fff0000             
  s_mov_b32     s1, s0                         
  s_mov_b32     s2, s6                         
  s_mov_b32     s3, s7                         
  s_mov_b32     s0, s4                         
  s_buffer_load_dwordx2  s[4:5], s[0:3], 0x00  
  s_buffer_load_dwordx2  s[0:1], s[0:3], 0x10  
  s_waitcnt     expcnt(0) & lgkmcnt(0)         
  v_mov_b32     v0, s4                         
  v_mov_b32     v1, s5                         
  v_mov_b32     v2, s0                         
  v_mov_b32     v3, s1                         
  exp           param0, v0, v1, v2, v3         
end

#version 450

uniform vec2 xy;
uniform float z;
uniform vec2 zw;

out vec4 v;

void main(){ 
    v.xy = xy; 
    v.zw = zw;
    v.w += z;
}

shader 
  asic(VI)
  type(VS)

  v_cndmask_b32  v0, s0, v0, vcc              
  v_mov_b32     v0, 0                         
  v_mov_b32     v1, 1.0                       
  s_andn2_b32   s0, s5, 0x3fff0000            
  exp           pos0, v0, v0, v0, v1 done     
  s_mov_b32     s1, s0                        
  s_mov_b32     s2, s6                        
  s_mov_b32     s3, s7                        
  s_mov_b32     s0, s4                        
  s_buffer_load_dword  s4, s[0:3], 0x10       
  s_buffer_load_dwordx2  s[6:7], s[0:3], 0x00 
  s_buffer_load_dwordx2  s[0:1], s[0:3], 0x20 
  s_waitcnt     expcnt(0) & lgkmcnt(0)        
  v_mov_b32     v0, s4                        
  v_add_f32     v0, s1, v0                    
  v_mov_b32     v1, s6                        
  v_mov_b32     v2, s7                        
  v_mov_b32     v3, s0                        
  exp           param0, v1, v2, v3, v0        
end
Joshua Waring
quelle
2
Die Definitionsreihenfolge hatte Auswirkungen auf das Layout. Der relevante Teil hier sind die s_buffer_load_dwordAnweisungen - diese lesen die Eingabeuniformen, und die letzte Zahl in hexadezimal ist der Versatz, aus dem gelesen werden soll. Es zeigt im ersten Fall xybei Offset 0 und zwbei Offset 16. Im zweiten Fall haben Sie xybei Offset 0, zbei Offset 16 und zwbei Offset 32. Es scheint, dass alle Uniformen einzeln 16-Byte-ausgerichtet und nicht gepackt sind zusammen oder neu bestellt.
Nathan Reed