From 96b22fb080894ba1840af2372f28a46cc0f40c76 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Kristensen Date: Wed, 4 Nov 2015 14:58:54 -0800 Subject: glsl: Use array deref for access to vector components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Kristian Høgsberg Kristensen --- src/glsl/ast_array_index.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/glsl/ast_array_index.cpp') diff --git a/src/glsl/ast_array_index.cpp b/src/glsl/ast_array_index.cpp index 74d403fdb65..ca7a9a10c36 100644 --- a/src/glsl/ast_array_index.cpp +++ b/src/glsl/ast_array_index.cpp @@ -319,10 +319,9 @@ _mesa_ast_array_index_to_hir(void *mem_ctx, * expression. */ if (array->type->is_array() - || array->type->is_matrix()) { + || array->type->is_matrix() + || array->type->is_vector()) { return new(mem_ctx) ir_dereference_array(array, idx); - } else if (array->type->is_vector()) { - return new(mem_ctx) ir_expression(ir_binop_vector_extract, array, idx); } else if (array->type->is_error()) { return array; } else { -- cgit v1.2.3