nir/spirv: Fix handling of vector component selects via OpAccessChain
authorJason Ekstrand <jason.ekstrand@intel.com>
Fri, 16 Oct 2015 04:16:41 +0000 (21:16 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Fri, 16 Oct 2015 04:18:57 +0000 (21:18 -0700)
When we get to the end of the _vtn_load/store_varaible recursion, we may
have one link left in the deref chain if there is a vector component select
on the end.  In this case, we need to truncate the deref chain early so
that, when we make the copy for the load, we don't get the extra deref.
The final deref will be handled by the vector extract/insert that comes
later.

src/glsl/nir/spirv_to_nir.c

index 6dfe530905d55c24c56ec94264d6c456208169cc..a62ec6661b065339cce523c23c88cc699b83ded1 100644 (file)
@@ -912,6 +912,11 @@ _vtn_variable_load(struct vtn_builder *b,
    nir_deref *old_child = src_deref_tail->child;
 
    if (glsl_type_is_vector_or_scalar(val->type)) {
+      /* Terminate the deref chain in case there is one more link to pick
+       * off a component of the vector.
+       */
+      src_deref_tail->child = NULL;
+
       nir_intrinsic_instr *load =
          nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var);
       load->variables[0] =
@@ -979,6 +984,11 @@ _vtn_variable_store(struct vtn_builder *b, struct vtn_type *dest_type,
    nir_deref *old_child = dest_deref_tail->child;
 
    if (glsl_type_is_vector_or_scalar(src->type)) {
+      /* Terminate the deref chain in case there is one more link to pick
+       * off a component of the vector.
+       */
+      dest_deref_tail->child = NULL;
+
       nir_intrinsic_instr *store =
          nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var);
       store->variables[0] =