diff options
-rw-r--r-- | src/glsl/ast.h | 4 | ||||
-rw-r--r-- | src/glsl/ast_to_hir.cpp | 68 |
2 files changed, 68 insertions, 4 deletions
diff --git a/src/glsl/ast.h b/src/glsl/ast.h index 9b194dbd043..335374de16b 100644 --- a/src/glsl/ast.h +++ b/src/glsl/ast.h @@ -610,6 +610,10 @@ public: virtual void print(void) const; bool has_qualifiers() const; + const struct glsl_type *glsl_type(const char **name, + struct _mesa_glsl_parse_state *state) + const; + ast_type_qualifier qualifier; ast_type_specifier *specifier; }; diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 88d9fd60b56..d94faa885b5 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1797,6 +1797,28 @@ ast_type_specifier::glsl_type(const char **name, return type; } +const glsl_type * +ast_fully_specified_type::glsl_type(const char **name, + struct _mesa_glsl_parse_state *state) const +{ + const struct glsl_type *type = this->specifier->glsl_type(name, state); + + if (type == NULL) + return NULL; + + if (type->base_type == GLSL_TYPE_FLOAT + && state->es_shader + && state->target == fragment_shader + && this->qualifier.precision == ast_precision_none + && state->symbols->get_variable("#default precision") == NULL) { + YYLTYPE loc = this->get_location(); + _mesa_glsl_error(&loc, state, + "no precision specified this scope for type `%s'", + type->name); + } + + return type; +} /** * Determine whether a toplevel variable declaration declares a varying. This @@ -2693,7 +2715,7 @@ ast_declarator_list::hir(exec_list *instructions, */ (void) this->type->specifier->hir(instructions, state); - decl_type = this->type->specifier->glsl_type(& type_name, state); + decl_type = this->type->glsl_type(& type_name, state); if (this->declarations.is_empty()) { /* If there is no structure involved in the program text, there are two * possible scenarios: @@ -3277,7 +3299,7 @@ ast_parameter_declarator::hir(exec_list *instructions, const char *name = NULL; YYLTYPE loc = this->get_location(); - type = this->type->specifier->glsl_type(& name, state); + type = this->type->glsl_type(& name, state); if (type == NULL) { if (name != NULL) { @@ -3484,7 +3506,7 @@ ast_function::hir(exec_list *instructions, const char *return_type_name; const glsl_type *return_type = - this->return_type->specifier->glsl_type(& return_type_name, state); + this->return_type->glsl_type(& return_type_name, state); if (!return_type) { YYLTYPE loc = this->get_location(); @@ -4288,6 +4310,44 @@ ast_type_specifier::hir(exec_list *instructions, return NULL; } + if (type->base_type == GLSL_TYPE_FLOAT + && state->es_shader + && state->target == fragment_shader) { + /* Section 4.5.3 (Default Precision Qualifiers) of the GLSL ES 1.00 + * spec says: + * + * "The fragment language has no default precision qualifier for + * floating point types." + * + * As a result, we have to track whether or not default precision has + * been specified for float in GLSL ES fragment shaders. + * + * Earlier in that same section, the spec says: + * + * "Non-precision qualified declarations will use the precision + * qualifier specified in the most recent precision statement + * that is still in scope. The precision statement has the same + * scoping rules as variable declarations. If it is declared + * inside a compound statement, its effect stops at the end of + * the innermost statement it was declared in. Precision + * statements in nested scopes override precision statements in + * outer scopes. Multiple precision statements for the same basic + * type can appear inside the same scope, with later statements + * overriding earlier statements within that scope." + * + * Default precision specifications follow the same scope rules as + * variables. So, we can track the state of the default float + * precision in the symbol table, and the rules will just work. This + * is a slight abuse of the symbol table, but it has the semantics + * that we want. + */ + ir_variable *const junk = + new(state) ir_variable(type, "#default precision", + ir_var_temporary); + + state->symbols->add_variable(junk); + } + /* FINISHME: Translate precision statements into IR. */ return NULL; } @@ -4368,7 +4428,7 @@ ast_process_structure_or_interface_block(exec_list *instructions, } const glsl_type *decl_type = - decl_list->type->specifier->glsl_type(& type_name, state); + decl_list->type->glsl_type(& type_name, state); foreach_list_typed (ast_declaration, decl, link, &decl_list->declarations) { |