glsl: fix packing of 64-bits types
This commits fixes packing of 64-bits types by changing glsl's component_slots() method.
Using piglit test vs-out-fs-in-S1-vec3-i64vec3.shader_test as an example:
struct S1 {
vec3 fv1;
i64vec3 iv1;
};
With this structure, num_components returns (3 + 6) = 9 floats.
Then varying_matches::assign_locations fills the component array like this: components[] = { 4, 4, 1}
Later, lower_packed_varyings_visitor::lower_rvalue() is called with fine_location = 128
.
So:
-
fv1
getslocation=32
and returnsfine_location=131
-
iv1
is going to be "double parked", but it can't fit in the remaining float, sofine_location
is incremented to 132, and we recurse -
iv1.xyz.xy
gets location 33 andfine_location
becomes 136 - finally
iv1.xyz.z
gets location 34
The problem is iv1.xyz.z
needs 2 floats because it's 64-bits, but components[2] is only 1.
So this generates an invalid IR where we assign (xy) to a int variable.
IR code:
(declare (location=32 shader_out flat) ivec4 packed:s1_1.fv1)
(declare (location=33 shader_out flat) ivec4 packed:s1_1.iv1.xyz.xy)
(declare (location=34 shader_out flat) int packed:s1_1.iv1.xyz.z)
`-> this is the main issue
[...]
(assign (xyz) (var_ref packed:s1_1.fv1) (swiz xyz (swiz xyzx (expression ivec3 bitcast_f2i (record_ref (var_ref s1_1) fv1) ) )))
(assign (xy) (var_ref pack) (expression ivec2 unpackInt2x32 (swiz x (swiz xy (swiz xyz (record_ref (var_ref s1_1) iv1) )))) )
(assign (zw) (var_ref pack) (expression ivec2 unpackInt2x32 (swiz y (swiz xy (swiz xyz (record_ref (var_ref s1_1) iv1) )))) )
(assign (xyzw) (var_ref packed:s1_1.iv1.xyz.xy) (swiz xyzw (swiz xyzw (var_ref pack) )))
(assign (xy) (var_ref packed:s1_1.iv1.xyz.z) (swiz xy (swiz x (expression ivec2 unpackInt2x32 (swiz z (swiz xyz (record_ref (var_ref s1_1) iv1) ))) )))
`-> this isn't correct: xyz.z is an int
This fixes 105 spec@arb_gpu_shader_int64@execution piglit tests and 58 spec@glsl-4.00@execution@inout piglit tests on radeonsi and doesn't regress any others.