我一直在寻找答案,所以我下载了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
s_buffer_load_dword
指令-那些正在读取输入的制服,十六进制的最后一个数字是要读取的偏移量。在第一种情况下,它显示xy
为偏移量0,zw
在偏移量16处。在第二种情况下xy
,偏移量为0,z
偏移量为16,zw
偏移量为32。似乎所有制服都分别按16字节对齐,并且未打包一起或重新排序。