Mesa (master): glsl: Don't allow gl_PerVertex to be redeclared after it' s been used.

Paul Berry stereotype441 at kemper.freedesktop.org
Thu Oct 10 21:46:58 UTC 2013


Module: Mesa
Branch: master
Commit: 8cb9cce0400362e913ad89f4ae981b8baf86bb57
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8cb9cce0400362e913ad89f4ae981b8baf86bb57

Author: Paul Berry <stereotype441 at gmail.com>
Date:   Tue Oct  1 15:48:07 2013 -0700

glsl: Don't allow gl_PerVertex to be redeclared after it's been used.

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

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

---

 src/glsl/ast_to_hir.cpp |   53 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index d64d548..dfa32d9 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 =




More information about the mesa-commit mailing list