diff options
Diffstat (limited to 'src/glsl/lower_ubo_reference.cpp')
-rw-r--r-- | src/glsl/lower_ubo_reference.cpp | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/src/glsl/lower_ubo_reference.cpp b/src/glsl/lower_ubo_reference.cpp index 24806ac..b74aa3d 100644 --- a/src/glsl/lower_ubo_reference.cpp +++ b/src/glsl/lower_ubo_reference.cpp @@ -390,7 +390,19 @@ lower_ubo_reference_visitor::setup_for_load_or_store(ir_variable *var, case ir_type_dereference_array: { ir_dereference_array *deref_array = (ir_dereference_array *) deref; unsigned array_stride; - if (deref_array->array->type->is_matrix() && *row_major) { + if (deref_array->array->type->is_vector()) { + /* We get this when storing or loading a component out of a vector + * with a non-constant index. This happens for v[i] = f where v is + * a vector (or m[i][j] = f where m is a matrix). If we don't + * lower that here, it gets turned into v = vector_insert(v, i, + * f), which loads the entire vector, modifies one component and + * then write the entire thing back. That breaks if another + * thread or SIMD channel is modifying the same vector. + */ + array_stride = 4; + if (deref_array->array->type->is_double()) + array_stride *= 2; + } else if (deref_array->array->type->is_matrix() && *row_major) { /* When loading a vector out of a row major matrix, the * step between the columns (vectors) is the size of a * float, while the step between the rows (elements of a |