diff options
| -rw-r--r-- | src/glsl/ast.h | 14 | ||||
| -rw-r--r-- | src/glsl/glsl_lexer.lpp | 1 | ||||
| -rw-r--r-- | src/glsl/glsl_parser.ypp | 55 | ||||
| -rw-r--r-- | src/glsl/glsl_parser_extras.cpp | 7 | ||||
| -rw-r--r-- | src/glsl/glsl_parser_extras.h | 2 | 
5 files changed, 75 insertions, 4 deletions
diff --git a/src/glsl/ast.h b/src/glsl/ast.h index 5fa932ec80..e5aa5c1b3b 100644 --- a/src/glsl/ast.h +++ b/src/glsl/ast.h @@ -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 { diff --git a/src/glsl/glsl_lexer.lpp b/src/glsl/glsl_lexer.lpp index ed3cb251a1..8be5c67fc2 100644 --- a/src/glsl/glsl_lexer.lpp +++ b/src/glsl/glsl_lexer.lpp @@ -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 { diff --git a/src/glsl/glsl_parser.ypp b/src/glsl/glsl_parser.ypp index 16d39dc565..ed18179beb 100644 --- a/src/glsl/glsl_parser.ypp +++ b/src/glsl/glsl_parser.ypp @@ -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: diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index 26e0721ced..844a746c65 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -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); diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h index ddc2138b76..b573831d5f 100644 --- a/src/glsl/glsl_parser_extras.h +++ b/src/glsl/glsl_parser_extras.h @@ -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;  | 
