<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Tue, Nov 13, 2018 at 9:48 AM Karol Herbst <<a href="mailto:kherbst@redhat.com">kherbst@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Rob Clark <<a href="mailto:robdclark@gmail.com" target="_blank">robdclark@gmail.com</a>><br>
<br>
For cl we can have structs with 8/16/32/64 bit scalar types (as well as,<br>
ofc, arrays/structs/etc), which are padded according to 'C' rules.  So<br>
for lowering struct deref's we need to not just consider a field's size,<br>
but also it's alignment.<br>
<br>
Signed-off-by: Karol Herbst <<a href="mailto:kherbst@redhat.com" target="_blank">kherbst@redhat.com</a>><br>
---<br>
 src/compiler/nir/nir.h          | 10 +++++++<br>
 src/compiler/nir/nir_lower_io.c | 52 ++++++++++++++++++++++++---------<br>
 2 files changed, 49 insertions(+), 13 deletions(-)<br>
<br>
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h<br>
index c469e111b2c..11e3d18320a 100644<br>
--- a/src/compiler/nir/nir.h<br>
+++ b/src/compiler/nir/nir.h<br>
@@ -2825,10 +2825,20 @@ typedef enum {<br>
     */<br>
    nir_lower_io_force_sample_interpolation = (1 << 1),<br>
 } nir_lower_io_options;<br>
+typedef struct nir_memory_model {<br>
+   int (*type_size)(const struct glsl_type *);<br>
+   int (*type_align)(const struct glsl_type *);<br>
+} nir_memory_model;<br></blockquote><div><br></div><div>I don't really like the name "memory model".  In my mind, that implies a lot more than just a scheme for laying out memory.  Maybe nir_io_layout_cb or nir_io_type_size_align_cb?</div><div><br></div><div>I made this comment to Karol on IRC but I did something similar but with a different approach with glsl_get_natural_size_align.  I think I like this approach better.  It's potentially a bit less efficient but it's way simpler.  We should convert the constant lowering code over to it so we can be consistent.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 bool nir_lower_io(nir_shader *shader,<br>
                   nir_variable_mode modes,<br>
                   int (*type_size)(const struct glsl_type *),<br>
                   nir_lower_io_options);<br>
+// TEMP use different name to avoid fixing all the callers yet:<br>
+bool nir_lower_io2(nir_shader *shader,<br>
+                  nir_variable_mode modes,<br>
+                  const nir_memory_model *mm,<br>
+                  nir_lower_io_options);<br>
+<br>
 nir_src *nir_get_io_offset_src(nir_intrinsic_instr *instr);<br>
 nir_src *nir_get_io_vertex_index_src(nir_intrinsic_instr *instr);<br>
<br>
diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c<br>
index 2a6c284de2b..292baf9e4fc 100644<br>
--- a/src/compiler/nir/nir_lower_io.c<br>
+++ b/src/compiler/nir/nir_lower_io.c<br>
@@ -38,7 +38,7 @@<br>
 struct lower_io_state {<br>
    void *dead_ctx;<br>
    nir_builder builder;<br>
-   int (*type_size)(const struct glsl_type *type);<br>
+   const nir_memory_model *mm;<br>
    nir_variable_mode modes;<br>
    nir_lower_io_options options;<br>
 };<br>
@@ -86,12 +86,26 @@ nir_is_per_vertex_io(const nir_variable *var, gl_shader_stage stage)<br>
    return false;<br>
 }<br>
