glsl: Use array deref for access to vector components
authorKristian Høgsberg Kristensen <krh@bitplanet.net>
Wed, 4 Nov 2015 22:58:54 +0000 (14:58 -0800)
committerKristian Høgsberg Kristensen <krh@bitplanet.net>
Tue, 10 Nov 2015 20:02:46 +0000 (12:02 -0800)
commit96b22fb080894ba1840af2372f28a46cc0f40c76
tree197f2454ecfd1778eeea2d81146682ff35fce01e
parent60dd5287ff8dbbbe0dbe76bdff6d13c7a5ea9ef0
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 <jordan.l.justen@intel.com>
Signed-off-by: Kristian Høgsberg Kristensen <krh@bitplanet.net>
src/glsl/Makefile.sources
src/glsl/ast_array_index.cpp
src/glsl/ast_function.cpp
src/glsl/ast_to_hir.cpp
src/glsl/ir_optimization.h
src/glsl/ir_validate.cpp
src/glsl/linker.cpp
src/glsl/lower_ubo_reference.cpp
src/glsl/lower_vector_derefs.cpp [new file with mode: 0644]
src/glsl/opt_dead_code_local.cpp