/* * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /** * \file ast_to_hir.c * Convert abstract syntax to to high-level intermediate reprensentation (HIR). * * During the conversion to HIR, the majority of the symantic checking is * preformed on the program. This includes: * * * Symbol table management * * Type checking * * Function binding * * The majority of this work could be done during parsing, and the parser could * probably generate HIR directly. However, this results in frequent changes * to the parser code. Since we do not assume that every system this complier * is built on will have Flex and Bison installed, we have to store the code * generated by these tools in our version control system. In other parts of * the system we've seen problems where a parser was changed but the generated * code was not committed, merge conflicts where created because two developers * had slightly different versions of Bison installed, etc. * * I have also noticed that running Bison generated parsers in GDB is very * irritating. When you get a segfault on '$$ = $1->foo', you can't very * well 'print $1' in GDB. * * As a result, my preference is to put as little C code as possible in the * parser (and lexer) sources. */ #include "glsl_symbol_table.h" #include "glsl_parser_extras.h" #include "ast.h" #include "glsl_types.h" #include "program/hash_table.h" #include "ir.h" #include "ir_builder.h" using namespace ir_builder; static void detect_conflicting_assignments(struct _mesa_glsl_parse_state *state, exec_list *instructions); static void remove_per_vertex_blocks(exec_list *instructions, _mesa_glsl_parse_state *state, ir_variable_mode mode); void _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { _mesa_glsl_initialize_variables(instructions, state); state->symbols->separate_function_namespace = state->language_version == 110; state->current_function = NULL; state->toplevel_ir = instructions; state->gs_input_prim_type_specified = false; state->cs_input_local_size_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, * available for user-defined functions and global variables, is nested * inside the scope containing the built-in functions." * * Since built-in functions like ftransform() access built-in variables, * it follows that those must be in the outer scope as well. * * We push scope here to create this nesting effect...but don't pop. * This way, a shader's globals are still in the symbol table for use * by the linker. */ state->symbols->push_scope(); foreach_list_typed (ast_node, ast, link, & state->translation_unit) ast->hir(instructions, state); detect_recursion_unlinked(state, instructions); 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); } /* Figure out if gl_FragCoord is actually used in fragment shader */ ir_variable *const var = state->symbols->get_variable("gl_FragCoord"); if (var != NULL) state->fs_uses_gl_fragcoord = var->data.used; /* From section 7.1 (Built-In Language Variables) of the GLSL 4.10 spec: * * If multiple shaders using members of a built-in block belonging to * the same interface are linked together in the same program, they * must all redeclare the built-in block in the same way, as described * in section 4.3.7 "Interface Blocks" for interface block matching, or * a link error will result. * * The phrase "using members of a built-in block" implies that if two * shaders are linked together and one of them *does not use* any members * of the built-in block, then that shader does not need to have a matching * redeclaration of the built-in block. * * This appears to be a clarification to the behaviour established for * gl_PerVertex by GLSL 1.50, therefore implement it regardless of GLSL * version. * * The definition of "interface" in section 4.3.7 that applies here is as * follows: * * The boundary between adjacent programmable pipeline stages: This * spans all the outputs in all compilation units of the first stage * and all the inputs in all compilation units of the second stage. * * Therefore this rule applies to both inter- and intra-stage linking. * * The easiest way to implement this is to check whether the shader uses * gl_PerVertex right after ast-to-ir conversion, and if it doesn't, simply * remove all the relevant variable declaration from the IR, so that the * linker won't see them and complain about mismatches. */ remove_per_vertex_blocks(instructions, state, ir_var_shader_in); remove_per_vertex_blocks(instructions, state, ir_var_shader_out); } static ir_expression_operation get_conversion_operation(const glsl_type *to, const glsl_type *from, struct _mesa_glsl_parse_state *state) { switch (to->base_type) { case GLSL_TYPE_FLOAT: switch (from->base_type) { case GLSL_TYPE_INT: return ir_unop_i2f; case GLSL_TYPE_UINT: return ir_unop_u2f; default: return (ir_expression_operation)0; } case GLSL_TYPE_UINT: if (!state->is_version(400, 0) && !state->ARB_gpu_shader5_enable) return (ir_expression_operation)0; switch (from->base_type) { case GLSL_TYPE_INT: return ir_unop_i2u; default: return (ir_expression_operation)0; } default: return (ir_expression_operation)0; } } /** * If a conversion is available, convert one operand to a different type * * The \c from \c ir_rvalue is converted "in place". * * \param to Type that the operand it to be converted to * \param from Operand that is being converted * \param state GLSL compiler state * * \return * If a conversion is possible (or unnecessary), \c true is returned. * Otherwise \c false is returned. */ bool apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, struct _mesa_glsl_parse_state *state) { void *ctx = state; if (to->base_type == from->type->base_type) return true; /* Prior to GLSL 1.20, there are no implicit conversions */ if (!state->is_version(120, 0)) return false; /* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec: * * "There are no implicit array or structure conversions. For * example, an array of int cannot be implicitly converted to an * array of float. */ if (!to->is_numeric() || !from->type->is_numeric()) return false; /* We don't actually want the specific type `to`, we want a type * with the same base type as `to`, but the same vector width as * `from`. */ to = glsl_type::get_instance(to->base_type, from->type->vector_elements, from->type->matrix_columns); ir_expression_operation op = get_conversion_operation(to, from->type, state); if (op) { from = new(ctx) ir_expression(op, to, from, NULL); return true; } else { return false; } } static const struct glsl_type * arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, bool multiply, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { const glsl_type *type_a = value_a->type; const glsl_type *type_b = value_b->type; /* From GLSL 1.50 spec, page 56: * * "The arithmetic binary operators add (+), subtract (-), * multiply (*), and divide (/) operate on integer and * floating-point scalars, vectors, and matrices." */ if (!type_a->is_numeric() || !type_b->is_numeric()) { _mesa_glsl_error(loc, state, "operands to arithmetic operators must be numeric"); return glsl_type::error_type; } /* "If one operand is floating-point based and the other is * not, then the conversions from Section 4.1.10 "Implicit * Conversions" are applied to the non-floating-point-based operand." */ 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 " "arithmetic operator"); return glsl_type::error_type; } type_a = value_a->type; type_b = value_b->type; /* "If the operands are integer types, they must both be signed or * both be unsigned." * * From this rule and the preceeding conversion it can be inferred that * both types must be GLSL_TYPE_FLOAT, or GLSL_TYPE_UINT, or GLSL_TYPE_INT. * The is_numeric check above already filtered out the case where either * type is not one of these, so now the base types need only be tested for * equality. */ if (type_a->base_type != type_b->base_type) { _mesa_glsl_error(loc, state, "base type mismatch for arithmetic operator"); return glsl_type::error_type; } /* "All arithmetic binary operators result in the same fundamental type * (signed integer, unsigned integer, or floating-point) as the * operands they operate on, after operand type conversion. After * conversion, the following cases are valid * * * The two operands are scalars. In this case the operation is * applied, resulting in a scalar." */ if (type_a->is_scalar() && type_b->is_scalar()) return type_a; /* "* One operand is a scalar, and the other is a vector or matrix. * In this case, the scalar operation is applied independently to each * component of the vector or matrix, resulting in the same size * vector or matrix." */ if (type_a->is_scalar()) { if (!type_b->is_scalar()) return type_b; } else if (type_b->is_scalar()) { return type_a; } /* All of the combinations of , , * , , and have been * handled. */ assert(!type_a->is_scalar()); assert(!type_b->is_scalar()); /* "* The two operands are vectors of the same size. In this case, the * operation is done component-wise resulting in the same size * vector." */ if (type_a->is_vector() && type_b->is_vector()) { if (type_a == type_b) { return type_a; } else { _mesa_glsl_error(loc, state, "vector size mismatch for arithmetic operator"); return glsl_type::error_type; } } /* All of the combinations of , , * , , , and * have been handled. At least one of the operands must * be matrix. Further, since there are no integer matrix types, the base * type of both operands must be float. */ assert(type_a->is_matrix() || type_b->is_matrix()); assert(type_a->base_type == GLSL_TYPE_FLOAT); assert(type_b->base_type == GLSL_TYPE_FLOAT); /* "* The operator is add (+), subtract (-), or divide (/), and the * operands are matrices with the same number of rows and the same * number of columns. In this case, the operation is done component- * wise resulting in the same size matrix." * * The operator is multiply (*), where both operands are matrices or * one operand is a vector and the other a matrix. A right vector * operand is treated as a column vector and a left vector operand as a * row vector. In all these cases, it is required that the number of * columns of the left operand is equal to the number of rows of the * right operand. Then, the multiply (*) operation does a linear * algebraic multiply, yielding an object that has the same number of * rows as the left operand and the same number of columns as the right * operand. Section 5.10 "Vector and Matrix Operations" explains in * more detail how vectors and matrices are operated on." */ if (! multiply) { if (type_a == type_b) return type_a; } else { if (type_a->is_matrix() && type_b->is_matrix()) { /* Matrix multiply. The columns of A must match the rows of B. Given * the other previously tested constraints, this means the vector type * of a row from A must be the same as the vector type of a column from * B. */ if (type_a->row_type() == type_b->column_type()) { /* The resulting matrix has the number of columns of matrix B and * the number of rows of matrix A. We get the row count of A by * looking at the size of a vector that makes up a column. The * transpose (size of a row) is done for B. */ const glsl_type *const type = glsl_type::get_instance(type_a->base_type, type_a->column_type()->vector_elements, type_b->row_type()->vector_elements); assert(type != glsl_type::error_type); return type; } } else if (type_a->is_matrix()) { /* A is a matrix and B is a column vector. Columns of A must match * rows of B. Given the other previously tested constraints, this * means the vector type of a row from A must be the same as the * vector the type of B. */ if (type_a->row_type() == type_b) { /* The resulting vector has a number of elements equal to * the number of rows of matrix A. */ const glsl_type *const type = glsl_type::get_instance(type_a->base_type, type_a->column_type()->vector_elements, 1); assert(type != glsl_type::error_type); return type; } } else { assert(type_b->is_matrix()); /* A is a row vector and B is a matrix. Columns of A must match rows * of B. Given the other previously tested constraints, this means * the type of A must be the same as the vector type of a column from * B. */ if (type_a == type_b->column_type()) { /* The resulting vector has a number of elements equal to * the number of columns of matrix B. */ const glsl_type *const type = glsl_type::get_instance(type_a->base_type, type_b->row_type()->vector_elements, 1); assert(type != glsl_type::error_type); return type; } } _mesa_glsl_error(loc, state, "size mismatch for matrix multiplication"); return glsl_type::error_type; } /* "All other cases are illegal." */ _mesa_glsl_error(loc, state, "type mismatch"); return glsl_type::error_type; } static const struct glsl_type * unary_arithmetic_result_type(const struct glsl_type *type, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { /* From GLSL 1.50 spec, page 57: * * "The arithmetic unary operators negate (-), post- and pre-increment * and decrement (-- and ++) operate on integer or floating-point * values (including vectors and matrices). All unary operators work * component-wise on their operands. These result with the same type * they operated on." */ if (!type->is_numeric()) { _mesa_glsl_error(loc, state, "operands to arithmetic operators must be numeric"); return glsl_type::error_type; } return type; } /** * \brief Return the result type of a bit-logic operation. * * If the given types to the bit-logic operator are invalid, return * glsl_type::error_type. * * \param type_a Type of LHS of bit-logic op * \param type_b Type of RHS of bit-logic op */ static const struct glsl_type * bit_logic_result_type(const struct glsl_type *type_a, const struct glsl_type *type_b, ast_operators op, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { if (!state->check_bitwise_operations_allowed(loc)) { return glsl_type::error_type; } /* From page 50 (page 56 of PDF) of GLSL 1.30 spec: * * "The bitwise operators and (&), exclusive-or (^), and inclusive-or * (|). The operands must be of type signed or unsigned integers or * integer vectors." */ if (!type_a->is_integer()) { _mesa_glsl_error(loc, state, "LHS of `%s' must be an integer", ast_expression::operator_string(op)); return glsl_type::error_type; } if (!type_b->is_integer()) { _mesa_glsl_error(loc, state, "RHS of `%s' must be an integer", ast_expression::operator_string(op)); return glsl_type::error_type; } /* "The fundamental types of the operands (signed or unsigned) must * match," */ if (type_a->base_type != type_b->base_type) { _mesa_glsl_error(loc, state, "operands of `%s' must have the same " "base type", ast_expression::operator_string(op)); return glsl_type::error_type; } /* "The operands cannot be vectors of differing size." */ if (type_a->is_vector() && type_b->is_vector() && type_a->vector_elements != type_b->vector_elements) { _mesa_glsl_error(loc, state, "operands of `%s' cannot be vectors of " "different sizes", ast_expression::operator_string(op)); return glsl_type::error_type; } /* "If one operand is a scalar and the other a vector, the scalar is * applied component-wise to the vector, resulting in the same type as * the vector. The fundamental types of the operands [...] will be the * resulting fundamental type." */ if (type_a->is_scalar()) return type_b; else return type_a; } static const struct glsl_type * modulus_result_type(const struct glsl_type *type_a, const struct glsl_type *type_b, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { if (!state->check_version(130, 300, loc, "operator '%%' is reserved")) { return glsl_type::error_type; } /* From GLSL 1.50 spec, page 56: * "The operator modulus (%) operates on signed or unsigned integers or * integer vectors. The operand types must both be signed or both be * unsigned." */ if (!type_a->is_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"); return glsl_type::error_type; } if (type_a->base_type != type_b->base_type) { _mesa_glsl_error(loc, state, "operands of %% must have the same base type"); return glsl_type::error_type; } /* "The operands cannot be vectors of differing size. If one operand is * a scalar and the other vector, then the scalar is applied component- * wise to the vector, resulting in the same type as the vector. If both * are vectors of the same size, the result is computed component-wise." */ if (type_a->is_vector()) { if (!type_b->is_vector() || (type_a->vector_elements == type_b->vector_elements)) return type_a; } else return type_b; /* "The operator modulus (%) is not defined for any other data types * (non-integer types)." */ _mesa_glsl_error(loc, state, "type mismatch"); return glsl_type::error_type; } static const struct glsl_type * relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { const glsl_type *type_a = value_a->type; const glsl_type *type_b = value_b->type; /* From GLSL 1.50 spec, page 56: * "The relational operators greater than (>), less than (<), greater * than or equal (>=), and less than or equal (<=) operate only on * scalar integer and scalar floating-point expressions." */ if (!type_a->is_numeric() || !type_b->is_numeric() || !type_a->is_scalar() || !type_b->is_scalar()) { _mesa_glsl_error(loc, state, "operands to relational operators must be scalar and " "numeric"); return glsl_type::error_type; } /* "Either the operands' types must match, or the conversions from * Section 4.1.10 "Implicit Conversions" will be applied to the integer * operand, after which the types must match." */ 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 " "relational operator"); return glsl_type::error_type; } type_a = value_a->type; type_b = value_b->type; if (type_a->base_type != type_b->base_type) { _mesa_glsl_error(loc, state, "base type mismatch"); return glsl_type::error_type; } /* "The result is scalar Boolean." */ return glsl_type::bool_type; } /** * \brief Return the result type of a bit-shift operation. * * If the given types to the bit-shift operator are invalid, return * glsl_type::error_type. * * \param type_a Type of LHS of bit-shift op * \param type_b Type of RHS of bit-shift op */ static const struct glsl_type * shift_result_type(const struct glsl_type *type_a, const struct glsl_type *type_b, ast_operators op, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { if (!state->check_bitwise_operations_allowed(loc)) { return glsl_type::error_type; } /* From page 50 (page 56 of the PDF) of the GLSL 1.30 spec: * * "The shift operators (<<) and (>>). For both operators, the operands * must be signed or unsigned integers or integer vectors. One operand * can be signed while the other is unsigned." */ if (!type_a->is_integer()) { _mesa_glsl_error(loc, state, "LHS of operator %s must be an integer or " "integer vector", ast_expression::operator_string(op)); return glsl_type::error_type; } if (!type_b->is_integer()) { _mesa_glsl_error(loc, state, "RHS of operator %s must be an integer or " "integer vector", ast_expression::operator_string(op)); return glsl_type::error_type; } /* "If the first operand is a scalar, the second operand has to be * 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 " "second must be scalar as well", ast_expression::operator_string(op)); return glsl_type::error_type; } /* If both operands are vectors, check that they have same number of * elements. */ 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 " "have same number of elements", ast_expression::operator_string(op)); return glsl_type::error_type; } /* "In all cases, the resulting type will be the same type as the left * operand." */ return type_a; } /** * Validates that a value can be assigned to a location with a specified type * * Validates that \c rhs can be assigned to some location. If the types are * not an exact match but an automatic conversion is possible, \c rhs will be * converted. * * \return * \c NULL if \c rhs cannot be assigned to a location with type \c lhs_type. * Otherwise the actual RHS to be assigned will be returned. This may be * \c rhs, or it may be \c rhs after some type conversion. * * \note * In addition to being used for assignments, this function is used to * type-check return values. */ ir_rvalue * validate_assignment(struct _mesa_glsl_parse_state *state, YYLTYPE loc, const glsl_type *lhs_type, ir_rvalue *rhs, bool is_initializer) { /* If there is already some error in the RHS, just return it. Anything * else will lead to an avalanche of error message back to the user. */ if (rhs->type->is_error()) return rhs; /* If the types are identical, the assignment can trivially proceed. */ if (rhs->type == lhs_type) return rhs; /* If the array element types are the same and the LHS is unsized, * the assignment is okay for initializers embedded in variable * declarations. * * Note: Whole-array assignments are not permitted in GLSL 1.10, but this * is handled by ir_dereference::is_lvalue. */ if (lhs_type->is_unsized_array() && rhs->type->is_array() && (lhs_type->element_type() == rhs->type->element_type())) { if (is_initializer) { return rhs; } else { _mesa_glsl_error(&loc, state, "implicitly sized arrays cannot be assigned"); return NULL; } } /* Check for implicit conversion in GLSL 1.20 */ if (apply_implicit_conversion(lhs_type, rhs, state)) { if (rhs->type == lhs_type) return rhs; } _mesa_glsl_error(&loc, state, "%s of type %s cannot be assigned to " "variable of type %s", is_initializer ? "initializer" : "value", rhs->type->name, lhs_type->name); return NULL; } static void mark_whole_array_access(ir_rvalue *access) { ir_dereference_variable *deref = access->as_dereference_variable(); if (deref && deref->var) { deref->var->data.max_array_access = deref->type->length - 1; } } static bool do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, const char *non_lvalue_description, ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue **out_rvalue, bool needs_rvalue, bool is_initializer, YYLTYPE lhs_loc) { void *ctx = state; bool error_emitted = (lhs->type->is_error() || rhs->type->is_error()); ir_rvalue *extract_channel = NULL; /* 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 lhs_expr = lhs->as_expression(); if (unlikely(lhs_expr->operation == ir_binop_vector_extract)) { ir_rvalue *new_rhs = validate_assignment(state, lhs_loc, lhs->type, rhs, is_initializer); if (new_rhs == NULL) { return lhs; } else { /* This converts: * - LHS: (expression float vector_extract ) * - RHS: * into: * - LHS: * - RHS: (expression vec2 vector_insert ) * * The LHS type is now a vector instead of a scalar. Since GLSL * allows assignments to be used as rvalues, we need to re-extract * the channel from assignment_temp when returning the rvalue. */ extract_channel = lhs_expr->operands[1]; rhs = new(ctx) ir_expression(ir_triop_vector_insert, lhs_expr->operands[0]->type, lhs_expr->operands[0], new_rhs, extract_channel); lhs = lhs_expr->operands[0]->clone(ctx, NULL); } } } ir_variable *lhs_var = lhs->variable_referenced(); if (lhs_var) lhs_var->data.assigned = true; if (!error_emitted) { if (non_lvalue_description != NULL) { _mesa_glsl_error(&lhs_loc, state, "assignment to %s", non_lvalue_description); error_emitted = true; } else if (lhs_var != NULL && lhs_var->data.read_only) { _mesa_glsl_error(&lhs_loc, state, "assignment to read-only variable '%s'", lhs_var->name); error_emitted = true; } else if (lhs->type->is_array() && !state->check_version(120, 300, &lhs_loc, "whole array assignment forbidden")) { /* From page 32 (page 38 of the PDF) of the GLSL 1.10 spec: * * "Other binary or unary expressions, non-dereferenced * arrays, function names, swizzles with repeated fields, * and constants cannot be l-values." * * The restriction on arrays is lifted in GLSL 1.20 and GLSL ES 3.00. */ error_emitted = true; } else if (!lhs->is_lvalue()) { _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment"); error_emitted = true; } } ir_rvalue *new_rhs = validate_assignment(state, lhs_loc, lhs->type, rhs, is_initializer); if (new_rhs != NULL) { rhs = new_rhs; /* If the LHS array was not declared with a size, it takes it size from * the RHS. If the LHS is an l-value and a whole array, it must be a * dereference of a variable. Any other case would require that the LHS * is either not an l-value or not a whole array. */ if (lhs->type->is_unsized_array()) { ir_dereference *const d = lhs->as_dereference(); assert(d != NULL); ir_variable *const var = d->variable_referenced(); assert(var != NULL); if (var->data.max_array_access >= unsigned(rhs->type->array_size())) { /* FINISHME: This should actually log the location of the RHS. */ _mesa_glsl_error(& lhs_loc, state, "array size must be > %u due to " "previous access", var->data.max_array_access); } var->type = glsl_type::get_array_instance(lhs->type->element_type(), rhs->type->array_size()); d->type = var->type; } if (lhs->type->is_array()) { mark_whole_array_access(rhs); mark_whole_array_access(lhs); } } /* Most callers of do_assignment (assign, add_assign, pre_inc/dec, * but not post_inc) need the converted assigned value as an rvalue * to handle things like: * * i = j += 1; */ if (needs_rvalue) { ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp", ir_var_temporary); instructions->push_tail(var); instructions->push_tail(assign(var, rhs)); if (!error_emitted) { ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var); instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var)); } ir_rvalue *rvalue = new(ctx) ir_dereference_variable(var); if (extract_channel) { rvalue = new(ctx) ir_expression(ir_binop_vector_extract, rvalue, extract_channel->clone(ctx, NULL)); } *out_rvalue = rvalue; } else { if (!error_emitted) instructions->push_tail(new(ctx) ir_assignment(lhs, rhs)); *out_rvalue = NULL; } return error_emitted; } static ir_rvalue * get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue) { void *ctx = ralloc_parent(lvalue); ir_variable *var; var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp", ir_var_temporary); instructions->push_tail(var); var->data.mode = ir_var_auto; instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var), lvalue)); return new(ctx) ir_dereference_variable(var); } ir_rvalue * ast_node::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { (void) instructions; (void) state; return NULL; } void ast_function_expression::hir_no_rvalue(exec_list *instructions, struct _mesa_glsl_parse_state *state) { (void)hir(instructions, state); } void ast_aggregate_initializer::hir_no_rvalue(exec_list *instructions, struct _mesa_glsl_parse_state *state) { (void)hir(instructions, state); } static ir_rvalue * do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1) { int join_op; ir_rvalue *cmp = NULL; if (operation == ir_binop_all_equal) join_op = ir_binop_logic_and; else join_op = ir_binop_logic_or; switch (op0->type->base_type) { case GLSL_TYPE_FLOAT: case GLSL_TYPE_UINT: case GLSL_TYPE_INT: case GLSL_TYPE_BOOL: return new(mem_ctx) ir_expression(operation, op0, op1); case GLSL_TYPE_ARRAY: { for (unsigned int i = 0; i < op0->type->length; i++) { ir_rvalue *e0, *e1, *result; e0 = new(mem_ctx) ir_dereference_array(op0->clone(mem_ctx, NULL), new(mem_ctx) ir_constant(i)); e1 = new(mem_ctx) ir_dereference_array(op1->clone(mem_ctx, NULL), new(mem_ctx) ir_constant(i)); result = do_comparison(mem_ctx, operation, e0, e1); if (cmp) { cmp = new(mem_ctx) ir_expression(join_op, cmp, result); } else { cmp = result; } } mark_whole_array_access(op0); mark_whole_array_access(op1); break; } case GLSL_TYPE_STRUCT: { for (unsigned int i = 0; i < op0->type->length; i++) { ir_rvalue *e0, *e1, *result; const char *field_name = op0->type->fields.structure[i].name; e0 = new(mem_ctx) ir_dereference_record(op0->clone(mem_ctx, NULL), field_name); e1 = new(mem_ctx) ir_dereference_record(op1->clone(mem_ctx, NULL), field_name); result = do_comparison(mem_ctx, operation, e0, e1); if (cmp) { cmp = new(mem_ctx) ir_expression(join_op, cmp, result); } else { cmp = result; } } break; } case GLSL_TYPE_ERROR: case GLSL_TYPE_VOID: case GLSL_TYPE_SAMPLER: case GLSL_TYPE_IMAGE: case GLSL_TYPE_INTERFACE: case GLSL_TYPE_ATOMIC_UINT: /* I assume a comparison of a struct containing a sampler just * ignores the sampler present in the type. */ break; } if (cmp == NULL) cmp = new(mem_ctx) ir_constant(true); return cmp; } /* For logical operations, we want to ensure that the operands are * scalar booleans. If it isn't, emit an error and return a constant * boolean to avoid triggering cascading error messages. */ ir_rvalue * get_scalar_boolean_operand(exec_list *instructions, struct _mesa_glsl_parse_state *state, ast_expression *parent_expr, int operand, const char *operand_name, bool *error_emitted) { ast_expression *expr = parent_expr->subexpressions[operand]; void *ctx = state; ir_rvalue *val = expr->hir(instructions, state); if (val->type->is_boolean() && val->type->is_scalar()) return val; if (!*error_emitted) { YYLTYPE loc = expr->get_location(); _mesa_glsl_error(&loc, state, "%s of `%s' must be scalar boolean", operand_name, parent_expr->operator_string(parent_expr->oper)); *error_emitted = true; } return new(ctx) ir_constant(true); } /** * If name refers to a builtin array whose maximum allowed size is less than * size, report an error and return true. Otherwise return false. */ void check_builtin_array_max_size(const char *name, unsigned size, YYLTYPE loc, struct _mesa_glsl_parse_state *state) { if ((strcmp("gl_TexCoord", name) == 0) && (size > state->Const.MaxTextureCoords)) { /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec: * * "The size [of gl_TexCoord] can be at most * gl_MaxTextureCoords." */ _mesa_glsl_error(&loc, state, "`gl_TexCoord' array size cannot " "be larger than gl_MaxTextureCoords (%u)", state->Const.MaxTextureCoords); } else if (strcmp("gl_ClipDistance", name) == 0 && size > state->Const.MaxClipPlanes) { /* From section 7.1 (Vertex Shader Special Variables) of the * GLSL 1.30 spec: * * "The gl_ClipDistance array is predeclared as unsized and * must be sized by the shader either redeclaring it with a * size or indexing it only with integral constant * expressions. ... The size can be at most * gl_MaxClipDistances." */ _mesa_glsl_error(&loc, state, "`gl_ClipDistance' array size cannot " "be larger than gl_MaxClipDistances (%u)", state->Const.MaxClipPlanes); } } /** * Create the constant 1, of a which is appropriate for incrementing and * decrementing values of the given GLSL type. For example, if type is vec4, * this creates a constant value of 1.0 having type float. * * If the given type is invalid for increment and decrement operators, return * a floating point 1--the error will be detected later. */ static ir_rvalue * constant_one_for_inc_dec(void *ctx, const glsl_type *type) { switch (type->base_type) { case GLSL_TYPE_UINT: return new(ctx) ir_constant((unsigned) 1); case GLSL_TYPE_INT: return new(ctx) ir_constant(1); default: case GLSL_TYPE_FLOAT: return new(ctx) ir_constant(1.0f); } } ir_rvalue * ast_expression::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { return do_hir(instructions, state, true); } void ast_expression::hir_no_rvalue(exec_list *instructions, struct _mesa_glsl_parse_state *state) { do_hir(instructions, state, false); } ir_rvalue * ast_expression::do_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state, bool needs_rvalue) { void *ctx = state; static const int operations[AST_NUM_OPERATORS] = { -1, /* ast_assign doesn't convert to ir_expression. */ -1, /* ast_plus doesn't convert to ir_expression. */ ir_unop_neg, ir_binop_add, ir_binop_sub, ir_binop_mul, ir_binop_div, ir_binop_mod, ir_binop_lshift, ir_binop_rshift, ir_binop_less, ir_binop_greater, ir_binop_lequal, ir_binop_gequal, ir_binop_all_equal, ir_binop_any_nequal, ir_binop_bit_and, ir_binop_bit_xor, ir_binop_bit_or, ir_unop_bit_not, ir_binop_logic_and, ir_binop_logic_xor, ir_binop_logic_or, ir_unop_logic_not, /* Note: The following block of expression types actually convert * to multiple IR instructions. */ ir_binop_mul, /* ast_mul_assign */ ir_binop_div, /* ast_div_assign */ ir_binop_mod, /* ast_mod_assign */ ir_binop_add, /* ast_add_assign */ ir_binop_sub, /* ast_sub_assign */ ir_binop_lshift, /* ast_ls_assign */ ir_binop_rshift, /* ast_rs_assign */ ir_binop_bit_and, /* ast_and_assign */ ir_binop_bit_xor, /* ast_xor_assign */ ir_binop_bit_or, /* ast_or_assign */ -1, /* ast_conditional doesn't convert to ir_expression. */ ir_binop_add, /* ast_pre_inc. */ ir_binop_sub, /* ast_pre_dec. */ ir_binop_add, /* ast_post_inc. */ ir_binop_sub, /* ast_post_dec. */ -1, /* ast_field_selection doesn't conv to ir_expression. */ -1, /* ast_array_index doesn't convert to ir_expression. */ -1, /* ast_function_call doesn't conv to ir_expression. */ -1, /* ast_identifier doesn't convert to ir_expression. */ -1, /* ast_int_constant doesn't convert to ir_expression. */ -1, /* ast_uint_constant doesn't conv to ir_expression. */ -1, /* ast_float_constant doesn't conv to ir_expression. */ -1, /* ast_bool_constant doesn't conv to ir_expression. */ -1, /* ast_sequence doesn't convert to ir_expression. */ }; ir_rvalue *result = NULL; ir_rvalue *op[3]; const struct glsl_type *type; /* a temporary variable for switch cases */ bool error_emitted = false; YYLTYPE loc; 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); error_emitted = do_assignment(instructions, state, this->subexpressions[0]->non_lvalue_description, op[0], op[1], &result, needs_rvalue, false, this->subexpressions[0]->get_location()); break; } case ast_plus: op[0] = this->subexpressions[0]->hir(instructions, state); type = unary_arithmetic_result_type(op[0]->type, state, & loc); error_emitted = type->is_error(); result = op[0]; break; case ast_neg: op[0] = this->subexpressions[0]->hir(instructions, state); type = unary_arithmetic_result_type(op[0]->type, state, & loc); error_emitted = type->is_error(); result = new(ctx) ir_expression(operations[this->oper], type, op[0], NULL); break; case ast_add: case ast_sub: case ast_mul: case ast_div: op[0] = this->subexpressions[0]->hir(instructions, state); op[1] = this->subexpressions[1]->hir(instructions, state); type = arithmetic_result_type(op[0], op[1], (this->oper == ast_mul), state, & loc); error_emitted = type->is_error(); result = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); break; case ast_mod: op[0] = this->subexpressions[0]->hir(instructions, state); op[1] = this->subexpressions[1]->hir(instructions, state); type = modulus_result_type(op[0]->type, op[1]->type, state, & loc); assert(operations[this->oper] == ir_binop_mod); result = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); error_emitted = type->is_error(); break; case ast_lshift: case ast_rshift: if (!state->check_bitwise_operations_allowed(&loc)) { error_emitted = true; } op[0] = this->subexpressions[0]->hir(instructions, state); op[1] = this->subexpressions[1]->hir(instructions, state); type = shift_result_type(op[0]->type, op[1]->type, this->oper, state, &loc); result = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); break; case ast_less: case ast_greater: case ast_lequal: case ast_gequal: op[0] = this->subexpressions[0]->hir(instructions, state); op[1] = this->subexpressions[1]->hir(instructions, state); type = relational_result_type(op[0], op[1], state, & loc); /* The relational operators must either generate an error or result * in a scalar boolean. See page 57 of the GLSL 1.50 spec. */ assert(type->is_error() || ((type->base_type == GLSL_TYPE_BOOL) && type->is_scalar())); result = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); error_emitted = type->is_error(); break; case ast_nequal: case ast_equal: op[0] = this->subexpressions[0]->hir(instructions, state); op[1] = this->subexpressions[1]->hir(instructions, state); /* From page 58 (page 64 of the PDF) of the GLSL 1.50 spec: * * "The equality operators equal (==), and not equal (!=) * operate on all types. They result in a scalar Boolean. If * the operand types do not match, then there must be a * conversion from Section 4.1.10 "Implicit Conversions" * applied to one operand that can make them match, in which * case this conversion is done." */ if ((!apply_implicit_conversion(op[0]->type, op[1], state) && !apply_implicit_conversion(op[1]->type, op[0], state)) || (op[0]->type != op[1]->type)) { _mesa_glsl_error(& loc, state, "operands of `%s' must have the same " "type", (this->oper == ast_equal) ? "==" : "!="); error_emitted = true; } else if ((op[0]->type->is_array() || op[1]->type->is_array()) && !state->check_version(120, 300, &loc, "array comparisons forbidden")) { error_emitted = true; } else if ((op[0]->type->contains_opaque() || op[1]->type->contains_opaque())) { _mesa_glsl_error(&loc, state, "opaque type comparisons forbidden"); error_emitted = true; } if (error_emitted) { result = new(ctx) ir_constant(false); } else { result = do_comparison(ctx, operations[this->oper], op[0], op[1]); assert(result->type == glsl_type::bool_type); } break; case ast_bit_and: case ast_bit_xor: case ast_bit_or: op[0] = this->subexpressions[0]->hir(instructions, state); op[1] = this->subexpressions[1]->hir(instructions, state); type = bit_logic_result_type(op[0]->type, op[1]->type, this->oper, state, &loc); result = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); break; case ast_bit_not: op[0] = this->subexpressions[0]->hir(instructions, state); if (!state->check_bitwise_operations_allowed(&loc)) { error_emitted = true; } if (!op[0]->type->is_integer()) { _mesa_glsl_error(&loc, state, "operand of `~' must be an integer"); error_emitted = true; } type = error_emitted ? glsl_type::error_type : op[0]->type; result = new(ctx) ir_expression(ir_unop_bit_not, type, op[0], NULL); break; case ast_logic_and: { exec_list rhs_instructions; op[0] = get_scalar_boolean_operand(instructions, state, this, 0, "LHS", &error_emitted); op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1, "RHS", &error_emitted); if (rhs_instructions.is_empty()) { result = new(ctx) ir_expression(ir_binop_logic_and, op[0], op[1]); type = result->type; } else { ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, "and_tmp", ir_var_temporary); instructions->push_tail(tmp); ir_if *const stmt = new(ctx) ir_if(op[0]); instructions->push_tail(stmt); stmt->then_instructions.append_list(&rhs_instructions); ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const then_assign = new(ctx) ir_assignment(then_deref, op[1]); stmt->then_instructions.push_tail(then_assign); ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const else_assign = new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false)); stmt->else_instructions.push_tail(else_assign); result = new(ctx) ir_dereference_variable(tmp); type = tmp->type; } break; } case ast_logic_or: { exec_list rhs_instructions; op[0] = get_scalar_boolean_operand(instructions, state, this, 0, "LHS", &error_emitted); op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1, "RHS", &error_emitted); if (rhs_instructions.is_empty()) { result = new(ctx) ir_expression(ir_binop_logic_or, op[0], op[1]); type = result->type; } else { ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, "or_tmp", ir_var_temporary); instructions->push_tail(tmp); ir_if *const stmt = new(ctx) ir_if(op[0]); instructions->push_tail(stmt); ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const then_assign = new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true)); stmt->then_instructions.push_tail(then_assign); stmt->else_instructions.append_list(&rhs_instructions); ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const else_assign = new(ctx) ir_assignment(else_deref, op[1]); stmt->else_instructions.push_tail(else_assign); result = new(ctx) ir_dereference_variable(tmp); type = tmp->type; } break; } case ast_logic_xor: /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec: * * "The logical binary operators and (&&), or ( | | ), and * exclusive or (^^). They operate only on two Boolean * expressions and result in a Boolean expression." */ op[0] = get_scalar_boolean_operand(instructions, state, this, 0, "LHS", &error_emitted); op[1] = get_scalar_boolean_operand(instructions, state, this, 1, "RHS", &error_emitted); result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type, op[0], op[1]); break; case ast_logic_not: op[0] = get_scalar_boolean_operand(instructions, state, this, 0, "operand", &error_emitted); result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type, op[0], NULL); break; case ast_mul_assign: case ast_div_assign: case ast_add_assign: case ast_sub_assign: { op[0] = this->subexpressions[0]->hir(instructions, state); op[1] = this->subexpressions[1]->hir(instructions, state); type = arithmetic_result_type(op[0], op[1], (this->oper == ast_mul_assign), state, & loc); ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); error_emitted = do_assignment(instructions, state, this->subexpressions[0]->non_lvalue_description, op[0]->clone(ctx, NULL), temp_rhs, &result, needs_rvalue, false, this->subexpressions[0]->get_location()); /* GLSL 1.10 does not allow array assignment. However, we don't have to * explicitly test for this because none of the binary expression * operators allow array operands either. */ break; } case ast_mod_assign: { op[0] = this->subexpressions[0]->hir(instructions, state); op[1] = this->subexpressions[1]->hir(instructions, state); type = modulus_result_type(op[0]->type, op[1]->type, state, & loc); assert(operations[this->oper] == ir_binop_mod); ir_rvalue *temp_rhs; temp_rhs = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); error_emitted = do_assignment(instructions, state, this->subexpressions[0]->non_lvalue_description, op[0]->clone(ctx, NULL), temp_rhs, &result, needs_rvalue, false, this->subexpressions[0]->get_location()); break; } case ast_ls_assign: case ast_rs_assign: { op[0] = this->subexpressions[0]->hir(instructions, state); op[1] = this->subexpressions[1]->hir(instructions, state); type = shift_result_type(op[0]->type, op[1]->type, this->oper, state, &loc); ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); error_emitted = do_assignment(instructions, state, this->subexpressions[0]->non_lvalue_description, op[0]->clone(ctx, NULL), temp_rhs, &result, needs_rvalue, false, this->subexpressions[0]->get_location()); break; } case ast_and_assign: case ast_xor_assign: case ast_or_assign: { op[0] = this->subexpressions[0]->hir(instructions, state); op[1] = this->subexpressions[1]->hir(instructions, state); type = bit_logic_result_type(op[0]->type, op[1]->type, this->oper, state, &loc); ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); error_emitted = do_assignment(instructions, state, this->subexpressions[0]->non_lvalue_description, op[0]->clone(ctx, NULL), temp_rhs, &result, needs_rvalue, false, this->subexpressions[0]->get_location()); break; } case ast_conditional: { /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec: * * "The ternary selection operator (?:). It operates on three * expressions (exp1 ? exp2 : exp3). This operator evaluates the * first expression, which must result in a scalar Boolean." */ op[0] = get_scalar_boolean_operand(instructions, state, this, 0, "condition", &error_emitted); /* The :? operator is implemented by generating an anonymous temporary * followed by an if-statement. The last instruction in each branch of * the if-statement assigns a value to the anonymous temporary. This * temporary is the r-value of the expression. */ exec_list then_instructions; exec_list else_instructions; op[1] = this->subexpressions[1]->hir(&then_instructions, state); op[2] = this->subexpressions[2]->hir(&else_instructions, state); /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec: * * "The second and third expressions can be any type, as * long their types match, or there is a conversion in * Section 4.1.10 "Implicit Conversions" that can be applied * to one of the expressions to make their types match. This * resulting matching type is the type of the entire * expression." */ if ((!apply_implicit_conversion(op[1]->type, op[2], state) && !apply_implicit_conversion(op[2]->type, op[1], state)) || (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"); error_emitted = true; type = glsl_type::error_type; } else { type = op[1]->type; } /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec: * * "The second and third expressions must be the same type, but can * be of any type other than an array." */ if (type->is_array() && !state->check_version(120, 300, &loc, "second and third operands of ?: operator " "cannot be arrays")) { error_emitted = true; } ir_constant *cond_val = op[0]->constant_expression_value(); ir_constant *then_val = op[1]->constant_expression_value(); ir_constant *else_val = op[2]->constant_expression_value(); if (then_instructions.is_empty() && else_instructions.is_empty() && (cond_val != NULL) && (then_val != NULL) && (else_val != NULL)) { result = (cond_val->value.b[0]) ? then_val : else_val; } else { ir_variable *const tmp = new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary); instructions->push_tail(tmp); ir_if *const stmt = new(ctx) ir_if(op[0]); instructions->push_tail(stmt); then_instructions.move_nodes_to(& stmt->then_instructions); ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const then_assign = new(ctx) ir_assignment(then_deref, op[1]); stmt->then_instructions.push_tail(then_assign); else_instructions.move_nodes_to(& stmt->else_instructions); ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const else_assign = new(ctx) ir_assignment(else_deref, op[2]); stmt->else_instructions.push_tail(else_assign); result = new(ctx) ir_dereference_variable(tmp); } break; } case ast_pre_inc: case ast_pre_dec: { this->non_lvalue_description = (this->oper == ast_pre_inc) ? "pre-increment operation" : "pre-decrement operation"; op[0] = this->subexpressions[0]->hir(instructions, state); op[1] = constant_one_for_inc_dec(ctx, op[0]->type); type = arithmetic_result_type(op[0], op[1], false, state, & loc); ir_rvalue *temp_rhs; temp_rhs = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); error_emitted = do_assignment(instructions, state, this->subexpressions[0]->non_lvalue_description, op[0]->clone(ctx, NULL), temp_rhs, &result, needs_rvalue, false, this->subexpressions[0]->get_location()); break; } case ast_post_inc: case ast_post_dec: { this->non_lvalue_description = (this->oper == ast_post_inc) ? "post-increment operation" : "post-decrement operation"; op[0] = this->subexpressions[0]->hir(instructions, state); op[1] = constant_one_for_inc_dec(ctx, op[0]->type); error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); type = arithmetic_result_type(op[0], op[1], false, state, & loc); ir_rvalue *temp_rhs; temp_rhs = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); /* Get a temporary of a copy of the lvalue before it's modified. * This may get thrown away later. */ result = get_lvalue_copy(instructions, op[0]->clone(ctx, NULL)); ir_rvalue *junk_rvalue; error_emitted = do_assignment(instructions, state, this->subexpressions[0]->non_lvalue_description, op[0]->clone(ctx, NULL), temp_rhs, &junk_rvalue, false, false, this->subexpressions[0]->get_location()); break; } case ast_field_selection: result = _mesa_ast_field_selection_to_hir(this, instructions, state); break; case ast_array_index: { YYLTYPE index_loc = subexpressions[1]->get_location(); op[0] = subexpressions[0]->hir(instructions, state); op[1] = subexpressions[1]->hir(instructions, state); result = _mesa_ast_array_index_to_hir(ctx, state, op[0], op[1], loc, index_loc); if (result->type->is_error()) error_emitted = true; break; } case ast_function_call: /* Should *NEVER* get here. ast_function_call should always be handled * by ast_function_expression::hir. */ assert(0); break; case ast_identifier: { /* ast_identifier can appear several places in a full abstract syntax * tree. This particular use must be at location specified in the grammar * as 'variable_identifier'. */ ir_variable *var = state->symbols->get_variable(this->primary_expression.identifier); if (var != NULL) { var->data.used = true; result = new(ctx) ir_dereference_variable(var); } else { _mesa_glsl_error(& loc, state, "`%s' undeclared", this->primary_expression.identifier); result = ir_rvalue::error_value(ctx); error_emitted = true; } break; } case ast_int_constant: result = new(ctx) ir_constant(this->primary_expression.int_constant); break; case ast_uint_constant: result = new(ctx) ir_constant(this->primary_expression.uint_constant); break; case ast_float_constant: result = new(ctx) ir_constant(this->primary_expression.float_constant); break; case ast_bool_constant: result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant)); break; case ast_sequence: { /* It should not be possible to generate a sequence in the AST without * any expressions in it. */ assert(!this->expressions.is_empty()); /* The r-value of a sequence is the last expression in the sequence. If * the other expressions in the sequence do not have side-effects (and * therefore add instructions to the instruction list), they get dropped * on the floor. */ exec_node *previous_tail_pred = NULL; YYLTYPE previous_operand_loc = loc; foreach_list_typed (ast_node, ast, link, &this->expressions) { /* If one of the operands of comma operator does not generate any * code, we want to emit a warning. At each pass through the loop * previous_tail_pred will point to the last instruction in the * stream *before* processing the previous operand. Naturally, * instructions->tail_pred will point to the last instruction in the * stream *after* processing the previous operand. If the two * pointers match, then the previous operand had no effect. * * The warning behavior here differs slightly from GCC. GCC will * only emit a warning if none of the left-hand operands have an * effect. However, it will emit a warning for each. I believe that * there are some cases in C (especially with GCC extensions) where * it is useful to have an intermediate step in a sequence have no * effect, but I don't think these cases exist in GLSL. Either way, * it would be a giant hassle to replicate that behavior. */ if (previous_tail_pred == instructions->tail_pred) { _mesa_glsl_warning(&previous_operand_loc, state, "left-hand operand of comma expression has " "no effect"); } /* tail_pred is directly accessed instead of using the get_tail() * method for performance reasons. get_tail() has extra code to * return NULL when the list is empty. We don't care about that * here, so using tail_pred directly is fine. */ previous_tail_pred = instructions->tail_pred; previous_operand_loc = ast->get_location(); result = ast->hir(instructions, state); } /* Any errors should have already been emitted in the loop above. */ error_emitted = true; break; } } type = NULL; /* use result->type, not type. */ assert(result != NULL || !needs_rvalue); if (result && result->type->is_error() && !error_emitted) _mesa_glsl_error(& loc, state, "type mismatch"); return result; } ir_rvalue * ast_expression_statement::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { /* It is possible to have expression statements that don't have an * expression. This is the solitary semicolon: * * for (i = 0; i < 5; i++) * ; * * In this case the expression will be NULL. Test for NULL and don't do * anything in that case. */ if (expression != NULL) expression->hir_no_rvalue(instructions, state); /* Statements do not have r-values. */ return NULL; } ir_rvalue * ast_compound_statement::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { if (new_scope) state->symbols->push_scope(); foreach_list_typed (ast_node, ast, link, &this->statements) ast->hir(instructions, state); if (new_scope) state->symbols->pop_scope(); /* Compound statements do not have r-values. */ return NULL; } /** * Evaluate the given exec_node (which should be an ast_node representing * a single array dimension) and return its integer value. */ static unsigned process_array_size(exec_node *node, struct _mesa_glsl_parse_state *state) { exec_list dummy_instructions; ast_node *array_size = exec_node_data(ast_node, node, link); ir_rvalue *const ir = array_size->hir(& dummy_instructions, state); YYLTYPE loc = array_size->get_location(); if (ir == NULL) { _mesa_glsl_error(& loc, state, "array size could not be resolved"); return 0; } if (!ir->type->is_integer()) { _mesa_glsl_error(& loc, state, "array size must be integer type"); return 0; } if (!ir->type->is_scalar()) { _mesa_glsl_error(& loc, state, "array size must be scalar type"); return 0; } ir_constant *const size = ir->constant_expression_value(); if (size == NULL) { _mesa_glsl_error(& loc, state, "array size must be a " "constant valued expression"); return 0; } if (size->value.i[0] <= 0) { _mesa_glsl_error(& loc, state, "array size must be > 0"); return 0; } assert(size->type == ir->type); /* If the array size is const (and we've verified that * it is) then no instructions should have been emitted * when we converted it to HIR. If they were emitted, * then either the array size isn't const after all, or * we are emitting unnecessary instructions. */ assert(dummy_instructions.is_empty()); return size->value.u[0]; } static const glsl_type * process_array_type(YYLTYPE *loc, const glsl_type *base, ast_array_specifier *array_specifier, struct _mesa_glsl_parse_state *state) { const glsl_type *array_type = base; if (array_specifier != NULL) { if (base->is_array()) { /* From page 19 (page 25) of the GLSL 1.20 spec: * * "Only one-dimensional arrays may be declared." */ if (!state->ARB_arrays_of_arrays_enable) { _mesa_glsl_error(loc, state, "invalid array of `%s'" "GL_ARB_arrays_of_arrays " "required for defining arrays of arrays", base->name); return glsl_type::error_type; } if (base->length == 0) { _mesa_glsl_error(loc, state, "only the outermost array dimension can " "be unsized", base->name); return glsl_type::error_type; } } for (exec_node *node = array_specifier->array_dimensions.tail_pred; !node->is_head_sentinel(); node = node->prev) { unsigned array_size = process_array_size(node, state); array_type = glsl_type::get_array_instance(array_type, array_size); } if (array_specifier->is_unsized_array) array_type = glsl_type::get_array_instance(array_type, 0); } return array_type; } const glsl_type * ast_type_specifier::glsl_type(const char **name, struct _mesa_glsl_parse_state *state) const { const struct glsl_type *type; type = state->symbols->get_type(this->type_name); *name = this->type_name; YYLTYPE loc = this->get_location(); type = process_array_type(&loc, type, this->array_specifier, state); 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->stage == MESA_SHADER_FRAGMENT && 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 * function operates by examining the variable's mode and the shader target, * so it correctly identifies linkage variables regardless of whether they are * declared using the deprecated "varying" syntax or the new "in/out" syntax. * * Passing a non-toplevel variable declaration (e.g. a function parameter) to * this function will produce undefined results. */ static bool is_varying_var(ir_variable *var, gl_shader_stage target) { switch (target) { case MESA_SHADER_VERTEX: return var->data.mode == ir_var_shader_out; case MESA_SHADER_FRAGMENT: return var->data.mode == ir_var_shader_in; default: return var->data.mode == ir_var_shader_out || var->data.mode == ir_var_shader_in; } } /** * Matrix layout qualifiers are only allowed on certain types */ static void validate_matrix_layout_for_type(struct _mesa_glsl_parse_state *state, YYLTYPE *loc, const glsl_type *type, ir_variable *var) { if (var && !var->is_in_uniform_block()) { /* Layout qualifiers may only apply to interface blocks and fields in * them. */ _mesa_glsl_error(loc, state, "uniform block layout qualifiers row_major and " "column_major may not be applied to variables " "outside of uniform blocks"); } else if (!type->is_matrix()) { /* The OpenGL ES 3.0 conformance tests did not originally allow * matrix layout qualifiers on non-matrices. However, the OpenGL * 4.4 and OpenGL ES 3.0 (revision TBD) specifications were * amended to specifically allow these layouts on all types. Emit * a warning so that people know their code may not be portable. */ _mesa_glsl_warning(loc, state, "uniform block layout qualifiers row_major and " "column_major applied to non-matrix types may " "be rejected by older compilers"); } else if (type->is_record()) { /* We allow 'layout(row_major)' on structure types because it's the only * way to get row-major layouts on matrices contained in structures. */ _mesa_glsl_warning(loc, state, "uniform block layout qualifiers row_major and " "column_major applied to structure types is not " "strictly conformant and may be rejected by other " "compilers"); } } static bool validate_binding_qualifier(struct _mesa_glsl_parse_state *state, YYLTYPE *loc, ir_variable *var, const ast_type_qualifier *qual) { if (var->data.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 = ctx->Const.Program[state->stage].MaxTextureImageUnits; 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 if (var->type->contains_atomic()) { assert(ctx->Const.MaxAtomicBufferBindings <= MAX_COMBINED_ATOMIC_BUFFERS); if (unsigned(qual->binding) >= ctx->Const.MaxAtomicBufferBindings) { _mesa_glsl_error(loc, state, "layout(binding = %d) exceeds the " " maximum number of atomic counter buffer bindings" "(%d)", qual->binding, ctx->Const.MaxAtomicBufferBindings); return false; } } else { _mesa_glsl_error(loc, state, "the \"binding\" qualifier only applies to uniform " "blocks, samplers, atomic counters, or arrays thereof"); return false; } return true; } static glsl_interp_qualifier interpret_interpolation_qualifier(const struct ast_type_qualifier *qual, ir_variable_mode mode, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { glsl_interp_qualifier interpolation; if (qual->flags.q.flat) interpolation = INTERP_QUALIFIER_FLAT; else if (qual->flags.q.noperspective) interpolation = INTERP_QUALIFIER_NOPERSPECTIVE; else if (qual->flags.q.smooth) interpolation = INTERP_QUALIFIER_SMOOTH; else interpolation = INTERP_QUALIFIER_NONE; if (interpolation != INTERP_QUALIFIER_NONE) { 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.", interpolation_string(interpolation)); } if ((state->stage == MESA_SHADER_VERTEX && mode == ir_var_shader_in) || (state->stage == MESA_SHADER_FRAGMENT && mode == ir_var_shader_out)) { _mesa_glsl_error(loc, state, "interpolation qualifier `%s' cannot be applied to " "vertex shader inputs or fragment shader outputs", interpolation_string(interpolation)); } } return interpolation; } static void validate_explicit_location(const struct ast_type_qualifier *qual, ir_variable *var, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { bool fail = false; /* Checks for GL_ARB_explicit_uniform_location. */ if (qual->flags.q.uniform) { if (!state->check_explicit_uniform_location_allowed(loc, var)) return; const struct gl_context *const ctx = state->ctx; unsigned max_loc = qual->location + var->type->uniform_locations() - 1; /* ARB_explicit_uniform_location specification states: * * "The explicitly defined locations and the generated locations * must be in the range of 0 to MAX_UNIFORM_LOCATIONS minus one." * * "Valid locations for default-block uniform variable locations * are in the range of 0 to the implementation-defined maximum * number of uniform locations." */ if (qual->location < 0) { _mesa_glsl_error(loc, state, "explicit location < 0 for uniform %s", var->name); return; } if (max_loc >= ctx->Const.MaxUserAssignableUniformLocations) { _mesa_glsl_error(loc, state, "location(s) consumed by uniform %s " ">= MAX_UNIFORM_LOCATIONS (%u)", var->name, ctx->Const.MaxUserAssignableUniformLocations); return; } var->data.explicit_location = true; var->data.location = qual->location; return; } /* Between GL_ARB_explicit_attrib_location an * GL_ARB_separate_shader_objects, the inputs and outputs of any shader * stage can be assigned explicit locations. The checking here associates * the correct extension with the correct stage's input / output: * * input output * ----- ------ * vertex explicit_loc sso * geometry sso sso * fragment sso explicit_loc */ switch (state->stage) { case MESA_SHADER_VERTEX: if (var->data.mode == ir_var_shader_in) { if (!state->check_explicit_attrib_location_allowed(loc, var)) return; break; } if (var->data.mode == ir_var_shader_out) { if (!state->check_separate_shader_objects_allowed(loc, var)) return; break; } fail = true; break; case MESA_SHADER_GEOMETRY: if (var->data.mode == ir_var_shader_in || var->data.mode == ir_var_shader_out) { if (!state->check_separate_shader_objects_allowed(loc, var)) return; break; } fail = true; break; case MESA_SHADER_FRAGMENT: if (var->data.mode == ir_var_shader_in) { if (!state->check_separate_shader_objects_allowed(loc, var)) return; break; } if (var->data.mode == ir_var_shader_out) { if (!state->check_explicit_attrib_location_allowed(loc, var)) return; break; } fail = true; break; case MESA_SHADER_COMPUTE: _mesa_glsl_error(loc, state, "compute shader variables cannot be given " "explicit locations"); return; }; if (fail) { _mesa_glsl_error(loc, state, "%s cannot be given an explicit location in %s shader", mode_string(var), _mesa_shader_stage_to_string(state->stage)); } else { var->data.explicit_location = true; /* This bit of silliness is needed because invalid explicit locations * are supposed to be flagged during linking. Small negative values * biased by VERT_ATTRIB_GENERIC0 or FRAG_RESULT_DATA0 could alias * built-in values (e.g., -16+VERT_ATTRIB_GENERIC0 = VERT_ATTRIB_POS). * The linker needs to be able to differentiate these cases. This * ensures that negative values stay negative. */ if (qual->location >= 0) { switch (state->stage) { case MESA_SHADER_VERTEX: var->data.location = (var->data.mode == ir_var_shader_in) ? (qual->location + VERT_ATTRIB_GENERIC0) : (qual->location + VARYING_SLOT_VAR0); break; case MESA_SHADER_GEOMETRY: var->data.location = qual->location + VARYING_SLOT_VAR0; break; case MESA_SHADER_FRAGMENT: var->data.location = (var->data.mode == ir_var_shader_out) ? (qual->location + FRAG_RESULT_DATA0) : (qual->location + VARYING_SLOT_VAR0); break; case MESA_SHADER_COMPUTE: assert(!"Unexpected shader type"); break; } } else { var->data.location = qual->location; } if (qual->flags.q.explicit_index) { /* From the GLSL 4.30 specification, section 4.4.2 (Output * Layout Qualifiers): * * "It is also a compile-time error if a fragment shader * sets a layout index to less than 0 or greater than 1." * * Older specifications don't mandate a behavior; we take * this as a clarification and always generate the error. */ if (qual->index < 0 || qual->index > 1) { _mesa_glsl_error(loc, state, "explicit index may only be 0 or 1"); } else { var->data.explicit_index = true; var->data.index = qual->index; } } } } static void apply_image_qualifier_to_variable(const struct ast_type_qualifier *qual, ir_variable *var, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { const glsl_type *base_type = (var->type->is_array() ? var->type->element_type() : var->type); if (base_type->is_image()) { if (var->data.mode != ir_var_uniform && var->data.mode != ir_var_function_in) { _mesa_glsl_error(loc, state, "image variables may only be declared as " "function parameters or uniform-qualified " "global variables"); } var->data.image.read_only |= qual->flags.q.read_only; var->data.image.write_only |= qual->flags.q.write_only; var->data.image.coherent |= qual->flags.q.coherent; var->data.image._volatile |= qual->flags.q._volatile; var->data.image.restrict_flag |= qual->flags.q.restrict_flag; var->data.read_only = true; if (qual->flags.q.explicit_image_format) { if (var->data.mode == ir_var_function_in) { _mesa_glsl_error(loc, state, "format qualifiers cannot be " "used on image function parameters"); } if (qual->image_base_type != base_type->sampler_type) { _mesa_glsl_error(loc, state, "format qualifier doesn't match the " "base data type of the image"); } var->data.image.format = qual->image_format; } else { if (var->data.mode == ir_var_uniform && !qual->flags.q.write_only) { _mesa_glsl_error(loc, state, "uniforms not qualified with " "`writeonly' must have a format layout " "qualifier"); } var->data.image.format = GL_NONE; } } } static inline const char* get_layout_qualifier_string(bool origin_upper_left, bool pixel_center_integer) { if (origin_upper_left && pixel_center_integer) return "origin_upper_left, pixel_center_integer"; else if (origin_upper_left) return "origin_upper_left"; else if (pixel_center_integer) return "pixel_center_integer"; else return " "; } static inline bool is_conflicting_fragcoord_redeclaration(struct _mesa_glsl_parse_state *state, const struct ast_type_qualifier *qual) { /* If gl_FragCoord was previously declared, and the qualifiers were * different in any way, return true. */ if (state->fs_redeclares_gl_fragcoord) { return (state->fs_pixel_center_integer != qual->flags.q.pixel_center_integer || state->fs_origin_upper_left != qual->flags.q.origin_upper_left); } return false; } static void apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, ir_variable *var, struct _mesa_glsl_parse_state *state, YYLTYPE *loc, bool is_parameter) { STATIC_ASSERT(sizeof(qual->flags.q) <= sizeof(qual->flags.i)); if (qual->flags.q.invariant) { if (var->data.used) { _mesa_glsl_error(loc, state, "variable `%s' may not be redeclared " "`invariant' after being used", var->name); } else { var->data.invariant = 1; } } if (qual->flags.q.precise) { if (var->data.used) { _mesa_glsl_error(loc, state, "variable `%s' may not be redeclared " "`precise' after being used", var->name); } else { var->data.precise = 1; } } if (qual->flags.q.constant || qual->flags.q.attribute || qual->flags.q.uniform || (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT))) var->data.read_only = 1; if (qual->flags.q.centroid) var->data.centroid = 1; if (qual->flags.q.sample) var->data.sample = 1; if (qual->flags.q.attribute && state->stage != MESA_SHADER_VERTEX) { var->type = glsl_type::error_type; _mesa_glsl_error(loc, state, "`attribute' variables may not be declared in the " "%s shader", _mesa_shader_stage_to_string(state->stage)); } /* Disallow layout qualifiers which may only appear on layout declarations. */ if (qual->flags.q.prim_type) { _mesa_glsl_error(loc, state, "Primitive type may only be specified on GS input or output " "layout declaration, not on variables."); } /* 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. */ if (qual->flags.q.in && qual->flags.q.out) var->data.mode = ir_var_function_inout; else if (qual->flags.q.in) var->data.mode = is_parameter ? ir_var_function_in : ir_var_shader_in; else if (qual->flags.q.attribute || (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT))) var->data.mode = ir_var_shader_in; else if (qual->flags.q.out) var->data.mode = is_parameter ? ir_var_function_out : ir_var_shader_out; else if (qual->flags.q.varying && (state->stage == MESA_SHADER_VERTEX)) var->data.mode = ir_var_shader_out; else if (qual->flags.q.uniform) var->data.mode = ir_var_uniform; if (!is_parameter && is_varying_var(var, state->stage)) { /* User-defined ins/outs are not permitted in compute shaders. */ if (state->stage == MESA_SHADER_COMPUTE) { _mesa_glsl_error(loc, state, "user-defined input and output variables are not " "permitted in compute shaders"); } /* This variable is being used to link data between shader stages (in * pre-glsl-1.30 parlance, it's a "varying"). Check that it has a type * that is allowed for such purposes. * * From page 25 (page 31 of the PDF) of the GLSL 1.10 spec: * * "The varying qualifier can be used only with the data types * float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of * these." * * This was relaxed in GLSL version 1.30 and GLSL ES version 3.00. From * page 31 (page 37 of the PDF) of the GLSL 1.30 spec: * * "Fragment inputs can only be signed and unsigned integers and * integer vectors, float, floating-point vectors, matrices, or * arrays of these. Structures cannot be input. * * Similar text exists in the section on vertex shader outputs. * * Similar text exists in the GLSL ES 3.00 spec, except that the GLSL ES * 3.00 spec allows structs as well. Varying structs are also allowed * in GLSL 1.50. */ switch (var->type->get_scalar_type()->base_type) { case GLSL_TYPE_FLOAT: /* Ok in all GLSL versions */ break; case GLSL_TYPE_UINT: case GLSL_TYPE_INT: if (state->is_version(130, 300)) break; _mesa_glsl_error(loc, state, "varying variables must be of base type float in %s", state->get_version_string()); break; case GLSL_TYPE_STRUCT: if (state->is_version(150, 300)) break; _mesa_glsl_error(loc, state, "varying variables may not be of type struct"); break; default: _mesa_glsl_error(loc, state, "illegal type for a varying variable"); break; } } if (state->all_invariant && (state->current_function == NULL)) { switch (state->stage) { case MESA_SHADER_VERTEX: if (var->data.mode == ir_var_shader_out) var->data.invariant = true; break; case MESA_SHADER_GEOMETRY: if ((var->data.mode == ir_var_shader_in) || (var->data.mode == ir_var_shader_out)) var->data.invariant = true; break; case MESA_SHADER_FRAGMENT: if (var->data.mode == ir_var_shader_in) var->data.invariant = true; break; case MESA_SHADER_COMPUTE: /* Invariance isn't meaningful in compute shaders. */ break; } } var->data.interpolation = interpret_interpolation_qualifier(qual, (ir_variable_mode) var->data.mode, state, loc); var->data.pixel_center_integer = qual->flags.q.pixel_center_integer; var->data.origin_upper_left = qual->flags.q.origin_upper_left; if ((qual->flags.q.origin_upper_left || qual->flags.q.pixel_center_integer) && (strcmp(var->name, "gl_FragCoord") != 0)) { const char *const qual_string = (qual->flags.q.origin_upper_left) ? "origin_upper_left" : "pixel_center_integer"; _mesa_glsl_error(loc, state, "layout qualifier `%s' can only be applied to " "fragment shader input `gl_FragCoord'", qual_string); } if (var->name != NULL && strcmp(var->name, "gl_FragCoord") == 0) { /* Section 4.3.8.1, page 39 of GLSL 1.50 spec says: * * "Within any shader, the first redeclarations of gl_FragCoord * must appear before any use of gl_FragCoord." * * Generate a compiler error if above condition is not met by the * fragment shader. */ ir_variable *earlier = state->symbols->get_variable("gl_FragCoord"); if (earlier != NULL && earlier->data.used && !state->fs_redeclares_gl_fragcoord) { _mesa_glsl_error(loc, state, "gl_FragCoord used before its first redeclaration " "in fragment shader"); } /* Make sure all gl_FragCoord redeclarations specify the same layout * qualifiers. */ if (is_conflicting_fragcoord_redeclaration(state, qual)) { const char *const qual_string = get_layout_qualifier_string(qual->flags.q.origin_upper_left, qual->flags.q.pixel_center_integer); const char *const state_string = get_layout_qualifier_string(state->fs_origin_upper_left, state->fs_pixel_center_integer); _mesa_glsl_error(loc, state, "gl_FragCoord redeclared with different layout " "qualifiers (%s) and (%s) ", state_string, qual_string); } state->fs_origin_upper_left = qual->flags.q.origin_upper_left; state->fs_pixel_center_integer = qual->flags.q.pixel_center_integer; state->fs_redeclares_gl_fragcoord_with_no_layout_qualifiers = !qual->flags.q.origin_upper_left && !qual->flags.q.pixel_center_integer; state->fs_redeclares_gl_fragcoord = state->fs_origin_upper_left || state->fs_pixel_center_integer || state->fs_redeclares_gl_fragcoord_with_no_layout_qualifiers; } if (qual->flags.q.explicit_location) { validate_explicit_location(qual, var, state, loc); } else if (qual->flags.q.explicit_index) { _mesa_glsl_error(loc, state, "explicit index requires explicit location"); } if (qual->flags.q.explicit_binding && validate_binding_qualifier(state, loc, var, qual)) { var->data.explicit_binding = true; var->data.binding = qual->binding; } if (var->type->contains_atomic()) { if (var->data.mode == ir_var_uniform) { if (var->data.explicit_binding) { unsigned *offset = &state->atomic_counter_offsets[var->data.binding]; if (*offset % ATOMIC_COUNTER_SIZE) _mesa_glsl_error(loc, state, "misaligned atomic counter offset"); var->data.atomic.offset = *offset; *offset += var->type->atomic_size(); } else { _mesa_glsl_error(loc, state, "atomic counters require explicit binding point"); } } else if (var->data.mode != ir_var_function_in) { _mesa_glsl_error(loc, state, "atomic counters may only be declared as " "function parameters or uniform-qualified " "global variables"); } } /* Does the declaration use the deprecated 'attribute' or 'varying' * keywords? */ const bool uses_deprecated_qualifier = qual->flags.q.attribute || qual->flags.q.varying; /* Validate auxiliary storage qualifiers */ /* From section 4.3.4 of the GLSL 1.30 spec: * "It is an error to use centroid in in a vertex shader." * * From section 4.3.4 of the GLSL ES 3.00 spec: * "It is an error to use centroid in or interpolation qualifiers in * a vertex shader input." */ /* 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 (qual->flags.q.sample && (!is_varying_var(var, state->stage) || uses_deprecated_qualifier)) { _mesa_glsl_error(loc, state, "sample qualifier may only be used on `in` or `out` " "variables between shader stages"); } if (qual->flags.q.centroid && !is_varying_var(var, state->stage)) { _mesa_glsl_error(loc, state, "centroid qualifier may only be used with `in', " "`out' or `varying' variables between shader stages"); } /* Is the 'layout' keyword used with parameters that allow relaxed checking. * Many implementations of GL_ARB_fragment_coord_conventions_enable and some * implementations (only Mesa?) GL_ARB_explicit_attrib_location_enable * allowed the layout qualifier to be used with 'varying' and 'attribute'. * These extensions and all following extensions that add the 'layout' * keyword have been modified to require the use of 'in' or 'out'. * * The following extension do not allow the deprecated keywords: * * GL_AMD_conservative_depth * GL_ARB_conservative_depth * GL_ARB_gpu_shader5 * GL_ARB_separate_shader_objects * GL_ARB_tesselation_shader * GL_ARB_transform_feedback3 * GL_ARB_uniform_buffer_object * * It is unknown whether GL_EXT_shader_image_load_store or GL_NV_gpu_shader5 * allow layout with the deprecated keywords. */ const bool relaxed_layout_qualifier_checking = state->ARB_fragment_coord_conventions_enable; if (qual->has_layout() && uses_deprecated_qualifier) { if (relaxed_layout_qualifier_checking) { _mesa_glsl_warning(loc, state, "`layout' qualifier may not be used with " "`attribute' or `varying'"); } else { _mesa_glsl_error(loc, state, "`layout' qualifier may not be used with " "`attribute' or `varying'"); } } /* Layout qualifiers for gl_FragDepth, which are enabled by extension * AMD_conservative_depth. */ int depth_layout_count = qual->flags.q.depth_any + qual->flags.q.depth_greater + qual->flags.q.depth_less + qual->flags.q.depth_unchanged; if (depth_layout_count > 0 && !state->AMD_conservative_depth_enable && !state->ARB_conservative_depth_enable) { _mesa_glsl_error(loc, state, "extension GL_AMD_conservative_depth or " "GL_ARB_conservative_depth must be enabled " "to use depth layout qualifiers"); } else if (depth_layout_count > 0 && strcmp(var->name, "gl_FragDepth") != 0) { _mesa_glsl_error(loc, state, "depth layout qualifiers can be applied only to " "gl_FragDepth"); } else if (depth_layout_count > 1 && strcmp(var->name, "gl_FragDepth") == 0) { _mesa_glsl_error(loc, state, "at most one depth layout qualifier can be applied to " "gl_FragDepth"); } if (qual->flags.q.depth_any) var->data.depth_layout = ir_depth_layout_any; else if (qual->flags.q.depth_greater) var->data.depth_layout = ir_depth_layout_greater; else if (qual->flags.q.depth_less) var->data.depth_layout = ir_depth_layout_less; else if (qual->flags.q.depth_unchanged) var->data.depth_layout = ir_depth_layout_unchanged; else var->data.depth_layout = ir_depth_layout_none; if (qual->flags.q.std140 || qual->flags.q.packed || qual->flags.q.shared) { _mesa_glsl_error(loc, state, "uniform block layout qualifiers std140, packed, and " "shared can only be applied to uniform blocks, not " "members"); } if (qual->flags.q.row_major || qual->flags.q.column_major) { validate_matrix_layout_for_type(state, loc, var->type, var); } if (var->type->contains_image()) apply_image_qualifier_to_variable(qual, var, state, loc); } /** * Get the variable that is being redeclared by this declaration * * Semantic checks to verify the validity of the redeclaration are also * performed. If semantic checks fail, compilation error will be emitted via * \c _mesa_glsl_error, but a non-\c NULL pointer will still be returned. * * \returns * A pointer to an existing variable in the current scope if the declaration * is a redeclaration, \c NULL otherwise. */ static ir_variable * get_variable_being_redeclared(ir_variable *var, YYLTYPE loc, struct _mesa_glsl_parse_state *state, bool allow_all_redeclarations) { /* Check if this declaration is actually a re-declaration, either to * resize an array or add qualifiers to an existing variable. * * This is allowed for variables in the current scope, or when at * global scope (for built-ins in the implicit outer scope). */ ir_variable *earlier = state->symbols->get_variable(var->name); if (earlier == NULL || (state->current_function != NULL && !state->symbols->name_declared_this_scope(var->name))) { return NULL; } /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec, * * "It is legal to declare an array without a size and then * later re-declare the same name as an array of the same * type and specify a size." */ if (earlier->type->is_unsized_array() && var->type->is_array() && (var->type->element_type() == earlier->type->element_type())) { /* FINISHME: This doesn't match the qualifiers on the two * FINISHME: declarations. It's not 100% clear whether this is * FINISHME: required or not. */ const unsigned size = unsigned(var->type->array_size()); check_builtin_array_max_size(var->name, size, loc, state); if ((size > 0) && (size <= earlier->data.max_array_access)) { _mesa_glsl_error(& loc, state, "array size must be > %u due to " "previous access", earlier->data.max_array_access); } earlier->type = var->type; delete var; var = NULL; } else if ((state->ARB_fragment_coord_conventions_enable || state->is_version(150, 0)) && strcmp(var->name, "gl_FragCoord") == 0 && earlier->type == var->type && earlier->data.mode == var->data.mode) { /* Allow redeclaration of gl_FragCoord for ARB_fcc layout * qualifiers. */ earlier->data.origin_upper_left = var->data.origin_upper_left; earlier->data.pixel_center_integer = var->data.pixel_center_integer; /* According to section 4.3.7 of the GLSL 1.30 spec, * the following built-in varaibles can be redeclared with an * interpolation qualifier: * * gl_FrontColor * * gl_BackColor * * gl_FrontSecondaryColor * * gl_BackSecondaryColor * * gl_Color * * gl_SecondaryColor */ } else if (state->is_version(130, 0) && (strcmp(var->name, "gl_FrontColor") == 0 || strcmp(var->name, "gl_BackColor") == 0 || strcmp(var->name, "gl_FrontSecondaryColor") == 0 || strcmp(var->name, "gl_BackSecondaryColor") == 0 || strcmp(var->name, "gl_Color") == 0 || strcmp(var->name, "gl_SecondaryColor") == 0) && earlier->type == var->type && earlier->data.mode == var->data.mode) { earlier->data.interpolation = var->data.interpolation; /* Layout qualifiers for gl_FragDepth. */ } else if ((state->AMD_conservative_depth_enable || state->ARB_conservative_depth_enable) && strcmp(var->name, "gl_FragDepth") == 0 && earlier->type == var->type && earlier->data.mode == var->data.mode) { /** From the AMD_conservative_depth spec: * Within any shader, the first redeclarations of gl_FragDepth * must appear before any use of gl_FragDepth. */ if (earlier->data.used) { _mesa_glsl_error(&loc, state, "the first redeclaration of gl_FragDepth " "must appear before any use of gl_FragDepth"); } /* Prevent inconsistent redeclaration of depth layout qualifier. */ if (earlier->data.depth_layout != ir_depth_layout_none && earlier->data.depth_layout != var->data.depth_layout) { _mesa_glsl_error(&loc, state, "gl_FragDepth: depth layout is declared here " "as '%s, but it was previously declared as " "'%s'", depth_layout_string(var->data.depth_layout), depth_layout_string(earlier->data.depth_layout)); } earlier->data.depth_layout = var->data.depth_layout; } else if (allow_all_redeclarations) { if (earlier->data.mode != var->data.mode) { _mesa_glsl_error(&loc, state, "redeclaration of `%s' with incorrect qualifiers", var->name); } else if (earlier->type != var->type) { _mesa_glsl_error(&loc, state, "redeclaration of `%s' has incorrect type", var->name); } } else { _mesa_glsl_error(&loc, state, "`%s' redeclared", var->name); } return earlier; } /** * Generate the IR for an initializer in a variable declaration */ ir_rvalue * process_initializer(ir_variable *var, ast_declaration *decl, ast_fully_specified_type *type, exec_list *initializer_instructions, struct _mesa_glsl_parse_state *state) { ir_rvalue *result = NULL; YYLTYPE initializer_loc = decl->initializer->get_location(); /* From page 24 (page 30 of the PDF) of the GLSL 1.10 spec: * * "All uniform variables are read-only and are initialized either * directly by an application via API commands, or indirectly by * OpenGL." */ if (var->data.mode == ir_var_uniform) { state->check_version(120, 0, &initializer_loc, "cannot initialize uniforms"); } /* From section 4.1.7 of the GLSL 4.40 spec: * * "Opaque variables [...] are initialized only through the * OpenGL API; they cannot be declared with an initializer in a * shader." */ if (var->type->contains_opaque()) { _mesa_glsl_error(& initializer_loc, state, "cannot initialize opaque variable"); } if ((var->data.mode == ir_var_shader_in) && (state->current_function == NULL)) { _mesa_glsl_error(& initializer_loc, state, "cannot initialize %s shader input / %s", _mesa_shader_stage_to_string(state->stage), (state->stage == MESA_SHADER_VERTEX) ? "attribute" : "varying"); } /* If the initializer is an ast_aggregate_initializer, recursively store * type information from the LHS into it, so that its hir() function can do * type checking. */ if (decl->initializer->oper == ast_aggregate) _mesa_ast_set_aggregate_type(var->type, decl->initializer); ir_dereference *const lhs = new(state) ir_dereference_variable(var); ir_rvalue *rhs = decl->initializer->hir(initializer_instructions, state); /* Calculate the constant value if this is a const or uniform * declaration. */ if (type->qualifier.flags.q.constant || type->qualifier.flags.q.uniform) { ir_rvalue *new_rhs = validate_assignment(state, initializer_loc, var->type, rhs, true); if (new_rhs != NULL) { rhs = new_rhs; ir_constant *constant_value = rhs->constant_expression_value(); if (!constant_value) { /* 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; } } else { if (var->type->is_numeric()) { /* Reduce cascading errors. */ var->constant_value = ir_constant::zero(state, var->type); } } } if (rhs && !rhs->type->is_error()) { bool temp = var->data.read_only; if (type->qualifier.flags.q.constant) var->data.read_only = false; /* Never emit code to initialize a uniform. */ const glsl_type *initializer_type; if (!type->qualifier.flags.q.uniform) { do_assignment(initializer_instructions, state, NULL, lhs, rhs, &result, true, true, type->get_location()); initializer_type = result->type; } else initializer_type = rhs->type; var->constant_initializer = rhs->constant_expression_value(); var->data.has_initializer = true; /* If the declared variable is an unsized array, it must inherrit * its full type from the initializer. A declaration such as * * uniform float a[] = float[](1.0, 2.0, 3.0, 3.0); * * becomes * * uniform float a[4] = float[](1.0, 2.0, 3.0, 3.0); * * The assignment generated in the if-statement (below) will also * automatically handle this case for non-uniforms. * * If the declared variable is not an array, the types must * already match exactly. As a result, the type assignment * here can be done unconditionally. For non-uniforms the call * to do_assignment can change the type of the initializer (via * the implicit conversion rules). For uniforms the initializer * must be a constant expression, and the type of that expression * was validated above. */ var->type = initializer_type; var->data.read_only = temp; } 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->in_qualifier->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->is_unsized_array()) { /* 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; } } } void validate_identifier(const char *identifier, YYLTYPE loc, struct _mesa_glsl_parse_state *state) { /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec, * * "Identifiers starting with "gl_" are reserved for use by * OpenGL, and may not be declared in a shader as either a * variable or a function." */ if (is_gl_identifier(identifier)) { _mesa_glsl_error(&loc, state, "identifier `%s' uses reserved `gl_' prefix", identifier); } else if (strstr(identifier, "__")) { /* From page 14 (page 20 of the PDF) of the GLSL 1.10 * spec: * * "In addition, all identifiers containing two * consecutive underscores (__) are reserved as * possible future keywords." * * The intention is that names containing __ are reserved for internal * use by the implementation, and names prefixed with GL_ are reserved * for use by Khronos. Names simply containing __ are dangerous to use, * but should be allowed. * * A future version of the GLSL specification will clarify this. */ _mesa_glsl_warning(&loc, state, "identifier `%s' uses reserved `__' string", identifier); } } ir_rvalue * ast_declarator_list::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { void *ctx = state; const struct glsl_type *decl_type; const char *type_name = NULL; ir_rvalue *result = NULL; YYLTYPE loc = this->get_location(); /* From page 46 (page 52 of the PDF) of the GLSL 1.50 spec: * * "To ensure that a particular output variable is invariant, it is * necessary to use the invariant qualifier. It can either be used to * qualify a previously declared variable as being invariant * * invariant gl_Position; // make existing gl_Position be invariant" * * In these cases the parser will set the 'invariant' flag in the declarator * list, and the type will be NULL. */ if (this->invariant) { assert(this->type == NULL); if (state->current_function != NULL) { _mesa_glsl_error(& loc, state, "all uses of `invariant' keyword must be at global " "scope"); } foreach_list_typed (ast_declaration, decl, link, &this->declarations) { assert(decl->array_specifier == NULL); assert(decl->initializer == NULL); ir_variable *const earlier = state->symbols->get_variable(decl->identifier); if (earlier == NULL) { _mesa_glsl_error(& loc, state, "undeclared variable `%s' cannot be marked " "invariant", decl->identifier); } else if (!is_varying_var(earlier, state->stage)) { _mesa_glsl_error(&loc, state, "`%s' cannot be marked invariant; interfaces between " "shader stages only.", decl->identifier); } else if (earlier->data.used) { _mesa_glsl_error(& loc, state, "variable `%s' may not be redeclared " "`invariant' after being used", earlier->name); } else { earlier->data.invariant = true; } } /* Invariant redeclarations do not have r-values. */ return NULL; } if (this->precise) { assert(this->type == NULL); foreach_list_typed (ast_declaration, decl, link, &this->declarations) { assert(decl->array_specifier == NULL); assert(decl->initializer == NULL); ir_variable *const earlier = state->symbols->get_variable(decl->identifier); if (earlier == NULL) { _mesa_glsl_error(& loc, state, "undeclared variable `%s' cannot be marked " "precise", decl->identifier); } else if (state->current_function != NULL && !state->symbols->name_declared_this_scope(decl->identifier)) { /* Note: we have to check if we're in a function, since * builtins are treated as having come from another scope. */ _mesa_glsl_error(& loc, state, "variable `%s' from an outer scope may not be " "redeclared `precise' in this scope", earlier->name); } else if (earlier->data.used) { _mesa_glsl_error(& loc, state, "variable `%s' may not be redeclared " "`precise' after being used", earlier->name); } else { earlier->data.precise = true; } } /* Precise redeclarations do not have r-values either. */ return NULL; } assert(this->type != NULL); assert(!this->invariant); assert(!this->precise); /* The type specifier may contain a structure definition. Process that * before any of the variable declarations. */ (void) this->type->specifier->hir(instructions, state); decl_type = this->type->glsl_type(& type_name, state); /* An offset-qualified atomic counter declaration sets the default * offset for the next declaration within the same atomic counter * buffer. */ if (decl_type && decl_type->contains_atomic()) { if (type->qualifier.flags.q.explicit_binding && type->qualifier.flags.q.explicit_offset) state->atomic_counter_offsets[type->qualifier.binding] = type->qualifier.offset; } if (this->declarations.is_empty()) { /* If there is no structure involved in the program text, there are two * possible scenarios: * * - The program text contained something like 'vec4;'. This is an * empty declaration. It is valid but weird. Emit a warning. * * - The program text contained something like 'S;' and 'S' is not the * 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 * code for the structure. There is no need to generate an additional, * confusing error. */ assert(this->type->specifier->structure == NULL || decl_type != NULL || state->error); if (decl_type == NULL) { _mesa_glsl_error(&loc, state, "invalid type `%s' in empty declaration", type_name); } else if (decl_type->base_type == GLSL_TYPE_ATOMIC_UINT) { /* Empty atomic counter declarations are allowed and useful * to set the default offset qualifier. */ return NULL; } 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 if (this->type->specifier->structure == NULL) { _mesa_glsl_warning(&loc, state, "empty declaration"); } } foreach_list_typed (ast_declaration, decl, link, &this->declarations) { const struct glsl_type *var_type; ir_variable *var; /* FINISHME: Emit a warning if a variable declaration shadows a * FINISHME: declaration at a higher scope. */ if ((decl_type == NULL) || decl_type->is_void()) { if (type_name != NULL) { _mesa_glsl_error(& loc, state, "invalid type `%s' in declaration of `%s'", type_name, decl->identifier); } else { _mesa_glsl_error(& loc, state, "invalid type in declaration of `%s'", decl->identifier); } continue; } var_type = process_array_type(&loc, decl_type, decl->array_specifier, state); 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, * attribute, uniform, or varying. Only one may be * specified. * * Local variables can only use the qualifier const." * * This is relaxed in GLSL 1.30 and GLSL ES 3.00. It is also relaxed by * any extension that adds the 'layout' keyword. */ if (!state->is_version(130, 300) && !state->has_explicit_attrib_location() && !state->has_separate_shader_objects() && !state->ARB_fragment_coord_conventions_enable) { 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", 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", decl->identifier, state->get_version_string()); } /* FINISHME: Test for other invalid qualifiers. */ } apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc, false); if (this->type->qualifier.flags.q.invariant) { if (!is_varying_var(var, state->stage)) { _mesa_glsl_error(&loc, state, "`%s' cannot be marked invariant; interfaces between " "shader stages only", var->name); } } if (state->current_function != NULL) { const char *mode = NULL; const char *extra = ""; /* There is no need to check for 'inout' here because the parser will * only allow that in function parameter lists. */ if (this->type->qualifier.flags.q.attribute) { mode = "attribute"; } else if (this->type->qualifier.flags.q.uniform) { mode = "uniform"; } else if (this->type->qualifier.flags.q.varying) { mode = "varying"; } else if (this->type->qualifier.flags.q.in) { mode = "in"; extra = " or in function parameter list"; } else if (this->type->qualifier.flags.q.out) { mode = "out"; extra = " or in function parameter list"; } if (mode) { _mesa_glsl_error(& loc, state, "%s variable `%s' must be declared at " "global scope%s", mode, var->name, extra); } } else if (var->data.mode == ir_var_shader_in) { var->data.read_only = true; if (state->stage == MESA_SHADER_VERTEX) { bool error_emitted = false; /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec: * * "Vertex shader inputs can only be float, floating-point * vectors, matrices, signed and unsigned integers and integer * vectors. Vertex shader inputs can also form arrays of these * types, but not structures." * * From page 31 (page 27 of the PDF) of the GLSL 1.30 spec: * * "Vertex shader inputs can only be float, floating-point * vectors, matrices, signed and unsigned integers and integer * vectors. They cannot be arrays or structures." * * From page 23 (page 29 of the PDF) of the GLSL 1.20 spec: * * "The attribute qualifier can be used only with float, * floating-point vectors, and matrices. Attribute variables * cannot be declared as arrays or structures." * * From page 33 (page 39 of the PDF) of the GLSL ES 3.00 spec: * * "Vertex shader inputs can only be float, floating-point * vectors, matrices, signed and unsigned integers and integer * vectors. Vertex shader inputs cannot be arrays or * structures." */ const glsl_type *check_type = var->type; while (check_type->is_array()) check_type = check_type->element_type(); switch (check_type->base_type) { case GLSL_TYPE_FLOAT: break; case GLSL_TYPE_UINT: case GLSL_TYPE_INT: if (state->is_version(120, 300)) break; /* FALLTHROUGH */ default: _mesa_glsl_error(& loc, state, "vertex shader input / attribute cannot have " "type %s`%s'", var->type->is_array() ? "array of " : "", check_type->name); error_emitted = true; } if (!error_emitted && var->type->is_array() && !state->check_version(150, 0, &loc, "vertex shader input / attribute " "cannot have array type")) { error_emitted = true; } } else if (state->stage == MESA_SHADER_GEOMETRY) { /* 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, * so must integer vertex outputs. * * From section 4.3.4 ("Inputs") of the GLSL 1.50 spec: * "Fragment shader inputs that are signed or unsigned integers or * integer vectors must be qualified with the interpolation qualifier * flat." * * From section 4.3.4 ("Input Variables") of the GLSL 3.00 ES spec: * "Fragment shader inputs that are, or contain, signed or unsigned * integers or integer vectors must be qualified with the * interpolation qualifier flat." * * From section 4.3.6 ("Output Variables") of the GLSL 3.00 ES spec: * "Vertex shader outputs that are, or contain, signed or unsigned * integers or integer vectors must be qualified with the * interpolation qualifier flat." * * Note that prior to GLSL 1.50, this requirement applied to vertex * outputs rather than fragment inputs. That creates problems in the * presence of geometry shaders, so we adopt the GLSL 1.50 rule for all * desktop GL shaders. For GLSL ES shaders, we follow the spec and * apply the restriction to both vertex outputs and fragment inputs. * * Note also that the desktop GLSL specs are missing the text "or * contain"; this is presumably an oversight, since there is no * reasonable way to interpolate a fragment shader input that contains * an integer. */ if (state->is_version(130, 300) && var->type->contains_integer() && var->data.interpolation != INTERP_QUALIFIER_FLAT && ((state->stage == MESA_SHADER_FRAGMENT && var->data.mode == ir_var_shader_in) || (state->stage == MESA_SHADER_VERTEX && var->data.mode == ir_var_shader_out && state->es_shader))) { const char *var_type = (state->stage == MESA_SHADER_VERTEX) ? "vertex output" : "fragment input"; _mesa_glsl_error(&loc, state, "if a %s is (or contains) " "an integer, then it must be qualified with 'flat'", var_type); } /* Interpolation qualifiers cannot be applied to 'centroid' and * 'centroid varying'. * * From page 29 (page 35 of the PDF) of the GLSL 1.30 spec: * "interpolation qualifiers may only precede the qualifiers in, * centroid in, out, or centroid out in a declaration. They do not apply * to the deprecated storage qualifiers varying or centroid varying." * * These deprecated storage qualifiers do not exist in GLSL ES 3.00. */ if (state->is_version(130, 0) && this->type->qualifier.has_interpolation() && this->type->qualifier.flags.q.varying) { const char *i = this->type->qualifier.interpolation_string(); assert(i != NULL); const char *s; if (this->type->qualifier.flags.q.centroid) s = "centroid varying"; else s = "varying"; _mesa_glsl_error(&loc, state, "qualifier '%s' cannot be applied to the " "deprecated storage qualifier '%s'", i, s); } /* Interpolation qualifiers can only apply to vertex shader outputs and * fragment shader inputs. * * From page 29 (page 35 of the PDF) of the GLSL 1.30 spec: * "Outputs from a vertex shader (out) and inputs to a fragment * shader (in) can be further qualified with one or more of these * interpolation qualifiers" * * From page 31 (page 37 of the PDF) of the GLSL ES 3.00 spec: * "These interpolation qualifiers may only precede the qualifiers * in, centroid in, out, or centroid out in a declaration. They do * not apply to inputs into a vertex shader or outputs from a * fragment shader." */ if (state->is_version(130, 300) && this->type->qualifier.has_interpolation()) { const char *i = this->type->qualifier.interpolation_string(); assert(i != NULL); switch (state->stage) { case MESA_SHADER_VERTEX: if (this->type->qualifier.flags.q.in) { _mesa_glsl_error(&loc, state, "qualifier '%s' cannot be applied to vertex " "shader inputs", i); } break; case MESA_SHADER_FRAGMENT: if (this->type->qualifier.flags.q.out) { _mesa_glsl_error(&loc, state, "qualifier '%s' cannot be applied to fragment " "shader outputs", i); } break; default: break; } } /* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30. */ if (this->type->qualifier.precision != ast_precision_none) { state->check_precision_qualifiers_allowed(&loc); } /* Precision qualifiers apply to floating point, integer and sampler * types. * * Section 4.5.2 (Precision Qualifiers) of the GLSL 1.30 spec says: * "Any floating point or any integer declaration can have the type * preceded by one of these precision qualifiers [...] Literal * constants do not have precision qualifiers. Neither do Boolean * variables. * * Section 4.5 (Precision and Precision Qualifiers) of the GLSL 1.30 * spec also says: * * "Precision qualifiers are added for code portability with OpenGL * ES, not for functionality. They have the same syntax as in OpenGL * ES." * * Section 8 (Built-In Functions) of the GLSL ES 1.00 spec says: * * "uniform lowp sampler2D sampler; * highp vec2 coord; * ... * lowp vec4 col = texture2D (sampler, coord); * // texture2D returns lowp" * * From this, we infer that GLSL 1.30 (and later) should allow precision * qualifiers on sampler types just like float and integer types. */ if (this->type->qualifier.precision != ast_precision_none && !var->type->is_float() && !var->type->is_integer() && !var->type->is_record() && !var->type->is_sampler() && !(var->type->is_array() && (var->type->fields.array->is_float() || var->type->fields.array->is_integer()))) { _mesa_glsl_error(&loc, state, "precision qualifiers apply only to floating point" ", integer and sampler types"); } /* From section 4.1.7 of the GLSL 4.40 spec: * * "[Opaque types] can only be declared as function * parameters or uniform-qualified variables." */ if (var_type->contains_opaque() && !this->type->qualifier.flags.q.uniform) { _mesa_glsl_error(&loc, state, "opaque variables must be declared uniform"); } /* Process the initializer and add its instructions to a temporary * list. This list will be added to the instruction stream (below) after * the declaration is added. This is done because in some cases (such as * redeclarations) the declaration may not actually be added to the * instruction stream. */ exec_list initializer_instructions; /* Examine var name here since var may get deleted in the next call */ bool var_is_gl_id = is_gl_identifier(var->name); ir_variable *earlier = get_variable_being_redeclared(var, decl->get_location(), state, false /* allow_all_redeclarations */); if (earlier != NULL) { if (var_is_gl_id && earlier->data.how_declared == ir_var_declared_in_block) { _mesa_glsl_error(&loc, state, "`%s' has already been redeclared using " "gl_PerVertex", var->name); } earlier->data.how_declared = ir_var_declared_normally; } if (decl->initializer != NULL) { result = process_initializer((earlier == NULL) ? var : earlier, decl, this->type, &initializer_instructions, state); } /* From page 23 (page 29 of the PDF) of the GLSL 1.10 spec: * * "It is an error to write to a const variable outside of * its declaration, so they must be initialized when * declared." */ if (this->type->qualifier.flags.q.constant && decl->initializer == NULL) { _mesa_glsl_error(& loc, state, "const declaration of `%s' must be initialized", decl->identifier); } if (state->es_shader) { const glsl_type *const t = (earlier == NULL) ? var->type : earlier->type; if (t->is_unsized_array()) /* 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. */ if (earlier == NULL) { validate_identifier(decl->identifier, loc, state); /* Add the variable to the symbol table. Note that the initializer's * IR was already processed earlier (though it hasn't been emitted * yet), without the variable in scope. * * This differs from most C-like languages, but it follows the GLSL * specification. From page 28 (page 34 of the PDF) of the GLSL 1.50 * spec: * * "Within a declaration, the scope of a name starts immediately * after the initializer if present or immediately after the name * being declared if not." */ if (!state->symbols->add_variable(var)) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(&loc, state, "name `%s' already taken in the " "current scope", decl->identifier); continue; } /* Push the variable declaration to the top. It means that all the * variable declarations will appear in a funny last-to-first order, * but otherwise we run into trouble if a function is prototyped, a * global var is decled, then the function is defined with usage of * the global var. See glslparsertest's CorrectModule.frag. */ instructions->push_head(var); } instructions->append_list(&initializer_instructions); } /* Generally, variable declarations do not have r-values. However, * one is used for the declaration in * * while (bool b = some_condition()) { * ... * } * * so we return the rvalue from the last seen declaration here. */ return result; } ir_rvalue * ast_parameter_declarator::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { void *ctx = state; const struct glsl_type *type; const char *name = NULL; YYLTYPE loc = this->get_location(); type = this->type->glsl_type(& name, state); if (type == NULL) { if (name != NULL) { _mesa_glsl_error(& loc, state, "invalid type `%s' in declaration of `%s'", name, this->identifier); } else { _mesa_glsl_error(& loc, state, "invalid type in declaration of `%s'", this->identifier); } type = glsl_type::error_type; } /* From page 62 (page 68 of the PDF) of the GLSL 1.50 spec: * * "Functions that accept no input arguments need not use void in the * argument list because prototypes (or definitions) are required and * therefore there is no ambiguity when an empty argument list "( )" is * declared. The idiom "(void)" as a parameter list is provided for * convenience." * * Placing this check here prevents a void parameter being set up * for a function, which avoids tripping up checks for main taking * parameters and lookups of an unnamed symbol. */ if (type->is_void()) { if (this->identifier != NULL) _mesa_glsl_error(& loc, state, "named parameter cannot have type `void'"); is_void = true; return NULL; } if (formal_parameter && (this->identifier == NULL)) { _mesa_glsl_error(& loc, state, "formal parameter lacks a name"); return NULL; } /* This only handles "vec4 foo[..]". The earlier specifier->glsl_type(...) * call already handled the "vec4[..] foo" case. */ type = process_array_type(&loc, type, this->array_specifier, state); if (!type->is_error() && type->is_unsized_array()) { _mesa_glsl_error(&loc, state, "arrays passed as parameters must have " "a declared size"); type = glsl_type::error_type; } is_void = false; ir_variable *var = new(ctx) ir_variable(type, this->identifier, ir_var_function_in); /* Apply any specified qualifiers to the parameter declaration. Note that * for function parameters the default mode is 'in'. */ apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc, true); /* From section 4.1.7 of the GLSL 4.40 spec: * * "Opaque variables cannot be treated as l-values; hence cannot * be used as out or inout function parameters, nor can they be * assigned into." */ if ((var->data.mode == ir_var_function_inout || var->data.mode == ir_var_function_out) && type->contains_opaque()) { _mesa_glsl_error(&loc, state, "out and inout parameters cannot " "contain opaque variables"); type = glsl_type::error_type; } /* From page 39 (page 45 of the PDF) of the GLSL 1.10 spec: * * "When calling a function, expressions that do not evaluate to * l-values cannot be passed to parameters declared as out or inout." * * From page 32 (page 38 of the PDF) of the GLSL 1.10 spec: * * "Other binary or unary expressions, non-dereferenced arrays, * function names, swizzles with repeated fields, and constants * cannot be l-values." * * So for GLSL 1.10, passing an array as an out or inout parameter is not * allowed. This restriction is removed in GLSL 1.20, and in GLSL ES. */ if ((var->data.mode == ir_var_function_inout || var->data.mode == ir_var_function_out) && type->is_array() && !state->check_version(120, 100, &loc, "arrays cannot be out or inout parameters")) { type = glsl_type::error_type; } instructions->push_tail(var); /* Parameter declarations do not have r-values. */ return NULL; } void ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters, bool formal, exec_list *ir_parameters, _mesa_glsl_parse_state *state) { ast_parameter_declarator *void_param = NULL; unsigned count = 0; foreach_list_typed (ast_parameter_declarator, param, link, ast_parameters) { param->formal_parameter = formal; param->hir(ir_parameters, state); if (param->is_void) void_param = param; count++; } if ((void_param != NULL) && (count > 1)) { YYLTYPE loc = void_param->get_location(); _mesa_glsl_error(& loc, state, "`void' parameter must be only parameter"); } } void emit_function(_mesa_glsl_parse_state *state, ir_function *f) { /* IR invariants disallow function declarations or definitions * nested within other function definitions. But there is no * requirement about the relative order of function declarations * and definitions with respect to one another. So simply insert * the new ir_function block at the end of the toplevel instruction * list. */ state->toplevel_ir->push_tail(f); } ir_rvalue * ast_function::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { void *ctx = state; ir_function *f = NULL; ir_function_signature *sig = NULL; exec_list hir_parameters; const char *const name = identifier; /* New functions are always added to the top-level IR instruction stream, * so this instruction list pointer is ignored. See also emit_function * (called below). */ (void) instructions; /* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec, * * "Function declarations (prototypes) cannot occur inside of functions; * they must be at global scope, or for the built-in functions, outside * the global scope." * * From page 27 (page 33 of the PDF) of the GLSL ES 1.00.16 spec, * * "User defined functions may only be defined within the global scope." * * Note that this language does not appear in GLSL 1.10. */ if ((state->current_function != NULL) && state->is_version(120, 100)) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(&loc, state, "declaration of function `%s' not allowed within " "function body", name); } validate_identifier(name, this->get_location(), state); /* Convert the list of function parameters to HIR now so that they can be * used below to compare this function's signature with previously seen * signatures for functions with the same name. */ ast_parameter_declarator::parameters_to_hir(& this->parameters, is_definition, & hir_parameters, state); const char *return_type_name; const glsl_type *return_type = this->return_type->glsl_type(& return_type_name, state); if (!return_type) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(&loc, state, "function `%s' has undeclared return type `%s'", name, return_type_name); return_type = glsl_type::error_type; } /* From page 56 (page 62 of the PDF) of the GLSL 1.30 spec: * "No qualifier is allowed on the return type of a function." */ if (this->return_type->has_qualifiers()) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "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_unsized_array()) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "function `%s' return type array must be explicitly " "sized", name); } /* From section 4.1.7 of the GLSL 4.40 spec: * * "[Opaque types] can only be declared as function parameters * or uniform-qualified variables." */ if (return_type->contains_opaque()) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(&loc, state, "function `%s' return type can't contain an opaque type", name); } /* Verify that this function's signature either doesn't match a previously * seen signature for a function with the same name, or, if a match is found, * that the previously seen signature does not have an associated definition. */ f = state->symbols->get_function(name); if (f != NULL && (state->es_shader || f->has_user_signature())) { sig = f->exact_matching_signature(state, &hir_parameters); if (sig != NULL) { const char *badvar = sig->qualifiers_match(&hir_parameters); if (badvar != NULL) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(&loc, state, "function `%s' parameter `%s' " "qualifiers don't match prototype", name, badvar); } if (sig->return_type != return_type) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(&loc, state, "function `%s' return type doesn't " "match prototype", 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 { f = new(ctx) ir_function(name); if (!state->symbols->add_function(f)) { /* This function name shadows a non-function use of the same name. */ YYLTYPE loc = this->get_location(); _mesa_glsl_error(&loc, state, "function name `%s' conflicts with " "non-function", name); return NULL; } emit_function(state, f); } /* Verify the return type of main() */ if (strcmp(name, "main") == 0) { if (! return_type->is_void()) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "main() must return void"); } if (!hir_parameters.is_empty()) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "main() must not take any parameters"); } } /* Finish storing the information about this new function in its signature. */ if (sig == NULL) { sig = new(ctx) ir_function_signature(return_type); f->add_signature(sig); } sig->replace_parameters(&hir_parameters); signature = sig; /* Function declarations (prototypes) do not have r-values. */ return NULL; } ir_rvalue * ast_function_definition::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { prototype->is_definition = true; prototype->hir(instructions, state); ir_function_signature *signature = prototype->signature; if (signature == NULL) return NULL; assert(state->current_function == NULL); state->current_function = signature; state->found_return = false; /* Duplicate parameters declared in the prototype as concrete variables. * Add these to the symbol table. */ state->symbols->push_scope(); foreach_list(n, &signature->parameters) { ir_variable *const var = ((ir_instruction *) n)->as_variable(); assert(var != NULL); /* The only way a parameter would "exist" is if two parameters have * the same name. */ if (state->symbols->name_declared_this_scope(var->name)) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name); } else { state->symbols->add_variable(var); } } /* Convert the body of the function to HIR. */ this->body->hir(&signature->body, state); signature->is_defined = true; state->symbols->pop_scope(); assert(state->current_function == signature); state->current_function = NULL; if (!signature->return_type->is_void() && !state->found_return) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "function `%s' has non-void return type " "%s, but no return statement", signature->function_name(), signature->return_type->name); } /* Function definitions do not have r-values. */ return NULL; } ir_rvalue * ast_jump_statement::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { void *ctx = state; switch (mode) { case ast_return: { ir_return *inst; assert(state->current_function); if (opt_return_value) { 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. * * NOTE: The GLSL spec doesn't say that this is an error. The type * of the return value is void. If the return type of the function is * also void, then this should compile without error. Seriously. */ const glsl_type *const ret_type = (ret == NULL) ? glsl_type::void_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(); 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 { if (state->current_function->return_type->base_type != GLSL_TYPE_VOID) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "`return' with no value, in function %s returning " "non-void", state->current_function->function_name()); } inst = new(ctx) ir_return; } state->found_return = true; instructions->push_tail(inst); break; } case ast_discard: if (state->stage != MESA_SHADER_FRAGMENT) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "`discard' may only appear in a fragment shader"); } instructions->push_tail(new(ctx) ir_discard); break; case ast_break: case ast_continue: if (mode == ast_continue && state->loop_nesting_ast == NULL) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "continue may only appear in a loop"); } else if (mode == ast_break && state->loop_nesting_ast == NULL && state->switch_state.switch_nesting_ast == NULL) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "break may only appear in a loop or a switch"); } else { /* For a loop, inline the for loop expression again, since we don't * know where near the end of the loop body the normal copy of it is * going to be placed. Same goes for the condition for a do-while * loop. */ if (state->loop_nesting_ast != NULL && mode == ast_continue) { if (state->loop_nesting_ast->rest_expression) { state->loop_nesting_ast->rest_expression->hir(instructions, state); } if (state->loop_nesting_ast->mode == ast_iteration_statement::ast_do_while) { state->loop_nesting_ast->condition_to_hir(instructions, state); } } if (state->switch_state.is_switch_innermost && mode == ast_break) { /* Force break out of switch by setting is_break switch state. */ ir_variable *const is_break_var = state->switch_state.is_break_var; ir_dereference_variable *const deref_is_break_var = new(ctx) ir_dereference_variable(is_break_var); ir_constant *const true_val = new(ctx) ir_constant(true); ir_assignment *const set_break_var = new(ctx) ir_assignment(deref_is_break_var, true_val); instructions->push_tail(set_break_var); } else { ir_loop_jump *const jump = new(ctx) ir_loop_jump((mode == ast_break) ? ir_loop_jump::jump_break : ir_loop_jump::jump_continue); instructions->push_tail(jump); } } break; } /* Jump instructions do not have r-values. */ return NULL; } ir_rvalue * ast_selection_statement::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { void *ctx = state; ir_rvalue *const condition = this->condition->hir(instructions, state); /* From page 66 (page 72 of the PDF) of the GLSL 1.50 spec: * * "Any expression whose type evaluates to a Boolean can be used as the * conditional expression bool-expression. Vector types are not accepted * as the expression to if." * * The checks are separated so that higher quality diagnostics can be * generated for cases where both rules are violated. */ if (!condition->type->is_boolean() || !condition->type->is_scalar()) { YYLTYPE loc = this->condition->get_location(); _mesa_glsl_error(& loc, state, "if-statement condition must be scalar " "boolean"); } ir_if *const stmt = new(ctx) ir_if(condition); if (then_statement != NULL) { state->symbols->push_scope(); then_statement->hir(& stmt->then_instructions, state); state->symbols->pop_scope(); } if (else_statement != NULL) { state->symbols->push_scope(); else_statement->hir(& stmt->else_instructions, state); state->symbols->pop_scope(); } instructions->push_tail(stmt); /* if-statements do not have r-values. */ return NULL; } ir_rvalue * ast_switch_statement::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { void *ctx = state; ir_rvalue *const test_expression = this->test_expression->hir(instructions, state); /* From page 66 (page 55 of the PDF) of the GLSL 1.50 spec: * * "The type of init-expression in a switch statement must be a * scalar integer." */ if (!test_expression->type->is_scalar() || !test_expression->type->is_integer()) { YYLTYPE loc = this->test_expression->get_location(); _mesa_glsl_error(& loc, state, "switch-statement expression must be scalar " "integer"); } /* Track the switch-statement nesting in a stack-like manner. */ struct glsl_switch_state saved = state->switch_state; state->switch_state.is_switch_innermost = true; state->switch_state.switch_nesting_ast = this; state->switch_state.labels_ht = hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare); state->switch_state.previous_default = NULL; /* Initalize is_fallthru state to false. */ ir_rvalue *const is_fallthru_val = new (ctx) ir_constant(false); state->switch_state.is_fallthru_var = new(ctx) ir_variable(glsl_type::bool_type, "switch_is_fallthru_tmp", ir_var_temporary); instructions->push_tail(state->switch_state.is_fallthru_var); ir_dereference_variable *deref_is_fallthru_var = new(ctx) ir_dereference_variable(state->switch_state.is_fallthru_var); instructions->push_tail(new(ctx) ir_assignment(deref_is_fallthru_var, is_fallthru_val)); /* Initalize is_break state to false. */ ir_rvalue *const is_break_val = new (ctx) ir_constant(false); state->switch_state.is_break_var = new(ctx) ir_variable(glsl_type::bool_type, "switch_is_break_tmp", ir_var_temporary); instructions->push_tail(state->switch_state.is_break_var); ir_dereference_variable *deref_is_break_var = new(ctx) ir_dereference_variable(state->switch_state.is_break_var); instructions->push_tail(new(ctx) ir_assignment(deref_is_break_var, is_break_val)); /* Cache test expression. */ test_to_hir(instructions, state); /* Emit code for body of switch stmt. */ body->hir(instructions, state); hash_table_dtor(state->switch_state.labels_ht); state->switch_state = saved; /* Switch statements do not have r-values. */ return NULL; } void ast_switch_statement::test_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { void *ctx = state; /* Cache value of test expression. */ ir_rvalue *const test_val = test_expression->hir(instructions, state); state->switch_state.test_var = new(ctx) ir_variable(test_val->type, "switch_test_tmp", ir_var_temporary); ir_dereference_variable *deref_test_var = new(ctx) ir_dereference_variable(state->switch_state.test_var); instructions->push_tail(state->switch_state.test_var); instructions->push_tail(new(ctx) ir_assignment(deref_test_var, test_val)); } ir_rvalue * ast_switch_body::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { if (stmts != NULL) stmts->hir(instructions, state); /* Switch bodies do not have r-values. */ return NULL; } ir_rvalue * ast_case_statement_list::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { foreach_list_typed (ast_case_statement, case_stmt, link, & this->cases) case_stmt->hir(instructions, state); /* Case statements do not have r-values. */ return NULL; } ir_rvalue * ast_case_statement::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { labels->hir(instructions, state); /* Conditionally set fallthru state based on break state. */ ir_constant *const false_val = new(state) ir_constant(false); ir_dereference_variable *const deref_is_fallthru_var = new(state) ir_dereference_variable(state->switch_state.is_fallthru_var); ir_dereference_variable *const deref_is_break_var = new(state) ir_dereference_variable(state->switch_state.is_break_var); ir_assignment *const reset_fallthru_on_break = new(state) ir_assignment(deref_is_fallthru_var, false_val, deref_is_break_var); instructions->push_tail(reset_fallthru_on_break); /* Guard case statements depending on fallthru state. */ ir_dereference_variable *const deref_fallthru_guard = new(state) ir_dereference_variable(state->switch_state.is_fallthru_var); ir_if *const test_fallthru = new(state) ir_if(deref_fallthru_guard); foreach_list_typed (ast_node, stmt, link, & this->stmts) stmt->hir(& test_fallthru->then_instructions, state); instructions->push_tail(test_fallthru); /* Case statements do not have r-values. */ return NULL; } ir_rvalue * ast_case_label_list::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { foreach_list_typed (ast_case_label, label, link, & this->labels) label->hir(instructions, state); /* Case labels do not have r-values. */ return NULL; } ir_rvalue * ast_case_label::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { void *ctx = state; ir_dereference_variable *deref_fallthru_var = new(ctx) ir_dereference_variable(state->switch_state.is_fallthru_var); ir_rvalue *const true_val = new(ctx) ir_constant(true); /* If not default case, ... */ if (this->test_value != NULL) { /* Conditionally set fallthru state based on * comparison of cached test expression value to case label. */ ir_rvalue *const label_rval = this->test_value->hir(instructions, state); ir_constant *label_const = label_rval->constant_expression_value(); if (!label_const) { YYLTYPE loc = this->test_value->get_location(); _mesa_glsl_error(& loc, state, "switch statement case label must be a " "constant expression"); /* Stuff a dummy value in to allow processing to continue. */ label_const = new(ctx) ir_constant(0); } else { ast_expression *previous_label = (ast_expression *) hash_table_find(state->switch_state.labels_ht, (void *)(uintptr_t)label_const->value.u[0]); if (previous_label) { YYLTYPE loc = this->test_value->get_location(); _mesa_glsl_error(& loc, state, "duplicate case value"); loc = previous_label->get_location(); _mesa_glsl_error(& loc, state, "this is the previous case label"); } else { hash_table_insert(state->switch_state.labels_ht, this->test_value, (void *)(uintptr_t)label_const->value.u[0]); } } ir_dereference_variable *deref_test_var = new(ctx) ir_dereference_variable(state->switch_state.test_var); ir_expression *test_cond = new(ctx) ir_expression(ir_binop_all_equal, label_const, deref_test_var); /* * From GLSL 4.40 specification section 6.2 ("Selection"): * * "The type of the init-expression value in a switch statement must * be a scalar int or uint. The type of the constant-expression value * in a case label also must be a scalar int or uint. When any pair * of these values is tested for "equal value" and the types do not * match, an implicit conversion will be done to convert the int to a * uint (see section 4.1.10 “Implicit Conversions”) before the compare * is done." */ if (label_const->type != state->switch_state.test_var->type) { YYLTYPE loc = this->test_value->get_location(); const glsl_type *type_a = label_const->type; const glsl_type *type_b = state->switch_state.test_var->type; /* Check if int->uint implicit conversion is supported. */ bool integer_conversion_supported = glsl_type::int_type->can_implicitly_convert_to(glsl_type::uint_type, state); if ((!type_a->is_integer() || !type_b->is_integer()) || !integer_conversion_supported) { _mesa_glsl_error(&loc, state, "type mismatch with switch " "init-expression and case label (%s != %s)", type_a->name, type_b->name); } else { /* Conversion of the case label. */ if (type_a->base_type == GLSL_TYPE_INT) { if (!apply_implicit_conversion(glsl_type::uint_type, test_cond->operands[0], state)) _mesa_glsl_error(&loc, state, "implicit type conversion error"); } else { /* Conversion of the init-expression value. */ if (!apply_implicit_conversion(glsl_type::uint_type, test_cond->operands[1], state)) _mesa_glsl_error(&loc, state, "implicit type conversion error"); } } } ir_assignment *set_fallthru_on_test = new(ctx) ir_assignment(deref_fallthru_var, true_val, test_cond); instructions->push_tail(set_fallthru_on_test); } else { /* default case */ if (state->switch_state.previous_default) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "multiple default labels in one switch"); loc = state->switch_state.previous_default->get_location(); _mesa_glsl_error(& loc, state, "this is the first default label"); } state->switch_state.previous_default = this; /* Set falltrhu state. */ ir_assignment *set_fallthru = new(ctx) ir_assignment(deref_fallthru_var, true_val); instructions->push_tail(set_fallthru); } /* Case statements do not have r-values. */ return NULL; } void ast_iteration_statement::condition_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { void *ctx = state; if (condition != NULL) { ir_rvalue *const cond = condition->hir(instructions, state); if ((cond == NULL) || !cond->type->is_boolean() || !cond->type->is_scalar()) { YYLTYPE loc = condition->get_location(); _mesa_glsl_error(& loc, state, "loop condition must be scalar boolean"); } else { /* As the first code in the loop body, generate a block that looks * like 'if (!condition) break;' as the loop termination condition. */ ir_rvalue *const not_cond = new(ctx) ir_expression(ir_unop_logic_not, cond); ir_if *const if_stmt = new(ctx) ir_if(not_cond); ir_jump *const break_stmt = new(ctx) ir_loop_jump(ir_loop_jump::jump_break); if_stmt->then_instructions.push_tail(break_stmt); instructions->push_tail(if_stmt); } } } ir_rvalue * ast_iteration_statement::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { void *ctx = state; /* For-loops and while-loops start a new scope, but do-while loops do not. */ if (mode != ast_do_while) state->symbols->push_scope(); if (init_statement != NULL) init_statement->hir(instructions, state); ir_loop *const stmt = new(ctx) ir_loop(); instructions->push_tail(stmt); /* Track the current loop nesting. */ ast_iteration_statement *nesting_ast = state->loop_nesting_ast; state->loop_nesting_ast = this; /* Likewise, indicate that following code is closest to a loop, * NOT closest to a switch. */ bool saved_is_switch_innermost = state->switch_state.is_switch_innermost; state->switch_state.is_switch_innermost = false; if (mode != ast_do_while) condition_to_hir(&stmt->body_instructions, state); if (body != NULL) body->hir(& stmt->body_instructions, state); if (rest_expression != NULL) rest_expression->hir(& stmt->body_instructions, state); if (mode == ast_do_while) condition_to_hir(&stmt->body_instructions, state); if (mode != ast_do_while) state->symbols->pop_scope(); /* Restore previous nesting before returning. */ state->loop_nesting_ast = nesting_ast; state->switch_state.is_switch_innermost = saved_is_switch_innermost; /* Loops do not have r-values. */ return NULL; } /** * Determine if the given type is valid for establishing a default precision * qualifier. * * From GLSL ES 3.00 section 4.5.4 ("Default Precision Qualifiers"): * * "The precision statement * * precision precision-qualifier type; * * can be used to establish a default precision qualifier. The type field * can be either int or float or any of the sampler types, and the * precision-qualifier can be lowp, mediump, or highp." * * GLSL ES 1.00 has similar language. GLSL 1.30 doesn't allow precision * qualifiers on sampler types, but this seems like an oversight (since the * intention of including these in GLSL 1.30 is to allow compatibility with ES * shaders). So we allow int, float, and all sampler types regardless of GLSL * version. */ static bool is_valid_default_precision_type(const struct glsl_type *const type) { if (type == NULL) return false; switch (type->base_type) { case GLSL_TYPE_INT: case GLSL_TYPE_FLOAT: /* "int" and "float" are valid, but vectors and matrices are not. */ return type->vector_elements == 1 && type->matrix_columns == 1; case GLSL_TYPE_SAMPLER: return true; default: return false; } } ir_rvalue * ast_type_specifier::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { if (this->default_precision == ast_precision_none && this->structure == NULL) return NULL; YYLTYPE loc = this->get_location(); /* If this is a precision statement, check that the type to which it is * applied is either float or int. * * From section 4.5.3 of the GLSL 1.30 spec: * "The precision statement * precision precision-qualifier type; * can be used to establish a default precision qualifier. The type * field can be either int or float [...]. Any other types or * qualifiers will result in an error. */ 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->array_specifier != NULL) { _mesa_glsl_error(&loc, state, "default precision statements do not apply to " "arrays"); return NULL; } 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 " "float, int, and sampler types"); return NULL; } if (type->base_type == GLSL_TYPE_FLOAT && state->es_shader && state->stage == MESA_SHADER_FRAGMENT) { /* 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; } /* _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; } /** * Process a structure or interface block tree into an array of structure fields * * After parsing, where there are some syntax differnces, structures and * interface blocks are almost identical. They are similar enough that the * AST for each can be processed the same way into a set of * \c glsl_struct_field to describe the members. * * If we're processing an interface block, var_mode should be the type of the * interface block (ir_var_shader_in, ir_var_shader_out, or ir_var_uniform). * If we're processing a structure, var_mode should be ir_var_auto. * * \return * The number of fields processed. A pointer to the array structure fields is * stored in \c *fields_ret. */ unsigned ast_process_structure_or_interface_block(exec_list *instructions, struct _mesa_glsl_parse_state *state, exec_list *declarations, YYLTYPE &loc, glsl_struct_field **fields_ret, bool is_interface, bool block_row_major, bool allow_reserved_names, ir_variable_mode var_mode) { unsigned decl_count = 0; /* Make an initial pass over the list of fields to determine how * many there are. Each element in this list is an ast_declarator_list. * This means that we actually need to count the number of elements in the * 'declarations' list in each of the elements. */ foreach_list_typed (ast_declarator_list, decl_list, link, declarations) { foreach_list_const (decl_ptr, & decl_list->declarations) { decl_count++; } } /* Allocate storage for the fields and process the field * declarations. As the declarations are processed, try to also convert * the types to HIR. This ensures that structure definitions embedded in * other structure definitions or in interface blocks are processed. */ glsl_struct_field *const fields = ralloc_array(state, glsl_struct_field, decl_count); unsigned i = 0; foreach_list_typed (ast_declarator_list, decl_list, link, declarations) { const char *type_name; decl_list->type->specifier->hir(instructions, state); /* Section 10.9 of the GLSL ES 1.00 specification states that * 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"); } const glsl_type *decl_type = decl_list->type->glsl_type(& type_name, state); foreach_list_typed (ast_declaration, decl, link, &decl_list->declarations) { if (!allow_reserved_names) validate_identifier(decl->identifier, loc, state); /* From section 4.3.9 of the GLSL 4.40 spec: * * "[In interface blocks] opaque types are not allowed." * * 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 != NULL ? decl_type : glsl_type::error_type; if (is_interface && field_type->contains_opaque()) { YYLTYPE loc = decl_list->get_location(); _mesa_glsl_error(&loc, state, "uniform in non-default uniform block contains " "opaque variable"); } if (field_type->contains_atomic()) { /* FINISHME: Add a spec quotation here once updated spec * FINISHME: language is available. See Khronos bug #10903 * FINISHME: on whether atomic counters are allowed in * FINISHME: structures. */ YYLTYPE loc = decl_list->get_location(); _mesa_glsl_error(&loc, state, "atomic counter in structure or " "uniform block"); } if (field_type->contains_image()) { /* FINISHME: Same problem as with atomic counters. * FINISHME: Request clarification from Khronos and add * FINISHME: spec quotation here. */ YYLTYPE loc = decl_list->get_location(); _mesa_glsl_error(&loc, state, "image in structure or uniform block"); } const struct ast_type_qualifier *const qual = & decl_list->type->qualifier; if (qual->flags.q.std140 || qual->flags.q.packed || qual->flags.q.shared) { _mesa_glsl_error(&loc, state, "uniform block layout qualifiers std140, packed, and " "shared can only be applied to uniform blocks, not " "members"); } field_type = process_array_type(&loc, decl_type, decl->array_specifier, state); fields[i].type = field_type; fields[i].name = decl->identifier; fields[i].location = -1; fields[i].interpolation = interpret_interpolation_qualifier(qual, var_mode, state, &loc); fields[i].centroid = qual->flags.q.centroid ? 1 : 0; fields[i].sample = qual->flags.q.sample ? 1 : 0; if (qual->flags.q.row_major || qual->flags.q.column_major) { if (!qual->flags.q.uniform) { _mesa_glsl_error(&loc, state, "row_major and column_major can only be " "applied to uniform interface blocks"); } else validate_matrix_layout_for_type(state, &loc, field_type, NULL); } if (qual->flags.q.uniform && qual->has_interpolation()) { _mesa_glsl_error(&loc, state, "interpolation qualifiers cannot be used " "with uniform interface blocks"); } if ((qual->flags.q.uniform || !is_interface) && qual->has_auxiliary_storage()) { _mesa_glsl_error(&loc, state, "auxiliary storage qualifiers cannot be used " "in uniform blocks or structures."); } if (field_type->is_matrix() || (field_type->is_array() && field_type->fields.array->is_matrix())) { fields[i].row_major = block_row_major; if (qual->flags.q.row_major) fields[i].row_major = true; else if (qual->flags.q.column_major) fields[i].row_major = false; } i++; } } assert(i == decl_count); *fields_ret = fields; return decl_count; } ir_rvalue * 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 declarations are not allowed"); state->struct_specifier_depth++; glsl_struct_field *fields; unsigned decl_count = ast_process_structure_or_interface_block(instructions, state, &this->declarations, loc, &fields, false, false, false /* allow_reserved_names */, ir_var_auto); validate_identifier(this->name, loc, state); const glsl_type *t = glsl_type::get_record_instance(fields, decl_count, this->name); if (!state->symbols->add_type(name, t)) { _mesa_glsl_error(& loc, state, "struct `%s' previously defined", name); } else { const glsl_type **s = reralloc(state, state->user_structures, const glsl_type *, state->num_user_structures + 1); if (s != NULL) { s[state->num_user_structures] = t; state->user_structures = s; state->num_user_structures++; } } state->struct_specifier_depth--; /* Structure type definitions do not have r-values. */ return NULL; } /** * Visitor class which detects whether a given interface block has been used. */ class interface_block_usage_visitor : public ir_hierarchical_visitor { public: interface_block_usage_visitor(ir_variable_mode mode, const glsl_type *block) : mode(mode), block(block), found(false) { } virtual ir_visitor_status visit(ir_dereference_variable *ir) { if (ir->var->data.mode == mode && ir->var->get_interface_type() == block) { found = true; return visit_stop; } return visit_continue; } bool usage_found() const { return this->found; } private: ir_variable_mode mode; const glsl_type *block; bool found; }; ir_rvalue * ast_interface_block::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { YYLTYPE loc = this->get_location(); /* 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. */ enum glsl_interface_packing packing; if (this->layout.flags.q.shared) { packing = GLSL_INTERFACE_PACKING_SHARED; } else if (this->layout.flags.q.packed) { packing = GLSL_INTERFACE_PACKING_PACKED; } else { /* The default layout is std140. */ packing = GLSL_INTERFACE_PACKING_STD140; } 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!"); } bool redeclaring_per_vertex = strcmp(this->block_name, "gl_PerVertex") == 0; bool block_row_major = this->layout.flags.q.row_major; exec_list declared_variables; glsl_struct_field *fields; /* Treat an interface block as one level of nesting, so that embedded struct * specifiers will be disallowed. */ state->struct_specifier_depth++; unsigned int num_variables = ast_process_structure_or_interface_block(&declared_variables, state, &this->declarations, loc, &fields, true, block_row_major, redeclaring_per_vertex, var_mode); state->struct_specifier_depth--; if (!redeclaring_per_vertex) validate_identifier(this->block_name, loc, state); const glsl_type *earlier_per_vertex = NULL; if (redeclaring_per_vertex) { /* Find the previous declaration of gl_PerVertex. If we're redeclaring * the named interface block gl_in, we can find it by looking at the * previous declaration of gl_in. Otherwise we can find it by looking * at the previous decalartion of any of the built-in outputs, * e.g. gl_Position. * * Also check that the instance name and array-ness of the redeclaration * are correct. */ switch (var_mode) { case ir_var_shader_in: if (ir_variable *earlier_gl_in = state->symbols->get_variable("gl_in")) { earlier_per_vertex = earlier_gl_in->get_interface_type(); } else { _mesa_glsl_error(&loc, state, "redeclaration of gl_PerVertex input not allowed " "in the %s shader", _mesa_shader_stage_to_string(state->stage)); } if (this->instance_name == NULL || strcmp(this->instance_name, "gl_in") != 0 || this->array_specifier == NULL) { _mesa_glsl_error(&loc, state, "gl_PerVertex input must be redeclared as " "gl_in[]"); } break; case ir_var_shader_out: if (ir_variable *earlier_gl_Position = state->symbols->get_variable("gl_Position")) { earlier_per_vertex = earlier_gl_Position->get_interface_type(); } else { _mesa_glsl_error(&loc, state, "redeclaration of gl_PerVertex output not " "allowed in the %s shader", _mesa_shader_stage_to_string(state->stage)); } if (this->instance_name != NULL) { _mesa_glsl_error(&loc, state, "gl_PerVertex input may not be redeclared with " "an instance name"); } break; default: _mesa_glsl_error(&loc, state, "gl_PerVertex must be declared as an input or an " "output"); break; } if (earlier_per_vertex == NULL) { /* An error has already been reported. Bail out to avoid null * dereferences later in this function. */ return NULL; } /* Copy locations from the old gl_PerVertex interface block. */ for (unsigned i = 0; i < num_variables; i++) { int j = earlier_per_vertex->field_index(fields[i].name); if (j == -1) { _mesa_glsl_error(&loc, state, "redeclaration of gl_PerVertex must be a subset " "of the built-in members of gl_PerVertex"); } else { fields[i].location = earlier_per_vertex->fields.structure[j].location; fields[i].interpolation = earlier_per_vertex->fields.structure[j].interpolation; fields[i].centroid = earlier_per_vertex->fields.structure[j].centroid; fields[i].sample = earlier_per_vertex->fields.structure[j].sample; } } /* From section 7.1 ("Built-in Language Variables") of the GLSL 4.10 * spec: * * If a built-in interface block is redeclared, it must appear in * the shader before any use of any member included in the built-in * declaration, or a compilation error will result. * * This appears to be a clarification to the behaviour established for * gl_PerVertex by GLSL 1.50, therefore we implement this behaviour * regardless of GLSL version. */ interface_block_usage_visitor v(var_mode, earlier_per_vertex); v.run(instructions); if (v.usage_found()) { _mesa_glsl_error(&loc, state, "redeclaration of a built-in interface block must " "appear before any use of any member of the " "interface block"); } } const glsl_type *block_type = glsl_type::get_interface_instance(fields, num_variables, packing, this->block_name); if (!state->symbols->add_interface(block_type->name, block_type, var_mode)) { YYLTYPE loc = this->get_location(); _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 * impossible for the block to generate any 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->stage == MESA_SHADER_GEOMETRY && this->array_specifier == NULL && 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: * * "If an instance name (instance-name) is used, then it puts all the * members inside a scope within its own name space, accessed with the * field selector ( . ) operator (analogously to structures)." */ if (this->instance_name) { if (redeclaring_per_vertex) { /* When a built-in in an unnamed interface block is redeclared, * get_variable_being_redeclared() calls * check_builtin_array_max_size() to make sure that built-in array * variables aren't redeclared to illegal sizes. But we're looking * at a redeclaration of a named built-in interface block. So we * have to manually call check_builtin_array_max_size() for all parts * of the interface that are arrays. */ for (unsigned i = 0; i < num_variables; i++) { if (fields[i].type->is_array()) { const unsigned size = fields[i].type->array_size(); check_builtin_array_max_size(fields[i].name, size, loc, state); } } } else { validate_identifier(this->instance_name, loc, state); } ir_variable *var; if (this->array_specifier != NULL) { /* 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_specifier->is_unsized_array && (state->stage != MESA_SHADER_GEOMETRY || !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_specifier, state); var = new(state) ir_variable(block_array_type, this->instance_name, var_mode); } else { var = new(state) ir_variable(block_type, this->instance_name, var_mode); } if (state->stage == MESA_SHADER_GEOMETRY && var_mode == ir_var_shader_in) handle_geometry_shader_input_decl(state, loc, var); if (ir_variable *earlier = state->symbols->get_variable(this->instance_name)) { if (!redeclaring_per_vertex) { _mesa_glsl_error(&loc, state, "`%s' redeclared", this->instance_name); } earlier->data.how_declared = ir_var_declared_normally; earlier->type = var->type; earlier->reinit_interface_type(block_type); delete var; } else { /* 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->data.explicit_binding = this->layout.flags.q.explicit_binding; var->data.binding = this->layout.binding; 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 instance name. */ assert(this->array_specifier == NULL); for (unsigned i = 0; i < num_variables; i++) { ir_variable *var = new(state) ir_variable(fields[i].type, ralloc_strdup(state, fields[i].name), var_mode); var->data.interpolation = fields[i].interpolation; var->data.centroid = fields[i].centroid; var->data.sample = fields[i].sample; var->init_interface_type(block_type); if (redeclaring_per_vertex) { ir_variable *earlier = get_variable_being_redeclared(var, loc, state, true /* allow_all_redeclarations */); if (!is_gl_identifier(var->name) || earlier == NULL) { _mesa_glsl_error(&loc, state, "redeclaration of gl_PerVertex can only " "include built-in variables"); } else if (earlier->data.how_declared == ir_var_declared_normally) { _mesa_glsl_error(&loc, state, "`%s' has already been redeclared", var->name); } else { earlier->data.how_declared = ir_var_declared_in_block; earlier->reinit_interface_type(block_type); } continue; } if (state->symbols->get_variable(var->name) != NULL) _mesa_glsl_error(&loc, state, "`%s' redeclared", var->name); /* 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->data.explicit_binding = this->layout.flags.q.explicit_binding; var->data.binding = this->layout.binding; state->symbols->add_variable(var); instructions->push_tail(var); } if (redeclaring_per_vertex && block_type != earlier_per_vertex) { /* From section 7.1 ("Built-in Language Variables") of the GLSL 4.10 spec: * * It is also a compilation error ... to redeclare a built-in * block and then use a member from that built-in block that was * not included in the redeclaration. * * This appears to be a clarification to the behaviour established * for gl_PerVertex by GLSL 1.50, therefore we implement this * behaviour regardless of GLSL version. * * To prevent the shader from using a member that was not included in * the redeclaration, we disable any ir_variables that are still * associated with the old declaration of gl_PerVertex (since we've * already updated all of the variables contained in the new * gl_PerVertex to point to it). * * As a side effect this will prevent * validate_intrastage_interface_blocks() from getting confused and * thinking there are conflicting definitions of gl_PerVertex in the * shader. */ foreach_list_safe(node, instructions) { ir_variable *const var = ((ir_instruction *) node)->as_variable(); if (var != NULL && var->get_interface_type() == earlier_per_vertex && var->data.mode == var_mode) { if (var->data.how_declared == ir_var_declared_normally) { _mesa_glsl_error(&loc, state, "redeclaration of gl_PerVertex cannot " "follow a redeclaration of `%s'", var->name); } state->symbols->disable_variable(var->name); var->remove(); } } } } 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->in_qualifier->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; /* 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->data.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_unsized_array()) { if (var->data.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->data.max_array_access, var->name); } else { var->type = glsl_type::get_array_instance(var->type->fields.array, num_vertices); } } } return NULL; } ir_rvalue * ast_cs_input_layout::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { YYLTYPE loc = this->get_location(); /* If any compute input layout declaration preceded this one, make sure it * was consistent with this one. */ if (state->cs_input_local_size_specified) { for (int i = 0; i < 3; i++) { if (state->cs_input_local_size[i] != this->local_size[i]) { _mesa_glsl_error(&loc, state, "compute shader input layout does not match" " previous declaration"); return NULL; } } } /* From the ARB_compute_shader specification: * * If the local size of the shader in any dimension is greater * than the maximum size supported by the implementation for that * dimension, a compile-time error results. * * It is not clear from the spec how the error should be reported if * the total size of the work group exceeds * MAX_COMPUTE_WORK_GROUP_INVOCATIONS, but it seems reasonable to * report it at compile time as well. */ GLuint64 total_invocations = 1; for (int i = 0; i < 3; i++) { if (this->local_size[i] > state->ctx->Const.MaxComputeWorkGroupSize[i]) { _mesa_glsl_error(&loc, state, "local_size_%c exceeds MAX_COMPUTE_WORK_GROUP_SIZE" " (%d)", 'x' + i, state->ctx->Const.MaxComputeWorkGroupSize[i]); break; } total_invocations *= this->local_size[i]; if (total_invocations > state->ctx->Const.MaxComputeWorkGroupInvocations) { _mesa_glsl_error(&loc, state, "product of local_sizes exceeds " "MAX_COMPUTE_WORK_GROUP_INVOCATIONS (%d)", state->ctx->Const.MaxComputeWorkGroupInvocations); break; } } state->cs_input_local_size_specified = true; for (int i = 0; i < 3; i++) state->cs_input_local_size[i] = this->local_size[i]; /* We may now declare the built-in constant gl_WorkGroupSize (see * builtin_variable_generator::generate_constants() for why we didn't * declare it earlier). */ ir_variable *var = new(state->symbols) ir_variable(glsl_type::ivec3_type, "gl_WorkGroupSize", ir_var_auto); var->data.how_declared = ir_var_declared_implicitly; var->data.read_only = true; instructions->push_tail(var); state->symbols->add_variable(var); ir_constant_data data; memset(&data, 0, sizeof(data)); for (int i = 0; i < 3; i++) data.i[i] = this->local_size[i]; var->constant_value = new(var) ir_constant(glsl_type::ivec3_type, &data); var->constant_initializer = new(var) ir_constant(glsl_type::ivec3_type, &data); var->data.has_initializer = true; return NULL; } static void detect_conflicting_assignments(struct _mesa_glsl_parse_state *state, exec_list *instructions) { bool gl_FragColor_assigned = false; bool gl_FragData_assigned = false; bool user_defined_fs_output_assigned = false; ir_variable *user_defined_fs_output = NULL; /* It would be nice to have proper location information. */ YYLTYPE loc; memset(&loc, 0, sizeof(loc)); foreach_list(node, instructions) { ir_variable *var = ((ir_instruction *)node)->as_variable(); if (!var || !var->data.assigned) continue; if (strcmp(var->name, "gl_FragColor") == 0) gl_FragColor_assigned = true; else if (strcmp(var->name, "gl_FragData") == 0) gl_FragData_assigned = true; else if (!is_gl_identifier(var->name)) { if (state->stage == MESA_SHADER_FRAGMENT && var->data.mode == ir_var_shader_out) { user_defined_fs_output_assigned = true; user_defined_fs_output = var; } } } /* From the GLSL 1.30 spec: * * "If a shader statically assigns a value to gl_FragColor, it * may not assign a value to any element of gl_FragData. If a * shader statically writes a value to any element of * gl_FragData, it may not assign a value to * gl_FragColor. That is, a shader may assign values to either * gl_FragColor or gl_FragData, but not both. Multiple shaders * linked together must also consistently write just one of * these variables. Similarly, if user declared output * variables are in use (statically assigned to), then the * built-in variables gl_FragColor and gl_FragData may not be * assigned to. These incorrect usages all generate compile * time errors." */ if (gl_FragColor_assigned && gl_FragData_assigned) { _mesa_glsl_error(&loc, state, "fragment shader writes to both " "`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'", 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'", user_defined_fs_output->name); } } static void remove_per_vertex_blocks(exec_list *instructions, _mesa_glsl_parse_state *state, ir_variable_mode mode) { /* Find the gl_PerVertex interface block of the appropriate (in/out) mode, * if it exists in this shader type. */ const glsl_type *per_vertex = NULL; switch (mode) { case ir_var_shader_in: if (ir_variable *gl_in = state->symbols->get_variable("gl_in")) per_vertex = gl_in->get_interface_type(); break; case ir_var_shader_out: if (ir_variable *gl_Position = state->symbols->get_variable("gl_Position")) { per_vertex = gl_Position->get_interface_type(); } break; default: assert(!"Unexpected mode"); break; } /* If we didn't find a built-in gl_PerVertex interface block, then we don't * need to do anything. */ if (per_vertex == NULL) return; /* If the interface block is used by the shader, then we don't need to do * anything. */ interface_block_usage_visitor v(mode, per_vertex); v.run(instructions); if (v.usage_found()) return; /* Remove any ir_variable declarations that refer to the interface block * we're removing. */ foreach_list_safe(node, instructions) { ir_variable *const var = ((ir_instruction *) node)->as_variable(); if (var != NULL && var->get_interface_type() == per_vertex && var->data.mode == mode) { state->symbols->disable_variable(var->name); var->remove(); } } }