Mesa (master): glsl: Error check redeclarations of gl_PerVertex.

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


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

Author: Paul Berry <stereotype441 at gmail.com>
Date:   Wed Oct  2 11:21:04 2013 -0700

glsl: Error check redeclarations of gl_PerVertex.

This patch verifies that:

- The gl_PerVertex input interface block may only be redeclared in a
  geometry shader, and that it may only be redeclared as gl_in[].

- The gl_PerVertex output interface block may only be redeclared in a
  vertex or geometry shader, and that it may only be redeclared as a
  non-array without an interface name.

- gl_PerVertex may not be redeclared as any other type of interface
  block (i.e. as a uniform interface block).

As a side-effect, the code now keeps track of what the previous
declaration of gl_PerVertex was--this will be needed in future
patches.

Fixes piglit tests:
- spec/glsl-1.50/compiler/gs-redeclares-pervertex-in-with-incorrect-name.geom
- spec/glsl-1.50/compiler/gs-redeclares-pervertex-out-as-array.geom
- spec/glsl-1.50/compiler/gs-redeclares-pervertex-out-with-instance-name.geom

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

---

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

diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index b1bfa06..eaaa7d9 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -4654,6 +4654,66 @@ ast_interface_block::hir(exec_list *instructions,
    if (!redeclaring_per_vertex)
       validate_identifier(this->block_name, loc, state);
 
+   const glsl_type *earlier_per_vertex = NULL;
+   if (redeclaring_per_vertex) {
+      /* Find the previous declaration of gl_PerVertex.  If we're redeclaring
+       * the named interface block gl_in, we can find it by looking at the
+       * previous declaration of gl_in.  Otherwise we can find it by looking
+       * at the previous decalartion of any of the built-in outputs,
+       * e.g. gl_Position.
+       *
+       * Also check that the instance name and array-ness of the redeclaration
+       * are correct.
+       */
+      switch (var_mode) {
+      case ir_var_shader_in:
+         if (ir_variable *earlier_gl_in =
+             state->symbols->get_variable("gl_in")) {
+            earlier_per_vertex = earlier_gl_in->get_interface_type();
+         } else {
+            _mesa_glsl_error(&loc, state,
+                             "redeclaration of gl_PerVertex input not allowed "
+                             "in the %s shader",
+                             _mesa_glsl_shader_target_name(state->target));
+         }
+         if (this->instance_name == NULL ||
+             strcmp(this->instance_name, "gl_in") != 0 || !this->is_array) {
+            _mesa_glsl_error(&loc, state,
+                             "gl_PerVertex input must be redeclared as "
+                             "gl_in[]");
+         }
+         break;
+      case ir_var_shader_out:
+         if (ir_variable *earlier_gl_Position =
+             state->symbols->get_variable("gl_Position")) {
+            earlier_per_vertex = earlier_gl_Position->get_interface_type();
+         } else {
+            _mesa_glsl_error(&loc, state,
+                             "redeclaration of gl_PerVertex output not "
+                             "allowed in the %s shader",
+                             _mesa_glsl_shader_target_name(state->target));
+         }
+         if (this->instance_name != NULL) {
+            _mesa_glsl_error(&loc, state,
+                             "gl_PerVertex input may not be redeclared with "
+                             "an instance name");
+         }
+         break;
+      default:
+         _mesa_glsl_error(&loc, state,
+                          "gl_PerVertex must be declared as an input or an "
+                          "output");
+         break;
+      }
+
+      if (earlier_per_vertex == NULL) {
+         /* An error has already been reported.  Bail out to avoid null
+          * dereferences later in this function.
+          */
+         return NULL;
+      }
+   }
+
    const glsl_type *block_type =
       glsl_type::get_interface_instance(fields,
                                         num_variables,




More information about the mesa-commit mailing list