aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2019-03-11 14:53:31 -0500
committerJason Ekstrand <[email protected]>2019-03-15 01:02:19 +0000
commit8f3ab8aa7824a2f306b542a50b304675ce8f7e1a (patch)
tree6359d7c4878da83e4f7e7105e72ba5d13737f644 /src
parent3c11fc76543f381ce8ebb315def510978ef274a7 (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.cpp21
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,