X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fast_to_hir.cpp;h=88d9fd60b561d17227421f1edb3d79043885b816;hb=b15b62c54c0e3c10aaf8573a62acfcdc93979b0d;hp=5980cb0b5bd8b810a0b303dd74592424e1fc4938;hpb=46934adb8d855a9505f2231ba3f1ad5449b896a4;p=mesa.git diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 5980cb0b5bd..88d9fd60b56 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -72,6 +72,8 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) state->toplevel_ir = instructions; + state->gs_input_prim_type_specified = false; + /* Section 4.2 of the GLSL 1.20 specification states: * "The built-in functions are scoped in a scope outside the global scope * users declare global variables in. That is, a shader's global scope, @@ -94,6 +96,24 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) detect_conflicting_assignments(state, instructions); state->toplevel_ir = NULL; + + /* Move all of the variable declarations to the front of the IR list, and + * reverse the order. This has the (intended!) side effect that vertex + * shader inputs and fragment shader outputs will appear in the IR in the + * same order that they appeared in the shader code. This results in the + * locations being assigned in the declared order. Many (arguably buggy) + * applications depend on this behavior, and it matches what nearly all + * other drivers do. + */ + foreach_list_safe(node, instructions) { + ir_variable *const var = ((ir_instruction *) node)->as_variable(); + + if (var == NULL) + continue; + + var->remove(); + instructions->push_head(var); + } } @@ -177,7 +197,7 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, */ if (!type_a->is_numeric() || !type_b->is_numeric()) { _mesa_glsl_error(loc, state, - "Operands to arithmetic operators must be numeric"); + "operands to arithmetic operators must be numeric"); return glsl_type::error_type; } @@ -189,7 +209,7 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, if (!apply_implicit_conversion(type_a, value_b, state) && !apply_implicit_conversion(type_b, value_a, state)) { _mesa_glsl_error(loc, state, - "Could not implicitly convert operands to " + "could not implicitly convert operands to " "arithmetic operator"); return glsl_type::error_type; } @@ -368,7 +388,7 @@ unary_arithmetic_result_type(const struct glsl_type *type, */ if (!type->is_numeric()) { _mesa_glsl_error(loc, state, - "Operands to arithmetic operators must be numeric"); + "operands to arithmetic operators must be numeric"); return glsl_type::error_type; } @@ -455,11 +475,11 @@ modulus_result_type(const struct glsl_type *type_a, * unsigned." */ if (!type_a->is_integer()) { - _mesa_glsl_error(loc, state, "LHS of operator %% must be an integer."); + _mesa_glsl_error(loc, state, "LHS of operator %% must be an integer"); return glsl_type::error_type; } if (!type_b->is_integer()) { - _mesa_glsl_error(loc, state, "RHS of operator %% must be an integer."); + _mesa_glsl_error(loc, state, "RHS of operator %% must be an integer"); return glsl_type::error_type; } if (type_a->base_type != type_b->base_type) { @@ -505,7 +525,7 @@ relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, || !type_a->is_scalar() || !type_b->is_scalar()) { _mesa_glsl_error(loc, state, - "Operands to relational operators must be scalar and " + "operands to relational operators must be scalar and " "numeric"); return glsl_type::error_type; } @@ -517,7 +537,7 @@ relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, if (!apply_implicit_conversion(type_a, value_b, state) && !apply_implicit_conversion(type_b, value_a, state)) { _mesa_glsl_error(loc, state, - "Could not implicitly convert operands to " + "could not implicitly convert operands to " "relational operator"); return glsl_type::error_type; } @@ -575,7 +595,7 @@ shift_result_type(const struct glsl_type *type_a, * a scalar as well." */ if (type_a->is_scalar() && !type_b->is_scalar()) { - _mesa_glsl_error(loc, state, "If the first operand of %s is scalar, the " + _mesa_glsl_error(loc, state, "if the first operand of %s is scalar, the " "second must be scalar as well", ast_expression::operator_string(op)); return glsl_type::error_type; @@ -587,7 +607,7 @@ shift_result_type(const struct glsl_type *type_a, if (type_a->is_vector() && type_b->is_vector() && type_a->vector_elements != type_b->vector_elements) { - _mesa_glsl_error(loc, state, "Vector operands to operator %s must " + _mesa_glsl_error(loc, state, "vector operands to operator %s must " "have same number of elements", ast_expression::operator_string(op)); return glsl_type::error_type; @@ -672,6 +692,30 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, void *ctx = state; bool error_emitted = (lhs->type->is_error() || rhs->type->is_error()); + /* If the assignment LHS comes back as an ir_binop_vector_extract + * expression, move it to the RHS as an ir_triop_vector_insert. + */ + if (lhs->ir_type == ir_type_expression) { + ir_expression *const expr = lhs->as_expression(); + + if (unlikely(expr->operation == ir_binop_vector_extract)) { + ir_rvalue *new_rhs = + validate_assignment(state, lhs->type, rhs, is_initializer); + + if (new_rhs == NULL) { + _mesa_glsl_error(& lhs_loc, state, "type mismatch"); + return lhs; + } else { + rhs = new(ctx) ir_expression(ir_triop_vector_insert, + expr->operands[0]->type, + expr->operands[0], + new_rhs, + expr->operands[1]); + lhs = expr->operands[0]->clone(ctx, NULL); + } + } + } + ir_variable *lhs_var = lhs->variable_referenced(); if (lhs_var) lhs_var->assigned = true; @@ -904,7 +948,7 @@ get_scalar_boolean_operand(exec_list *instructions, * If name refers to a builtin array whose maximum allowed size is less than * size, report an error and return true. Otherwise return false. */ -bool +void check_builtin_array_max_size(const char *name, unsigned size, YYLTYPE loc, struct _mesa_glsl_parse_state *state) { @@ -916,9 +960,8 @@ check_builtin_array_max_size(const char *name, unsigned size, * gl_MaxTextureCoords." */ _mesa_glsl_error(&loc, state, "`gl_TexCoord' array size cannot " - "be larger than gl_MaxTextureCoords (%u)\n", + "be larger than gl_MaxTextureCoords (%u)", state->Const.MaxTextureCoords); - return true; } else if (strcmp("gl_ClipDistance", name) == 0 && size > state->Const.MaxClipPlanes) { /* From section 7.1 (Vertex Shader Special Variables) of the @@ -931,11 +974,9 @@ check_builtin_array_max_size(const char *name, unsigned size, * gl_MaxClipDistances." */ _mesa_glsl_error(&loc, state, "`gl_ClipDistance' array size cannot " - "be larger than gl_MaxClipDistances (%u)\n", + "be larger than gl_MaxClipDistances (%u)", state->Const.MaxClipPlanes); - return true; } - return false; } /** @@ -1029,6 +1070,10 @@ ast_expression::hir(exec_list *instructions, loc = this->get_location(); switch (this->oper) { + case ast_aggregate: + assert(!"ast_aggregate: Should never get here."); + break; + case ast_assign: { op[0] = this->subexpressions[0]->hir(instructions, state); op[1] = this->subexpressions[1]->hir(instructions, state); @@ -1401,8 +1446,8 @@ ast_expression::hir(exec_list *instructions, || (op[1]->type != op[2]->type)) { YYLTYPE loc = this->subexpressions[1]->get_location(); - _mesa_glsl_error(& loc, state, "Second and third operands of ?: " - "operator must have matching types."); + _mesa_glsl_error(& loc, state, "second and third operands of ?: " + "operator must have matching types"); error_emitted = true; type = glsl_type::error_type; } else { @@ -1416,7 +1461,7 @@ ast_expression::hir(exec_list *instructions, */ if (type->is_array() && !state->check_version(120, 300, &loc, - "Second and third operands of ?: operator " + "second and third operands of ?: operator " "cannot be arrays")) { error_emitted = true; } @@ -1517,10 +1562,8 @@ ast_expression::hir(exec_list *instructions, op[0] = subexpressions[0]->hir(instructions, state); op[1] = subexpressions[1]->hir(instructions, state); - error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); - result = _mesa_ast_array_index_to_hir(ctx, state, op[0], op[1], - loc, index_loc, error_emitted); + loc, index_loc); if (result->type->is_error()) error_emitted = true; @@ -1683,6 +1726,9 @@ process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size, { unsigned length = 0; + if (base == NULL) + return glsl_type::error_type; + /* From page 19 (page 25) of the GLSL 1.20 spec: * * "Only one-dimensional arrays may be declared." @@ -1727,15 +1773,10 @@ process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size, } } } - } else if (state->es_shader) { - /* Section 10.17 of the GLSL ES 1.00 specification states that unsized - * array declarations have been removed from the language. - */ - _mesa_glsl_error(loc, state, "unsized array declarations are not " - "allowed in GLSL ES 1.00."); } - return glsl_type::get_array_instance(base, length); + const glsl_type *array_type = glsl_type::get_array_instance(base, length); + return array_type != NULL ? array_type : glsl_type::error_type; } @@ -1805,6 +1846,84 @@ validate_matrix_layout_for_type(struct _mesa_glsl_parse_state *state, } } +static bool +validate_binding_qualifier(struct _mesa_glsl_parse_state *state, + YYLTYPE *loc, + ir_variable *var, + const ast_type_qualifier *qual) +{ + if (var->mode != ir_var_uniform) { + _mesa_glsl_error(loc, state, + "the \"binding\" qualifier only applies to uniforms"); + return false; + } + + if (qual->binding < 0) { + _mesa_glsl_error(loc, state, "binding values must be >= 0"); + return false; + } + + const struct gl_context *const ctx = state->ctx; + unsigned elements = var->type->is_array() ? var->type->length : 1; + unsigned max_index = qual->binding + elements - 1; + + if (var->type->is_interface()) { + /* UBOs. From page 60 of the GLSL 4.20 specification: + * "If the binding point for any uniform block instance is less than zero, + * or greater than or equal to the implementation-dependent maximum + * number of uniform buffer bindings, a compilation error will occur. + * When the binding identifier is used with a uniform block instanced as + * an array of size N, all elements of the array from binding through + * binding + N – 1 must be within this range." + * + * The implementation-dependent maximum is GL_MAX_UNIFORM_BUFFER_BINDINGS. + */ + if (max_index >= ctx->Const.MaxUniformBufferBindings) { + _mesa_glsl_error(loc, state, "layout(binding = %d) for %d UBOs exceeds " + "the maximum number of UBO binding points (%d)", + qual->binding, elements, + ctx->Const.MaxUniformBufferBindings); + return false; + } + } else if (var->type->is_sampler() || + (var->type->is_array() && var->type->fields.array->is_sampler())) { + /* Samplers. From page 63 of the GLSL 4.20 specification: + * "If the binding is less than zero, or greater than or equal to the + * implementation-dependent maximum supported number of units, a + * compilation error will occur. When the binding identifier is used + * with an array of size N, all elements of the array from binding + * through binding + N - 1 must be within this range." + */ + unsigned limit; + switch (state->target) { + case vertex_shader: + limit = ctx->Const.VertexProgram.MaxTextureImageUnits; + break; + case geometry_shader: + limit = ctx->Const.GeometryProgram.MaxTextureImageUnits; + break; + case fragment_shader: + limit = ctx->Const.FragmentProgram.MaxTextureImageUnits; + break; + } + + if (max_index >= limit) { + _mesa_glsl_error(loc, state, "layout(binding = %d) for %d samplers " + "exceeds the maximum number of texture image units " + "(%d)", qual->binding, elements, limit); + + return false; + } + } else { + _mesa_glsl_error(loc, state, + "the \"binding\" qualifier only applies to uniform " + "blocks, samplers, or arrays of samplers"); + return false; + } + + return true; +} + static void apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, ir_variable *var, @@ -1813,6 +1932,8 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, bool ubo_qualifiers_valid, bool is_parameter) { + STATIC_ASSERT(sizeof(qual->flags.q) <= sizeof(qual->flags.i)); + if (qual->flags.q.invariant) { if (var->used) { _mesa_glsl_error(loc, state, @@ -1840,6 +1961,21 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, _mesa_glsl_shader_target_name(state->target)); } + /* Section 6.1.1 (Function Calling Conventions) of the GLSL 1.10 spec says: + * + * "However, the const qualifier cannot be used with out or inout." + * + * The same section of the GLSL 4.40 spec further clarifies this saying: + * + * "The const qualifier cannot be used with out or inout, or a + * compile-time error results." + */ + if (is_parameter && qual->flags.q.constant && qual->flags.q.out) { + _mesa_glsl_error(loc, state, + "`const' may not be applied to `out' or `inout' " + "function parameters"); + } + /* If there is no qualifier that changes the mode of the variable, leave * the setting alone. */ @@ -1932,13 +2068,24 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, else var->interpolation = INTERP_QUALIFIER_NONE; - if (var->interpolation != INTERP_QUALIFIER_NONE && - !(state->target == vertex_shader && var->mode == ir_var_shader_out) && - !(state->target == fragment_shader && var->mode == ir_var_shader_in)) { - _mesa_glsl_error(loc, state, - "interpolation qualifier `%s' can only be applied to " - "vertex shader outputs and fragment shader inputs.", - var->interpolation_string()); + if (var->interpolation != INTERP_QUALIFIER_NONE) { + ir_variable_mode mode = (ir_variable_mode) var->mode; + + if (mode != ir_var_shader_in && mode != ir_var_shader_out) { + _mesa_glsl_error(loc, state, + "interpolation qualifier `%s' can only be applied to " + "shader inputs or outputs.", + var->interpolation_string()); + + } + + if ((state->target == vertex_shader && mode == ir_var_shader_in) || + (state->target == fragment_shader && mode == ir_var_shader_out)) { + _mesa_glsl_error(loc, state, + "interpolation qualifier `%s' cannot be applied to " + "vertex shader inputs or fragment shader outputs", + var->interpolation_string()); + } } var->pixel_center_integer = qual->flags.q.pixel_center_integer; @@ -1976,7 +2123,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, case geometry_shader: _mesa_glsl_error(loc, state, "geometry shader variables cannot be given " - "explicit locations\n"); + "explicit locations"); break; case fragment_shader: @@ -1990,7 +2137,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, if (fail) { _mesa_glsl_error(loc, state, "only %s shader %s variables can be given an " - "explicit location\n", + "explicit location", _mesa_glsl_shader_target_name(state->target), string); } else { @@ -2023,7 +2170,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, */ if (qual->index < 0 || qual->index > 1) { _mesa_glsl_error(loc, state, - "explicit index may only be 0 or 1\n"); + "explicit index may only be 0 or 1"); } else { var->explicit_index = true; var->index = qual->index; @@ -2032,14 +2179,14 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, } } else if (qual->flags.q.explicit_index) { _mesa_glsl_error(loc, state, - "explicit index requires explicit location\n"); + "explicit index requires explicit location"); } - /* Does the declaration use the 'layout' keyword? - */ - const bool uses_layout = qual->flags.q.pixel_center_integer - || qual->flags.q.origin_upper_left - || qual->flags.q.explicit_location; /* no need for index since it relies on location */ + if (qual->flags.q.explicit_binding && + validate_binding_qualifier(state, loc, var, qual)) { + var->explicit_binding = true; + var->binding = qual->binding; + } /* Does the declaration use the deprecated 'attribute' or 'varying' * keywords? @@ -2070,7 +2217,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, const bool relaxed_layout_qualifier_checking = state->ARB_fragment_coord_conventions_enable; - if (uses_layout && uses_deprecated_qualifier) { + if (qual->has_layout() && uses_deprecated_qualifier) { if (relaxed_layout_qualifier_checking) { _mesa_glsl_warning(loc, state, "`layout' qualifier may not be used with " @@ -2194,7 +2341,8 @@ get_variable_being_redeclared(ir_variable *var, ast_declaration *decl, earlier->type = var->type; delete var; var = NULL; - } else if (state->ARB_fragment_coord_conventions_enable + } else if ((state->ARB_fragment_coord_conventions_enable || + state->is_version(150, 0)) && strcmp(var->name, "gl_FragCoord") == 0 && earlier->type == var->type && earlier->mode == var->mode) { @@ -2314,17 +2462,25 @@ process_initializer(ir_variable *var, ast_declaration *decl, ir_constant *constant_value = rhs->constant_expression_value(); if (!constant_value) { - _mesa_glsl_error(& initializer_loc, state, - "initializer of %s variable `%s' must be a " - "constant expression", - (type->qualifier.flags.q.constant) - ? "const" : "uniform", - decl->identifier); - if (var->type->is_numeric()) { - /* Reduce cascading errors. */ - var->constant_value = ir_constant::zero(state, var->type); - } - } else { + /* If ARB_shading_language_420pack is enabled, initializers of + * const-qualified local variables do not have to be constant + * expressions. Const-qualified global variables must still be + * initialized with constant expressions. + */ + if (!state->ARB_shading_language_420pack_enable + || state->current_function == NULL) { + _mesa_glsl_error(& initializer_loc, state, + "initializer of %s variable `%s' must be a " + "constant expression", + (type->qualifier.flags.q.constant) + ? "const" : "uniform", + decl->identifier); + if (var->type->is_numeric()) { + /* Reduce cascading errors. */ + var->constant_value = ir_constant::zero(state, var->type); + } + } + } else { rhs = constant_value; var->constant_value = constant_value; } @@ -2388,6 +2544,81 @@ process_initializer(ir_variable *var, ast_declaration *decl, return result; } + +/** + * Do additional processing necessary for geometry shader input declarations + * (this covers both interface blocks arrays and bare input variables). + */ +static void +handle_geometry_shader_input_decl(struct _mesa_glsl_parse_state *state, + YYLTYPE loc, ir_variable *var) +{ + unsigned num_vertices = 0; + if (state->gs_input_prim_type_specified) { + num_vertices = vertices_per_prim(state->gs_input_prim_type); + } + + /* Geometry shader input variables must be arrays. Caller should have + * reported an error for this. + */ + if (!var->type->is_array()) { + assert(state->error); + + /* To avoid cascading failures, short circuit the checks below. */ + return; + } + + if (var->type->length == 0) { + /* Section 4.3.8.1 (Input Layout Qualifiers) of the GLSL 1.50 spec says: + * + * All geometry shader input unsized array declarations will be + * sized by an earlier input layout qualifier, when present, as per + * the following table. + * + * Followed by a table mapping each allowed input layout qualifier to + * the corresponding input length. + */ + if (num_vertices != 0) + var->type = glsl_type::get_array_instance(var->type->fields.array, + num_vertices); + } else { + /* Section 4.3.8.1 (Input Layout Qualifiers) of the GLSL 1.50 spec + * includes the following examples of compile-time errors: + * + * // code sequence within one shader... + * in vec4 Color1[]; // size unknown + * ...Color1.length()...// illegal, length() unknown + * in vec4 Color2[2]; // size is 2 + * ...Color1.length()...// illegal, Color1 still has no size + * in vec4 Color3[3]; // illegal, input sizes are inconsistent + * layout(lines) in; // legal, input size is 2, matching + * in vec4 Color4[3]; // illegal, contradicts layout + * ... + * + * To detect the case illustrated by Color3, we verify that the size of + * an explicitly-sized array matches the size of any previously declared + * explicitly-sized array. To detect the case illustrated by Color4, we + * verify that the size of an explicitly-sized array is consistent with + * any previously declared input layout. + */ + if (num_vertices != 0 && var->type->length != num_vertices) { + _mesa_glsl_error(&loc, state, + "geometry shader input size contradicts previously" + " declared layout (size is %u, but layout requires a" + " size of %u)", var->type->length, num_vertices); + } else if (state->gs_input_size != 0 && + var->type->length != state->gs_input_size) { + _mesa_glsl_error(&loc, state, + "geometry shader input sizes are " + "inconsistent (size is %u, but a previous " + "declaration has size %u)", + var->type->length, state->gs_input_size); + } else { + state->gs_input_size = var->type->length; + } + } +} + ir_rvalue * ast_declarator_list::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) @@ -2414,8 +2645,8 @@ ast_declarator_list::hir(exec_list *instructions, if (state->current_function != NULL) { _mesa_glsl_error(& loc, state, - "All uses of `invariant' keyword must be at global " - "scope\n"); + "all uses of `invariant' keyword must be at global " + "scope"); } foreach_list_typed (ast_declaration, decl, link, &this->declarations) { @@ -2427,18 +2658,18 @@ ast_declarator_list::hir(exec_list *instructions, state->symbols->get_variable(decl->identifier); if (earlier == NULL) { _mesa_glsl_error(& loc, state, - "Undeclared variable `%s' cannot be marked " - "invariant\n", decl->identifier); + "undeclared variable `%s' cannot be marked " + "invariant", decl->identifier); } else if ((state->target == vertex_shader) && (earlier->mode != ir_var_shader_out)) { _mesa_glsl_error(& loc, state, "`%s' cannot be marked invariant, vertex shader " - "outputs only\n", decl->identifier); + "outputs only", decl->identifier); } else if ((state->target == fragment_shader) && (earlier->mode != ir_var_shader_in)) { _mesa_glsl_error(& loc, state, "`%s' cannot be marked invariant, fragment shader " - "inputs only\n", decl->identifier); + "inputs only", decl->identifier); } else if (earlier->used) { _mesa_glsl_error(& loc, state, "variable `%s' may not be redeclared " @@ -2474,6 +2705,11 @@ ast_declarator_list::hir(exec_list *instructions, * name of a known structure type. This is both invalid and weird. * Emit an error. * + * - The program text contained something like 'mediump float;' + * when the programmer probably meant 'precision mediump + * float;' Emit a warning with a description of what they + * probably meant to do. + * * Note that if decl_type is NULL and there is a structure involved, * there must have been some sort of error with the structure. In this * case we assume that an error was already generated on this line of @@ -2482,14 +2718,33 @@ ast_declarator_list::hir(exec_list *instructions, */ assert(this->type->specifier->structure == NULL || decl_type != NULL || state->error); - if (this->type->specifier->structure == NULL) { - if (decl_type != NULL) { - _mesa_glsl_warning(&loc, state, "empty declaration"); - } else { - _mesa_glsl_error(&loc, state, - "invalid type `%s' in empty declaration", - type_name); - } + + if (decl_type == NULL) { + _mesa_glsl_error(&loc, state, + "invalid type `%s' in empty declaration", + type_name); + } else if (this->type->qualifier.precision != ast_precision_none) { + if (this->type->specifier->structure != NULL) { + _mesa_glsl_error(&loc, state, + "precision qualifiers can't be applied " + "to structures"); + } else { + static const char *const precision_names[] = { + "highp", + "highp", + "mediump", + "lowp" + }; + + _mesa_glsl_warning(&loc, state, + "empty declaration with precision qualifier, " + "to set the default precision, use " + "`precision %s %s;'", + precision_names[this->type->qualifier.precision], + type_name); + } + } else { + _mesa_glsl_warning(&loc, state, "empty declaration"); } } @@ -2525,6 +2780,26 @@ ast_declarator_list::hir(exec_list *instructions, var = new(ctx) ir_variable(var_type, decl->identifier, ir_var_auto); + /* The 'varying in' and 'varying out' qualifiers can only be used with + * ARB_geometry_shader4 and EXT_geometry_shader4, which we don't support + * yet. + */ + if (this->type->qualifier.flags.q.varying) { + if (this->type->qualifier.flags.q.in) { + _mesa_glsl_error(& loc, state, + "`varying in' qualifier in declaration of " + "`%s' only valid for geometry shaders using " + "ARB_geometry_shader4 or EXT_geometry_shader4", + decl->identifier); + } else if (this->type->qualifier.flags.q.out) { + _mesa_glsl_error(& loc, state, + "`varying out' qualifier in declaration of " + "`%s' only valid for geometry shaders using " + "ARB_geometry_shader4 or EXT_geometry_shader4", + decl->identifier); + } + } + /* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification; * * "Global variables can only use the qualifiers const, @@ -2542,13 +2817,13 @@ ast_declarator_list::hir(exec_list *instructions, if (this->type->qualifier.flags.q.out) { _mesa_glsl_error(& loc, state, "`out' qualifier in declaration of `%s' " - "only valid for function parameters in %s.", + "only valid for function parameters in %s", decl->identifier, state->get_version_string()); } if (this->type->qualifier.flags.q.in) { _mesa_glsl_error(& loc, state, "`in' qualifier in declaration of `%s' " - "only valid for function parameters in %s.", + "only valid for function parameters in %s", decl->identifier, state->get_version_string()); } /* FINISHME: Test for other invalid qualifiers. */ @@ -2562,7 +2837,7 @@ ast_declarator_list::hir(exec_list *instructions, var->mode != ir_var_shader_out) { _mesa_glsl_error(& loc, state, "`%s' cannot be marked invariant, vertex shader " - "outputs only\n", var->name); + "outputs only", var->name); } else if ((state->target == fragment_shader) && var->mode != ir_var_shader_in) { /* FINISHME: Note that this doesn't work for invariant on @@ -2570,7 +2845,7 @@ ast_declarator_list::hir(exec_list *instructions, */ _mesa_glsl_error(& loc, state, "`%s' cannot be marked invariant, fragment shader " - "inputs only\n", var->name); + "inputs only", var->name); } } @@ -2654,12 +2929,27 @@ ast_declarator_list::hir(exec_list *instructions, } if (!error_emitted && var->type->is_array() && - !state->check_version(140, 0, &loc, + !state->check_version(150, 0, &loc, "vertex shader input / attribute " "cannot have array type")) { error_emitted = true; } - } + } else if (state->target == geometry_shader) { + /* From section 4.3.4 (Inputs) of the GLSL 1.50 spec: + * + * Geometry shader input variables get the per-vertex values + * written out by vertex shader output variables of the same + * names. Since a geometry shader operates on a set of + * vertices, each input varying variable (or input block, see + * interface blocks below) needs to be declared as an array. + */ + if (!var->type->is_array()) { + _mesa_glsl_error(&loc, state, + "geometry shader inputs must be arrays"); + } + + handle_geometry_shader_input_decl(state, loc, var); + } } /* Integer fragment inputs must be qualified with 'flat'. In GLSL ES, @@ -2699,7 +2989,7 @@ ast_declarator_list::hir(exec_list *instructions, && state->es_shader))) { const char *var_type = (state->target == vertex_shader) ? "vertex output" : "fragment input"; - _mesa_glsl_error(&loc, state, "If a %s is (or contains) " + _mesa_glsl_error(&loc, state, "if a %s is (or contains) " "an integer, then it must be qualified with 'flat'", var_type); } @@ -2769,7 +3059,7 @@ ast_declarator_list::hir(exec_list *instructions, } break; default: - assert(0); + break; } } @@ -2790,10 +3080,24 @@ ast_declarator_list::hir(exec_list *instructions, "'centroid in' cannot be used in a vertex shader"); } + /* Section 4.3.6 of the GLSL 1.30 specification states: + * "It is an error to use centroid out in a fragment shader." + * + * The GL_ARB_shading_language_420pack extension specification states: + * "It is an error to use auxiliary storage qualifiers or interpolation + * qualifiers on an output in a fragment shader." + */ + if (state->target == fragment_shader && + this->type->qualifier.flags.q.out && + this->type->qualifier.has_auxiliary_storage()) { + _mesa_glsl_error(&loc, state, + "auxiliary storage qualifiers cannot be used on " + "fragment shader outputs"); + } /* 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); } @@ -2811,9 +3115,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() @@ -2863,6 +3168,33 @@ ast_declarator_list::hir(exec_list *instructions, decl->identifier); } + if (state->es_shader) { + const glsl_type *const t = (earlier == NULL) + ? var->type : earlier->type; + + if (t->is_array() && t->length == 0) + /* Section 10.17 of the GLSL ES 1.00 specification states that + * unsized array declarations have been removed from the language. + * Arrays that are sized using an initializer are still explicitly + * sized. However, GLSL ES 1.00 does not allow array + * initializers. That is only allowed in GLSL ES 3.00. + * + * Section 4.1.9 (Arrays) of the GLSL ES 3.00 spec says: + * + * "An array type can also be formed without specifying a size + * if the definition includes an initializer: + * + * float x[] = float[2] (1.0, 2.0); // declares an array of size 2 + * float y[] = float[] (1.0, 2.0, 3.0); // declares an array of size 3 + * + * float a[5]; + * float b[] = a;" + */ + _mesa_glsl_error(& loc, state, + "unsized array declarations are not allowed in " + "GLSL ES"); + } + /* If the declaration is not a redeclaration, there are a few additional * semantic checks that must be applied. In addition, variable that was * created for the declaration should be added to the IR stream. @@ -2996,7 +3328,7 @@ ast_parameter_declarator::hir(exec_list *instructions, if (!type->is_error() && type->array_size() == 0) { _mesa_glsl_error(&loc, state, "arrays passed as parameters must have " - "a declared size."); + "a declared size"); type = glsl_type::error_type; } @@ -3039,7 +3371,7 @@ ast_parameter_declarator::hir(exec_list *instructions, if ((var->mode == ir_var_function_inout || var->mode == ir_var_function_out) && type->is_array() && !state->check_version(120, 100, &loc, - "Arrays cannot be out or inout parameters")) { + "arrays cannot be out or inout parameters")) { type = glsl_type::error_type; } @@ -3171,6 +3503,18 @@ ast_function::hir(exec_list *instructions, "function `%s' return type has qualifiers", name); } + /* Section 6.1 (Function Definitions) of the GLSL 1.20 spec says: + * + * "Arrays are allowed as arguments and as the return type. In both + * cases, the array must be explicitly sized." + */ + if (return_type->is_array() && return_type->length == 0) { + YYLTYPE loc = this->get_location(); + _mesa_glsl_error(& loc, state, + "function `%s' return type array must be explicitly " + "sized", name); + } + /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec: * * "[Sampler types] can only be declared as function parameters @@ -3206,10 +3550,17 @@ ast_function::hir(exec_list *instructions, "match prototype", name); } - if (is_definition && sig->is_defined) { - YYLTYPE loc = this->get_location(); - - _mesa_glsl_error(& loc, state, "function `%s' redefined", name); + if (sig->is_defined) { + if (is_definition) { + YYLTYPE loc = this->get_location(); + _mesa_glsl_error(& loc, state, "function `%s' redefined", name); + } else { + /* We just encountered a prototype that exactly matches a + * function that's already been defined. This is redundant, + * and we should ignore it. + */ + return NULL; + } } } } else { @@ -3328,7 +3679,7 @@ ast_jump_statement::hir(exec_list *instructions, assert(state->current_function); if (opt_return_value) { - ir_rvalue *const ret = opt_return_value->hir(instructions, state); + ir_rvalue *ret = opt_return_value->hir(instructions, state); /* The value of the return type can be NULL if the shader says * 'return foo();' and foo() is a function that returns void. @@ -3340,17 +3691,46 @@ ast_jump_statement::hir(exec_list *instructions, const glsl_type *const ret_type = (ret == NULL) ? glsl_type::void_type : ret->type; - /* Implicit conversions are not allowed for return values. */ - if (state->current_function->return_type != ret_type) { + /* Implicit conversions are not allowed for return values prior to + * ARB_shading_language_420pack. + */ + if (state->current_function->return_type != ret_type) { YYLTYPE loc = this->get_location(); - _mesa_glsl_error(& loc, state, - "`return' with wrong type %s, in function `%s' " - "returning %s", - ret_type->name, - state->current_function->function_name(), - state->current_function->return_type->name); - } + if (state->ARB_shading_language_420pack_enable) { + if (!apply_implicit_conversion(state->current_function->return_type, + ret, state)) { + _mesa_glsl_error(& loc, state, + "could not implicitly convert return value " + "to %s, in function `%s'", + state->current_function->return_type->name, + state->current_function->function_name()); + } + } else { + _mesa_glsl_error(& loc, state, + "`return' with wrong type %s, in function `%s' " + "returning %s", + ret_type->name, + state->current_function->function_name(), + state->current_function->return_type->name); + } + } else if (state->current_function->return_type->base_type == + GLSL_TYPE_VOID) { + YYLTYPE loc = this->get_location(); + + /* The ARB_shading_language_420pack, GLSL ES 3.0, and GLSL 4.20 + * specs add a clarification: + * + * "A void function can only use return without a return argument, even if + * the return argument has void type. Return statements only accept values: + * + * void func1() { } + * void func2() { return func1(); } // illegal return statement" + */ + _mesa_glsl_error(& loc, state, + "void functions can only use `return' without a " + "return argument"); + } inst = new(ctx) ir_return(ret); } else { @@ -3845,10 +4225,8 @@ ast_iteration_statement::hir(exec_list *instructions, * version. */ static bool -is_valid_default_precision_type(const struct _mesa_glsl_parse_state *state, - const char *type_name) +is_valid_default_precision_type(const struct glsl_type *const type) { - const struct glsl_type *type = state->symbols->get_type(type_name); if (type == NULL) return false; @@ -3869,22 +4247,11 @@ ir_rvalue * ast_type_specifier::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { - if (!this->is_precision_statement && this->structure == NULL) + if (this->default_precision == ast_precision_none && this->structure == NULL) return NULL; 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. * @@ -3895,19 +4262,28 @@ ast_type_specifier::hir(exec_list *instructions, * field can be either int or float [...]. Any other types or * qualifiers will result in an error. */ - if (this->is_precision_statement) { - assert(this->precision != ast_precision_none); - assert(this->structure == NULL); /* The check for structures was - * performed above. */ + if (this->default_precision != ast_precision_none) { + 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 " "arrays"); return NULL; } - if (!is_valid_default_precision_type(state, this->type_name)) { + + const struct glsl_type *const type = + state->symbols->get_type(this->type_name); + if (!is_valid_default_precision_type(type)) { _mesa_glsl_error(&loc, state, - "default precision statements apply only to types " + "default precision statements apply only to " "float, int, and sampler types"); return NULL; } @@ -3916,7 +4292,19 @@ ast_type_specifier::hir(exec_list *instructions, return NULL; } - if (this->structure != NULL) + /* _mesa_ast_set_aggregate_type() sets the field so that + * process_record_constructor() can do type-checking on C-style initializer + * expressions of structs, but ast_struct_specifier should only be translated + * to HIR if it is declaring the type of a structure. + * + * The ->is_declaration field is false for initializers of variables + * declared separately from the struct's type definition. + * + * struct S { ... }; (is_declaration = true) + * struct T { ... } t = { ... }; (is_declaration = true) + * S s = { ... }; (is_declaration = false) + */ + if (this->structure != NULL && this->structure->is_declaration) return this->structure->hir(instructions, state); return NULL; @@ -3975,8 +4363,8 @@ ast_process_structure_or_interface_block(exec_list *instructions, * embedded structure definitions have been removed from the language. */ if (state->es_shader && decl_list->type->specifier->structure != NULL) { - _mesa_glsl_error(&loc, state, "Embedded structure definitions are " - "not allowed in GLSL ES 1.00."); + _mesa_glsl_error(&loc, state, "embedded structure definitions are " + "not allowed in GLSL ES 1.00"); } const glsl_type *decl_type = @@ -3990,13 +4378,19 @@ ast_process_structure_or_interface_block(exec_list *instructions, * blocks. All other types, arrays, and structures * allowed for uniforms are allowed within a uniform * block." + * + * It should be impossible for decl_type to be NULL here. Cases that + * might naturally lead to decl_type being NULL, especially for the + * is_interface case, will have resulted in compilation having + * already halted due to a syntax error. */ - const struct glsl_type *field_type = decl_type; + const struct glsl_type *field_type = + decl_type != NULL ? decl_type : glsl_type::error_type; if (is_interface && field_type->contains_sampler()) { YYLTYPE loc = decl_list->get_location(); _mesa_glsl_error(&loc, state, - "Uniform in non-default uniform block contains sampler\n"); + "uniform in non-default uniform block contains sampler"); } const struct ast_type_qualifier *const qual = @@ -4014,12 +4408,15 @@ ast_process_structure_or_interface_block(exec_list *instructions, field_type = process_array_type(&loc, decl_type, decl->array_size, state); } - fields[i].type = (field_type != NULL) - ? field_type : glsl_type::error_type; + fields[i].type = field_type; fields[i].name = decl->identifier; if (qual->flags.q.row_major || qual->flags.q.column_major) { - if (!field_type->is_matrix() && !field_type->is_record()) { + if (!qual->flags.q.uniform) { + _mesa_glsl_error(&loc, state, + "row_major and column_major can only be " + "applied to uniform interface blocks"); + } else if (!field_type->is_matrix() && !field_type->is_record()) { _mesa_glsl_error(&loc, state, "uniform block layout qualifiers row_major and " "column_major can only be applied to matrix and " @@ -4028,6 +4425,12 @@ ast_process_structure_or_interface_block(exec_list *instructions, validate_matrix_layout_for_type(state, &loc, field_type); } + if (qual->flags.q.uniform && qual->has_interpolation()) { + _mesa_glsl_error(&loc, state, + "interpolation qualifiers cannot be used " + "with uniform interface blocks"); + } + if (field_type->is_matrix() || (field_type->is_array() && field_type->fields.array->is_matrix())) { fields[i].row_major = block_row_major; @@ -4053,6 +4456,34 @@ ast_struct_specifier::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { YYLTYPE loc = this->get_location(); + + /* Section 4.1.8 (Structures) of the GLSL 1.10 spec says: + * + * "Anonymous structures are not supported; so embedded structures must + * have a declarator. A name given to an embedded struct is scoped at + * the same level as the struct it is embedded in." + * + * The same section of the GLSL 1.20 spec says: + * + * "Anonymous structures are not supported. Embedded structures are not + * supported. + * + * struct S { float f; }; + * struct T { + * S; // Error: anonymous structures disallowed + * struct { ... }; // Error: embedded structures disallowed + * S s; // Okay: nested structures with name are allowed + * };" + * + * The GLSL ES 1.00 and 3.00 specs have similar langauge and examples. So, + * we allow embedded structures in 1.10 only. + */ + if (state->language_version != 110 && state->struct_specifier_depth != 0) + _mesa_glsl_error(&loc, state, + "embedded structure declartions are not allowed"); + + state->struct_specifier_depth++; + glsl_struct_field *fields; unsigned decl_count = ast_process_structure_or_interface_block(instructions, @@ -4079,18 +4510,20 @@ ast_struct_specifier::hir(exec_list *instructions, } } + state->struct_specifier_depth--; + /* Structure type definitions do not have r-values. */ return NULL; } ir_rvalue * -ast_uniform_block::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) +ast_interface_block::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) { YYLTYPE loc = this->get_location(); - /* The ast_uniform_block has a list of ast_declarator_lists. We + /* The ast_interface_block has a list of ast_declarator_lists. We * need to turn those into ir_variables with an association * with this uniform block. */ @@ -4117,16 +4550,34 @@ ast_uniform_block::hir(exec_list *instructions, true, block_row_major); + ir_variable_mode var_mode; + const char *iface_type_name; + if (this->layout.flags.q.in) { + var_mode = ir_var_shader_in; + iface_type_name = "in"; + } else if (this->layout.flags.q.out) { + var_mode = ir_var_shader_out; + iface_type_name = "out"; + } else if (this->layout.flags.q.uniform) { + var_mode = ir_var_uniform; + iface_type_name = "uniform"; + } else { + var_mode = ir_var_auto; + iface_type_name = "UNKNOWN"; + assert(!"interface block layout qualifier not found!"); + } + const glsl_type *block_type = glsl_type::get_interface_instance(fields, num_variables, packing, this->block_name); - if (!state->symbols->add_type(block_type->name, block_type)) { + if (!state->symbols->add_interface(block_type->name, block_type, var_mode)) { YYLTYPE loc = this->get_location(); - _mesa_glsl_error(&loc, state, "Uniform block name `%s' already taken in " - "the current scope.\n", this->block_name); + _mesa_glsl_error(&loc, state, "interface block `%s' with type `%s' " + "already taken in the current scope", + this->block_name, iface_type_name); } /* Since interface blocks cannot contain statements, it should be @@ -4134,6 +4585,19 @@ ast_uniform_block::hir(exec_list *instructions, */ assert(declared_variables.is_empty()); + /* From section 4.3.4 (Inputs) of the GLSL 1.50 spec: + * + * Geometry shader input variables get the per-vertex values written + * out by vertex shader output variables of the same names. Since a + * geometry shader operates on a set of vertices, each input varying + * variable (or input block, see interface blocks below) needs to be + * declared as an array. + */ + if (state->target == geometry_shader && !this->is_array && + var_mode == ir_var_shader_in) { + _mesa_glsl_error(&loc, state, "geometry shader inputs must be arrays"); + } + /* Page 39 (page 45 of the PDF) of section 4.3.7 in the GLSL ES 3.00 spec * says: * @@ -4144,35 +4608,71 @@ ast_uniform_block::hir(exec_list *instructions, if (this->instance_name) { ir_variable *var; - if (this->array_size != NULL) { + if (this->is_array) { + /* Section 4.3.7 (Interface Blocks) of the GLSL 1.50 spec says: + * + * For uniform blocks declared an array, each individual array + * element corresponds to a separate buffer object backing one + * instance of the block. As the array size indicates the number + * of buffer objects needed, uniform block array declarations + * must specify an array size. + * + * And a few paragraphs later: + * + * Geometry shader input blocks must be declared as arrays and + * follow the array declaration and linking rules for all + * geometry shader inputs. All other input and output block + * arrays must specify an array size. + * + * The upshot of this is that the only circumstance where an + * interface array size *doesn't* need to be specified is on a + * geometry shader input. + */ + if (this->array_size == NULL && + (state->target != geometry_shader || !this->layout.flags.q.in)) { + _mesa_glsl_error(&loc, state, + "only geometry shader inputs may be unsized " + "instance block arrays"); + + } + const glsl_type *block_array_type = process_array_type(&loc, block_type, this->array_size, state); var = new(state) ir_variable(block_array_type, this->instance_name, - ir_var_uniform); + var_mode); } else { var = new(state) ir_variable(block_type, this->instance_name, - ir_var_uniform); + var_mode); } var->interface_type = block_type; + if (state->target == geometry_shader && var_mode == ir_var_shader_in) + handle_geometry_shader_input_decl(state, loc, var); state->symbols->add_variable(var); instructions->push_tail(var); } else { /* In order to have an array size, the block must also be declared with * an instane name. */ - assert(this->array_size == NULL); + assert(!this->is_array); for (unsigned i = 0; i < num_variables; i++) { ir_variable *var = new(state) ir_variable(fields[i].type, ralloc_strdup(state, fields[i].name), - ir_var_uniform); + var_mode); var->interface_type = block_type; + /* Propagate the "binding" keyword into this UBO's fields; + * the UBO declaration itself doesn't get an ir_variable unless it + * has an instance name. This is ugly. + */ + var->explicit_binding = this->layout.flags.q.explicit_binding; + var->binding = this->layout.binding; + state->symbols->add_variable(var); instructions->push_tail(var); } @@ -4181,6 +4681,72 @@ ast_uniform_block::hir(exec_list *instructions, return NULL; } + +ir_rvalue * +ast_gs_input_layout::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + YYLTYPE loc = this->get_location(); + + /* If any geometry input layout declaration preceded this one, make sure it + * was consistent with this one. + */ + if (state->gs_input_prim_type_specified && + state->gs_input_prim_type != this->prim_type) { + _mesa_glsl_error(&loc, state, + "geometry shader input layout does not match" + " previous declaration"); + return NULL; + } + + /* If any shader inputs occurred before this declaration and specified an + * array size, make sure the size they specified is consistent with the + * primitive type. + */ + unsigned num_vertices = vertices_per_prim(this->prim_type); + if (state->gs_input_size != 0 && state->gs_input_size != num_vertices) { + _mesa_glsl_error(&loc, state, + "this geometry shader input layout implies %u vertices" + " per primitive, but a previous input is declared" + " with size %u", num_vertices, state->gs_input_size); + return NULL; + } + + state->gs_input_prim_type_specified = true; + state->gs_input_prim_type = this->prim_type; + + /* If any shader inputs occurred before this declaration and did not + * specify an array size, their size is determined now. + */ + foreach_list (node, instructions) { + ir_variable *var = ((ir_instruction *) node)->as_variable(); + if (var == NULL || var->mode != ir_var_shader_in) + continue; + + /* Note: gl_PrimitiveIDIn has mode ir_var_shader_in, but it's not an + * array; skip it. + */ + if (!var->type->is_array()) + continue; + + if (var->type->length == 0) { + if (var->max_array_access >= num_vertices) { + _mesa_glsl_error(&loc, state, + "this geometry shader input layout implies %u" + " vertices, but an access to element %u of input" + " `%s' already exists", num_vertices, + var->max_array_access, var->name); + } else { + var->type = glsl_type::get_array_instance(var->type->fields.array, + num_vertices); + } + } + } + + return NULL; +} + + static void detect_conflicting_assignments(struct _mesa_glsl_parse_state *state, exec_list *instructions) @@ -4230,14 +4796,14 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state, */ if (gl_FragColor_assigned && gl_FragData_assigned) { _mesa_glsl_error(&loc, state, "fragment shader writes to both " - "`gl_FragColor' and `gl_FragData'\n"); + "`gl_FragColor' and `gl_FragData'"); } else if (gl_FragColor_assigned && user_defined_fs_output_assigned) { _mesa_glsl_error(&loc, state, "fragment shader writes to both " - "`gl_FragColor' and `%s'\n", + "`gl_FragColor' and `%s'", user_defined_fs_output->name); } else if (gl_FragData_assigned && user_defined_fs_output_assigned) { _mesa_glsl_error(&loc, state, "fragment shader writes to both " - "`gl_FragData' and `%s'\n", + "`gl_FragData' and `%s'", user_defined_fs_output->name); } }