默认情况下,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?
如果编译器可以进行此类优化,它们的效果如何?我们可以明确地告诉编译器是否打包,什么时候应该打包?
#1 楼
我一直在寻找答案,所以我下载了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
评论
$ \ begingroup $
定义顺序确实影响了布局。此处的相关部分是s_buffer_load_dword指令-那些正在读取输入制服,而十六进制的最后一个数字是要读取的偏移量。在第一种情况下,它显示xy在偏移量0处,而zw在偏移量16处。在第二种情况下,您在偏移量0处具有xy,在偏移量16处具有zy,在偏移量32处具有zw。看来所有统一都是16字节的对齐,没有包装在一起或重新排序。
$ \ endgroup $
–内森·里德(Nathan Reed)
2015年10月6日17:27