glsl: Make lower_constant_arrays_to_uniforms require dereferences.
authorKenneth Graunke <kenneth@whitecape.org>
Sat, 22 Nov 2014 22:14:05 +0000 (14:14 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 24 Nov 2014 23:30:09 +0000 (15:30 -0800)
Ilia noticed that my lowering pass was converting the constant array
used by textureGatherOffsets' offsets parameter to a uniform.  This
broke textureGather for Nouveau, and is generally a horrible plan,
since it violates the GLSL constraint that offsets must be an
immediate constant.

When I wrote this pass, I neglected to consider whole array assignment.
I figured opt_array_splitting would handle constant indexing, so this
pass was really about fixing variable indexing.

textureGatherOffsets is an example of whole array access that we really
don't want to touch.  Whole array copies don't appear to benefit from
this either - they're most likely initializers for temporary arrays
which are going to be mutated anyway.  Since you're copying, you may
as well copy from immediates, not uniforms.

This patch makes the pass look for ir_dereference_arrays of
ir_constants, rather than looking for any ir_constant directly.
This way, it ignores whole array assignment.

No shader-db changes or Piglit regressions on Haswell.  Some Piglit
tests generate different code (fixing textureGatherOffsets on Nouveau).

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Tested-by: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Cc: "10.4" <mesa-stable@lists.freedesktop.org>
src/glsl/lower_const_arrays_to_uniforms.cpp

index 700e9039f74d869b7afc7bc24b6619e499773d45..2243f479a119a5e9f57d9c6758c7825271ed4c30 100644 (file)
@@ -72,7 +72,11 @@ lower_const_array_visitor::handle_rvalue(ir_rvalue **rvalue)
    if (!*rvalue)
       return;
 
-   ir_constant *con = (*rvalue)->as_constant();
+   ir_dereference_array *dra = (*rvalue)->as_dereference_array();
+   if (!dra)
+      return;
+
+   ir_constant *con = dra->array->as_constant();
    if (!con || !con->type->is_array())
       return;
 
@@ -91,7 +95,8 @@ lower_const_array_visitor::handle_rvalue(ir_rvalue **rvalue)
    uni->data.max_array_access = uni->type->length - 1;
    instructions->push_head(uni);
 
-   *rvalue = new(mem_ctx) ir_dereference_variable(uni);
+   ir_dereference_variable *varref = new(mem_ctx) ir_dereference_variable(uni);
+   *rvalue = new(mem_ctx) ir_dereference_array(varref, dra->array_index);
 
    progress = true;
 }