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

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to