<div dir="ltr"><div>Ok, I think there's a decent chance we've got them all now.</div><div><br></div><div>Reviewed-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>></div><div><br></div><div>It'd be great if we had some sort of test which put the access qualifiers on the variable so we could be sure it worked. :/<br></div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Oct 10, 2018 at 3:43 AM Samuel Pitoiset <<a href="mailto:samuel.pitoiset@gmail.com">samuel.pitoiset@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">v2: - change how the access qualifiers are accumulated<br>
v3: - duplicate members in struct_member_decoration_cb()<br>
    - handle access qualifiers on variables<br>
    - remove access qualifiers handling in _vtn_variable_load_store()<br>
    - fix setting access qualifiers on type->array_element<br>
<br>
Signed-off-by: Samuel Pitoiset <<a href="mailto:samuel.pitoiset@gmail.com" target="_blank">samuel.pitoiset@gmail.com</a>><br>
---<br>
 src/compiler/nir/nir_intrinsics.py |  4 +--<br>
 src/compiler/spirv/spirv_to_nir.c  | 24 +++++++++++--<br>
 src/compiler/spirv/vtn_private.h   |  9 +++++<br>
 src/compiler/spirv/vtn_variables.c | 54 +++++++++++++++++++++++++-----<br>
 4 files changed, 77 insertions(+), 14 deletions(-)<br>
<br>
diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py<br>
index b06b38fc2c..ec3049ca06 100644<br>
--- a/src/compiler/nir/nir_intrinsics.py<br>
+++ b/src/compiler/nir/nir_intrinsics.py<br>
@@ -565,7 +565,7 @@ intrinsic("load_interpolated_input", src_comp=[2, 1], dest_comp=0,<br>
           indices=[BASE, COMPONENT], flags=[CAN_ELIMINATE, CAN_REORDER])<br>
<br>
 # src[] = { buffer_index, offset }. No const_index<br>
-load("ssbo", 2, flags=[CAN_ELIMINATE])<br>
+load("ssbo", 2, flags=[CAN_ELIMINATE], indices=[ACCESS])<br>
 # src[] = { offset }. const_index[] = { base, component }<br>
 load("output", 1, [BASE, COMPONENT], flags=[CAN_ELIMINATE])<br>
 # src[] = { vertex, offset }. const_index[] = { base }<br>
@@ -591,6 +591,6 @@ store("output", 2, [BASE, WRMASK, COMPONENT])<br>
 # const_index[] = { base, write_mask, component }<br>
 store("per_vertex_output", 3, [BASE, WRMASK, COMPONENT])<br>
 # src[] = { value, block_index, offset }. const_index[] = { write_mask }<br>
-store("ssbo", 3, [WRMASK])<br>
+store("ssbo", 3, [WRMASK, ACCESS])<br>
 # src[] = { value, offset }. const_index[] = { base, write_mask }<br>
 store("shared", 2, [BASE, WRMASK])<br>
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c<br>
index 2ad83196e4..37a801037b 100644<br>
--- a/src/compiler/spirv/spirv_to_nir.c<br>
+++ b/src/compiler/spirv/spirv_to_nir.c<br>
@@ -668,6 +668,16 @@ mutable_matrix_member(struct vtn_builder *b, struct vtn_type *type, int member)<br>
    return type;<br>
 }<br>
