<div dir="auto"><div><div class="gmail_extra"><div class="gmail_quote" dir="auto">Thanks for doing this!</div><div class="gmail_quote" dir="auto"><br></div><div class="gmail_quote">On Dec 17, 2016 17:44, "Lionel Landwerlin" <<a href="mailto:lionel.g.landwerlin@intel.com">lionel.g.landwerlin@intel.com</a>> wrote:<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Signed-off-by: Lionel Landwerlin <<a href="mailto:lionel.g.landwerlin@intel.com">lionel.g.landwerlin@intel.com</a><wbr>><br>
---<br>
 src/compiler/spirv/vtn_<wbr>variables.c              | 85 +++++++++++++++++++------<br>
 src/intel/vulkan/anv_nir_<wbr>lower_push_constants.c |  1 -<br>
 2 files changed, 66 insertions(+), 20 deletions(-)<br>
<br>
diff --git a/src/compiler/spirv/vtn_<wbr>variables.c b/src/compiler/spirv/vtn_<wbr>variables.c<br>
index f27d75cbec..ded58ef922 100644<br>
--- a/src/compiler/spirv/vtn_<wbr>variables.c<br>
+++ b/src/compiler/spirv/vtn_<wbr>variables.c<br>
@@ -435,9 +435,39 @@ vtn_type_block_size(struct vtn_type *type)<br>
 }<br>
<br>
 static void<br>
+vtn_access_chain_get_offset_<wbr>size(struct vtn_access_chain *chain,<br>
+                                 unsigned *access_offset,<br>
+                                 unsigned *access_size)<br>
+{<br>
+   /* Only valid for push constants accesses now. */<br>
+   assert(chain->var->mode == vtn_variable_mode_push_<wbr>constant);<br>
+<br>
+   struct vtn_type *type = chain->var->type;<br>
+<br>
+   *access_offset = 0;<br>
+<br>
+   for (unsigned i = 0; i < chain->length; i++) {<br>
+      if (chain->link[i].mode != vtn_access_mode_literal)<br>
+         break;<br>
+<br>
+      if (glsl_type_is_struct(type-><wbr>type)) {<br>
+         *access_offset += type->offsets[chain->link[i].<wbr>id];<br>
+         type = type->members[chain->link[i].<wbr>id];<br>
+      } else {<br>
+         *access_offset += type->stride * chain->link[i].id;<br>
+         type = type->array_element;<br>
+      }<br>
+   }<br>
+<br>
+   *access_size = vtn_type_block_size(type);<br>
+}<br>
+<br>
+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>
-                     struct vtn_ssa_value **inout, const struct glsl_type *type)<br>
+                     struct vtn_ssa_value **inout,<br>
+                     const struct glsl_type *type,<br>
+                     unsigned access_offset, unsigned access_size)<br></blockquote></div></div></div><div dir="auto"><br></div><div dir="auto">Please move these arguments to right after "offset" like they are in the function below.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 {<br>
    nir_intrinsic_instr *instr = nir_intrinsic_instr_create(b-><wbr>nb.shader, op);<br>
    instr->num_components = glsl_get_vector_elements(type)<wbr>;<br>
@@ -448,12 +478,11 @@ _vtn_load_store_tail(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
       instr->src[src++] = nir_src_for_ssa((*inout)->def)<wbr>;<br>
    }<br>
<br>
-   /* We set the base and size for push constant load to the entire push<br>
-    * constant block for now.<br>
-    */<br>
    if (op == nir_intrinsic_load_push_<wbr>constant) {<br>
-      nir_intrinsic_set_base(instr, 0);<br>
-      nir_intrinsic_set_range(instr, 128);<br>
+      assert(access_offset % 4 == 0);<br>
+<br>
+      nir_intrinsic_set_base(instr, access_offset);<br>
+      nir_intrinsic_set_range(instr, access_size);<br>
    }<br>
<br>
    if (index)<br>
@@ -477,6 +506,7 @@ _vtn_load_store_tail(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
 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_access_chain *chain, unsigned chain_idx,<br>
                       struct vtn_type *type, struct vtn_ssa_value **inout)<br>
 {<br>
@@ -522,7 +552,8 @@ _vtn_block_load_store(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
                            nir_imm_int(&b->nb, i * type->stride));<br>
                _vtn_load_store_tail(b, op, load, index, elem_offset,<br>
                                     &(*inout)->elems[i],<br>
-                                    glsl_vector_type(base_type, vec_width));<br>
+                                    glsl_vector_type(base_type, vec_width),<br>
+                                    access_offset, access_size);<br>
             }<br>
