glsl: Mark array access when copying to a temporary for the ?: operator.
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 6 Mar 2015 07:18:36 +0000 (23:18 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 9 Mar 2015 03:03:36 +0000 (20:03 -0700)
Piglit's spec/glsl-1.20/compiler/structure-and-array-operations/
array-selection.vert test contains the following code:

   gl_Position = (pick_from_a_or_b ? a : b)[i];

where "a" and "b" are uniform vec4[2] variables.

ast_to_hir creates a temporary vec4[2] variable, conditional_tmp, and
generates an if-block to copy one or the other:

   (declare (temporary) (array vec4 2) conditional_tmp)
   (if (var_ref pick_from_a_or_b)
     ((assign () (var_ref conditional_tmp) (var_ref a)))
     ((assign () (var_ref conditional_tmp) (var_ref b))))

However, we failed to update max_array_access for "a" and "b", so it
remained 0 - here, the whole array is being accessed.  At link time,
update_array_sizes() used this bogus information to change the types
of "a" and "b" to vec4[1].  We then had assignments from a vec4[1] to
a vec4[2], which is highly illegal.

This tripped assertions in nir_split_var_copies with scalar VS.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
Cc: mesa-stable@lists.freedesktop.org
src/glsl/ast_to_hir.cpp

index acb5c763c43c0cab7fb9aa0f7f24ed3bfe9f546f..d387b2e3565e2e4e0d8206b7b81716fc9ad10235 100644 (file)
@@ -1617,6 +1617,12 @@ ast_expression::do_hir(exec_list *instructions,
           && cond_val != NULL) {
          result = cond_val->value.b[0] ? op[1] : op[2];
       } else {
+         /* The copy to conditional_tmp reads the whole array. */
+         if (type->is_array()) {
+            mark_whole_array_access(op[1]);
+            mark_whole_array_access(op[2]);
+         }
+
          ir_variable *const tmp =
             new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary);
          instructions->push_tail(tmp);