glsl: Add parser support for GL_ARB_explicit_attrib_location layouts
authorIan Romanick <ian.d.romanick@intel.com>
Wed, 6 Oct 2010 00:00:31 +0000 (17:00 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Fri, 8 Oct 2010 21:21:22 +0000 (14:21 -0700)
Only layout(location=#) is supported.  Setting the index requires GLSL
1.30 and GL_ARB_blend_func_extended.

src/glsl/ast.h
src/glsl/glsl_lexer.lpp
src/glsl/glsl_parser.ypp
src/glsl/glsl_parser_extras.cpp
src/glsl/glsl_parser_extras.h

index 5fa932ec80635c2ac2592e7ee9335f9ca301a5a8..e5aa5c1b3b5925207702eff31edca7b68c5f2b6c 100644 (file)
@@ -343,9 +343,23 @@ struct ast_type_qualifier {
         unsigned origin_upper_left:1;
         unsigned pixel_center_integer:1;
         /*@}*/
+
+        /**
+         * Flag set if GL_ARB_explicit_attrib_location "location" layout
+         * qualifier is used.
+         */
+        unsigned explicit_location:1;
       } q;
       unsigned i;
    } flags;
+
+   /**
+    * Location specified via GL_ARB_explicit_attrib_location layout
+    *
+    * \note
+    * This field is only valid if \c explicit_location is set.
+    */
+   unsigned location;
 };
 
 class ast_struct_specifier : public ast_node {
index ed3cb251a1a81eb2f544b22ba3d7ba48ebe5fe8b..8be5c67fc2b7152b8a19b59b8da215fceb9943f7 100644 (file)
@@ -218,6 +218,7 @@ void                return VOID_TOK;
 
 layout         {
                  if ((yyextra->language_version >= 140)
+                     || yyextra->ARB_explicit_attrib_location_enable
                      || (yyextra->ARB_fragment_coord_conventions_enable)){
                      return LAYOUT_TOK;
                   } else {
index 16d39dc565ef8af4f5149feb8b9e41c52bd94a93..ed18179beb701c211c701e9cb208a03287caa1c4 100644 (file)
@@ -983,10 +983,19 @@ layout_qualifier_id_list:
        layout_qualifier_id
        | layout_qualifier_id_list ',' layout_qualifier_id
        {
-          /* FINISHME: Should check for conflicting / duplicate flags here.
-           */
-          $$ = $1;
-          $$.flags.i |= $3.flags.i;
+          if (($1.flags.i & $3.flags.i) != 0) {
+             _mesa_glsl_error(& @3, state,
+                              "duplicate layout qualifiers used\n");
+             YYERROR;
+          }
+
+          $$.flags.i = $1.flags.i | $3.flags.i;
+
+          if ($1.flags.q.explicit_location)
+             $$.location = $1.location;
+
+          if ($3.flags.q.explicit_location)
+             $$.location = $3.location;
        }
        ;
 
@@ -1020,6 +1029,44 @@ layout_qualifier_id:
                                 "identifier `%s' used\n", $1);
           }
        }
+       | IDENTIFIER '=' INTCONSTANT
+       {
+          bool got_one = false;
+
+          memset(& $$, 0, sizeof($$));
+
+          if (state->ARB_explicit_attrib_location_enable) {
+             /* FINISHME: Handle 'index' once GL_ARB_blend_func_exteneded and
+              * FINISHME: GLSL 1.30 (or later) are supported.
+              */
+             if (strcmp("location", $1) == 0) {
+                got_one = true;
+
+                $$.flags.q.explicit_location = 1;
+
+                if ($3 >= 0) {
+                   $$.location = $3;
+                } else {
+                   _mesa_glsl_error(& @3, state,
+                                    "invalid location %d specified\n", $3);
+                   YYERROR;
+                }
+             }
+          }
+
+          /* If the identifier didn't match any known layout identifiers,
+           * emit an error.
+           */
+          if (!got_one) {
+             _mesa_glsl_error(& @1, state, "unrecognized layout identifier "
+                              "`%s'\n", $1);
+             YYERROR;
+          } else if (state->ARB_explicit_attrib_location_warn) {
+             _mesa_glsl_warning(& @1, state,
+                                "GL_ARB_explicit_attrib_location layout "
+                                "identifier `%s' used\n", $1);
+          }
+       }
        ;
 
 interpolation_qualifier:
index 26e0721cedea16c22d0ffff8a279a375390ac115..844a746c65cc5b6b287679b8681f6881b10777fc 100644 (file)
@@ -181,6 +181,13 @@ _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
         state->ARB_draw_buffers_enable = (ext_mode != extension_disable);
         state->ARB_draw_buffers_warn = (ext_mode == extension_warn);
       }
+   } else if (strcmp(name, "GL_ARB_explicit_attrib_location") == 0) {
+      state->ARB_explicit_attrib_location_enable =
+        (ext_mode != extension_disable);
+      state->ARB_explicit_attrib_location_warn =
+        (ext_mode == extension_warn);
+
+      unsupported = !state->extensions->ARB_explicit_attrib_location;
    } else if (strcmp(name, "GL_ARB_fragment_coord_conventions") == 0) {
       state->ARB_fragment_coord_conventions_enable =
         (ext_mode != extension_disable);
index ddc2138b765a73ebcee139aca201ce526bc95787..b573831d5f0010bc1a520c3e5594a1b439669c8a 100644 (file)
@@ -125,6 +125,8 @@ struct _mesa_glsl_parse_state {
    /*@{*/
    unsigned ARB_draw_buffers_enable:1;
    unsigned ARB_draw_buffers_warn:1;
+   unsigned ARB_explicit_attrib_location_enable:1;
+   unsigned ARB_explicit_attrib_location_warn:1;
    unsigned ARB_fragment_coord_conventions_enable:1;
    unsigned ARB_fragment_coord_conventions_warn:1;
    unsigned ARB_texture_rectangle_enable:1;