Sự sắp xếp và thứ tự khai báo của đồng phục có vấn đề?


10

Trong phần 6.4 Bộ đệm liên tục của cuốn sách Kết xuất và tính toán thực tế với Direct3D 11 (trang 325, 326), nó được đề cập:

Theo mặc định, trình biên dịch HLSL sẽ cố gắng căn chỉnh các hằng số sao cho chúng không mở rộng nhiều thanh ghi float4. [...] Việc đóng gói cho bộ đệm không đổi HLSL cũng có thể được chỉ định thủ công thông qua từ khóa packoffset.

Tôi giả sử một quy tắc tương tự sẽ áp dụng cho các Đối tượng bộ đệm đồng nhất, tương đương OpenGL, vì chúng ánh xạ tới cùng một tính năng phần cứng.

Thế còn đồng phục vani thì sao? Các quy tắc áp dụng khi khai báo đồng phục là gì?

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?

Nếu trình biên dịch có thể thực hiện tối ưu hóa như vậy, thì chúng tốt như thế nào? Chúng ta có thể nói rõ ràng trình biên dịch sẽ đóng gói hay không, và khi nào chúng ta nên?

Câu trả lời:


4

Tôi đã đi tìm câu trả lời, vì vậy tôi đã tải xuống bộ phân tích đổ bóng của AMD để xem bản lắp ráp được sản xuất khi được biên dịch cho GCN. Trong tập hợp bên dưới các thanh ghi vector là v # và các thanh ghi vô hướng là s #.

Dường như các đồng phục thậm chí đồng phục vector được truyền vào shader dưới dạng các vô hướng riêng biệt, vì vậy một vec3 sẽ sử dụng 3 thanh ghi vô hướng. Bit tôi thấy khó hiểu là v0 đến v4, tôi không chắc là v0 là một thanh ghi float 4 đầy đủ hay một float duy nhất trong một thanh ghi, với một thanh ghi vector đầy đủ kéo dài từ v0 đến v3. Bằng cách này hay cách khác, nó dường như không thay đổi giữa hai phiên bản vì vậy tôi có thể cho rằng thứ tự định nghĩa không ảnh hưởng đến việc lắp ráp.

http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/07/AMD_GCN3_Inocate_Set_Arch 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
Thứ tự định nghĩa đã ảnh hưởng đến bố cục. Phần có liên quan ở đây là các s_buffer_load_dwordhướng dẫn - những người đang đọc đồng phục đầu vào và số cuối cùng trong hex là phần bù để đọc từ đó. Nó hiển thị trong trường hợp đầu tiên xylà ở offset 0 và zwở offset 16. Trong trường hợp thứ hai, bạn có xyở offset 0, zở offset 16 và zwở offset 32. Nó xuất hiện tất cả các đồng phục được căn chỉnh 16 byte riêng lẻ và không được đóng gói cùng nhau hoặc sắp xếp lại.
Nathan Reed
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.