diff options
author | Jason Ekstrand <[email protected]> | 2019-03-11 14:53:31 -0500 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2019-03-15 01:02:19 +0000 |
commit | 8f3ab8aa7824a2f306b542a50b304675ce8f7e1a (patch) | |
tree | 6359d7c4878da83e4f7e7105e72ba5d13737f644 /src | |
parent | 3c11fc76543f381ce8ebb315def510978ef274a7 (diff) |
glsl: Don't lower vector derefs for SSBOs, UBOs, and shared
All of these are backed by some sort of memory so if you have multiple
threads writing to different components of the same vector at the same
time, the load-vec-store pattern that GLSL IR emits won't work. This
shouldn't affect any drivers today as they all call GLSL IR lowering
which lowers access to these variables to index+offset intrinsics before
we get to this point. However, NIR will start handling the derefs
itself and won't want the lowering.
Reviewed-by: Caio Marcelo de Oliveira Filho <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/glsl/lower_vector_derefs.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/compiler/glsl/lower_vector_derefs.cpp b/src/compiler/glsl/lower_vector_derefs.cpp index 2aae30d8201..0c09630fa03 100644 --- a/src/compiler/glsl/lower_vector_derefs.cpp +++ b/src/compiler/glsl/lower_vector_derefs.cpp @@ -63,6 +63,16 @@ vector_deref_visitor::visit_enter(ir_assignment *ir) if (!deref->array->type->is_vector()) return ir_rvalue_enter_visitor::visit_enter(ir); + /* SSBOs and shared variables are backed by memory and may be accessed by + * multiple threads simultaneously. It's not safe to lower a single + * component store to a load-vec-store because it may race with writes to + * other components. + */ + ir_variable *var = deref->variable_referenced(); + if (var->data.mode == ir_var_shader_storage || + var->data.mode == ir_var_shader_shared) + return ir_rvalue_enter_visitor::visit_enter(ir); + ir_rvalue *const new_lhs = deref->array; void *mem_ctx = ralloc_parent(ir); @@ -150,6 +160,17 @@ vector_deref_visitor::handle_rvalue(ir_rvalue **rv) if (!deref->array->type->is_vector()) return; + /* Back-ends need to be able to handle derefs on vectors for SSBOs, UBOs, + * and shared variables. They have to handle it for writes anyway so we + * may as well require it for reads. + */ + ir_variable *var = deref->variable_referenced(); + if (var && (var->data.mode == ir_var_shader_storage || + var->data.mode == ir_var_shader_shared || + (var->data.mode == ir_var_uniform && + var->get_interface_type()))) + return; + void *mem_ctx = ralloc_parent(deref); *rv = new(mem_ctx) ir_expression(ir_binop_vector_extract, deref->array, |