%token VERSION_TOK EXTENSION LINE COLON EOL INTERFACE OUTPUT
%token PRAGMA_DEBUG_ON PRAGMA_DEBUG_OFF
%token PRAGMA_OPTIMIZE_ON PRAGMA_OPTIMIZE_OFF
+%token PRAGMA_WARNING_ON PRAGMA_WARNING_OFF
%token PRAGMA_INVARIANT_ALL
%token LAYOUT_TOK
%token DOT_TOK
%type <n> unary_operator
%type <expression> function_identifier
%type <node> external_declaration
+%type <node> pragma_statement
%type <declarator_list> init_declarator_list
%type <declarator_list> single_declaration
%type <expression> initializer
;
pragma_statement:
- PRAGMA_DEBUG_ON EOL
- | PRAGMA_DEBUG_OFF EOL
- | PRAGMA_OPTIMIZE_ON EOL
- | PRAGMA_OPTIMIZE_OFF EOL
+ PRAGMA_DEBUG_ON EOL { $$ = NULL; }
+ | PRAGMA_DEBUG_OFF EOL { $$ = NULL; }
+ | PRAGMA_OPTIMIZE_ON EOL { $$ = NULL; }
+ | PRAGMA_OPTIMIZE_OFF EOL { $$ = NULL; }
| PRAGMA_INVARIANT_ALL EOL
{
/* Pragma invariant(all) cannot be used in a fragment shader.
} else {
state->all_invariant = true;
}
+
+ $$ = NULL;
+ }
+ | PRAGMA_WARNING_ON EOL
+ {
+ void *mem_ctx = state->linalloc;
+ $$ = new(mem_ctx) ast_warnings_toggle(true);
+ }
+ | PRAGMA_WARNING_OFF EOL
+ {
+ void *mem_ctx = state->linalloc;
+ $$ = new(mem_ctx) ast_warnings_toggle(false);
}
;
$$->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;
"only valid in fragment shader input layout declaration.");
} else if (pixel_interlock_ordered + pixel_interlock_unordered +
sample_interlock_ordered + sample_interlock_unordered > 0 &&
- !state->ARB_fragment_shader_interlock_enable) {
+ !state->ARB_fragment_shader_interlock_enable &&
+ !state->NV_fragment_shader_interlock_enable) {
_mesa_glsl_error(& @1, state,
"interlock layout qualifier present, but the "
- "GL_ARB_fragment_shader_interlock extension is not "
+ "GL_ARB_fragment_shader_interlock or "
+ "GL_NV_fragment_shader_interlock extension is not "
"enabled.");
} else {
$$.flags.q.pixel_interlock_ordered = pixel_interlock_ordered;
$$.flags.q.non_coherent = 1;
}
+ // Layout qualifiers for NV_compute_shader_derivatives.
+ if (!$$.flags.i) {
+ if (match_layout_qualifier($1, "derivative_group_quadsNV", state) == 0) {
+ $$.flags.q.derivative_group = 1;
+ $$.derivative_group = DERIVATIVE_GROUP_QUADS;
+ } else if (match_layout_qualifier($1, "derivative_group_linearNV", state) == 0) {
+ $$.flags.q.derivative_group = 1;
+ $$.derivative_group = DERIVATIVE_GROUP_LINEAR;
+ }
+
+ if ($$.flags.i) {
+ if (!state->has_compute_shader()) {
+ _mesa_glsl_error(& @1, state,
+ "qualifier `%s' requires "
+ "a compute shader", $1);
+ }
+
+ if (!state->NV_compute_shader_derivatives_enable) {
+ _mesa_glsl_error(& @1, state,
+ "qualifier `%s' requires "
+ "NV_compute_shader_derivatives", $1);
+ }
+
+ if (state->NV_compute_shader_derivatives_warn) {
+ _mesa_glsl_warning(& @1, state,
+ "NV_compute_shader_derivatives layout "
+ "qualifier `%s' used", $1);
+ }
+ }
+ }
+
if (!$$.flags.i) {
_mesa_glsl_error(& @1, state, "unrecognized layout identifier "
"`%s'", $1);
"duplicate auxiliary storage qualifier (centroid or sample)");
}
- if (!state->has_420pack_or_es31() &&
+ if ((!state->has_420pack_or_es31() && !state->EXT_gpu_shader4_enable) &&
($2.flags.q.precise || $2.flags.q.invariant ||
$2.has_interpolation() || $2.has_layout())) {
_mesa_glsl_error(&@1, state, "auxiliary storage qualifiers must come "
/* Section 4.3 of the GLSL 1.20 specification states:
* "Variable declarations may have a storage qualifier specified..."
* 1.30 clarifies this to "may have one storage qualifier".
+ *
+ * GL_EXT_gpu_shader4 allows "varying out" in fragment shaders.
*/
- if ($2.has_storage())
+ if ($2.has_storage() &&
+ (!state->EXT_gpu_shader4_enable ||
+ state->stage != MESA_SHADER_FRAGMENT ||
+ !$1.flags.q.varying || !$2.flags.q.out))
_mesa_glsl_error(&@1, state, "duplicate storage qualifier");
if (!state->has_420pack_or_es31() &&
basic_type_specifier_nonarray:
VOID_TOK { $$ = glsl_type::void_type; }
- | BASIC_TYPE_TOK { $$ = $1; };
+ | BASIC_TYPE_TOK { $$ = $1; }
+ | UNSIGNED BASIC_TYPE_TOK
+ {
+ if ($2 == glsl_type::int_type) {
+ $$ = glsl_type::uint_type;
+ } else {
+ _mesa_glsl_error(&@1, state,
+ "\"unsigned\" is only allowed before \"int\"");
+ }
+ }
;
precision_qualifier:
$$ = $1;
$$->link.insert_before(& $2->link);
}
+ | statement_list extension_statement
+ {
+ if (!state->allow_extension_directive_midshader) {
+ _mesa_glsl_error(& @1, state,
+ "#extension directive is not allowed "
+ "in the middle of a shader");
+ YYERROR;
+ }
+ }
;
expression_statement:
external_declaration:
function_definition { $$ = $1; }
| declaration { $$ = $1; }
- | pragma_statement { $$ = NULL; }
+ | pragma_statement { $$ = $1; }
| layout_defaults { $$ = $1; }
+ | ';' { $$ = NULL; }
;
function_definition: