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

Timothy Arceri timothy.arceri at collabora.com
Mon Dec 21 22:02:03 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 | 20 ++++++++++++--------
 3 files changed, 39 insertions(+), 15 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 543153e..dd96c03 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -1583,7 +1583,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 */
@@ -1599,10 +1600,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);
@@ -1793,8 +1794,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.
@@ -1822,10 +1823,28 @@ assign_varying_locations(struct gl_context *ctx,
    hash_table_dtor(consumer_interface_inputs);
 
    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);
+      }
+
       remove_unused_shader_inputs_and_outputs(prog, producer,
                                               ir_var_shader_out);
       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);
    }
 
@@ -1833,7 +1852,7 @@ assign_varying_locations(struct gl_context *ctx,
       remove_unused_shader_inputs_and_outputs(prog, consumer,
                                               ir_var_shader_in);
       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 cfba9af..9a8c336 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)
 {
    exec_list *instructions = shader->ir;
    ir_function *main_func = shader->symbols->get_function("main");
@@ -761,6 +764,7 @@ lower_packed_varyings(void *mem_ctx, unsigned locations_used,
                                          gs_input_vertices,
                                          &new_instructions,
                                          &new_variables,
+                                         base_location,
                                          disable_varying_packing,
                                          has_enhanced_layouts);
    visitor.run(shader);
-- 
2.4.3



More information about the mesa-dev mailing list