glsl: add a mechanism to allow layout qualifiers on function params
authorTimothy Arceri <tarceri@itsqueeze.com>
Wed, 29 Aug 2018 05:48:46 +0000 (15:48 +1000)
committerTimothy Arceri <tarceri@itsqueeze.com>
Wed, 29 Aug 2018 23:54:40 +0000 (09:54 +1000)
The spec is quite clear this is not allowed:

    From Section 4.4. (Layout Qualifiers) of the GLSL 4.60 spec:

       "Layout qualifiers can appear in several forms of declaration.
       They can appear as part of an interface block definition or
       block member, as shown in the grammar in the previous section.
       They can also appear with just an interface-qualifier to establish
       layouts of other declarations made with that qualifier:

          layout-qualifier interface-qualifier ;

       Or, they can appear with an individual variable declared with
       an interface qualifier:

          layout-qualifier interface-qualifier declaration ;"

    From Section 4.10 (Memory Qualifiers) of the GLSL 4.60 spec:

       "Layout qualifiers cannot be used on formal function parameters,
       and layout qualification is not included in parameter matching."

However on the Nvidia binary driver they actually fail to compile
if image function params don't have a layout qualifier. This results
in applications such as No Mans Sky using layout qualifiers on params.

I've submitted a CTS test to expose this problem in the Nvidia driver
but until that is resolved this patch will help Mesa drivers work
around the issue.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/compiler/glsl/glsl_parser.yy
src/compiler/glsl/glsl_parser_extras.cpp
src/compiler/glsl/glsl_parser_extras.h
src/mesa/main/mtypes.h

index bc2571b6844cde301b9d56a911e732a9c67ae8b5..fd1592beca0e3ddc02f4d8d74c7f6f2cfe0ce1f6 100644 (file)
@@ -897,6 +897,23 @@ parameter_declarator:
       $$->identifier = $2;
       state->symbols->add_variable(new(state) ir_variable(NULL, $2, ir_var_auto));
    }
+   | layout_qualifier type_specifier any_identifier
+   {
+      if (state->allow_layout_qualifier_on_function_parameter) {
+         void *ctx = state->linalloc;
+         $$ = new(ctx) ast_parameter_declarator();
+         $$->set_location_range(@2, @3);
+         $$->type = new(ctx) ast_fully_specified_type();
+         $$->type->set_location(@2);
+         $$->type->specifier = $2;
+         $$->identifier = $3;
+         state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
+      } else {
+         _mesa_glsl_error(&@1, state,
+                          "is is not allowed on function parameter");
+         YYERROR;
+      }
+   }
    | type_specifier any_identifier array_specifier
    {
       void *ctx = state->linalloc;
index 21d41224440461a32b0c092f64c97190cb1c81b8..1bdd7c4bf17cd259678e8f736a33cb01e0ffef15 100644 (file)
@@ -311,6 +311,8 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
       ctx->Const.AllowGLSLExtensionDirectiveMidShader;
    this->allow_builtin_variable_redeclaration =
       ctx->Const.AllowGLSLBuiltinVariableRedeclaration;
+   this->allow_layout_qualifier_on_function_parameter =
+      ctx->Const.AllowLayoutQualifiersOnFunctionParameters;
 
    this->cs_input_local_size_variable_specified = false;
 
index e03b34d7d6c10dee7381d1632c4a67b84e51d3f7..966d848509cf111055240d29ac78b6b95dc21290 100644 (file)
@@ -868,6 +868,7 @@ struct _mesa_glsl_parse_state {
 
    bool allow_extension_directive_midshader;
    bool allow_builtin_variable_redeclaration;
+   bool allow_layout_qualifier_on_function_parameter;
 
    /**
     * Known subroutine type declarations.
index 718293be116bfe05f86a8b011a04f535290a5203..5ff0d3227a85738b6c1ffe6dd345afb50f64a73e 100644 (file)
@@ -3768,6 +3768,11 @@ struct gl_constants
     */
    GLboolean AllowHigherCompatVersion;
 
+   /**
+    * Allow layout qualifiers on function parameters.
+    */
+   GLboolean AllowLayoutQualifiersOnFunctionParameters;
+
    /**
     * Force computing the absolute value for sqrt() and inversesqrt() to follow
     * D3D9 when apps rely on this behaviour.