[Mesa-dev] [PATCH 09/18] i965: add support for packing arrays

Timothy Arceri timothy.arceri at collabora.com
Wed Jun 15 05:38:41 UTC 2016


Here we add a new helper function calc_type_size_offset() to help
calculate the size of a varying once packing is taken into account.
---
 src/compiler/nir/nir_lower_io.c | 55 +++++++++++++++++++++++++++++++++++------
 1 file changed, 48 insertions(+), 7 deletions(-)

diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c
index c25790a..b966348 100644
--- a/src/compiler/nir/nir_lower_io.c
+++ b/src/compiler/nir/nir_lower_io.c
@@ -41,6 +41,36 @@ struct lower_io_state {
    nir_variable_mode modes;
 };
 
+/**
+ * Calculates the offset for a type by allowing for other components that are
+ * packed into the same location.
+ */
+static unsigned
+calc_type_size_offset(unsigned num_packed_components,
+                      const struct glsl_type *type,
+                      int (*type_size)(const struct glsl_type *))
+{
+   unsigned base_size;
+   const struct glsl_type *wa = glsl_without_array(type);
+   int comp_diff = num_packed_components - glsl_get_vector_elements(wa);
+
+   /* If there is no difference in component sizes or the type_size function
+    * being used treats everything as a vec4 return.
+    */
+   if (comp_diff <= 0 ||
+       type_size(glsl_float_type()) == type_size(glsl_double_type()))
+      return 0;
+
+   if (glsl_get_base_type(wa) == GLSL_TYPE_DOUBLE) {
+      base_size = type_size(glsl_dvec_type(comp_diff));
+   } else {
+      base_size = type_size(glsl_vec_type(comp_diff));
+   }
+
+   return glsl_type_is_array(type) ? base_size * glsl_get_aoa_size(type) :
+      base_size;
+}
+
 void
 nir_assign_var_locations(struct exec_list *var_list, unsigned *size,
                          unsigned base_offset,
@@ -74,13 +104,17 @@ nir_assign_var_locations(struct exec_list *var_list, unsigned *size,
          if (locations[idx][var->data.index] == -1) {
             var->data.driver_location = location;
             locations[idx][var->data.index] = location;
-            location += type_size(var->type);
+            location += type_size(var->type) +
+               calc_type_size_offset(var->data.num_packed_components,
+                                     var->type, type_size);
          } else {
             var->data.driver_location = locations[idx][var->data.index];
          }
       } else {
          var->data.driver_location = location;
-         location += type_size(var->type);
+         location += type_size(var->type) +
+            calc_type_size_offset(var->data.num_packed_components, var->type,
+                                  type_size);
       }
    }
 
@@ -113,7 +147,8 @@ is_per_vertex_output(struct lower_io_state *state, nir_variable *var)
 static nir_ssa_def *
 get_io_offset(nir_builder *b, nir_deref_var *deref,
               nir_ssa_def **vertex_index,
-              int (*type_size)(const struct glsl_type *))
+              int (*type_size)(const struct glsl_type *),
+              unsigned num_packed_components)
 {
    nir_deref *tail = &deref->deref;
 
@@ -141,7 +176,9 @@ get_io_offset(nir_builder *b, nir_deref_var *deref,
 
       if (tail->deref_type == nir_deref_type_array) {
          nir_deref_array *deref_array = nir_deref_as_array(tail);
-         unsigned size = type_size(tail->type);
+         unsigned size = type_size(tail->type) +
+            calc_type_size_offset(num_packed_components, tail->type,
+                                  type_size);
 
          offset = nir_iadd(b, offset,
                            nir_imm_int(b, size * deref_array->base_offset));
@@ -289,7 +326,9 @@ nir_lower_io_block(nir_block *block,
 
          offset = get_io_offset(b, intrin->variables[0],
                                 per_vertex ? &vertex_index : NULL,
-                                state->type_size);
+                                state->type_size,
+                                intrin->variables[0]->var->
+                                   data.num_packed_components);
 
          nir_intrinsic_instr *load =
             nir_intrinsic_instr_create(state->mem_ctx,
@@ -339,7 +378,9 @@ nir_lower_io_block(nir_block *block,
 
          offset = get_io_offset(b, intrin->variables[0],
                                 per_vertex ? &vertex_index : NULL,
-                                state->type_size);
+                                state->type_size,
+                                intrin->variables[0]->var->
+                                   data.num_packed_components);
 
          nir_intrinsic_instr *store =
             nir_intrinsic_instr_create(state->mem_ctx,
@@ -381,7 +422,7 @@ nir_lower_io_block(nir_block *block,
          nir_ssa_def *offset;
 
          offset = get_io_offset(b, intrin->variables[0],
-                                NULL, state->type_size);
+                                NULL, state->type_size, 0);
 
          nir_intrinsic_instr *atomic =
             nir_intrinsic_instr_create(state->mem_ctx,
-- 
2.5.5



More information about the mesa-dev mailing list