[Mesa-dev] [PATCH V2 05/12] glsl: add layout qualifier validation for the shader outside the parser

Timothy Arceri t_arceri at yahoo.com.au
Sun Nov 8 14:34:34 PST 2015


From: Timothy Arceri <timothy.arceri at collabora.com>

This is in preparation for compile-time constant support, a later patch
will remove the validation from the shader.

The global shader layout qualifiers will now mostly be validated in
glsl_parser_extras.cpp.

In order to do validation at the later stage in glsl_parser_extras.cpp we
need to temporarily add a field in ast_type_qualifier to keep track of the
parser location, this will be removed in a following patch when we
introduce a new type for storing the comiple-time qualifiers.

Also as the set_shader_inout_layout() function in glsl parser extras is
normally called after all validation is done we need to move the code that
sets CompileStatus and InfoLog otherwise the newly add error messages would
be ignored.
---
 src/glsl/ast_to_hir.cpp         | 14 ++++++++++++--
 src/glsl/ast_type.cpp           |  2 ++
 src/glsl/glsl_parser_extras.cpp | 37 ++++++++++++++++++++++++++++++++-----
 3 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 0cea607..5643c86 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -3544,10 +3544,19 @@ static void
 handle_tess_ctrl_shader_output_decl(struct _mesa_glsl_parse_state *state,
                                     YYLTYPE loc, ir_variable *var)
 {
-   unsigned num_vertices = 0;
+   int num_vertices = 0;
 
    if (state->tcs_output_vertices_specified) {
       num_vertices = state->out_qualifier->vertices;
+      if (num_vertices <= 0) {
+         _mesa_glsl_error(&loc, state, "invalid vertices (%d) specified",
+                          num_vertices);
+         return;
+      } else if ((unsigned) num_vertices > state->Const.MaxPatchVertices) {
+         _mesa_glsl_error(&loc, state, "vertices (%d) exceeds "
+                          "GL_MAX_PATCH_VERTICES", num_vertices);
+         return;
+      }
    }
 
    if (!var->type->is_array() && !var->data.patch) {
@@ -3561,7 +3570,8 @@ handle_tess_ctrl_shader_output_decl(struct _mesa_glsl_parse_state *state,
    if (var->data.patch)
       return;
 
-   validate_layout_qualifier_vertex_count(state, loc, var, num_vertices,
+   validate_layout_qualifier_vertex_count(state, loc, var,
+                                          (unsigned) num_vertices,
                                           &state->tcs_output_size,
                                           "tessellation control shader output");
 }
diff --git a/src/glsl/ast_type.cpp b/src/glsl/ast_type.cpp
index 08a4504..53d1023 100644
--- a/src/glsl/ast_type.cpp
+++ b/src/glsl/ast_type.cpp
@@ -310,6 +310,7 @@ ast_type_qualifier::merge_out_qualifier(YYLTYPE *loc,
 {
    void *mem_ctx = state;
    const bool r = this->merge_qualifier(loc, state, q);
+   this->loc = loc;
 
    if (state->stage == MESA_SHADER_TESS_CTRL) {
       node = new(mem_ctx) ast_tcs_output_layout(*loc, q.vertices);
@@ -329,6 +330,7 @@ ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc,
    bool create_cs_ast = false;
    ast_type_qualifier valid_in_mask;
    valid_in_mask.flags.i = 0;
+   this->loc = loc;
 
    switch (state->stage) {
    case MESA_SHADER_TESS_EVAL:
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index 2dba7d9..7d7f45c 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -947,6 +947,14 @@ _mesa_ast_process_interface_block(YYLTYPE *locp,
 
    if (state->stage == MESA_SHADER_GEOMETRY &&
        state->has_explicit_attrib_stream()) {
+
+      if (state->out_qualifier->flags.q.explicit_stream) {
+         if (state->out_qualifier->stream < 0) {
+            _mesa_glsl_error(locp, state, "invalid stream %d specified",
+                             state->out_qualifier->stream);
+         }
+      }
+
       /* Assign global layout's stream value. */
       block->layout.flags.q.stream = 1;
       block->layout.flags.q.explicit_stream = 0;
@@ -1615,7 +1623,7 @@ void ast_subroutine_list::print(void) const
 
 static void
 set_shader_inout_layout(struct gl_shader *shader,
-		     struct _mesa_glsl_parse_state *state)
+                        struct _mesa_glsl_parse_state *state)
 {
    /* Should have been prevented by the parser. */
    if (shader->Stage == MESA_SHADER_TESS_CTRL) {
@@ -1666,8 +1674,14 @@ set_shader_inout_layout(struct gl_shader *shader,
       break;
    case MESA_SHADER_GEOMETRY:
       shader->Geom.VerticesOut = 0;
-      if (state->out_qualifier->flags.q.max_vertices)
+      if (state->out_qualifier->flags.q.max_vertices) {
+         if (state->out_qualifier->max_vertices < 0) {
+            _mesa_glsl_error(state->out_qualifier->loc, state,
+                             "invalid max_vertices %d specified",
+                             state->out_qualifier->max_vertices);
+         }
          shader->Geom.VerticesOut = state->out_qualifier->max_vertices;
+      }
 
       if (state->gs_input_prim_type_specified) {
          shader->Geom.InputType = state->in_qualifier->prim_type;
@@ -1682,8 +1696,20 @@ set_shader_inout_layout(struct gl_shader *shader,
       }
 
       shader->Geom.Invocations = 0;
-      if (state->in_qualifier->flags.q.invocations)
+      if (state->in_qualifier->flags.q.invocations) {
+         if (state->in_qualifier->invocations <= 0) {
+            _mesa_glsl_error(state->in_qualifier->loc, state,
+                             "invalid invocations %d specified",
+                             state->in_qualifier->invocations);
+         } else if (state->in_qualifier->invocations >
+                    MAX_GEOMETRY_SHADER_INVOCATIONS) {
+            _mesa_glsl_error(state->in_qualifier->loc, state,
+                             "invocations (%d) exceeds "
+                             "GL_MAX_GEOMETRY_SHADER_INVOCATIONS",
+                             state->in_qualifier->invocations);
+         }
          shader->Geom.Invocations = state->in_qualifier->invocations;
+      }
       break;
 
    case MESA_SHADER_COMPUTE:
@@ -1796,8 +1822,6 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
       ralloc_free(shader->InfoLog);
 
    shader->symbols = new(shader->ir) glsl_symbol_table;
-   shader->CompileStatus = !state->error;
-   shader->InfoLog = state->info_log;
    shader->Version = state->language_version;
    shader->IsES = state->es_shader;
    shader->uses_builtin_functions = state->uses_builtin_functions;
@@ -1805,6 +1829,9 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
    if (!state->error)
       set_shader_inout_layout(shader, state);
 
+   shader->CompileStatus = !state->error;
+   shader->InfoLog = state->info_log;
+
    /* Retain any live IR, but trash the rest. */
    reparent_ir(shader->ir, shader->ir);
 
-- 
2.4.3



More information about the mesa-dev mailing list