<br>
+static int<br>
+default_type_align(const struct glsl_type *type)<br>
+{<br>
+   return 1;<br>
+}<br>
+<br>
+static inline int<br>
+align(int value, int alignment)<br>
+{<br>
+   return (value + alignment - 1) & ~(alignment - 1);<br>
+}<br></blockquote><div><br></div><div>we have an ALIGN macro which should be accessible from here which does exactly that.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
 static nir_ssa_def *<br>
 get_io_offset(nir_deref_instr *deref, nir_ssa_def **vertex_index,<br>
               struct lower_io_state *state, unsigned *component)<br>
 {<br>
    nir_builder *b = &state->builder;<br>
-   int (*type_size)(const struct glsl_type *) = state->type_size;<br>
+   int (*type_size)(const struct glsl_type *) = state->mm->type_size;<br>
+   int (*type_align)(const struct glsl_type *) = state->mm->type_align ?<br>
+      state->mm->type_align : default_type_align;<br>
    nir_deref_path path;<br>
    nir_deref_path_init(&path, deref, NULL);<br>
<br>
@@ -137,7 +151,10 @@ get_io_offset(nir_deref_instr *deref, nir_ssa_def **vertex_index,<br>
<br>
          unsigned field_offset = 0;<br>
          for (unsigned i = 0; i < (*p)->strct.index; i++) {<br>
-            field_offset += type_size(glsl_get_struct_field(parent->type, i));<br>
+            const struct glsl_type *field_type =<br>
+               glsl_get_struct_field(parent->type, i);<br>
+            field_offset = align(field_offset, type_align(field_type));<br>
+            field_offset += type_size(field_type);<br>
          }<br>
          offset = nir_iadd(b, offset, nir_imm_int(b, field_offset));<br>
       } else {<br>
@@ -207,7 +224,7 @@ lower_load(nir_intrinsic_instr *intrin, struct lower_io_state *state,<br>
       nir_intrinsic_set_component(load, component);<br>
<br>
    if (load->intrinsic == nir_intrinsic_load_uniform)<br>
-      nir_intrinsic_set_range(load, state->type_size(var->type));<br>
+      nir_intrinsic_set_range(load, state->mm->type_size(var->type));<br>
<br>
    if (vertex_index) {<br>
       load->src[0] = nir_src_for_ssa(vertex_index);<br>
@@ -488,10 +505,8 @@ nir_lower_io_block(nir_block *block,<br>
 }<br>
<br>
 static bool<br>
-nir_lower_io_impl(nir_function_impl *impl,<br>
-                  nir_variable_mode modes,<br>
-                  int (*type_size)(const struct glsl_type *),<br>
-                  nir_lower_io_options options)<br>
+nir_lower_io_impl(nir_function_impl *impl, nir_variable_mode modes,<br>
+                  const nir_memory_model *mm, nir_lower_io_options options)<br>
 {<br>
    struct lower_io_state state;<br>
    bool progress = false;<br>
@@ -499,7 +514,7 @@ nir_lower_io_impl(nir_function_impl *impl,<br>
    nir_builder_init(&state.builder, impl);<br>
    state.dead_ctx = ralloc_context(NULL);<br>
    state.modes = modes;<br>
-   state.type_size = type_size;<br>
+   <a href="http://state.mm" rel="noreferrer" target="_blank">state.mm</a> = mm;<br>
    state.options = options;<br>
<br>
    nir_foreach_block(block, impl) {<br>
@@ -514,22 +529,33 @@ nir_lower_io_impl(nir_function_impl *impl,<br>
 }<br>
<br>
 bool<br>
-nir_lower_io(nir_shader *shader, nir_variable_mode modes,<br>
-             int (*type_size)(const struct glsl_type *),<br>
-             nir_lower_io_options options)<br>
+nir_lower_io2(nir_shader *shader, nir_variable_mode modes,<br>
+             const nir_memory_model *mm, nir_lower_io_options options)<br>
 {<br>
    bool progress = false;<br>
<br>
    nir_foreach_function(function, shader) {<br>
       if (function->impl) {<br>
          progress |= nir_lower_io_impl(function->impl, modes,<br>
-                                       type_size, options);<br>
+                                       mm, options);<br>
       }<br>
    }<br>
<br>
    return progress;<br>
 }<br>
<br>
+<br>
+bool<br>
+nir_lower_io(nir_shader *shader, nir_variable_mode modes,<br>
+             int (*type_size)(const struct glsl_type *),<br>
+             nir_lower_io_options options)<br>
+{<br>
+   nir_memory_model mm = {<br>
+         .type_size = type_size,<br>
+   };<br>
+   return nir_lower_io2(shader, modes, &mm, options);<br>
+}<br>
+<br>
 /**<br>
  * Return the offset source for a load/store intrinsic.<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></div>