Чи мають значення порядок відчуження та декларування уніформи?


10

У розділі 6.4 Постійні буфери книги Практичне візуалізація та обчислення з Direct3D 11 (стор. 325, 326) згадується:

За замовчуванням компілятор HLSL спробує вирівняти константи таким чином, щоб вони не охоплювали декілька регістрів float4. [...] Упаковка для постійного буфера HLSL також може бути визначена вручну за допомогою ключового слова packoffset.

Я припускаю, що аналогічне правило застосовуватиметься до еквівалента об'єктів буферного буфера OpenGL, оскільки вони відображають однакову апаратну функцію.

А як із ванільною формою? Які правила застосовуються при декларуванні уніформи?

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?

Якщо компілятор може робити такі оптимізації, наскільки вони хороші? Чи можемо ми прямо сказати компілятору упакувати чи ні, і коли ми маємо?

Відповіді:


4

Я пішов шукати відповідь, тому я завантажив шейдерний аналізатор AMD, щоб переглянути збірку, вироблену під час компіляції для GCN. На зборі нижче векторних регістрів знаходяться v #, а скалярні регістри - s #.

Здається, що уніформи навіть векторні форми передаються в шейдер як окремі скаляри, тому vec3 використовує 3 скалярні регістри. Біт, який я знайшов заплутаним, був v0 до v4, я не впевнений, чи v0 - це повний реєстр 4 поплавця або один поплавок у регістрі, з повним векторним регістром, що охоплює v0 до v3. Так чи інакше, схоже, це не змінювалося між двома версіями, тому я можу припустити, що порядок визначення не вплинув на збірку.

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

2
Порядок визначення вплинув на макет. Відповідна частина тут - s_buffer_load_dwordінструкції - вони читають вхідну форму, а останнє число в шістнадцятковій частині - це зміщення, яке слід прочитати. Він показує, що в першому випадку xyвстановлено зсув 0 і zwзсув 16. У другому випадку ви маєте xyзсув 0, zзсув 16 та zwзсув 32. Здається, всі уніформи індивідуально вирівнюються в 16 байтах, а не упаковуються. разом або упорядковано.
Натан Рід
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.