[Mesa-stable] [PATCH v2] glsl: fix array assignments of a swizzled vector

Ilia Mirkin imirkin at alum.mit.edu
Sat Oct 6 05:23:53 UTC 2018


This happens in situations where we might do

  vec.wzyx[i] = ...

The swizzle would get effectively ignored because of the interaction
between how ir_assignment->set_lhs works and overwriting the write_mask.
There are two cases, one where i is a constant, and another where i is
variable. We have to be extra-careful in both cases.

Fixes the following WebGL test:

  https://www.khronos.org/registry/webgl/sdk/tests/conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html

And the new piglit tests:

  swizzled-writemask-indexing-nonconst.shader_test
  swizzled-writemask-indexing.shader_test

Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
Cc: mesa-stable at lists.freedesktop.org
---

v1 -> v2:
 - include info about piglit tests
 - add a fix for the nonconst case -- doing set_lhs last instead of
   first.

Ian Romanick reviewed v1, but given the subtlety of the additional
change for v2, going to leave that off, prefering another review.

No regressions running this through Intel CI.

 src/compiler/glsl/lower_vector_derefs.cpp | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/compiler/glsl/lower_vector_derefs.cpp b/src/compiler/glsl/lower_vector_derefs.cpp
index 7583d1fdd3e..223e420550b 100644
--- a/src/compiler/glsl/lower_vector_derefs.cpp
+++ b/src/compiler/glsl/lower_vector_derefs.cpp
@@ -59,8 +59,7 @@ vector_deref_visitor::visit_enter(ir_assignment *ir)
    if (!deref->array->type->is_vector())
       return ir_rvalue_enter_visitor::visit_enter(ir);
 
-   ir_dereference *const new_lhs = (ir_dereference *) deref->array;
-   ir->set_lhs(new_lhs);
+   ir_rvalue *const new_lhs = deref->array;
 
    void *mem_ctx = ralloc_parent(ir);
    ir_constant *old_index_constant =
@@ -72,8 +71,15 @@ vector_deref_visitor::visit_enter(ir_assignment *ir)
                                            ir->rhs,
                                            deref->array_index);
       ir->write_mask = (1 << new_lhs->type->vector_elements) - 1;
+      ir->set_lhs(new_lhs);
+   } else if (new_lhs->ir_type != ir_type_swizzle) {
+      ir->set_lhs(new_lhs);
+      ir->write_mask = 1 << old_index_constant->get_uint_component(0);
    } else {
-      ir->write_mask = 1 << old_index_constant->get_int_component(0);
+      // If there "new" lhs is a swizzle, use the set_lhs helper to instead
+      // swizzle the rhs.
+      unsigned component[1] = { old_index_constant->get_uint_component(0) };
+      ir->set_lhs(new(mem_ctx) ir_swizzle(new_lhs, component, 1));
    }
 
    return ir_rvalue_enter_visitor::visit_enter(ir);
-- 
2.16.4



More information about the mesa-stable mailing list