diff options
Diffstat (limited to 'src/glsl/ast_function.cpp')
-rw-r--r-- | src/glsl/ast_function.cpp | 95 |
1 files changed, 89 insertions, 6 deletions
diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index 26d4c62ce36..c5c5cae333b 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -437,13 +437,54 @@ generate_call(exec_list *instructions, ir_function_signature *sig, } } - /* If the function call is a constant expression, don't generate any - * instructions; just generate an ir_constant. + /* Section 4.3.2 (Const) of the GLSL 1.10.59 spec says: + * + * "Initializers for const declarations must be formed from literal + * values, other const variables (not including function call + * paramaters), or expressions of these. + * + * Constructors may be used in such expressions, but function calls may + * not." + * + * Section 4.3.3 (Constant Expressions) of the GLSL 1.20.8 spec says: + * + * "A constant expression is one of + * + * ... + * + * - a built-in function call whose arguments are all constant + * expressions, with the exception of the texture lookup + * functions, the noise functions, and ftransform. The built-in + * functions dFdx, dFdy, and fwidth must return 0 when evaluated + * inside an initializer with an argument that is a constant + * expression." + * + * Section 5.10 (Constant Expressions) of the GLSL ES 1.00.17 spec says: + * + * "A constant expression is one of * - * Function calls were first allowed to be constant expressions in GLSL - * 1.20 and GLSL ES 3.00. + * ... + * + * - a built-in function call whose arguments are all constant + * expressions, with the exception of the texture lookup + * functions." + * + * Section 4.3.3 (Constant Expressions) of the GLSL ES 3.00.4 spec says: + * + * "A constant expression is one of + * + * ... + * + * - a built-in function call whose arguments are all constant + * expressions, with the exception of the texture lookup + * functions. The built-in functions dFdx, dFdy, and fwidth must + * return 0 when evaluated inside an initializer with an argument + * that is a constant expression." + * + * If the function call is a constant expression, don't generate any + * instructions; just generate an ir_constant. */ - if (state->is_version(120, 300)) { + if (state->is_version(120, 100)) { ir_constant *value = sig->constant_expression_value(actual_parameters, NULL); if (value != NULL) { return value; @@ -950,6 +991,7 @@ process_array_constructor(exec_list *instructions, } bool all_parameters_are_constant = true; + const glsl_type *element_type = constructor_type->fields.array; /* Type cast each parameter and, if possible, fold constants. */ foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) { @@ -976,12 +1018,34 @@ process_array_constructor(exec_list *instructions, } } - if (result->type != constructor_type->fields.array) { + if (constructor_type->fields.array->is_unsized_array()) { + /* As the inner parameters of the constructor are created without + * knowledge of each other we need to check to make sure unsized + * parameters of unsized constructors all end up with the same size. + * + * e.g we make sure to fail for a constructor like this: + * vec4[][] a = vec4[][](vec4[](vec4(0.0), vec4(1.0)), + * vec4[](vec4(0.0), vec4(1.0), vec4(1.0)), + * vec4[](vec4(0.0), vec4(1.0))); + */ + if (element_type->is_unsized_array()) { + /* This is the first parameter so just get the type */ + element_type = result->type; + } else if (element_type != result->type) { + _mesa_glsl_error(loc, state, "type error in array constructor: " + "expected: %s, found %s", + element_type->name, + result->type->name); + return ir_rvalue::error_value(ctx); + } + } else if (result->type != constructor_type->fields.array) { _mesa_glsl_error(loc, state, "type error in array constructor: " "expected: %s, found %s", constructor_type->fields.array->name, result->type->name); return ir_rvalue::error_value(ctx); + } else { + element_type = result->type; } /* Attempt to convert the parameter to a constant valued expression. @@ -998,6 +1062,14 @@ process_array_constructor(exec_list *instructions, ir->replace_with(result); } + if (constructor_type->fields.array->is_unsized_array()) { + constructor_type = + glsl_type::get_array_instance(element_type, + parameter_count); + assert(constructor_type != NULL); + assert(constructor_type->length == parameter_count); + } + if (all_parameters_are_constant) return new(ctx) ir_constant(constructor_type, &actual_parameters); @@ -1958,6 +2030,17 @@ ast_function_expression::hir(exec_list *instructions, unreachable("not reached"); } +bool +ast_function_expression::has_sequence_subexpression() const +{ + foreach_list_typed(const ast_node, ast, link, &this->expressions) { + if (ast->has_sequence_subexpression()) + return true; + } + + return false; +} + ir_rvalue * ast_aggregate_initializer::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) |