<br>
             if (load && type->row_major)<br>
@@ -543,7 +574,8 @@ _vtn_block_load_store(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
                if (load)<br>
                   *inout = vtn_create_ssa_value(b, glsl_scalar_type(base_type));<br>
                _vtn_load_store_tail(b, op, load, index, offset, inout,<br>
-                                    glsl_scalar_type(base_type));<br>
+                                    glsl_scalar_type(base_type),<br>
+                                    access_offset, access_size);<br>
             } else {<br>
                /* Grabbing a column; picking one element off each row */<br>
                unsigned num_comps = glsl_get_vector_elements(type-<wbr>>type);<br>
@@ -563,7 +595,8 @@ _vtn_block_load_store(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
                   }<br>
                   comp = &temp_val;<br>
                   _vtn_load_store_tail(b, op, load, index, elem_offset,<br>
-                                       &comp, glsl_scalar_type(base_type));<br>
+                                       &comp, glsl_scalar_type(base_type),<br>
+                                       access_offset, access_size);<br>
                   comps[i] = comp->def;<br>
                }<br>
<br>
@@ -581,20 +614,24 @@ _vtn_block_load_store(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
             offset = nir_iadd(&b->nb, offset, col_offset);<br>
<br>
             _vtn_block_load_store(b, op, load, index, offset,<br>
+                                  access_offset, access_size,<br>
                                   chain, chain_idx + 1,<br>
                                   type->array_element, inout);<br>
          }<br>
       } else if (chain == NULL) {<br>
          /* Single whole vector */<br>
          assert(glsl_type_is_vector_or_<wbr>scalar(type->type));<br>
-         _vtn_load_store_tail(b, op, load, index, offset, inout, type->type);<br>
+         _vtn_load_store_tail(b, op, load, index, offset, inout,<br>
+                              type->type, access_offset, access_size);<br>
       } else {<br>
          /* Single component of a vector. Fall through to array case. */<br>
          nir_ssa_def *elem_offset =<br>
             vtn_access_link_as_ssa(b, chain->link[chain_idx], type->stride);<br>
          offset = nir_iadd(&b->nb, offset, elem_offset);<br>
<br>
-         _vtn_block_load_store(b, op, load, index, offset, NULL, 0,<br>
+         _vtn_block_load_store(b, op, load, index, offset,<br>
+                               access_offset, access_size,<br>
+                               NULL, 0,<br>
                                type->array_element, inout);<br>
       }<br>
       return;<br>
@@ -604,7 +641,9 @@ _vtn_block_load_store(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
       for (unsigned i = 0; i < elems; i++) {<br>
          nir_ssa_def *elem_off =<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, NULL, 0,<br>
+         _vtn_block_load_store(b, op, load, index, elem_off,<br>
+                               access_offset, access_size,<br>
+                               NULL, 0,<br>
                                type->array_element, &(*inout)->elems[i]);<br>
       }<br>
       return;<br>
@@ -615,7 +654,9 @@ _vtn_block_load_store(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
       for (unsigned i = 0; i < elems; i++) {<br>
          nir_ssa_def *elem_off =<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, NULL, 0,<br>
+         _vtn_block_load_store(b, op, load, index, elem_off,<br>
+                               access_offset, access_size,<br>
+                               NULL, 0,<br>
                                type->members[i], &(*inout)->elems[i]);<br>
       }<br>
       return;<br>
@@ -629,7 +670,13 @@ _vtn_block_load_store(struct vtn_builder *b, nir_intrinsic_op op, bool load,<br>
 static struct vtn_ssa_value *<br>
 vtn_block_load(struct vtn_builder *b, struct vtn_access_chain *src)<br>
 {<br>
+   nir_ssa_def *offset, *index = NULL;<br>
+   struct vtn_type *type;<br>
+   unsigned chain_idx;<br>
+   offset = vtn_access_chain_to_offset(b, src, &index, &type, &chain_idx, true);<br>
+<br>
    nir_intrinsic_op op;<br>
+   unsigned access_offset = 0, access_size = 0;<br>
    switch (src->var->mode) {<br>
    case vtn_variable_mode_ubo:<br>
       op = nir_intrinsic_load_ubo;<br>
@@ -639,18 +686,18 @@ vtn_block_load(struct vtn_builder *b, struct vtn_access_chain *src)<br>
       break;<br>
    case vtn_variable_mode_push_<wbr>constant:<br>
       op = nir_intrinsic_load_push_<wbr>constant;<br>
+      vtn_access_chain_get_offset_<wbr>size(src, &access_offset, &access_size);<br>
+      /* We need to subtract the offset from where the intrinsic will load the<br>
+       * data. */<br>
+      offset = nir_isub(&b->nb, offset, nir_imm_int(&b->nb, access_offset));<br></blockquote></div></div></div><div dir="auto"><br></div><div dir="auto">I'm not so sure what I think of this... It would probably be better to start the access chain calcilations at the point where we get our first indirect rather than do the whole offset calculation and then subtract.  Is this reasonable or would it just make hash of everything?  We could easily make <span style="font-family:sans-serif">_vtn_load_store_tail set the intrinsic constants in the push constant case and make it emit an iadd otherwise.</span></div><div dir="auto"><br></div><div dir="auto"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
       break;<br>
    default:<br>
       assert(!"Invalid block variable mode");<br>
    }<br>
<br>
-   nir_ssa_def *offset, *index = NULL;<br>
-   struct vtn_type *type;<br>
-   unsigned chain_idx;<br>
-   offset = vtn_access_chain_to_offset(b, src, &index, &type, &chain_idx, true);<br>
-<br>
    struct vtn_ssa_value *value = NULL;<br>
    _vtn_block_load_store(b, op, true, index, offset,<br>
+                         access_offset, access_size,<br>
                          src, chain_idx, type, &value);<br>
    return value;<br>
 }<br>
@@ -665,7 +712,7 @@ vtn_block_store(struct vtn_builder *b, struct vtn_ssa_value *src,<br>
    offset = vtn_access_chain_to_offset(b, dst, &index, &type, &chain_idx, true);<br>
<br>
    _vtn_block_load_store(b, nir_intrinsic_store_ssbo, false, index, offset,<br>
-                         dst, chain_idx, type, &src);<br>
+                         0, 0, dst, chain_idx, type, &src);<br>
 }<br>
<br>
 static bool<br>
diff --git a/src/intel/vulkan/anv_nir_<wbr>lower_push_constants.c b/src/intel/vulkan/anv_nir_<wbr>lower_push_constants.c<br>
index 64c155372f..b66552825b 100644<br>
--- a/src/intel/vulkan/anv_nir_<wbr>lower_push_constants.c<br>
+++ b/src/intel/vulkan/anv_nir_<wbr>lower_push_constants.c<br>
@@ -42,7 +42,6 @@ anv_nir_lower_push_constants(<wbr>nir_shader *shader)<br>
                continue;<br>
<br>
             assert(intrin->const_index[0] % 4 == 0);<br>
-            assert(intrin->const_index[1] == 128);<br>
<br>
             /* We just turn them into uniform loads */<br>
             intrin->intrinsic = nir_intrinsic_load_uniform;<br>
<font color="#888888">--<br>
2.11.0<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">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/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></blockquote></div><br></div></div></div>