Mesa (master): spirv: propagate access qualifiers through ssa & pointer

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jul 26 14:20:09 UTC 2019


Module: Mesa
Branch: master
Commit: 0fb61dfdebac802e4b4c7b5dbebf3d7ba1e60dc2
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0fb61dfdebac802e4b4c7b5dbebf3d7ba1e60dc2

Author: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Date:   Thu May 16 13:06:27 2019 +0100

spirv: propagate access qualifiers through ssa & pointer

Not only variables can be flagged as NonUniformEXT but also
expressions. We're currently ignoring it in an expression such as :

   imageLoad(data[nonuniformEXT(rIndex)], 0)

The associated SPIRV :

   OpDecorate %69 NonUniformEXT
   ...
   %69 = OpLoad %61 %68

This changes propagates access qualifiers through ssa & pointers so
that when it hits a OpLoad/OpStore style instructions, qualifiers are
not forgotten.

Fixes failure the following tests :

   dEQP-VK.descriptor_indexing.*

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Fixes: 8ed583fe523703 ("spirv: Handle the NonUniformEXT decoration")
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira at intel.com>

---

 src/compiler/spirv/spirv_to_nir.c  |  2 ++
 src/compiler/spirv/vtn_private.h   | 34 ++++++++++++++++++++++++++++++++++
 src/compiler/spirv/vtn_variables.c | 30 ++++++++++++++++++++++++++----
 3 files changed, 62 insertions(+), 4 deletions(-)

diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c
index c2528cef35a..7a2e30707ce 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -2575,6 +2575,8 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
       intrin->src[2] = nir_src_for_ssa(image.sample);
    }
 
