glsl: Combine GS and TES array resizing visitors.
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 8 Jul 2016 20:29:31 +0000 (13:29 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 8 Aug 2016 06:53:59 +0000 (23:53 -0700)
These are largely identical, except that the GS version has a few
extra error conditions.  We can just pass in the stage and skip these.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Timothy Arceri <timothy.arceri@collabora.com>
src/compiler/glsl/linker.cpp

index 1c8860ece2539dd9ccc153ec9889c51f0dcfaa6f..f4049133ee69b201a977352f6ec3cb78a6071e60 100644 (file)
@@ -180,49 +180,57 @@ private:
 };
 
 
-class geom_array_resize_visitor : public ir_hierarchical_visitor {
+class array_resize_visitor : public ir_hierarchical_visitor {
 public:
    unsigned num_vertices;
    gl_shader_program *prog;
+   gl_shader_stage stage;
 
-   geom_array_resize_visitor(unsigned num_vertices, gl_shader_program *prog)
+   array_resize_visitor(unsigned num_vertices,
+                        gl_shader_program *prog,
+                        gl_shader_stage stage)
    {
       this->num_vertices = num_vertices;
       this->prog = prog;
+      this->stage = stage;
    }
 
-   virtual ~geom_array_resize_visitor()
+   virtual ~array_resize_visitor()
    {
       /* empty */
    }
 
    virtual ir_visitor_status visit(ir_variable *var)
    {
-      if (!var->type->is_array() || var->data.mode != ir_var_shader_in)
+      if (!var->type->is_array() || var->data.mode != ir_var_shader_in ||
+          var->data.patch)
          return visit_continue;
 
       unsigned size = var->type->length;
 
-      /* Generate a link error if the shader has declared this array with an
-       * incorrect size.
-       */
-      if (!var->data.implicit_sized_array &&
-          size && size != this->num_vertices) {
-         linker_error(this->prog, "size of array %s declared as %u, "
-                      "but number of input vertices is %u\n",
-                      var->name, size, this->num_vertices);
-         return visit_continue;
-      }
+      if (stage == MESA_SHADER_GEOMETRY) {
+         /* Generate a link error if the shader has declared this array with
+          * an incorrect size.
+          */
+         if (!var->data.implicit_sized_array &&
+             size && size != this->num_vertices) {
+            linker_error(this->prog, "size of array %s declared as %u, "
+                         "but number of input vertices is %u\n",
+                         var->name, size, this->num_vertices);
+            return visit_continue;
+         }
 
-      /* Generate a link error if the shader attempts to access an input
-       * array using an index too large for its actual size assigned at link
-       * time.
-       */
-      if (var->data.max_array_access >= (int)this->num_vertices) {
-         linker_error(this->prog, "geometry shader accesses element %i of "
-                      "%s, but only %i input vertices\n",
-                      var->data.max_array_access, var->name, this->num_vertices);
-         return visit_continue;
+         /* Generate a link error if the shader attempts to access an input
+          * array using an index too large for its actual size assigned at
+          * link time.
+          */
+         if (var->data.max_array_access >= (int)this->num_vertices) {
+            linker_error(this->prog, "%s shader accesses element %i of "
+                         "%s, but only %i input vertices\n",
+                         _mesa_shader_stage_to_string(this->stage),
+                         var->data.max_array_access, var->name, this->num_vertices);
+            return visit_continue;
+         }
       }
 
       var->type = glsl_type::get_array_instance(var->type->fields.array,
@@ -251,53 +259,6 @@ public:
    }
 };
 
-class tess_eval_array_resize_visitor : public ir_hierarchical_visitor {
-public:
-   unsigned num_vertices;
-   gl_shader_program *prog;
-
-   tess_eval_array_resize_visitor(unsigned num_vertices, gl_shader_program *prog)
-   {
-      this->num_vertices = num_vertices;
-      this->prog = prog;
-   }
-
-   virtual ~tess_eval_array_resize_visitor()
-   {
-      /* empty */
-   }
-
-   virtual ir_visitor_status visit(ir_variable *var)
-   {
-      if (!var->type->is_array() || var->data.mode != ir_var_shader_in || var->data.patch)
-         return visit_continue;
-
-      var->type = glsl_type::get_array_instance(var->type->fields.array,
-                                                this->num_vertices);
-      var->data.max_array_access = this->num_vertices - 1;
-
-      return visit_continue;
-   }
-
-   /* Dereferences of input variables need to be updated so that their type
-    * matches the newly assigned type of the variable they are accessing. */
-   virtual ir_visitor_status visit(ir_dereference_variable *ir)
-   {
-      ir->type = ir->var->type;
-      return visit_continue;
-   }
-
-   /* Dereferences of 2D input arrays need to be updated so that their type
-    * matches the newly assigned type of the array they are accessing. */
-   virtual ir_visitor_status visit_leave(ir_dereference_array *ir)
-   {
-      const glsl_type *const vt = ir->array->type;
-      if (vt->is_array())
-         ir->type = vt->fields.array;
-      return visit_continue;
-   }
-};
-
 class barrier_use_visitor : public ir_hierarchical_visitor {
 public:
    barrier_use_visitor(gl_shader_program *prog)
@@ -2369,7 +2330,8 @@ link_intrastage_shaders(void *mem_ctx,
    /* Set the size of geometry shader input arrays */
    if (linked->Stage == MESA_SHADER_GEOMETRY) {
       unsigned num_vertices = vertices_per_prim(linked->info.Geom.InputType);
-      geom_array_resize_visitor input_resize_visitor(num_vertices, prog);
+      array_resize_visitor input_resize_visitor(num_vertices, prog,
+                                                MESA_SHADER_GEOMETRY);
       foreach_in_list(ir_instruction, ir, linked->ir) {
          ir->accept(&input_resize_visitor);
       }
@@ -2496,7 +2458,8 @@ resize_tes_inputs(struct gl_context *ctx,
       ? tcs->info.TessCtrl.VerticesOut
       : ctx->Const.MaxPatchVertices;
 
-   tess_eval_array_resize_visitor input_resize_visitor(num_vertices, prog);
+   array_resize_visitor input_resize_visitor(num_vertices, prog,
+                                             MESA_SHADER_TESS_EVAL);
    foreach_in_list(ir_instruction, ir, tes->ir) {
       ir->accept(&input_resize_visitor);
    }