diff options
author | Kenneth Graunke <[email protected]> | 2015-03-05 23:18:36 -0800 |
---|---|---|
committer | Emil Velikov <[email protected]> | 2015-03-11 18:11:56 +0000 |
commit | cddbb3a7ba632e525b5c5a57c39e78b1a926c70f (patch) | |
tree | a592990c8b2679387c34b7d3a558d319a82136d6 /src | |
parent | e4d3bd685540e59cd7fe722ad6bd3a2c32f277ec (diff) |
glsl: Mark array access when copying to a temporary for the ?: operator.
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 <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
Cc: [email protected]
(cherry picked from commit 9f1e250e77ebd9255bbd9a83bd68c9e4068c2aab)
Diffstat (limited to 'src')
-rw-r--r-- | src/glsl/ast_to_hir.cpp | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index ed0eb0982dd..1dcb9244104 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1603,6 +1603,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); |