+   nir_intrinsic_set_access(intrin, image.image->access);
+
    switch (opcode) {
    case SpvOpAtomicLoad:
    case SpvOpImageQuerySize:
diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h
index 5998196a838..4c1e4f6bb04 100644
--- a/src/compiler/spirv/vtn_private.h
+++ b/src/compiler/spirv/vtn_private.h
@@ -269,6 +269,9 @@ struct vtn_ssa_value {
    struct vtn_ssa_value *transposed;
 
    const struct glsl_type *type;
+
+   /* Access qualifiers */
+   enum gl_access_qualifier access;
 };
 
 enum vtn_base_type {
@@ -418,6 +421,9 @@ struct vtn_access_chain {
     */
    bool ptr_as_array;
 
+   /* Access qualifiers */
+   enum gl_access_qualifier access;
+
    /** Struct elements and array offsets.
     *
     * This is an array of 1 so that it can conveniently be created on the
@@ -724,6 +730,34 @@ vtn_constant_int(struct vtn_builder *b, uint32_t value_id)
    }
 }
 
+static inline enum gl_access_qualifier vtn_value_access(struct vtn_value *value)
+{
+   switch (value->value_type) {
+   case vtn_value_type_invalid:
+   case vtn_value_type_undef:
+   case vtn_value_type_string:
+   case vtn_value_type_decoration_group:
+   case vtn_value_type_constant:
+   case vtn_value_type_function:
+   case vtn_value_type_block:
+   case vtn_value_type_extension:
+      return 0;
+   case vtn_value_type_type:
+      return value->type->access;
+   case vtn_value_type_pointer:
+      return value->pointer->access;
+   case vtn_value_type_ssa:
+      return value->ssa->access;
+   case vtn_value_type_image_pointer:
+      return value->image->image->access;
+   case vtn_value_type_sampled_image:
+      return value->sampled_image->image->access |
+         value->sampled_image->sampler->access;
+   }
+
+   unreachable("invalid type");
+}
+
 struct vtn_ssa_value *vtn_ssa_value(struct vtn_builder *b, uint32_t value_id);
 
 struct vtn_value *vtn_push_value_pointer(struct vtn_builder *b,
diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c
index 0b03c224af7..c73cbd37cec 100644
--- a/src/compiler/spirv/vtn_variables.c
+++ b/src/compiler/spirv/vtn_variables.c
@@ -45,6 +45,22 @@ vtn_push_value_pointer(struct vtn_builder *b, uint32_t value_id,
    return val;
 }
 
+static void
+ssa_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
+                  const struct vtn_decoration *dec, void *void_ssa)
+{
+   struct vtn_ssa_value *ssa = void_ssa;
+
+   switch (dec->decoration) {
+   case SpvDecorationNonUniformEXT:
+      ssa->access |= ACCESS_NON_UNIFORM;
+      break;
+
+   default:
+      break;
+   }
+}
+
 struct vtn_value *
 vtn_push_ssa(struct vtn_builder *b, uint32_t value_id,
              struct vtn_type *type, struct vtn_ssa_value *ssa)
@@ -55,6 +71,7 @@ vtn_push_ssa(struct vtn_builder *b, uint32_t value_id,
    } else {
       val = vtn_push_value(b, value_id, vtn_value_type_ssa);
       val->ssa = ssa;
+      vtn_foreach_decoration(b, val, ssa_decoration_cb, val->ssa);
    }
    return val;
 }
@@ -225,7 +242,7 @@ vtn_nir_deref_pointer_dereference(struct vtn_builder *b,
                                   struct vtn_access_chain *deref_chain)
 {
    struct vtn_type *type = base->type;
-   enum gl_access_qualifier access = base->access;
+   enum gl_access_qualifier access = base->access | deref_chain->access;
    unsigned idx = 0;
 
    nir_deref_instr *tail;
@@ -2450,6 +2467,7 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
    case SpvOpInBoundsAccessChain:
    case SpvOpInBoundsPtrAccessChain: {
       struct vtn_access_chain *chain = vtn_access_chain_create(b, count - 4);
+      enum gl_access_qualifier access = 0;
       chain->ptr_as_array = (opcode == SpvOpPtrAccessChain || opcode == SpvOpInBoundsPtrAccessChain);
 
       unsigned idx = 0;
@@ -2461,8 +2479,8 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
          } else {
             chain->link[idx].mode = vtn_access_mode_id;
             chain->link[idx].id = w[i];
-
          }
+         access |= vtn_value_access(link_val);
          idx++;
       }
 
@@ -2492,6 +2510,7 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
          struct vtn_pointer *ptr =
             vtn_pointer_dereference(b, base_val->pointer, chain);
          ptr->ptr_type = ptr_type;
+         ptr->access = access;
          vtn_push_value_pointer(b, w[2], ptr);
       }
       break;
@@ -2629,10 +2648,11 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
                   "scalar type");
 
       /* The pointer will be converted to an SSA value automatically */
-      nir_ssa_def *ptr_ssa = vtn_ssa_value(b, w[3])->def;
+      struct vtn_ssa_value *ptr_ssa = vtn_ssa_value(b, w[3]);
 
       u_val->ssa = vtn_create_ssa_value(b, u_val->type->type);
-      u_val->ssa->def = nir_sloppy_bitcast(&b->nb, ptr_ssa, u_val->type->type);
+      u_val->ssa->def = nir_sloppy_bitcast(&b->nb, ptr_ssa->def, u_val->type->type);
+      u_val->ssa->access |= ptr_ssa->access;
       break;
    }
 
@@ -2652,6 +2672,8 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
       nir_ssa_def *ptr_ssa = nir_sloppy_bitcast(&b->nb, u_val->ssa->def,
                                                 ptr_val->type->type);
       ptr_val->pointer = vtn_pointer_from_ssa(b, ptr_ssa, ptr_val->type);
+      vtn_foreach_decoration(b, ptr_val, ptr_decoration_cb, ptr_val->pointer);
+      ptr_val->pointer->access |= u_val->ssa->access;
       break;
    }
 




More information about the mesa-commit mailing list