glsl: fix the type of ir_constant_data::u16
[mesa.git] / src / compiler / glsl / lower_vector_derefs.cpp
index 2aae30d8201101d2c4afcf6ce4a632aad3eda02a..0c09630fa0301b3f9f8949a37b92a91bf35767d3 100644 (file)
@@ -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,