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


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.