[Mesa-dev] [PATCH 20/28] glsl: pack vertex attributes with component layout qualifiers

Timothy Arceri timothy.arceri at collabora.com
Mon Dec 28 21:00:20 PST 2015


This actually tries to pack any input with an explicit location we
just let the optimisiation passes clean up the extra assignments if
there was no actual packing done.
---
 src/glsl/ir_optimization.h         |  1 +
 src/glsl/link_varyings.cpp         | 33 ++++++++++++++++++++++++++-------
 src/glsl/lower_packed_varyings.cpp | 28 +++++++++++++++-------------
 3 files changed, 42 insertions(+), 20 deletions(-)

diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
index eab76ff..a313e30 100644
--- a/src/glsl/ir_optimization.h
+++ b/src/glsl/ir_optimization.h
@@ -129,6 +129,7 @@ void lower_ubo_reference(struct gl_shader *shader);
 void lower_packed_varyings(void *mem_ctx,
                            unsigned locations_used, ir_variable_mode mode,
                            unsigned gs_input_vertices, gl_shader *shader,
+                           unsigned base_location,
                            bool disable_varying_packing,
                            bool has_enhanced_layouts);
 bool lower_vector_insert(exec_list *instructions, bool lower_nonconstant_index);
diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
index 7066481..7f77f7c 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -1582,7 +1582,8 @@ canonicalize_shader_io(exec_list *ir, enum ir_variable_mode io_mode)
  * In theory a 32 bits value will be enough but a 64 bits value is future proof.
  */
 uint64_t
-reserved_varying_slot(struct gl_shader *stage, ir_variable_mode io_mode)
+reserved_varying_slot(struct gl_shader *stage, ir_variable_mode io_mode,
+                      int base_location)
 {
    assert(io_mode == ir_var_shader_in || io_mode == ir_var_shader_out);
    assert(MAX_VARYING <= 64); /* avoid an overflow of the returned value */
@@ -1598,10 +1599,10 @@ reserved_varying_slot(struct gl_shader *stage, ir_variable_mode io_mode)
 
       if (var == NULL || var->data.mode != io_mode ||
           !var->data.explicit_location ||
-          var->data.location < VARYING_SLOT_VAR0)
+          var->data.location < base_location)
          continue;
 
-      var_slot = var->data.location - VARYING_SLOT_VAR0;
+      var_slot = var->data.location - base_location;
 
       unsigned num_elements = get_varying_type(var, stage->Stage)
          ->count_attribute_slots(stage->Stage == MESA_SHADER_VERTEX);
@@ -1792,8 +1793,8 @@ assign_varying_locations(struct gl_context *ctx,
    }
 
    const uint64_t reserved_slots =
-      reserved_varying_slot(producer, ir_var_shader_out) |
-      reserved_varying_slot(consumer, ir_var_shader_in);
+      reserved_varying_slot(producer, ir_var_shader_out, VARYING_SLOT_VAR0) |
+      reserved_varying_slot(consumer, ir_var_shader_in, VARYING_SLOT_VAR0);
 
    /* Add varyings with explicit locations to varyings with implicit locations
     * to get the total number of slots used.
@@ -1875,14 +1876,32 @@ assign_varying_locations(struct gl_context *ctx,
    }
 
    if (producer) {
+      if (producer->Stage == MESA_SHADER_VERTEX) {
+         /* Since we only pack vertex inputs with an explicit location we only
+          * need to count those inputs.
+          */
+         const uint64_t reserved_slots =
+            reserved_varying_slot(producer, ir_var_shader_in,
+                                  VERT_ATTRIB_GENERIC0);
+
+         /* Pack vertex inputs with the component layout qualifier */
+         unsigned vertex_attributes = _mesa_bitcount_64(reserved_slots);
+         if (vertex_attributes > 0)
+            lower_packed_varyings(mem_ctx, vertex_attributes,
+                                  ir_var_shader_in, 0, producer,
+                                  VERT_ATTRIB_GENERIC0, true,
+                                  ctx->Extensions.ARB_enhanced_layouts);
+      }
+
       lower_packed_varyings(mem_ctx, slots_used, ir_var_shader_out,
-                            0, producer, disable_varying_packing,
+                            0, producer, VARYING_SLOT_VAR0,
+                            disable_varying_packing,
                             ctx->Extensions.ARB_enhanced_layouts);
    }
 
    if (consumer) {
       lower_packed_varyings(mem_ctx, slots_used, ir_var_shader_in,
-                            consumer_vertices, consumer,
+                            consumer_vertices, consumer, VARYING_SLOT_VAR0,
                             disable_varying_packing,
                             ctx->Extensions.ARB_enhanced_layouts);
    }
