Skip to content

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 gets location=32 and returns fine_location=131
  • iv1 is going to be "double parked", but it can't fit in the remaining float, so fine_location is incremented to 132, and we recurse
  • iv1.xyz.xy gets location 33 and fine_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.

Merge request reports