diff options
-rw-r--r-- | src/glsl/ast.h | 11 | ||||
-rw-r--r-- | src/glsl/ast_to_hir.cpp | 34 | ||||
-rw-r--r-- | src/glsl/glsl_parser.yy | 43 |
3 files changed, 52 insertions, 36 deletions
diff --git a/src/glsl/ast.h b/src/glsl/ast.h index 1208704ff6d..6aede009c8c 100644 --- a/src/glsl/ast.h +++ b/src/glsl/ast.h @@ -437,6 +437,9 @@ struct ast_type_qualifier { unsigned i; } flags; + /** Precision of the type (highp/medium/lowp). */ + unsigned precision:2; + /** * Location specified via GL_ARB_explicit_attrib_location layout * @@ -533,7 +536,7 @@ public: ast_type_specifier(const ast_type_specifier *that, bool is_array, ast_expression *array_size) : ast_node(), type_name(that->type_name), structure(that->structure), - is_array(is_array), array_size(array_size), precision(that->precision), + is_array(is_array), array_size(array_size), default_precision(that->default_precision) { /* empty */ @@ -542,7 +545,7 @@ public: /** Construct a type specifier from a type name */ ast_type_specifier(const char *name) : type_name(name), structure(NULL), - is_array(false), array_size(NULL), precision(ast_precision_none), + is_array(false), array_size(NULL), default_precision(ast_precision_none) { /* empty */ @@ -551,7 +554,7 @@ public: /** Construct a type specifier from a structure definition */ ast_type_specifier(ast_struct_specifier *s) : type_name(s->name), structure(s), - is_array(false), array_size(NULL), precision(ast_precision_none), + is_array(false), array_size(NULL), default_precision(ast_precision_none) { /* empty */ @@ -571,8 +574,6 @@ public: bool is_array; ast_expression *array_size; - unsigned precision:2; - /** For precision statements, this is the given precision; otherwise none. */ unsigned default_precision:2; }; diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index c1a2af30aea..3ed6f017503 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2544,6 +2544,12 @@ ast_declarator_list::hir(exec_list *instructions, type_name); } } + + if (this->type->qualifier.precision != ast_precision_none && + this->type->specifier->structure != NULL) { + _mesa_glsl_error(&loc, state, "Precision qualifiers can't be applied " + "to structures.\n"); + } } foreach_list_typed (ast_declaration, decl, link, &this->declarations) { @@ -2846,7 +2852,7 @@ ast_declarator_list::hir(exec_list *instructions, /* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30. */ - if (this->type->specifier->precision != ast_precision_none) { + if (this->type->qualifier.precision != ast_precision_none) { state->check_precision_qualifiers_allowed(&loc); } @@ -2864,9 +2870,10 @@ ast_declarator_list::hir(exec_list *instructions, * From page 87 of the GLSL ES spec: * "RESOLUTION: Allow sampler types to take a precision qualifier." */ - if (this->type->specifier->precision != ast_precision_none + if (this->type->qualifier.precision != ast_precision_none && !var->type->is_float() && !var->type->is_integer() + && !var->type->is_record() && !(var->type->is_sampler() && state->es_shader) && !(var->type->is_array() && (var->type->fields.array->is_float() @@ -3963,17 +3970,6 @@ ast_type_specifier::hir(exec_list *instructions, YYLTYPE loc = this->get_location(); - if (this->precision != ast_precision_none - && !state->check_precision_qualifiers_allowed(&loc)) { - return NULL; - } - if (this->precision != ast_precision_none - && this->structure != NULL) { - _mesa_glsl_error(&loc, state, - "precision qualifiers do not apply to structures"); - return NULL; - } - /* If this is a precision statement, check that the type to which it is * applied is either float or int. * @@ -3985,9 +3981,15 @@ ast_type_specifier::hir(exec_list *instructions, * qualifiers will result in an error. */ if (this->default_precision != ast_precision_none) { - assert(this->precision != ast_precision_none); - assert(this->structure == NULL); /* The check for structures was - * performed above. */ + if (!state->check_precision_qualifiers_allowed(&loc)) + return NULL; + + if (this->structure != NULL) { + _mesa_glsl_error(&loc, state, + "precision qualifiers do not apply to structures"); + return NULL; + } + if (this->is_array) { _mesa_glsl_error(&loc, state, "default precision statements do not apply to " diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy index 1a13f485503..08806a32bcf 100644 --- a/src/glsl/glsl_parser.yy +++ b/src/glsl/glsl_parser.yy @@ -169,7 +169,6 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg) %type <type_qualifier> interface_block_layout_qualifier %type <type_qualifier> interface_qualifier %type <type_specifier> type_specifier -%type <type_specifier> type_specifier_no_prec %type <type_specifier> type_specifier_nonarray %type <identifier> basic_type_specifier_nonarray %type <fully_specified_type> fully_specified_type @@ -790,9 +789,8 @@ declaration: { $$ = $1; } - | PRECISION precision_qualifier type_specifier_no_prec ';' + | PRECISION precision_qualifier type_specifier ';' { - $3->precision = $2; $3->default_precision = $2; $$ = $3; } @@ -905,6 +903,17 @@ parameter_qualifier: $$ = $1; $$.merge_qualifier(&@1, state, $2); } + | precision_qualifier parameter_qualifier + { + if ($2.precision != ast_precision_none) + _mesa_glsl_error(&@1, state, "Duplicate precision qualifier.\n"); + + if ($2.flags.i != 0) + _mesa_glsl_error(&@1, state, "Precision qualifiers must come last.\n"); + + $$ = $2; + $$.precision = $1; + } parameter_direction_qualifier: IN_TOK @@ -1319,6 +1328,11 @@ type_qualifier: | storage_qualifier | interpolation_qualifier | layout_qualifier + | precision_qualifier + { + memset(&$$, 0, sizeof($$)); + $$.precision = $1; + } /* Multiple qualifiers: * In GLSL 4.20, these can be specified in any order. In earlier versions, @@ -1414,6 +1428,17 @@ type_qualifier: $$ = $1; $$.merge_qualifier(&@1, state, $2); } + | precision_qualifier type_qualifier + { + if ($2.precision != ast_precision_none) + _mesa_glsl_error(&@1, state, "Duplicate precision qualifier.\n"); + + if ($2.flags.i != 0) + _mesa_glsl_error(&@1, state, "Precision qualifiers must come last.\n"); + + $$ = $2; + $$.precision = $1; + } ; storage_qualifier: @@ -1466,18 +1491,6 @@ storage_qualifier: ; type_specifier: - type_specifier_no_prec - { - $$ = $1; - } - | precision_qualifier type_specifier_no_prec - { - $$ = $2; - $$->precision = $1; - } - ; - -type_specifier_no_prec: type_specifier_nonarray | type_specifier_nonarray '[' ']' { |