diff --git a/src/glsl/lower_packed_varyings.cpp b/src/glsl/lower_packed_varyings.cpp
index 1696373..3ba0af8 100644
--- a/src/glsl/lower_packed_varyings.cpp
+++ b/src/glsl/lower_packed_varyings.cpp
@@ -169,6 +169,7 @@ public:
                                  unsigned gs_input_vertices,
                                  exec_list *out_instructions,
                                  exec_list *out_variables,
+                                 unsigned base_location,
                                  bool disable_varying_packing,
                                  bool has_enhanced_layouts);
 
@@ -197,11 +198,13 @@ private:
     */
    void * const mem_ctx;
 
+   const unsigned base_location;
+
    /**
     * Number of generic varying slots which are used by this shader.  This is
     * used to allocate temporary intermediate data structures.  If any varying
     * used by this shader has a location greater than or equal to
-    * VARYING_SLOT_VAR0 + locations_used, an assertion will fire.
+    * base_location + locations_used, an assertion will fire.
     */
    const unsigned locations_used;
 
@@ -245,9 +248,10 @@ private:
 lower_packed_varyings_visitor::lower_packed_varyings_visitor(
       void *mem_ctx, unsigned locations_used, ir_variable_mode mode,
       unsigned gs_input_vertices, exec_list *out_instructions,
-      exec_list *out_variables, bool disable_varying_packing,
-      bool has_enhanced_layouts)
+      exec_list *out_variables, unsigned base_location,
+      bool disable_varying_packing, bool has_enhanced_layouts)
    : mem_ctx(mem_ctx),
+     base_location(base_location),
      locations_used(locations_used),
      packed_varyings((ir_variable **)
                      rzalloc_array_size(mem_ctx, sizeof(*packed_varyings),
@@ -270,7 +274,7 @@ lower_packed_varyings_visitor::run(struct gl_shader *shader)
          continue;
 
       if (var->data.mode != this->mode ||
-          var->data.location < VARYING_SLOT_VAR0 ||
+          var->data.location < (int) this->base_location ||
           !this->needs_lowering(var))
          continue;
 
@@ -594,7 +598,6 @@ lower_packed_varyings_visitor::lower_arraylike(ir_rvalue *rvalue,
       } else {
          char *subscripted_name
             = ralloc_asprintf(this->mem_ctx, "%s[%d]", name, i);
-
          fine_location =
             this->lower_rvalue(dereference_array, fine_location,
                                unpacked_var, subscripted_name,
@@ -621,7 +624,7 @@ lower_packed_varyings_visitor::get_packed_varying_deref(
       unsigned location, ir_variable *unpacked_var, const char *name,
       unsigned vertex_index)
 {
-   unsigned slot = location - VARYING_SLOT_VAR0;
+   unsigned slot = location - this->base_location;
    assert(slot < locations_used);
    if (this->packed_varyings[slot] == NULL) {
       char *packed_name = ralloc_asprintf(this->mem_ctx, "packed:%s", name);
@@ -748,8 +751,8 @@ lower_packed_varyings_gs_splicer::visit_leave(ir_emit_vertex *ev)
 void
 lower_packed_varyings(void *mem_ctx, unsigned locations_used,
                       ir_variable_mode mode, unsigned gs_input_vertices,
-                      gl_shader *shader, bool disable_varying_packing,
-                      bool has_enhanced_layouts)
+                      gl_shader *shader, unsigned base_location,
+                      bool disable_varying_packing, bool has_enhanced_layouts)
 {
    ir_function *main_func = shader->symbols->get_function("main");
    exec_list void_parameters;
@@ -760,21 +763,20 @@ lower_packed_varyings(void *mem_ctx, unsigned locations_used,
          shader->Stage == MESA_SHADER_TESS_EVAL)) {
       exec_list *instructions = shader->ir;
       exec_list new_instructions, new_variables;
-
       lower_packed_varyings_visitor visitor(mem_ctx, locations_used, mode,
                                             gs_input_vertices,
                                             &new_instructions,
                                             &new_variables,
+                                            base_location,
                                             disable_varying_packing,
                                             has_enhanced_layouts);
       visitor.run(shader);
       if (mode == ir_var_shader_out) {
          if (shader->Stage == MESA_SHADER_GEOMETRY) {
-            /* For geometry shaders, outputs need to be lowered before each
-             * call to EmitVertex()
+            /* For geometry shaders, outputs need to be lowered before each call
+             * to EmitVertex()
              */
-            lower_packed_varyings_gs_splicer splicer(mem_ctx,
-                                                     &new_instructions);
+            lower_packed_varyings_gs_splicer splicer(mem_ctx, &new_instructions);
 
             /* Add all the variables in first. */
             main_func_sig->body.head->insert_before(&new_variables);
-- 
2.4.3



More information about the mesa-dev mailing list