[Mesa-dev] [PATCH 03/12] glsl/nir: add new num_packed_components field

Timothy Arceri timothy.arceri at collabora.com
Wed May 25 03:07:07 UTC 2016


This will be used to store the total number of components used at this location
when packing via ARB_enhanced_layouts.
---
 src/compiler/glsl/ir.h              |  5 +++
 src/compiler/glsl/link_varyings.cpp | 74 ++++++++++++++++++++++++++++++++++++-
 src/compiler/glsl/linker.cpp        |  2 +
 src/compiler/glsl/linker.h          |  4 ++
 src/compiler/nir/glsl_to_nir.cpp    |  1 +
 src/compiler/nir/nir.h              |  5 +++
 6 files changed, 89 insertions(+), 2 deletions(-)

diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h
index d52dbf8..6236245 100644
--- a/src/compiler/glsl/ir.h
+++ b/src/compiler/glsl/ir.h
@@ -759,6 +759,11 @@ public:
       unsigned location_frac:2;
 
       /**
+       * The total number of components packed into this location.
+       */
+      unsigned num_packed_components:3;
+
+      /**
        * Layout of the matrix.  Uses glsl_matrix_layout values.
        */
       unsigned matrix_layout:2;
diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp
index dd5c9cc..fcd285d 100644
--- a/src/compiler/glsl/link_varyings.cpp
+++ b/src/compiler/glsl/link_varyings.cpp
@@ -1940,6 +1940,70 @@ reserved_varying_slot(struct gl_shader *stage, ir_variable_mode io_mode)
    return slots;
 }
 
+void
+set_num_packed_components(struct gl_shader *shader, ir_variable_mode io_mode,
+                          unsigned base_offset)
+{
+   /* Find the max number of components used at this location */
+   unsigned num_components[MAX_VARYINGS_INCL_PATCH] = { 0 };
+
+   foreach_in_list(ir_instruction, node, shader->ir) {
+      ir_variable *const var = node->as_variable();
+
+      if (var == NULL || var->data.mode != io_mode ||
+          !var->data.explicit_location)
+         continue;
+
+      int idx = var->data.location - base_offset;
+      if (idx < 0 || idx >= MAX_VARYINGS_INCL_PATCH ||
+          var->type->without_array()->is_record() ||
+          var->type->without_array()->is_matrix())
+         continue;
+
+      if (var->type->is_array()) {
+         const glsl_type *type = get_varying_type(var, shader->Stage);
+         unsigned array_components = type->without_array()->vector_elements +
+            var->data.location_frac;
+         assert(type->arrays_of_arrays_size() + idx <=
+                ARRAY_SIZE(num_components));
+         for (unsigned i = idx; i < type->arrays_of_arrays_size(); i++) {
+            num_components[i] = MAX2(array_components, num_components[i]);
+         }
+      } else {
+         unsigned comps = var->type->vector_elements +
+            var->data.location_frac;
+         num_components[idx] = MAX2(comps, num_components[idx]);
+      }
+   }
+
+   foreach_in_list(ir_instruction, node, shader->ir) {
+      ir_variable *const var = node->as_variable();
+
+      if (var == NULL || var->data.mode != io_mode ||
+          !var->data.explicit_location)
+         continue;
+
+      int idx = var->data.location - base_offset;
+      if (idx < 0 || idx >= MAX_VARYINGS_INCL_PATCH ||
+          var->type->without_array()->is_record() ||
+          var->type->without_array()->is_matrix())
+         continue;
+
+      /* For arrays we need to check all elements in order to find the max
+       * number of components used.
+       */
+      unsigned c = 0;
+      if (var->type->is_array()) {
+         const glsl_type *type = get_varying_type(var, shader->Stage);
+         for (unsigned i = idx; i < type->arrays_of_arrays_size(); i++) {
+            c = MAX2(c, num_components[i]);
+         }
+      } else {
+         c = num_components[idx];
+      }
+      var->data.num_packed_components = c;
+   }
+}
 
 /**
  * Assign locations for all variables that are produced in one pipeline stage
@@ -2054,11 +2118,17 @@ assign_varying_locations(struct gl_context *ctx,
     * 4. Mark input variables in the consumer that do not have locations as
     *    not being inputs.  This lets the optimizer eliminate them.
     */
-   if (consumer)
+   if (consumer) {
       canonicalize_shader_io(consumer->ir, ir_var_shader_in);
+      set_num_packed_components(consumer, ir_var_shader_in,
+                                VARYING_SLOT_VAR0);
+   }
 
-   if (producer)
+   if (producer) {
       canonicalize_shader_io(producer->ir, ir_var_shader_out);
+      set_num_packed_components(producer, ir_var_shader_out,
+                                VARYING_SLOT_VAR0);
+   }
 
    if (consumer)
       linker::populate_consumer_input_sets(mem_ctx, consumer->ir,
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
index 5c0e4b6..e388b26 100644
--- a/src/compiler/glsl/linker.cpp
+++ b/src/compiler/glsl/linker.cpp
@@ -2587,6 +2587,8 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
       (target_index == MESA_SHADER_VERTEX)
       ? ir_var_shader_in : ir_var_shader_out;
 
+   set_num_packed_components(sh, direction, generic_base);
+
 
    /* Temporary storage for the set of attributes that need locations assigned.
     */
diff --git a/src/compiler/glsl/linker.h b/src/compiler/glsl/linker.h
index 3a0ec8b..060693e 100644
--- a/src/compiler/glsl/linker.h
+++ b/src/compiler/glsl/linker.h
@@ -91,6 +91,10 @@ extern void
 link_check_atomic_counter_resources(struct gl_context *ctx,
                                     struct gl_shader_program *prog);
 
+void
+set_num_packed_components(struct gl_shader *shader, ir_variable_mode io_mode,
+                          unsigned base_offset);
+
 /**
  * Class for processing all of the leaf fields of a variable that corresponds
  * to a program resource.
diff --git a/src/compiler/nir/glsl_to_nir.cpp b/src/compiler/nir/glsl_to_nir.cpp
index 00e3fd5..415e3bc 100644
--- a/src/compiler/nir/glsl_to_nir.cpp
+++ b/src/compiler/nir/glsl_to_nir.cpp
@@ -375,6 +375,7 @@ nir_visitor::visit(ir_variable *ir)
    var->data.explicit_binding = ir->data.explicit_binding;
    var->data.has_initializer = ir->data.has_initializer;
    var->data.location_frac = ir->data.location_frac;
+   var->data.num_packed_components = ir->data.num_packed_components;
 
    switch (ir->data.depth_layout) {
    case ir_depth_layout_none:
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 4dd38a7..e06c4d5 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -227,6 +227,11 @@ typedef struct nir_variable {
       unsigned location_frac:2;
 
       /**
+       * The total number of components packed into this location.
+       */
+      unsigned num_packed_components:3;
+
+      /**
        * \brief Layout qualifier for gl_FragDepth.
        *
        * This is not equal to \c ir_depth_layout_none if and only if this
-- 
2.5.5



More information about the mesa-dev mailing list