diff options
author | Kristian Høgsberg Kristensen <[email protected]> | 2015-11-04 14:58:54 -0800 |
---|---|---|
committer | Kristian Høgsberg Kristensen <[email protected]> | 2015-11-10 12:02:46 -0800 |
commit | 96b22fb080894ba1840af2372f28a46cc0f40c76 (patch) | |
tree | 197f2454ecfd1778eeea2d81146682ff35fce01e /src/glsl/ir_validate.cpp | |
parent | 60dd5287ff8dbbbe0dbe76bdff6d13c7a5ea9ef0 (diff) |
glsl: Use array deref for access to vector components
We've assumed that we could lower per-component vector access from
vec[i] = scalar
to
vec = ir_triop_vector_insert(vec, scalar, i)
but with SSBOs (and compute shader SLM and tesselation outputs) this is
no longer valid. If a vector is "externally visible", multiple threads
can write independent components simultaneously. With lowering to
ir_triop_vector_insert, each thread read the entire vector, changes one
component, then writes out the entire vector. This is racy.
Instead of generating a ir_binop_vector_extract when we see v[i], we
generate ir_dereference_array. We then add a lowering pass to lower the
ir_dereference_array to ir_binop_vector_extract for rvalues and for to
vector_insert for lvalues in a separate lowering pass.
The resulting IR is the same as before, but we now have a window between
ast->ir conversion and the lowering pass where v[i] appears in the IR as
an array deref. This lets us run lowering passes that lower the vector
access to I/O (eg for SSBO load/store) before we lower the per-component
access to full vector writes.
Reviewed-by: Jordan Justen <[email protected]>
Signed-off-by: Kristian Høgsberg Kristensen <[email protected]>
Diffstat (limited to 'src/glsl/ir_validate.cpp')
-rw-r--r-- | src/glsl/ir_validate.cpp | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp index 935571ae1d6..e63b5c318e3 100644 --- a/src/glsl/ir_validate.cpp +++ b/src/glsl/ir_validate.cpp @@ -110,9 +110,10 @@ ir_validate::visit(ir_dereference_variable *ir) ir_visitor_status ir_validate::visit_enter(class ir_dereference_array *ir) { - if (!ir->array->type->is_array() && !ir->array->type->is_matrix()) { - printf("ir_dereference_array @ %p does not specify an array or a " - "matrix\n", + if (!ir->array->type->is_array() && !ir->array->type->is_matrix() && + !ir->array->type->is_vector()) { + printf("ir_dereference_array @ %p does not specify an array, a vector " + "or a matrix\n", (void *) ir); ir->print(); printf("\n"); |