[Mesa-dev] [PATCH 19/19] glsl: Don't allow gl_PerVertex to be redeclared after it's been used.

Paul Berry stereotype441 at gmail.com
Wed Oct 2 17:45:32 PDT 2013


Fixes piglit tests:
- spec/glsl-1.50/compiler/gs-redeclares-pervertex-in-after-other-usage.geom
- spec/glsl-1.50/compiler/gs-redeclares-pervertex-out-after-other-usage.geom
- spec/glsl-1.50/compiler/gs-redeclares-pervertex-out-after-usage.geom
- spec/glsl-1.50/compiler/vs-redeclares-pervertex-out-after-other-usage.vert
- spec/glsl-1.50/compiler/vs-redeclares-pervertex-out-after-usage.vert
---
 src/glsl/ast_to_hir.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index a4af562..0294036 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -4611,6 +4611,39 @@ ast_struct_specifier::hir(exec_list *instructions,
    return NULL;
 }
 
+
+/**
+ * Visitor class which detects whether a given interface block has been used.
+ */
+class interface_block_usage_visitor : public ir_hierarchical_visitor
+{
+public:
+   interface_block_usage_visitor(ir_variable_mode mode, const glsl_type *block)
+      : mode(mode), block(block), found(false)
+   {
+   }
+
+   virtual ir_visitor_status visit(ir_dereference_variable *ir)
+   {
+      if (ir->var->mode == mode && ir->var->get_interface_type() == block) {
+         found = true;
+         return visit_stop;
+      }
+      return visit_continue;
+   }
+
+   bool usage_found() const
+   {
+      return this->found;
+   }
+
+private:
+   ir_variable_mode mode;
+   const glsl_type *block;
+   bool found;
+};
+
+
 ir_rvalue *
 ast_interface_block::hir(exec_list *instructions,
 		          struct _mesa_glsl_parse_state *state)
@@ -4737,6 +4770,26 @@ ast_interface_block::hir(exec_list *instructions,
                earlier_per_vertex->fields.structure[j].location;
          }
       }
+
+      /* From section 7.1 ("Built-in Language Variables") of the GLSL 4.10
+       * spec:
+       *
+       *     If a built-in interface block is redeclared, it must appear in
+       *     the shader before any use of any member included in the built-in
+       *     declaration, or a compilation error will result.
+       *
+       * This appears to be a clarification to the behaviour established for
+       * gl_PerVertex by GLSL 1.50, therefore we implement this behaviour
+       * regardless of GLSL version.
+       */
+      interface_block_usage_visitor v(var_mode, earlier_per_vertex);
+      v.run(instructions);
+      if (v.usage_found()) {
+         _mesa_glsl_error(&loc, state,
+                          "redeclaration of a built-in interface block must "
+                          "appear before any use of any member of the "
+                          "interface block");
+      }
    }
 
    const glsl_type *block_type =
-- 
1.8.4



More information about the mesa-dev mailing list