[Mesa-dev] [RFC PATCH 47/56] glsl: support separate vertex count for producer when linking

Chris Forbes chrisf at ijw.co.nz
Sat Sep 20 18:41:27 PDT 2014


Before tessellation, the only special case was linking VS -> GS, where
the VS has one output vertex and the GS has N input vertices.

Now we also get to deal with the TCS -> TES linking, where both
sides are arrays of vertices.
---
 src/glsl/ir_optimization.h         |  2 +-
 src/glsl/link_varyings.cpp         | 19 ++++++++++++++++---
 src/glsl/lower_packed_varyings.cpp | 32 ++++++++++++++++----------------
 3 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h
index 389aed1..be9d4ad 100644
--- a/src/glsl/ir_optimization.h
+++ b/src/glsl/ir_optimization.h
@@ -120,7 +120,7 @@ bool lower_packing_builtins(exec_list *instructions, int op_mask);
 void lower_ubo_reference(struct gl_shader *shader, exec_list *instructions);
 void lower_packed_varyings(void *mem_ctx,
                            unsigned locations_used, ir_variable_mode mode,
-                           unsigned gs_input_vertices, gl_shader *shader);
+                           unsigned num_vertices, gl_shader *shader);
 bool lower_vector_insert(exec_list *instructions, bool lower_nonconstant_index);
 void lower_named_interface_blocks(void *mem_ctx, gl_shader *shader);
 bool optimize_redundant_jumps(exec_list *instructions);
diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
index 4d45797..05d90a6 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -1345,8 +1345,21 @@ assign_varying_locations(struct gl_context *ctx,
    };
 
    unsigned consumer_vertices = 0;
-   if (consumer && consumer->Stage == MESA_SHADER_GEOMETRY)
-      consumer_vertices = prog->Geom.VerticesIn;
+   unsigned producer_vertices = 0;
+
+   if (consumer) {
+      if (consumer->Stage == MESA_SHADER_GEOMETRY)
+         consumer_vertices = prog->Geom.VerticesIn;
+      if (consumer->Stage == MESA_SHADER_TESS_CTRL)
+         consumer_vertices = ctx->Const.MaxPatchVertices;
+      if (consumer->Stage == MESA_SHADER_TESS_EVAL)
+         consumer_vertices = ctx->Const.MaxPatchVertices;
+   }
+
+   if (producer) {
+      if (producer->Stage == MESA_SHADER_TESS_CTRL)
+         producer_vertices = prog->TessCtrl.VerticesOut;
+   }
 
    /* Operate in a total of four passes.
     *
@@ -1483,7 +1496,7 @@ assign_varying_locations(struct gl_context *ctx,
    } else {
       if (producer) {
          lower_packed_varyings(mem_ctx, slots_used, ir_var_shader_out,
-                               0, producer);
+                               producer_vertices, producer);
       }
       if (consumer) {
          lower_packed_varyings(mem_ctx, slots_used, ir_var_shader_in,
diff --git a/src/glsl/lower_packed_varyings.cpp b/src/glsl/lower_packed_varyings.cpp
index 0c8696d..41ce8f4 100644
--- a/src/glsl/lower_packed_varyings.cpp
+++ b/src/glsl/lower_packed_varyings.cpp
@@ -162,7 +162,7 @@ class lower_packed_varyings_visitor
 public:
    lower_packed_varyings_visitor(void *mem_ctx, unsigned locations_used,
                                  ir_variable_mode mode,
-                                 unsigned gs_input_vertices,
+                                 unsigned num_vertices,
                                  exec_list *out_instructions);
 
    void run(exec_list *instructions);
@@ -210,10 +210,10 @@ private:
    const ir_variable_mode mode;
 
    /**
-    * If we are currently lowering geometry shader inputs, the number of input
-    * vertices the geometry shader accepts.  Otherwise zero.
+    * If we are currently lowering an interface consisting of multiple vertices,
+    * the number of vertices accepted. Otherwise zero.
     */