<br>
+static void<br>
+vtn_handle_access_qualifier(struct vtn_builder *b, struct vtn_type *type,<br>
+                            int member, enum gl_access_qualifier access)<br>
+{<br>
+   type->members[member] = vtn_type_copy(b, type->members[member]);<br>
+   type = type->members[member];<br>
+<br>
+   type->access |= access;<br>
+}<br>
+<br>
 static void<br>
 struct_member_decoration_cb(struct vtn_builder *b,<br>
                             struct vtn_value *val, int member,<br>
@@ -681,13 +691,21 @@ struct_member_decoration_cb(struct vtn_builder *b,<br>
    assert(member < ctx->num_fields);<br>
<br>
    switch (dec->decoration) {<br>
+   case SpvDecorationRelaxedPrecision:<br>
+   case SpvDecorationUniform:<br>
+      break; /* FIXME: Do nothing with this for now. */<br>
    case SpvDecorationNonWritable:<br>
+      vtn_handle_access_qualifier(b, ctx->type, member, ACCESS_NON_WRITEABLE);<br>
+      break;<br>
    case SpvDecorationNonReadable:<br>
-   case SpvDecorationRelaxedPrecision:<br>
+      vtn_handle_access_qualifier(b, ctx->type, member, ACCESS_NON_READABLE);<br>
+      break;<br>
    case SpvDecorationVolatile:<br>
+      vtn_handle_access_qualifier(b, ctx->type, member, ACCESS_VOLATILE);<br>
+      break;<br>
    case SpvDecorationCoherent:<br>
-   case SpvDecorationUniform:<br>
-      break; /* FIXME: Do nothing with this for now. */<br>
+      vtn_handle_access_qualifier(b, ctx->type, member, ACCESS_COHERENT);<br>
+      break;<br>
    case SpvDecorationNoPerspective:<br>
       ctx->fields[member].interpolation = INTERP_MODE_NOPERSPECTIVE;<br>
       break;<br>
diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h<br>
index a31202d129..da7a04ce59 100644<br>
--- a/src/compiler/spirv/vtn_private.h<br>
+++ b/src/compiler/spirv/vtn_private.h<br>
@@ -296,6 +296,9 @@ struct vtn_type {<br>
    /* for arrays, matrices and pointers, the array stride */<br>
    unsigned stride;<br>
<br>
+   /* Access qualifiers */<br>
+   enum gl_access_qualifier access;<br>
+<br>
    union {<br>
       /* Members for scalar, vector, and array-like types */<br>
       struct {<br>
@@ -457,6 +460,9 @@ struct vtn_pointer {<br>
    /** A (block_index, offset) pair representing a UBO or SSBO position. */<br>
    struct nir_ssa_def *block_index;<br>
    struct nir_ssa_def *offset;<br>
+<br>
+   /* Access qualifiers */<br>
+   enum gl_access_qualifier access;<br>
 };<br>
<br>
 struct vtn_variable {<br>
@@ -488,6 +494,9 @@ struct vtn_variable {<br>
     * hack at some point in the future.<br>
     */<br>
    struct vtn_pointer *copy_prop_sampler;<br>
+<br>
+   /* Access qualifiers. */<br>
+   enum gl_access_qualifier access;<br>
 };<br>
<br>
 struct vtn_image_pointer {<br>
diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c<br>
index 636fdb8689..cc3438bff2 100644<br>
--- a/src/compiler/spirv/vtn_variables.c<br>
+++ b/src/compiler/spirv/vtn_variables.c<br>
@@ -89,6 +89,7 @@ vtn_access_chain_pointer_dereference(struct vtn_builder *b,<br>
    struct vtn_access_chain *chain =<br>
       vtn_access_chain_extend(b, base->chain, deref_chain->length);<br>
    struct vtn_type *type = base->type;<br>
+   enum gl_access_qualifier access = base->access;<br>
<br>
    /* OpPtrAccessChain is only allowed on things which support variable<br>
     * pointers.  For everything else, the client is expected to just pass us<br>
@@ -106,6 +107,8 @@ vtn_access_chain_pointer_dereference(struct vtn_builder *b,<br>
       } else {<br>
          type = type->array_element;<br>
       }<br>
+<br>
+      access |= type->access;<br>
    }<br>
<br>
    struct vtn_pointer *ptr = rzalloc(b, struct vtn_pointer);<br>
@@ -114,6 +117,7 @@ vtn_access_chain_pointer_dereference(struct vtn_builder *b,<br>
    ptr->var = base->var;<br>
    ptr->deref = base->deref;<br>
    ptr->chain = chain;<br>
+   ptr->access = access;<br>
<br>
    return ptr;<br>
 }<br>
@@ -184,6 +188,7 @@ vtn_ssa_offset_pointer_dereference(struct vtn_builder *b,<br>
    nir_ssa_def *block_index = base->block_index;<br>
    nir_ssa_def *offset = base->offset;<br>
    struct vtn_type *type = base->type;<br>
+   enum gl_access_qualifier access = base->access;<br>
<br>
    unsigned idx = 0;<br>
    if (base->mode == vtn_variable_mode_ubo ||<br>
@@ -198,6 +203,7 @@ vtn_ssa_offset_pointer_dereference(struct vtn_builder *b,<br>
                idx++;<br>
                /* This consumes a level of type */<br>
                type = type->array_element;<br>
+               access |= type->access;<br>
             } else {<br>
                /* This is annoying.  We've been asked for a pointer to the<br>
                 * array of UBOs/SSBOs and not a specifc buffer.  Return a<br>
@@ -319,6 +325,7 @@ vtn_ssa_offset_pointer_dereference(struct vtn_builder *b,<br>
             vtn_access_link_as_ssa(b, deref_chain->link[idx], type->stride);<br>
          offset = nir_iadd(&b->nb, offset, elem_offset);<br>
          type = type->array_element;<br>
+         access |= type->access;<br>
          break;<br>
       }<br>
<br>
@@ -328,6 +335,7 @@ vtn_ssa_offset_pointer_dereference(struct vtn_builder *b,<br>
          nir_ssa_def *mem_offset = nir_imm_int(&b->nb, type->offsets[member]);<br>
          offset = nir_iadd(&b->nb, offset, mem_offset);<br>
          type = type->members[member];<br>
+         access |= type->access;<br>
          break;<br>
       }<br>
<br>
@@ -341,6 +349,7 @@ vtn_ssa_offset_pointer_dereference(struct vtn_builder *b,<br>
    ptr->type = type;<br>
    ptr->block_index = block_index;<br>
    ptr->offset = offset;<br>
+   ptr->access = access;<br>
<br>
    return ptr;<br>
 }<br>
@@ -370,6 +379,7 @@ vtn_pointer_for_variable(struct vtn_builder *b,<br>
    vtn_assert(ptr_type->deref->type == var->type->type);<br>
    pointer->ptr_type = ptr_type;<br>
    pointer->var = var;<br>
+   pointer->access = var->access | var->type->access;<br>
<br>
    return pointer;<br>
 }<br>
@@ -608,7 +618,8 @@ static void<br>
 _vtn_load_store_tail(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
                      nir_ssa_def *index, nir_ssa_def *offset,<br>
                      unsigned access_offset, unsigned access_size,<br>
-                     struct vtn_ssa_value **inout, const struct glsl_type *type)<br>
+                     struct vtn_ssa_value **inout, const struct glsl_type *type,<br>
+                     enum gl_access_qualifier access)<br>
 {<br>
    nir_intrinsic_instr *instr = nir_intrinsic_instr_create(b->nb.shader, op);<br>
    instr->num_components = glsl_get_vector_elements(type);<br>
@@ -624,6 +635,11 @@ _vtn_load_store_tail(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
       nir_intrinsic_set_range(instr, access_size);<br>
    }<br>
<br>
+   if (op == nir_intrinsic_load_ssbo ||<br>
+       op == nir_intrinsic_store_ssbo) {<br>
+      nir_intrinsic_set_access(instr, access);<br>
+   }<br>
+<br>
    if (index)<br>
       instr->src[src++] = nir_src_for_ssa(index);<br>
<br>
@@ -654,7 +670,8 @@ static void<br>
 _vtn_block_load_store(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
                       nir_ssa_def *index, nir_ssa_def *offset,<br>
                       unsigned access_offset, unsigned access_size,<br>
-                      struct vtn_type *type, struct vtn_ssa_value **inout)<br>
+                      struct vtn_type *type, enum gl_access_qualifier access,<br>
+                      struct vtn_ssa_value **inout)<br>
 {<br>
    if (load && *inout == NULL)<br>
       *inout = vtn_create_ssa_value(b, type->type);<br>
@@ -704,7 +721,8 @@ _vtn_block_load_store(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
             _vtn_load_store_tail(b, op, load, index, elem_offset,<br>
                                  access_offset, access_size,<br>
                                  &(*inout)->elems[i],<br>
-                                 glsl_vector_type(base_type, vec_width));<br>
+                                 glsl_vector_type(base_type, vec_width),<br>
+                                 type->access | access);<br>
          }<br>
<br>
          if (load && type->row_major)<br>
@@ -717,7 +735,8 @@ _vtn_block_load_store(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
             vtn_assert(glsl_type_is_vector_or_scalar(type->type));<br>
             _vtn_load_store_tail(b, op, load, index, offset,<br>
                                  access_offset, access_size,<br>
-                                 inout, type->type);<br>
+                                 inout, type->type,<br>
+                                 type->access | access);<br>
          } else {<br>
             /* This is a strided load.  We have to load N things separately.<br>
              * This is the single column of a row-major matrix case.<br>
@@ -738,7 +757,8 @@ _vtn_block_load_store(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
                comp = &temp_val;<br>
                _vtn_load_store_tail(b, op, load, index, elem_offset,<br>
                                     access_offset, access_size,<br>
-                                    &comp, glsl_scalar_type(base_type));<br>
+                                    &comp, glsl_scalar_type(base_type),<br>
+                                    type->access | access);<br>
                per_comp[i] = comp->def;<br>
             }<br>
<br>
@@ -758,7 +778,9 @@ _vtn_block_load_store(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
             nir_iadd(&b->nb, offset, nir_imm_int(&b->nb, i * type->stride));<br>
          _vtn_block_load_store(b, op, load, index, elem_off,<br>
                                access_offset, access_size,<br>
-                               type->array_element, &(*inout)->elems[i]);<br>
+                               type->array_element,<br>
+                               type->array_element->access | access,<br>
+                               &(*inout)->elems[i]);<br>
       }<br>
       return;<br>
    }<br>
@@ -770,7 +792,9 @@ _vtn_block_load_store(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
             nir_iadd(&b->nb, offset, nir_imm_int(&b->nb, type->offsets[i]));<br>
          _vtn_block_load_store(b, op, load, index, elem_off,<br>
                                access_offset, access_size,<br>
-                               type->members[i], &(*inout)->elems[i]);<br>
+                               type->members[i],<br>
+                               type->members[i]->access | access,<br>
+                               &(*inout)->elems[i]);<br>
       }<br>
       return;<br>
    }<br>
@@ -809,7 +833,7 @@ vtn_block_load(struct vtn_builder *b, struct vtn_pointer *src)<br>
    struct vtn_ssa_value *value = NULL;<br>
    _vtn_block_load_store(b, op, true, index, offset,<br>
                          access_offset, access_size,<br>
-                         src->type, &value);<br>
+                         src->type, src->access, &value);<br>
    return value;<br>
 }<br>
<br>
@@ -833,7 +857,7 @@ vtn_block_store(struct vtn_builder *b, struct vtn_ssa_value *src,<br>
    offset = vtn_pointer_to_offset(b, dst, &index);<br>
<br>
    _vtn_block_load_store(b, op, false, index, offset,<br>
-                         0, 0, dst->type, &src);<br>
+                         0, 0, dst->type, dst->access, &src);<br>
 }<br>
<br>
 static void<br>
@@ -1389,6 +1413,18 @@ var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,<br>
    case SpvDecorationOffset:<br>
       vtn_var->offset = dec->literals[0];<br>
       break;<br>
+   case SpvDecorationNonWritable:<br>
+      vtn_var->access |= ACCESS_NON_WRITEABLE;<br>
+      break;<br>
+   case SpvDecorationNonReadable:<br>
+      vtn_var->access |= ACCESS_NON_READABLE;<br>
+      break;<br>
+   case SpvDecorationVolatile:<br>
+      vtn_var->access |= ACCESS_VOLATILE;<br>
+      break;<br>
+   case SpvDecorationCoherent:<br>
+      vtn_var->access |= ACCESS_COHERENT;<br>
+      break;<br>
    default:<br>
       break;<br>
    }<br>
-- <br>
2.19.1<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</blockquote></div>