유니폼의 정렬 및 선언 순서가 중요합니까?


10

Direct3D 11을 사용한 실용 렌더링 및 컴퓨팅 (325, 326 페이지) 책의 6.4 상수 버퍼 섹션에 다음이 언급되어 있습니다.

기본적으로 HLSL 컴파일러는 여러 float4 레지스터에 걸쳐 있지 않도록 상수를 정렬하려고 시도합니다. [...] packoffset 키워드를 통해 HLSL 상수 버퍼의 패킹을 수동으로 지정할 수도 있습니다.

비슷한 규칙이 OpenGL과 동등한 Uniform Buffer Objects에 적용된다고 가정합니다. 동일한 하드웨어 기능에 매핑되기 때문입니다.

바닐라 유니폼은 어떻습니까? 유니폼을 신고 할 때 적용되는 규칙은 무엇입니까?

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

나는 답을 찾고 GCN 용으로 컴파일 할 때 생성 된 어셈블리를보기 위해 AMD의 쉐이더 분석기를 다운로드했다. 아래 어셈블리에서 벡터 레지스터는 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지침입니다-입력 유니폼을 읽는 중이며 16 진수의 마지막 숫자는 읽을 오프셋입니다. 첫 번째 경우 xy에는 오프셋 0과 zw오프셋 16에 표시됩니다. 두 번째 경우에는 xy오프셋 0, z오프셋 16 및 zw오프셋 32에 있습니다. 모든 유니폼은 개별적으로 16 바이트로 정렬되고 압축되지 않은 것으로 나타납니다. 함께 또는 재정렬.
Nathan Reed
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.