-   const unsigned gs_input_vertices;
+   const unsigned num_vertices;
 
    /**
     * Exec list into which the visitor should insert the packing instructions.
@@ -227,14 +227,14 @@ 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)
+      unsigned num_vertices, exec_list *out_instructions)
    : mem_ctx(mem_ctx),
      locations_used(locations_used),
      packed_varyings((ir_variable **)
                      rzalloc_array_size(mem_ctx, sizeof(*packed_varyings),
                                         locations_used)),
      mode(mode),
-     gs_input_vertices(gs_input_vertices),
+     num_vertices(num_vertices),
      out_instructions(out_instructions)
 {
 }
@@ -269,7 +269,7 @@ lower_packed_varyings_visitor::run(exec_list *instructions)
 
       /* Recursively pack or unpack it. */
       this->lower_rvalue(deref, var->data.location * 4 + var->data.location_frac, var,
-                         var->name, this->gs_input_vertices != 0, 0);
+                         var->name, this->num_vertices != 0, 0);
    }
 }
 
@@ -540,18 +540,18 @@ lower_packed_varyings_visitor::get_packed_varying_deref(
          packed_type = glsl_type::ivec4_type;
       else
          packed_type = glsl_type::vec4_type;
-      if (this->gs_input_vertices != 0) {
+      if (this->num_vertices != 0) {
          packed_type =
             glsl_type::get_array_instance(packed_type,
-                                          this->gs_input_vertices);
+                                          this->num_vertices);
       }
       ir_variable *packed_var = new(this->mem_ctx)
          ir_variable(packed_type, packed_name, this->mode);
-      if (this->gs_input_vertices != 0) {
+      if (this->num_vertices != 0) {
          /* Prevent update_array_sizes() from messing with the size of the
           * array.
           */
-         packed_var->data.max_array_access = this->gs_input_vertices - 1;
+         packed_var->data.max_array_access = this->num_vertices - 1;
       }
       packed_var->data.centroid = unpacked_var->data.centroid;
       packed_var->data.sample = unpacked_var->data.sample;
@@ -564,7 +564,7 @@ lower_packed_varyings_visitor::get_packed_varying_deref(
       /* For geometry shader inputs, only update the packed variable name the
        * first time we visit each component.
        */
-      if (this->gs_input_vertices == 0 || vertex_index == 0) {
+      if (this->num_vertices == 0 || vertex_index == 0) {
          ralloc_asprintf_append((char **) &this->packed_varyings[slot]->name,
                                 ",%s", name);
       }
@@ -572,7 +572,7 @@ lower_packed_varyings_visitor::get_packed_varying_deref(
 
    ir_dereference *deref = new(this->mem_ctx)
       ir_dereference_variable(this->packed_varyings[slot]);
-   if (this->gs_input_vertices != 0) {
+   if (this->num_vertices != 0) {
       /* When lowering GS inputs, the packed variable is an array, so we need
        * to dereference it using vertex_index.
        */
@@ -592,7 +592,7 @@ lower_packed_varyings_visitor::needs_lowering(ir_variable *var)
       return false;
 
    const glsl_type *type = var->type;
-   if (this->gs_input_vertices != 0) {
+   if (this->num_vertices != 0) {
       assert(type->is_array());
       type = type->element_type();
    }
@@ -649,7 +649,7 @@ 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,
+                      ir_variable_mode mode, unsigned num_vertices,
                       gl_shader *shader)
 {
    exec_list *instructions = shader->ir;
@@ -659,7 +659,7 @@ lower_packed_varyings(void *mem_ctx, unsigned locations_used,
       = main_func->matching_signature(NULL, &void_parameters, false);
    exec_list new_instructions;
    lower_packed_varyings_visitor visitor(mem_ctx, locations_used, mode,
-                                         gs_input_vertices, &new_instructions);
+                                         num_vertices, &new_instructions);
    visitor.run(instructions);
    if (mode == ir_var_shader_out) {
       if (shader->Stage == MESA_SHADER_GEOMETRY) {
-- 
2.1.0



More information about the mesa-dev mailing list