Üniformaların hizalanması ve beyan düzeni önemli midir?


10

6.4 Direct3D 11 ile Pratik Oluşturma ve Hesaplama (Sayfa 325, 326) kitabının 6.4 Sabit Tamponları bölümünde belirtilmiştir:

Varsayılan olarak, HLSL derleyicisi sabitleri birden çok float4 kaydına yayılmayacak şekilde hizalamaya çalışır. [...] Bir HLSL sabit tamponu için paketleme ayrıca packoffset anahtar sözcüğü aracılığıyla manuel olarak belirtilebilir.

Benzer bir kuralın aynı donanım özelliğiyle eşleştiği için OpenGL eşdeğeri, Tekdüzen Tampon Nesneleri için geçerli olacağını varsayıyorum.

Peki ya vanilya üniformaları? Üniforma ilan ederken geçerli olan kurallar nelerdir?

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?

Derleyici bu tür optimizasyonlar yapabilirse, ne kadar iyidir? Derleyiciye paketlenip paketlenmeyeceğini açıkça söyleyebilir miyiz ve ne zaman yapmalıyız?

Yanıtlar:


4

Bir cevap aramaya gittim, bu yüzden GCN için derlendiğinde üretilen montajı görüntülemek için AMD'nin gölgelendirici analizcisini indirdim. Aşağıdaki montajda vektör kayıtları v # ve skaler kayıtları s # 'dır.

Üniformalar vektör üniformaları bile gölgelendiriciye ayrı skaler olarak geçirilir gibi görünmektedir, bu nedenle bir vec3 3 skaler kayıt kullanacaktır. Kafa karıştırıcı buldum bit v0 v4 oldu, v0 tam bir 4 float kayıt veya bir kayıtta tek bir float olup olmadığını emin değilim, v0 to v3 kapsayan bir tam vektör kayıt. Öyle ya da böyle iki versiyon arasında değişmediği için tanım sırasının montajı etkilemediğini varsayabilirim.

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
Tanım sırası düzeni etkiledi. Buradaki ilgili bölüm s_buffer_load_dwordtalimatlardır - giriş üniformalarını okuyorlar ve onaltılık son sayı okunacak ofset. İlk durumda xy0 ofsetinde ve zw16 ofsetinde gösterilir. İkinci durumda xyofset 0'da, zofset 16'da ve zwofset 32'de görünür. Tüm üniformalar ayrı ayrı 16 bayt hizalıdır ve paketlenmemiş gibi görünür. birlikte veya yeniden sıralanmıştır.
Nathan Reed
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.