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>
This commit is contained in:
@@ -197,6 +197,11 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments)
|
||||
if (entry->lhs != var)
|
||||
continue;
|
||||
|
||||
/* Skip if the assignment we're trying to eliminate isn't a plain
|
||||
* variable deref. */
|
||||
if (entry->ir->lhs->ir_type != ir_type_dereference_variable)
|
||||
continue;
|
||||
|
||||
int remove = entry->unused & ir->write_mask;
|
||||
if (debug) {
|
||||
printf("%s 0x%01x - 0x%01x = 0x%01x\n",
|
||||
|
||||
Reference in New Issue
Block a user