1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2010 Intel Corporation 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"), 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions: 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software. 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DEALINGS IN THE SOFTWARE. 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file ast_to_hir.c 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convert abstract syntax to to high-level intermediate reprensentation (HIR). 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * During the conversion to HIR, the majority of the symantic checking is 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * preformed on the program. This includes: 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * * Symbol table management 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * * Type checking 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * * Function binding 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The majority of this work could be done during parsing, and the parser could 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * probably generate HIR directly. However, this results in frequent changes 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to the parser code. Since we do not assume that every system this complier 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is built on will have Flex and Bison installed, we have to store the code 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * generated by these tools in our version control system. In other parts of 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the system we've seen problems where a parser was changed but the generated 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * code was not committed, merge conflicts where created because two developers 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * had slightly different versions of Bison installed, etc. 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * I have also noticed that running Bison generated parsers in GDB is very 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * irritating. When you get a segfault on '$$ = $1->foo', you can't very 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * well 'print $1' in GDB. 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * As a result, my preference is to put as little C code as possible in the 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * parser (and lexer) sources. 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/core.h" /* for struct gl_extensions */ 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_symbol_table.h" 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_parser_extras.h" 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ast.h" 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_types.h" 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/hash_table.h" 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir.h" 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdetect_conflicting_assignments(struct _mesa_glsl_parse_state *state, 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list *instructions); 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_initialize_variables(instructions, state); 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->language_version = state->language_version; 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->current_function = NULL; 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->toplevel_ir = instructions; 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Section 4.2 of the GLSL 1.20 specification states: 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The built-in functions are scoped in a scope outside the global scope 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * users declare global variables in. That is, a shader's global scope, 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * available for user-defined functions and global variables, is nested 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * inside the scope containing the built-in functions." 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Since built-in functions like ftransform() access built-in variables, 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * it follows that those must be in the outer scope as well. 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We push scope here to create this nesting effect...but don't pop. 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This way, a shader's globals are still in the symbol table for use 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * by the linker. 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->push_scope(); 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_typed (ast_node, ast, link, & state->translation_unit) 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ast->hir(instructions, state); 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org detect_recursion_unlinked(state, instructions); 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org detect_conflicting_assignments(state, instructions); 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->toplevel_ir = NULL; 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If a conversion is available, convert one operand to a different type 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The \c from \c ir_rvalue is converted "in place". 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param to Type that the operand it to be converted to 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param from Operand that is being converted 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param state GLSL compiler state 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If a conversion is possible (or unnecessary), \c true is returned. 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Otherwise \c false is returned. 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgapply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ctx = state; 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (to->base_type == from->type->base_type) 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This conversion was added in GLSL 1.20. If the compilation mode is 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GLSL 1.10, the conversion is skipped. 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->language_version < 120) 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec: 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "There are no implicit array or structure conversions. For 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * example, an array of int cannot be implicitly converted to an 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * array of float. There are no implicit conversions between 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * signed and unsigned integers." 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* FINISHME: The above comment is partially a lie. There is int/uint 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FINISHME: conversion for immediate constants. 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!to->is_float() || !from->type->is_numeric()) 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Convert to a floating point type with the same number of components 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * as the original type - i.e. int to float, not int to vec4. 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org to = glsl_type::get_instance(GLSL_TYPE_FLOAT, from->type->vector_elements, 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org from->type->matrix_columns); 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (from->type->base_type) { 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_INT: 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org from = new(ctx) ir_expression(ir_unop_i2f, to, from, NULL); 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_UINT: 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org from = new(ctx) ir_expression(ir_unop_u2f, to, from, NULL); 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_BOOL: 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org from = new(ctx) ir_expression(ir_unop_b2f, to, from, NULL); 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glsl_type * 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgarithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool multiply, 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state, YYLTYPE *loc) 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *type_a = value_a->type; 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *type_b = value_b->type; 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From GLSL 1.50 spec, page 56: 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The arithmetic binary operators add (+), subtract (-), 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * multiply (*), and divide (/) operate on integer and 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * floating-point scalars, vectors, and matrices." 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!type_a->is_numeric() || !type_b->is_numeric()) { 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "Operands to arithmetic operators must be numeric"); 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "If one operand is floating-point based and the other is 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * not, then the conversions from Section 4.1.10 "Implicit 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Conversions" are applied to the non-floating-point-based operand." 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!apply_implicit_conversion(type_a, value_b, state) 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !apply_implicit_conversion(type_b, value_a, state)) { 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "Could not implicitly convert operands to " 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "arithmetic operator"); 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_a = value_a->type; 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_b = value_b->type; 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "If the operands are integer types, they must both be signed or 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * both be unsigned." 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * From this rule and the preceeding conversion it can be inferred that 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * both types must be GLSL_TYPE_FLOAT, or GLSL_TYPE_UINT, or GLSL_TYPE_INT. 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The is_numeric check above already filtered out the case where either 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * type is not one of these, so now the base types need only be tested for 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * equality. 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a->base_type != type_b->base_type) { 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "base type mismatch for arithmetic operator"); 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "All arithmetic binary operators result in the same fundamental type 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (signed integer, unsigned integer, or floating-point) as the 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * operands they operate on, after operand type conversion. After 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * conversion, the following cases are valid 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * * The two operands are scalars. In this case the operation is 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * applied, resulting in a scalar." 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a->is_scalar() && type_b->is_scalar()) 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type_a; 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "* One operand is a scalar, and the other is a vector or matrix. 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In this case, the scalar operation is applied independently to each 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * component of the vector or matrix, resulting in the same size 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * vector or matrix." 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a->is_scalar()) { 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!type_b->is_scalar()) 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type_b; 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (type_b->is_scalar()) { 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type_a; 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* All of the combinations of <scalar, scalar>, <vector, scalar>, 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * <scalar, vector>, <scalar, matrix>, and <matrix, scalar> have been 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * handled. 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!type_a->is_scalar()); 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!type_b->is_scalar()); 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "* The two operands are vectors of the same size. In this case, the 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * operation is done component-wise resulting in the same size 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * vector." 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a->is_vector() && type_b->is_vector()) { 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a == type_b) { 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type_a; 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "vector size mismatch for arithmetic operator"); 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* All of the combinations of <scalar, scalar>, <vector, scalar>, 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * <scalar, vector>, <scalar, matrix>, <matrix, scalar>, and 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * <vector, vector> have been handled. At least one of the operands must 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * be matrix. Further, since there are no integer matrix types, the base 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * type of both operands must be float. 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(type_a->is_matrix() || type_b->is_matrix()); 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(type_a->base_type == GLSL_TYPE_FLOAT); 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(type_b->base_type == GLSL_TYPE_FLOAT); 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "* The operator is add (+), subtract (-), or divide (/), and the 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * operands are matrices with the same number of rows and the same 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * number of columns. In this case, the operation is done component- 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * wise resulting in the same size matrix." 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * * The operator is multiply (*), where both operands are matrices or 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * one operand is a vector and the other a matrix. A right vector 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * operand is treated as a column vector and a left vector operand as a 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * row vector. In all these cases, it is required that the number of 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * columns of the left operand is equal to the number of rows of the 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * right operand. Then, the multiply (*) operation does a linear 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * algebraic multiply, yielding an object that has the same number of 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * rows as the left operand and the same number of columns as the right 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * operand. Section 5.10 "Vector and Matrix Operations" explains in 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * more detail how vectors and matrices are operated on." 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (! multiply) { 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a == type_b) 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type_a; 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a->is_matrix() && type_b->is_matrix()) { 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Matrix multiply. The columns of A must match the rows of B. Given 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the other previously tested constraints, this means the vector type 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of a row from A must be the same as the vector type of a column from 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * B. 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a->row_type() == type_b->column_type()) { 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The resulting matrix has the number of columns of matrix B and 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the number of rows of matrix A. We get the row count of A by 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * looking at the size of a vector that makes up a column. The 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * transpose (size of a row) is done for B. 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *const type = 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_type::get_instance(type_a->base_type, 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_a->column_type()->vector_elements, 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_b->row_type()->vector_elements); 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(type != glsl_type::error_type); 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type; 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (type_a->is_matrix()) { 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* A is a matrix and B is a column vector. Columns of A must match 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * rows of B. Given the other previously tested constraints, this 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * means the vector type of a row from A must be the same as the 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * vector the type of B. 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a->row_type() == type_b) { 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The resulting vector has a number of elements equal to 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the number of rows of matrix A. */ 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *const type = 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_type::get_instance(type_a->base_type, 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_a->column_type()->vector_elements, 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1); 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(type != glsl_type::error_type); 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type; 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(type_b->is_matrix()); 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* A is a row vector and B is a matrix. Columns of A must match rows 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of B. Given the other previously tested constraints, this means 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the type of A must be the same as the vector type of a column from 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * B. 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a == type_b->column_type()) { 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The resulting vector has a number of elements equal to 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the number of columns of matrix B. */ 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *const type = 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_type::get_instance(type_a->base_type, 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_b->row_type()->vector_elements, 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1); 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(type != glsl_type::error_type); 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type; 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "size mismatch for matrix multiplication"); 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "All other cases are illegal." 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "type mismatch"); 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glsl_type * 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunary_arithmetic_result_type(const struct glsl_type *type, 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state, YYLTYPE *loc) 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From GLSL 1.50 spec, page 57: 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The arithmetic unary operators negate (-), post- and pre-increment 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and decrement (-- and ++) operate on integer or floating-point 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * values (including vectors and matrices). All unary operators work 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * component-wise on their operands. These result with the same type 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * they operated on." 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!type->is_numeric()) { 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "Operands to arithmetic operators must be numeric"); 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type; 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \brief Return the result type of a bit-logic operation. 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If the given types to the bit-logic operator are invalid, return 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * glsl_type::error_type. 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param type_a Type of LHS of bit-logic op 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param type_b Type of RHS of bit-logic op 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glsl_type * 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbit_logic_result_type(const struct glsl_type *type_a, 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct glsl_type *type_b, 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ast_operators op, 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state, YYLTYPE *loc) 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->language_version < 130) { 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "bit operations require GLSL 1.30"); 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 50 (page 56 of PDF) of GLSL 1.30 spec: 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The bitwise operators and (&), exclusive-or (^), and inclusive-or 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (|). The operands must be of type signed or unsigned integers or 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * integer vectors." 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!type_a->is_integer()) { 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "LHS of `%s' must be an integer", 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ast_expression::operator_string(op)); 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!type_b->is_integer()) { 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "RHS of `%s' must be an integer", 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ast_expression::operator_string(op)); 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "The fundamental types of the operands (signed or unsigned) must 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * match," 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a->base_type != type_b->base_type) { 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "operands of `%s' must have the same " 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "base type", ast_expression::operator_string(op)); 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "The operands cannot be vectors of differing size." */ 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a->is_vector() && 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_b->is_vector() && 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_a->vector_elements != type_b->vector_elements) { 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "operands of `%s' cannot be vectors of " 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "different sizes", ast_expression::operator_string(op)); 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "If one operand is a scalar and the other a vector, the scalar is 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * applied component-wise to the vector, resulting in the same type as 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the vector. The fundamental types of the operands [...] will be the 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * resulting fundamental type." 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a->is_scalar()) 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type_b; 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type_a; 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glsl_type * 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgmodulus_result_type(const struct glsl_type *type_a, 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct glsl_type *type_b, 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state, YYLTYPE *loc) 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->language_version < 130) { 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "operator '%%' is reserved in %s", 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->version_string); 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From GLSL 1.50 spec, page 56: 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The operator modulus (%) operates on signed or unsigned integers or 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * integer vectors. The operand types must both be signed or both be 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * unsigned." 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!type_a->is_integer()) { 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "LHS of operator %% must be an integer."); 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!type_b->is_integer()) { 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "RHS of operator %% must be an integer."); 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a->base_type != type_b->base_type) { 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "operands of %% must have the same base type"); 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "The operands cannot be vectors of differing size. If one operand is 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a scalar and the other vector, then the scalar is applied component- 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * wise to the vector, resulting in the same type as the vector. If both 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * are vectors of the same size, the result is computed component-wise." 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a->is_vector()) { 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!type_b->is_vector() 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || (type_a->vector_elements == type_b->vector_elements)) 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type_a; 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type_b; 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "The operator modulus (%) is not defined for any other data types 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (non-integer types)." 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "type mismatch"); 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glsl_type * 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgrelational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state, YYLTYPE *loc) 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *type_a = value_a->type; 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *type_b = value_b->type; 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From GLSL 1.50 spec, page 56: 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The relational operators greater than (>), less than (<), greater 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * than or equal (>=), and less than or equal (<=) operate only on 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * scalar integer and scalar floating-point expressions." 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!type_a->is_numeric() 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || !type_b->is_numeric() 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || !type_a->is_scalar() 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || !type_b->is_scalar()) { 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "Operands to relational operators must be scalar and " 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "numeric"); 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "Either the operands' types must match, or the conversions from 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Section 4.1.10 "Implicit Conversions" will be applied to the integer 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * operand, after which the types must match." 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!apply_implicit_conversion(type_a, value_b, state) 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !apply_implicit_conversion(type_b, value_a, state)) { 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "Could not implicitly convert operands to " 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "relational operator"); 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_a = value_a->type; 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_b = value_b->type; 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a->base_type != type_b->base_type) { 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "base type mismatch"); 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "The result is scalar Boolean." 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::bool_type; 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \brief Return the result type of a bit-shift operation. 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If the given types to the bit-shift operator are invalid, return 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * glsl_type::error_type. 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param type_a Type of LHS of bit-shift op 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param type_b Type of RHS of bit-shift op 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct glsl_type * 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgshift_result_type(const struct glsl_type *type_a, 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct glsl_type *type_b, 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ast_operators op, 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state, YYLTYPE *loc) 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->language_version < 130) { 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "bit operations require GLSL 1.30"); 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 50 (page 56 of the PDF) of the GLSL 1.30 spec: 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The shift operators (<<) and (>>). For both operators, the operands 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * must be signed or unsigned integers or integer vectors. One operand 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * can be signed while the other is unsigned." 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!type_a->is_integer()) { 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "LHS of operator %s must be an integer or " 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "integer vector", ast_expression::operator_string(op)); 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!type_b->is_integer()) { 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "RHS of operator %s must be an integer or " 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "integer vector", ast_expression::operator_string(op)); 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "If the first operand is a scalar, the second operand has to be 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a scalar as well." 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a->is_scalar() && !type_b->is_scalar()) { 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "If the first operand of %s is scalar, the " 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "second must be scalar as well", 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ast_expression::operator_string(op)); 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If both operands are vectors, check that they have same number of 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * elements. 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_a->is_vector() && 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_b->is_vector() && 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_a->vector_elements != type_b->vector_elements) { 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "Vector operands to operator %s must " 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "have same number of elements", 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ast_expression::operator_string(op)); 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "In all cases, the resulting type will be the same type as the left 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * operand." 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type_a; 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Validates that a value can be assigned to a location with a specified type 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Validates that \c rhs can be assigned to some location. If the types are 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * not an exact match but an automatic conversion is possible, \c rhs will be 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * converted. 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \c NULL if \c rhs cannot be assigned to a location with type \c lhs_type. 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Otherwise the actual RHS to be assigned will be returned. This may be 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \c rhs, or it may be \c rhs after some type conversion. 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \note 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In addition to being used for assignments, this function is used to 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * type-check return values. 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvalidate_assignment(struct _mesa_glsl_parse_state *state, 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *lhs_type, ir_rvalue *rhs, 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool is_initializer) 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If there is already some error in the RHS, just return it. Anything 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * else will lead to an avalanche of error message back to the user. 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rhs->type->is_error()) 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return rhs; 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If the types are identical, the assignment can trivially proceed. 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rhs->type == lhs_type) 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return rhs; 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If the array element types are the same and the size of the LHS is zero, 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the assignment is okay for initializers embedded in variable 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * declarations. 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note: Whole-array assignments are not permitted in GLSL 1.10, but this 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is handled by ir_dereference::is_lvalue. 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (is_initializer && lhs_type->is_array() && rhs->type->is_array() 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && (lhs_type->element_type() == rhs->type->element_type()) 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && (lhs_type->array_size() == 0)) { 649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return rhs; 650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Check for implicit conversion in GLSL 1.20 */ 653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (apply_implicit_conversion(lhs_type, rhs, state)) { 654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rhs->type == lhs_type) 655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return rhs; 656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgmark_whole_array_access(ir_rvalue *access) 663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *deref = access->as_dereference_variable(); 665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (deref && deref->var) { 667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org deref->var->max_array_access = deref->type->length - 1; 668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdo_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, 673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *non_lvalue_description, 674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *lhs, ir_rvalue *rhs, bool is_initializer, 675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE lhs_loc) 676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ctx = state; 678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool error_emitted = (lhs->type->is_error() || rhs->type->is_error()); 679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *lhs_var = lhs->variable_referenced(); 681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lhs_var) 682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lhs_var->assigned = true; 683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!error_emitted) { 685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (non_lvalue_description != NULL) { 686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&lhs_loc, state, 687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "assignment to %s", 688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org non_lvalue_description); 689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (lhs->variable_referenced() != NULL 691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && lhs->variable_referenced()->read_only) { 692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&lhs_loc, state, 693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "assignment to read-only variable '%s'", 694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lhs->variable_referenced()->name); 695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (state->language_version <= 110 && lhs->type->is_array()) { 698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 32 (page 38 of the PDF) of the GLSL 1.10 spec: 699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Other binary or unary expressions, non-dereferenced 701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * arrays, function names, swizzles with repeated fields, 702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and constants cannot be l-values." 703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&lhs_loc, state, "whole array assignment is not " 705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "allowed in GLSL 1.10 or GLSL ES 1.00."); 706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (!lhs->is_lvalue()) { 708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment"); 709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *new_rhs = 714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org validate_assignment(state, lhs->type, rhs, is_initializer); 715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (new_rhs == NULL) { 716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& lhs_loc, state, "type mismatch"); 717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rhs = new_rhs; 719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If the LHS array was not declared with a size, it takes it size from 721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the RHS. If the LHS is an l-value and a whole array, it must be a 722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * dereference of a variable. Any other case would require that the LHS 723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is either not an l-value or not a whole array. 724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lhs->type->array_size() == 0) { 726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference *const d = lhs->as_dereference(); 727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(d != NULL); 729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *const var = d->variable_referenced(); 731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(var != NULL); 733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var->max_array_access >= unsigned(rhs->type->array_size())) { 735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* FINISHME: This should actually log the location of the RHS. */ 736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& lhs_loc, state, "array size must be > %u due to " 737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "previous access", 738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->max_array_access); 739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->type = glsl_type::get_array_instance(lhs->type->element_type(), 742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rhs->type->array_size()); 743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d->type = var->type; 744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mark_whole_array_access(rhs); 746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mark_whole_array_access(lhs); 747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Most callers of do_assignment (assign, add_assign, pre_inc/dec, 750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * but not post_inc) need the converted assigned value as an rvalue 751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to handle things like: 752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * i = j += 1; 754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * So we always just store the computed value being assigned to a 756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * temporary and return a deref of that temporary. If the rvalue 757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ends up not being used, the temp will get copy-propagated out. 758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp", 760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_var_temporary); 761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var); 762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(var); 763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(new(ctx) ir_assignment(deref_var, rhs)); 764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org deref_var = new(ctx) ir_dereference_variable(var); 765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!error_emitted) 767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var)); 768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(ctx) ir_dereference_variable(var); 770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic ir_rvalue * 773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue) 774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ctx = ralloc_parent(lvalue); 776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *var; 777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp", 779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_var_temporary); 780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(var); 781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->mode = ir_var_auto; 782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var), 784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lvalue)); 785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(ctx) ir_dereference_variable(var); 787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_node::hir(exec_list *instructions, 792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void) instructions; 795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void) state; 796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic ir_rvalue * 801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdo_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1) 802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int join_op; 804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *cmp = NULL; 805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (operation == ir_binop_all_equal) 807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org join_op = ir_binop_logic_and; 808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org join_op = ir_binop_logic_or; 810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (op0->type->base_type) { 812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_FLOAT: 813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_UINT: 814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_INT: 815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_BOOL: 816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(mem_ctx) ir_expression(operation, op0, op1); 817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_ARRAY: { 819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned int i = 0; i < op0->type->length; i++) { 820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *e0, *e1, *result; 821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org e0 = new(mem_ctx) ir_dereference_array(op0->clone(mem_ctx, NULL), 823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(mem_ctx) ir_constant(i)); 824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org e1 = new(mem_ctx) ir_dereference_array(op1->clone(mem_ctx, NULL), 825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(mem_ctx) ir_constant(i)); 826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = do_comparison(mem_ctx, operation, e0, e1); 827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cmp) { 829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmp = new(mem_ctx) ir_expression(join_op, cmp, result); 830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmp = result; 832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mark_whole_array_access(op0); 836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mark_whole_array_access(op1); 837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_STRUCT: { 841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned int i = 0; i < op0->type->length; i++) { 842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *e0, *e1, *result; 843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *field_name = op0->type->fields.structure[i].name; 844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org e0 = new(mem_ctx) ir_dereference_record(op0->clone(mem_ctx, NULL), 846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org field_name); 847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org e1 = new(mem_ctx) ir_dereference_record(op1->clone(mem_ctx, NULL), 848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org field_name); 849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = do_comparison(mem_ctx, operation, e0, e1); 850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cmp) { 852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmp = new(mem_ctx) ir_expression(join_op, cmp, result); 853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmp = result; 855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_ERROR: 861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_VOID: 862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_SAMPLER: 863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* I assume a comparison of a struct containing a sampler just 864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ignores the sampler present in the type. 865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"Should not get here."); 870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cmp == NULL) 874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cmp = new(mem_ctx) ir_constant(true); 875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return cmp; 877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* For logical operations, we want to ensure that the operands are 880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * scalar booleans. If it isn't, emit an error and return a constant 881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * boolean to avoid triggering cascading error messages. 882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_scalar_boolean_operand(exec_list *instructions, 885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state, 886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ast_expression *parent_expr, 887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int operand, 888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *operand_name, 889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool *error_emitted) 890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ast_expression *expr = parent_expr->subexpressions[operand]; 892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ctx = state; 893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *val = expr->hir(instructions, state); 894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (val->type->is_boolean() && val->type->is_scalar()) 896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return val; 897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!*error_emitted) { 899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = expr->get_location(); 900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "%s of `%s' must be scalar boolean", 901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org operand_name, 902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org parent_expr->operator_string(parent_expr->oper)); 903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *error_emitted = true; 904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(ctx) ir_constant(true); 907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If name refers to a builtin array whose maximum allowed size is less than 911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * size, report an error and return true. Otherwise return false. 912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic bool 914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcheck_builtin_array_max_size(const char *name, unsigned size, 915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc, struct _mesa_glsl_parse_state *state) 916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((strcmp("gl_TexCoord", name) == 0) 918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && (size > state->Const.MaxTextureCoords)) { 919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec: 920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The size [of gl_TexCoord] can be at most 922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * gl_MaxTextureCoords." 923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "`gl_TexCoord' array size cannot " 925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "be larger than gl_MaxTextureCoords (%u)\n", 926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->Const.MaxTextureCoords); 927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (strcmp("gl_ClipDistance", name) == 0 929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && size > state->Const.MaxClipPlanes) { 930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From section 7.1 (Vertex Shader Special Variables) of the 931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GLSL 1.30 spec: 932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The gl_ClipDistance array is predeclared as unsized and 934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * must be sized by the shader either redeclaring it with a 935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * size or indexing it only with integral constant 936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * expressions. ... The size can be at most 937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * gl_MaxClipDistances." 938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "`gl_ClipDistance' array size cannot " 940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "be larger than gl_MaxClipDistances (%u)\n", 941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->Const.MaxClipPlanes); 942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Create the constant 1, of a which is appropriate for incrementing and 949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * decrementing values of the given GLSL type. For example, if type is vec4, 950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * this creates a constant value of 1.0 having type float. 951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If the given type is invalid for increment and decrement operators, return 953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a floating point 1--the error will be detected later. 954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic ir_rvalue * 956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconstant_one_for_inc_dec(void *ctx, const glsl_type *type) 957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (type->base_type) { 959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_UINT: 960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(ctx) ir_constant((unsigned) 1); 961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_INT: 962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(ctx) ir_constant(1); 963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_FLOAT: 965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new(ctx) ir_constant(1.0f); 966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_expression::hir(exec_list *instructions, 971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ctx = state; 974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static const int operations[AST_NUM_OPERATORS] = { 975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org -1, /* ast_assign doesn't convert to ir_expression. */ 976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org -1, /* ast_plus doesn't convert to ir_expression. */ 977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_unop_neg, 978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_add, 979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_sub, 980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_mul, 981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_div, 982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_mod, 983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_lshift, 984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_rshift, 985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_less, 986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_greater, 987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_lequal, 988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_gequal, 989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_all_equal, 990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_any_nequal, 991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_bit_and, 992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_bit_xor, 993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_bit_or, 994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_unop_bit_not, 995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_logic_and, 996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_logic_xor, 997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_logic_or, 998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_unop_logic_not, 999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Note: The following block of expression types actually convert 1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to multiple IR instructions. 1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_mul, /* ast_mul_assign */ 1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_div, /* ast_div_assign */ 1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_mod, /* ast_mod_assign */ 1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_add, /* ast_add_assign */ 1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_sub, /* ast_sub_assign */ 1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_lshift, /* ast_ls_assign */ 1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_rshift, /* ast_rs_assign */ 1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_bit_and, /* ast_and_assign */ 1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_bit_xor, /* ast_xor_assign */ 1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_bit_or, /* ast_or_assign */ 1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org -1, /* ast_conditional doesn't convert to ir_expression. */ 1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_add, /* ast_pre_inc. */ 1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_sub, /* ast_pre_dec. */ 1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_add, /* ast_post_inc. */ 1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_binop_sub, /* ast_post_dec. */ 1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org -1, /* ast_field_selection doesn't conv to ir_expression. */ 1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org -1, /* ast_array_index doesn't convert to ir_expression. */ 1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org -1, /* ast_function_call doesn't conv to ir_expression. */ 1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org -1, /* ast_identifier doesn't convert to ir_expression. */ 1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org -1, /* ast_int_constant doesn't convert to ir_expression. */ 1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org -1, /* ast_uint_constant doesn't conv to ir_expression. */ 1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org -1, /* ast_float_constant doesn't conv to ir_expression. */ 1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org -1, /* ast_bool_constant doesn't conv to ir_expression. */ 1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org -1, /* ast_sequence doesn't convert to ir_expression. */ 1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org }; 1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *result = NULL; 1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *op[3]; 1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct glsl_type *type; /* a temporary variable for switch cases */ 1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool error_emitted = false; 1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc; 1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loc = this->get_location(); 1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (this->oper) { 1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_assign: { 1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = this->subexpressions[0]->hir(instructions, state); 1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = this->subexpressions[1]->hir(instructions, state); 1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = do_assignment(instructions, state, 1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->subexpressions[0]->non_lvalue_description, 1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0], op[1], false, 1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->subexpressions[0]->get_location()); 1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = result->type->is_error(); 1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_plus: 1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = this->subexpressions[0]->hir(instructions, state); 1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = unary_arithmetic_result_type(op[0]->type, state, & loc); 1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = type->is_error(); 1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = op[0]; 1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_neg: 1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = this->subexpressions[0]->hir(instructions, state); 1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = unary_arithmetic_result_type(op[0]->type, state, & loc); 1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = type->is_error(); 1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_expression(operations[this->oper], type, 1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0], NULL); 1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_add: 1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_sub: 1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_mul: 1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_div: 1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = this->subexpressions[0]->hir(instructions, state); 1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = this->subexpressions[1]->hir(instructions, state); 1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = arithmetic_result_type(op[0], op[1], 1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (this->oper == ast_mul), 1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state, & loc); 1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = type->is_error(); 1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_expression(operations[this->oper], type, 1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0], op[1]); 1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_mod: 1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = this->subexpressions[0]->hir(instructions, state); 1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = this->subexpressions[1]->hir(instructions, state); 1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = modulus_result_type(op[0]->type, op[1]->type, state, & loc); 1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(operations[this->oper] == ir_binop_mod); 1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_expression(operations[this->oper], type, 1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0], op[1]); 1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = type->is_error(); 1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_lshift: 1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_rshift: 1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->language_version < 130) { 1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "operator %s requires GLSL 1.30", 1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org operator_string(this->oper)); 1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = this->subexpressions[0]->hir(instructions, state); 1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = this->subexpressions[1]->hir(instructions, state); 1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = shift_result_type(op[0]->type, op[1]->type, this->oper, state, 1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &loc); 1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_expression(operations[this->oper], type, 1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0], op[1]); 1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); 1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_less: 1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_greater: 1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_lequal: 1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_gequal: 1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = this->subexpressions[0]->hir(instructions, state); 1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = this->subexpressions[1]->hir(instructions, state); 1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = relational_result_type(op[0], op[1], state, & loc); 1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The relational operators must either generate an error or result 1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in a scalar boolean. See page 57 of the GLSL 1.50 spec. 1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(type->is_error() 1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || ((type->base_type == GLSL_TYPE_BOOL) 1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && type->is_scalar())); 1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_expression(operations[this->oper], type, 1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0], op[1]); 1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = type->is_error(); 1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_nequal: 1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_equal: 1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = this->subexpressions[0]->hir(instructions, state); 1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = this->subexpressions[1]->hir(instructions, state); 1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 58 (page 64 of the PDF) of the GLSL 1.50 spec: 1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The equality operators equal (==), and not equal (!=) 1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * operate on all types. They result in a scalar Boolean. If 1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the operand types do not match, then there must be a 1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * conversion from Section 4.1.10 "Implicit Conversions" 1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * applied to one operand that can make them match, in which 1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * case this conversion is done." 1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((!apply_implicit_conversion(op[0]->type, op[1], state) 1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !apply_implicit_conversion(op[1]->type, op[0], state)) 1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || (op[0]->type != op[1]->type)) { 1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "operands of `%s' must have the same " 1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "type", (this->oper == ast_equal) ? "==" : "!="); 1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if ((state->language_version <= 110) 1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && (op[0]->type->is_array() || op[1]->type->is_array())) { 1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "array comparisons forbidden in " 1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "GLSL 1.10"); 1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (error_emitted) { 1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_constant(false); 1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = do_comparison(ctx, operations[this->oper], op[0], op[1]); 1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(result->type == glsl_type::bool_type); 1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_bit_and: 1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_bit_xor: 1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_bit_or: 1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = this->subexpressions[0]->hir(instructions, state); 1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = this->subexpressions[1]->hir(instructions, state); 1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = bit_logic_result_type(op[0]->type, op[1]->type, this->oper, 1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state, &loc); 1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_expression(operations[this->oper], type, 1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0], op[1]); 1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); 1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_bit_not: 1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = this->subexpressions[0]->hir(instructions, state); 1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->language_version < 130) { 1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "bit-wise operations require GLSL 1.30"); 1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!op[0]->type->is_integer()) { 1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "operand of `~' must be an integer"); 1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = error_emitted ? glsl_type::error_type : op[0]->type; 1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_expression(ir_unop_bit_not, type, op[0], NULL); 1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_logic_and: { 1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list rhs_instructions; 1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = get_scalar_boolean_operand(instructions, state, this, 0, 1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "LHS", &error_emitted); 1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1, 1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "RHS", &error_emitted); 1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rhs_instructions.is_empty()) { 1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_expression(ir_binop_logic_and, op[0], op[1]); 1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = result->type; 1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, 1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "and_tmp", 1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_var_temporary); 1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(tmp); 1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_if *const stmt = new(ctx) ir_if(op[0]); 1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(stmt); 1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stmt->then_instructions.append_list(&rhs_instructions); 1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); 1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_assignment *const then_assign = 1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_assignment(then_deref, op[1]); 1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stmt->then_instructions.push_tail(then_assign); 1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp); 1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_assignment *const else_assign = 1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false)); 1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stmt->else_instructions.push_tail(else_assign); 1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_dereference_variable(tmp); 1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = tmp->type; 1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_logic_or: { 1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list rhs_instructions; 1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = get_scalar_boolean_operand(instructions, state, this, 0, 1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "LHS", &error_emitted); 1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1, 1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "RHS", &error_emitted); 1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rhs_instructions.is_empty()) { 1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_expression(ir_binop_logic_or, op[0], op[1]); 1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = result->type; 1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, 1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "or_tmp", 1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_var_temporary); 1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(tmp); 1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_if *const stmt = new(ctx) ir_if(op[0]); 1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(stmt); 1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); 1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_assignment *const then_assign = 1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true)); 1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stmt->then_instructions.push_tail(then_assign); 1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stmt->else_instructions.append_list(&rhs_instructions); 1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp); 1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_assignment *const else_assign = 1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_assignment(else_deref, op[1]); 1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stmt->else_instructions.push_tail(else_assign); 1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_dereference_variable(tmp); 1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = tmp->type; 1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_logic_xor: 1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec: 1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The logical binary operators and (&&), or ( | | ), and 1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * exclusive or (^^). They operate only on two Boolean 1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * expressions and result in a Boolean expression." 1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = get_scalar_boolean_operand(instructions, state, this, 0, "LHS", 1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &error_emitted); 1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = get_scalar_boolean_operand(instructions, state, this, 1, "RHS", 1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &error_emitted); 1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type, 1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0], op[1]); 1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_logic_not: 1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = get_scalar_boolean_operand(instructions, state, this, 0, 1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "operand", &error_emitted); 1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type, 1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0], NULL); 1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_mul_assign: 1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_div_assign: 1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_add_assign: 1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_sub_assign: { 1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = this->subexpressions[0]->hir(instructions, state); 1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = this->subexpressions[1]->hir(instructions, state); 1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = arithmetic_result_type(op[0], op[1], 1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (this->oper == ast_mul_assign), 1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state, & loc); 1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type, 1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0], op[1]); 1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = do_assignment(instructions, state, 1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->subexpressions[0]->non_lvalue_description, 1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0]->clone(ctx, NULL), temp_rhs, false, 1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->subexpressions[0]->get_location()); 1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = (op[0]->type->is_error()); 1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* GLSL 1.10 does not allow array assignment. However, we don't have to 1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * explicitly test for this because none of the binary expression 1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * operators allow array operands either. 1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_mod_assign: { 1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = this->subexpressions[0]->hir(instructions, state); 1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = this->subexpressions[1]->hir(instructions, state); 1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = modulus_result_type(op[0]->type, op[1]->type, state, & loc); 1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(operations[this->oper] == ir_binop_mod); 1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *temp_rhs; 1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp_rhs = new(ctx) ir_expression(operations[this->oper], type, 1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0], op[1]); 1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = do_assignment(instructions, state, 1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->subexpressions[0]->non_lvalue_description, 1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0]->clone(ctx, NULL), temp_rhs, false, 1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->subexpressions[0]->get_location()); 1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = type->is_error(); 1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_ls_assign: 1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_rs_assign: { 1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = this->subexpressions[0]->hir(instructions, state); 1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = this->subexpressions[1]->hir(instructions, state); 1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = shift_result_type(op[0]->type, op[1]->type, this->oper, state, 1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &loc); 1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], 1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type, op[0], op[1]); 1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = do_assignment(instructions, state, 1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->subexpressions[0]->non_lvalue_description, 1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0]->clone(ctx, NULL), temp_rhs, false, 1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->subexpressions[0]->get_location()); 1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); 1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_and_assign: 1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_xor_assign: 1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_or_assign: { 1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = this->subexpressions[0]->hir(instructions, state); 1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = this->subexpressions[1]->hir(instructions, state); 1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = bit_logic_result_type(op[0]->type, op[1]->type, this->oper, 1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state, &loc); 1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], 1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type, op[0], op[1]); 1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = do_assignment(instructions, state, 1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->subexpressions[0]->non_lvalue_description, 1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0]->clone(ctx, NULL), temp_rhs, false, 1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->subexpressions[0]->get_location()); 1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); 1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_conditional: { 1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec: 1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The ternary selection operator (?:). It operates on three 1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * expressions (exp1 ? exp2 : exp3). This operator evaluates the 1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * first expression, which must result in a scalar Boolean." 1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = get_scalar_boolean_operand(instructions, state, this, 0, 1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "condition", &error_emitted); 1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The :? operator is implemented by generating an anonymous temporary 1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * followed by an if-statement. The last instruction in each branch of 1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the if-statement assigns a value to the anonymous temporary. This 1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * temporary is the r-value of the expression. 1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list then_instructions; 1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list else_instructions; 1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = this->subexpressions[1]->hir(&then_instructions, state); 1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[2] = this->subexpressions[2]->hir(&else_instructions, state); 1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec: 1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The second and third expressions can be any type, as 1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * long their types match, or there is a conversion in 1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Section 4.1.10 "Implicit Conversions" that can be applied 1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to one of the expressions to make their types match. This 1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * resulting matching type is the type of the entire 1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * expression." 1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((!apply_implicit_conversion(op[1]->type, op[2], state) 1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !apply_implicit_conversion(op[2]->type, op[1], state)) 1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || (op[1]->type != op[2]->type)) { 1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->subexpressions[1]->get_location(); 1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "Second and third operands of ?: " 1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "operator must have matching types."); 1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = glsl_type::error_type; 1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = op[1]->type; 1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec: 1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The second and third expressions must be the same type, but can 1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * be of any type other than an array." 1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((state->language_version <= 110) && type->is_array()) { 1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "Second and third operands of ?: " 1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "operator must not be arrays."); 1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant *cond_val = op[0]->constant_expression_value(); 1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant *then_val = op[1]->constant_expression_value(); 1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant *else_val = op[2]->constant_expression_value(); 1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (then_instructions.is_empty() 1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && else_instructions.is_empty() 1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && (cond_val != NULL) && (then_val != NULL) && (else_val != NULL)) { 1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = (cond_val->value.b[0]) ? then_val : else_val; 1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *const tmp = 1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary); 1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(tmp); 1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_if *const stmt = new(ctx) ir_if(op[0]); 1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(stmt); 1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org then_instructions.move_nodes_to(& stmt->then_instructions); 1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference *const then_deref = 1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_dereference_variable(tmp); 1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_assignment *const then_assign = 1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_assignment(then_deref, op[1]); 1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stmt->then_instructions.push_tail(then_assign); 1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else_instructions.move_nodes_to(& stmt->else_instructions); 1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference *const else_deref = 1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_dereference_variable(tmp); 1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_assignment *const else_assign = 1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_assignment(else_deref, op[2]); 1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stmt->else_instructions.push_tail(else_assign); 1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_dereference_variable(tmp); 1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_pre_inc: 1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_pre_dec: { 1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->non_lvalue_description = (this->oper == ast_pre_inc) 1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ? "pre-increment operation" : "pre-decrement operation"; 1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = this->subexpressions[0]->hir(instructions, state); 1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = constant_one_for_inc_dec(ctx, op[0]->type); 1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = arithmetic_result_type(op[0], op[1], false, state, & loc); 1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *temp_rhs; 1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp_rhs = new(ctx) ir_expression(operations[this->oper], type, 1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0], op[1]); 1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = do_assignment(instructions, state, 1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->subexpressions[0]->non_lvalue_description, 1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0]->clone(ctx, NULL), temp_rhs, false, 1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->subexpressions[0]->get_location()); 1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = op[0]->type->is_error(); 1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_post_inc: 1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_post_dec: { 1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->non_lvalue_description = (this->oper == ast_post_inc) 1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ? "post-increment operation" : "post-decrement operation"; 1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = this->subexpressions[0]->hir(instructions, state); 1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = constant_one_for_inc_dec(ctx, op[0]->type); 1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); 1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = arithmetic_result_type(op[0], op[1], false, state, & loc); 1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *temp_rhs; 1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp_rhs = new(ctx) ir_expression(operations[this->oper], type, 1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0], op[1]); 1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Get a temporary of a copy of the lvalue before it's modified. 1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This may get thrown away later. 1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = get_lvalue_copy(instructions, op[0]->clone(ctx, NULL)); 1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void)do_assignment(instructions, state, 1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->subexpressions[0]->non_lvalue_description, 1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0]->clone(ctx, NULL), temp_rhs, false, 1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->subexpressions[0]->get_location()); 1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = op[0]->type->is_error(); 1516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_field_selection: 1520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = _mesa_ast_field_selection_to_hir(this, instructions, state); 1521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_array_index: { 1524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE index_loc = subexpressions[1]->get_location(); 1525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = subexpressions[0]->hir(instructions, state); 1527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[1] = subexpressions[1]->hir(instructions, state); 1528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); 1530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *const array = op[0]; 1532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_dereference_array(op[0], op[1]); 1534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Do not use op[0] after this point. Use array. 1536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0] = NULL; 1538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (error_emitted) 1541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!array->type->is_array() 1544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !array->type->is_matrix() 1545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !array->type->is_vector()) { 1546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& index_loc, state, 1547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "cannot dereference non-array / non-matrix / " 1548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "non-vector"); 1549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 1550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!op[1]->type->is_integer()) { 1553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& index_loc, state, 1554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "array index must be integer type"); 1555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 1556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (!op[1]->type->is_scalar()) { 1557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& index_loc, state, 1558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "array index must be scalar"); 1559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 1560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If the array index is a constant expression and the array has a 1563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * declared size, ensure that the access is in-bounds. If the array 1564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * index is not a constant expression, ensure that the array has a 1565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * declared size. 1566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant *const const_index = op[1]->constant_expression_value(); 1568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (const_index != NULL) { 1569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const int idx = const_index->value.i[0]; 1570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *type_name; 1571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned bound = 0; 1572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (array->type->is_matrix()) { 1574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_name = "matrix"; 1575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (array->type->is_vector()) { 1576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_name = "vector"; 1577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_name = "array"; 1579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec: 1582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "It is illegal to declare an array with a size, and then 1584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * later (in the same shader) index the same array with an 1585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * integral constant expression greater than or equal to the 1586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * declared size. It is also illegal to index an array with a 1587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * negative constant expression." 1588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (array->type->is_matrix()) { 1590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (array->type->row_type()->vector_elements <= idx) { 1591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bound = array->type->row_type()->vector_elements; 1592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (array->type->is_vector()) { 1594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (array->type->vector_elements <= idx) { 1595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bound = array->type->vector_elements; 1596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((array->type->array_size() > 0) 1599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && (array->type->array_size() <= idx)) { 1600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bound = array->type->array_size(); 1601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (bound > 0) { 1605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "%s index must be < %u", 1606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_name, bound); 1607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 1608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (idx < 0) { 1609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "%s index must be >= 0", 1610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_name); 1611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 1612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (array->type->is_array()) { 1615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If the array is a variable dereference, it dereferences the 1616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * whole array, by definition. Use this to get the variable. 1617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FINISHME: Should some methods for getting / setting / testing 1619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FINISHME: array access limits be added to ir_dereference? 1620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *const v = array->whole_variable_referenced(); 1622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((v != NULL) && (unsigned(idx) > v->max_array_access)) { 1623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->max_array_access = idx; 1624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Check whether this access will, as a side effect, implicitly 1626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * cause the size of a built-in array to be too large. 1627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (check_builtin_array_max_size(v->name, idx+1, loc, state)) 1629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 1630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (array->type->array_size() == 0) { 1633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "unsized array index must be constant"); 1634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (array->type->is_array()) { 1636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* whole_variable_referenced can return NULL if the array is a 1637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * member of a structure. In this case it is safe to not update 1638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the max_array_access field because it is never used for fields 1639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of structures. 1640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *v = array->whole_variable_referenced(); 1642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (v != NULL) 1643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->max_array_access = array->type->array_size() - 1; 1644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 23 (29 of the PDF) of the GLSL 1.30 spec: 1648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Samplers aggregated into arrays within a shader (using square 1650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * brackets [ ]) can only be indexed with integral constant 1651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * expressions [...]." 1652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This restriction was added in GLSL 1.30. Shaders using earlier version 1654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the language should not be rejected by the compiler front-end for 1655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * using this construct. This allows useful things such as using a loop 1656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * counter as the index to an array of samplers. If the loop in unrolled, 1657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the code should compile correctly. Instead, emit a warning. 1658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (array->type->is_array() && 1660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org array->type->element_type()->is_sampler() && 1661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const_index == NULL) { 1662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->language_version == 100) { 1664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_warning(&loc, state, 1665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "sampler arrays indexed with non-constant " 1666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "expressions is optional in GLSL ES 1.00"); 1667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (state->language_version < 130) { 1668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_warning(&loc, state, 1669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "sampler arrays indexed with non-constant " 1670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "expressions is forbidden in GLSL 1.30 and " 1671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "later"); 1672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 1674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "sampler arrays indexed with non-constant " 1675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "expressions is forbidden in GLSL 1.30 and " 1676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "later"); 1677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 1678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (error_emitted) 1682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result->type = glsl_type::error_type; 1683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_function_call: 1688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Should *NEVER* get here. ast_function_call should always be handled 1689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * by ast_function_expression::hir. 1690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 1692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_identifier: { 1695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* ast_identifier can appear several places in a full abstract syntax 1696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * tree. This particular use must be at location specified in the grammar 1697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * as 'variable_identifier'. 1698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *var = 1700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->get_variable(this->primary_expression.identifier); 1701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var != NULL) { 1703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->used = true; 1704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_dereference_variable(var); 1705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "`%s' undeclared", 1707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->primary_expression.identifier); 1708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = ir_rvalue::error_value(ctx); 1710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 1711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_int_constant: 1716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_constant(this->primary_expression.int_constant); 1717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_uint_constant: 1720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_constant(this->primary_expression.uint_constant); 1721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_float_constant: 1724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_constant(this->primary_expression.float_constant); 1725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_bool_constant: 1728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant)); 1729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_sequence: { 1732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* It should not be possible to generate a sequence in the AST without 1733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * any expressions in it. 1734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!this->expressions.is_empty()); 1736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The r-value of a sequence is the last expression in the sequence. If 1738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the other expressions in the sequence do not have side-effects (and 1739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * therefore add instructions to the instruction list), they get dropped 1740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * on the floor. 1741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_node *previous_tail_pred = NULL; 1743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE previous_operand_loc = loc; 1744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_typed (ast_node, ast, link, &this->expressions) { 1746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If one of the operands of comma operator does not generate any 1747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * code, we want to emit a warning. At each pass through the loop 1748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * previous_tail_pred will point to the last instruction in the 1749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * stream *before* processing the previous operand. Naturally, 1750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instructions->tail_pred will point to the last instruction in the 1751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * stream *after* processing the previous operand. If the two 1752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pointers match, then the previous operand had no effect. 1753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The warning behavior here differs slightly from GCC. GCC will 1755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * only emit a warning if none of the left-hand operands have an 1756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * effect. However, it will emit a warning for each. I believe that 1757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * there are some cases in C (especially with GCC extensions) where 1758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * it is useful to have an intermediate step in a sequence have no 1759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * effect, but I don't think these cases exist in GLSL. Either way, 1760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * it would be a giant hassle to replicate that behavior. 1761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (previous_tail_pred == instructions->tail_pred) { 1763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_warning(&previous_operand_loc, state, 1764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "left-hand operand of comma expression has " 1765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "no effect"); 1766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* tail_pred is directly accessed instead of using the get_tail() 1769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * method for performance reasons. get_tail() has extra code to 1770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * return NULL when the list is empty. We don't care about that 1771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * here, so using tail_pred directly is fine. 1772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org previous_tail_pred = instructions->tail_pred; 1774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org previous_operand_loc = ast->get_location(); 1775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = ast->hir(instructions, state); 1777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Any errors should have already been emitted in the loop above. 1780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 1782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = NULL; /* use result->type, not type. */ 1786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(result != NULL); 1787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (result->type->is_error() && !error_emitted) 1789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "type mismatch"); 1790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return result; 1792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 1796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_expression_statement::hir(exec_list *instructions, 1797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 1798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* It is possible to have expression statements that don't have an 1800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * expression. This is the solitary semicolon: 1801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * for (i = 0; i < 5; i++) 1803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ; 1804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In this case the expression will be NULL. Test for NULL and don't do 1806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * anything in that case. 1807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (expression != NULL) 1809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org expression->hir(instructions, state); 1810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Statements do not have r-values. 1812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 1814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 1818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_compound_statement::hir(exec_list *instructions, 1819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 1820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (new_scope) 1822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->push_scope(); 1823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_typed (ast_node, ast, link, &this->statements) 1825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ast->hir(instructions, state); 1826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (new_scope) 1828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->pop_scope(); 1829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Compound statements do not have r-values. 1831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 1833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const glsl_type * 1837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprocess_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size, 1838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 1839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned length = 0; 1841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 19 (page 25) of the GLSL 1.20 spec: 1843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Only one-dimensional arrays may be declared." 1845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (base->is_array()) { 1847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 1848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "invalid array of `%s' (only one-dimensional arrays " 1849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "may be declared)", 1850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base->name); 1851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::error_type; 1852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (array_size != NULL) { 1855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list dummy_instructions; 1856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *const ir = array_size->hir(& dummy_instructions, state); 1857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = array_size->get_location(); 1858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir != NULL) { 1860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ir->type->is_integer()) { 1861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "array size must be integer type"); 1862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (!ir->type->is_scalar()) { 1863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "array size must be scalar type"); 1864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant *const size = ir->constant_expression_value(); 1866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (size == NULL) { 1868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "array size must be a " 1869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "constant valued expression"); 1870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (size->value.i[0] <= 0) { 1871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "array size must be > 0"); 1872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(size->type == ir->type); 1874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org length = size->value.u[0]; 1875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If the array size is const (and we've verified that 1877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * it is) then no instructions should have been emitted 1878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * when we converted it to HIR. If they were emitted, 1879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * then either the array size isn't const after all, or 1880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * we are emitting unnecessary instructions. 1881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(dummy_instructions.is_empty()); 1883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (state->es_shader) { 1887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Section 10.17 of the GLSL ES 1.00 specification states that unsized 1888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * array declarations have been removed from the language. 1889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, "unsized array declarations are not " 1891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "allowed in GLSL ES 1.00."); 1892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return glsl_type::get_array_instance(base, length); 1895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst glsl_type * 1899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_type_specifier::glsl_type(const char **name, 1900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) const 1901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct glsl_type *type; 1903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = state->symbols->get_type(this->type_name); 1905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *name = this->type_name; 1906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->is_array) { 1908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 1909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = process_array_type(&loc, type, this->array_size, state); 1910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type; 1913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 1917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgapply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, 1918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *var, 1919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state, 1920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE *loc, 1921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool ubo_qualifiers_valid) 1922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qual->flags.q.invariant) { 1924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var->used) { 1925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 1926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "variable `%s' may not be redeclared " 1927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`invariant' after being used", 1928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->name); 1929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->invariant = 1; 1931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qual->flags.q.constant || qual->flags.q.attribute 1935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || qual->flags.q.uniform 1936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || (qual->flags.q.varying && (state->target == fragment_shader))) 1937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->read_only = 1; 1938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qual->flags.q.centroid) 1940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->centroid = 1; 1941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qual->flags.q.attribute && state->target != vertex_shader) { 1943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->type = glsl_type::error_type; 1944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 1945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`attribute' variables may not be declared in the " 1946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "%s shader", 1947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_shader_target_name(state->target)); 1948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 25 (page 31 of the PDF) of the GLSL 1.10 spec: 1951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The varying qualifier can be used only with the data types 1953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of 1954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * these." 1955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qual->flags.q.varying) { 1957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *non_array_type; 1958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var->type && var->type->is_array()) 1960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org non_array_type = var->type->fields.array; 1961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org non_array_type = var->type; 1963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (non_array_type && non_array_type->base_type != GLSL_TYPE_FLOAT) { 1965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->type = glsl_type::error_type; 1966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 1967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "varying variables must be of base type float"); 1968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If there is no qualifier that changes the mode of the variable, leave 1972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the setting alone. 1973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qual->flags.q.in && qual->flags.q.out) 1975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->mode = ir_var_inout; 1976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (qual->flags.q.attribute || qual->flags.q.in 1977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || (qual->flags.q.varying && (state->target == fragment_shader))) 1978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->mode = ir_var_in; 1979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (qual->flags.q.out 1980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || (qual->flags.q.varying && (state->target == vertex_shader))) 1981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->mode = ir_var_out; 1982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (qual->flags.q.uniform) 1983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->mode = ir_var_uniform; 1984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->all_invariant && (state->current_function == NULL)) { 1986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (state->target) { 1987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case vertex_shader: 1988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var->mode == ir_var_out) 1989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->invariant = true; 1990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case geometry_shader: 1992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((var->mode == ir_var_in) || (var->mode == ir_var_out)) 1993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->invariant = true; 1994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case fragment_shader: 1996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var->mode == ir_var_in) 1997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->invariant = true; 1998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qual->flags.q.flat) 2003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->interpolation = INTERP_QUALIFIER_FLAT; 2004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (qual->flags.q.noperspective) 2005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->interpolation = INTERP_QUALIFIER_NOPERSPECTIVE; 2006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (qual->flags.q.smooth) 2007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->interpolation = INTERP_QUALIFIER_SMOOTH; 2008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 2009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->interpolation = INTERP_QUALIFIER_NONE; 2010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var->interpolation != INTERP_QUALIFIER_NONE && 2012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !(state->target == vertex_shader && var->mode == ir_var_out) && 2013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !(state->target == fragment_shader && var->mode == ir_var_in)) { 2014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 2015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "interpolation qualifier `%s' can only be applied to " 2016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "vertex shader outputs and fragment shader inputs.", 2017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->interpolation_string()); 2018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->pixel_center_integer = qual->flags.q.pixel_center_integer; 2021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->origin_upper_left = qual->flags.q.origin_upper_left; 2022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((qual->flags.q.origin_upper_left || qual->flags.q.pixel_center_integer) 2023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && (strcmp(var->name, "gl_FragCoord") != 0)) { 2024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *const qual_string = (qual->flags.q.origin_upper_left) 2025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ? "origin_upper_left" : "pixel_center_integer"; 2026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 2028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "layout qualifier `%s' can only be applied to " 2029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "fragment shader input `gl_FragCoord'", 2030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qual_string); 2031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qual->flags.q.explicit_location) { 2034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const bool global_scope = (state->current_function == NULL); 2035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool fail = false; 2036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *string = ""; 2037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* In the vertex shader only shader inputs can be given explicit 2039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * locations. 2040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In the fragment shader only shader outputs can be given explicit 2042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * locations. 2043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (state->target) { 2045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case vertex_shader: 2046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!global_scope || (var->mode != ir_var_in)) { 2047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail = true; 2048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org string = "input"; 2049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case geometry_shader: 2053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 2054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "geometry shader variables cannot be given " 2055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "explicit locations\n"); 2056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case fragment_shader: 2059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!global_scope || (var->mode != ir_var_out)) { 2060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail = true; 2061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org string = "output"; 2062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org }; 2065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (fail) { 2067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 2068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "only %s shader %s variables can be given an " 2069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "explicit location\n", 2070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_shader_target_name(state->target), 2071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org string); 2072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->explicit_location = true; 2074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This bit of silliness is needed because invalid explicit locations 2076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * are supposed to be flagged during linking. Small negative values 2077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * biased by VERT_ATTRIB_GENERIC0 or FRAG_RESULT_DATA0 could alias 2078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * built-in values (e.g., -16+VERT_ATTRIB_GENERIC0 = VERT_ATTRIB_POS). 2079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The linker needs to be able to differentiate these cases. This 2080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ensures that negative values stay negative. 2081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qual->location >= 0) { 2083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->location = (state->target == vertex_shader) 2084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ? (qual->location + VERT_ATTRIB_GENERIC0) 2085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : (qual->location + FRAG_RESULT_DATA0); 2086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->location = qual->location; 2088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qual->flags.q.explicit_index) { 2091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From the GLSL 4.30 specification, section 4.4.2 (Output 2092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Layout Qualifiers): 2093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "It is also a compile-time error if a fragment shader 2095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * sets a layout index to less than 0 or greater than 1." 2096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Older specifications don't mandate a behavior; we take 2098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * this as a clarification and always generate the error. 2099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qual->index < 0 || qual->index > 1) { 2101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 2102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "explicit index may only be 0 or 1\n"); 2103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->explicit_index = true; 2105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->index = qual->index; 2106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (qual->flags.q.explicit_index) { 2110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 2111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "explicit index requires explicit location\n"); 2112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Does the declaration use the 'layout' keyword? 2115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const bool uses_layout = qual->flags.q.pixel_center_integer 2117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || qual->flags.q.origin_upper_left 2118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || qual->flags.q.explicit_location; /* no need for index since it relies on location */ 2119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Does the declaration use the deprecated 'attribute' or 'varying' 2121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * keywords? 2122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const bool uses_deprecated_qualifier = qual->flags.q.attribute 2124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || qual->flags.q.varying; 2125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Is the 'layout' keyword used with parameters that allow relaxed checking. 2127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Many implementations of GL_ARB_fragment_coord_conventions_enable and some 2128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * implementations (only Mesa?) GL_ARB_explicit_attrib_location_enable 2129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * allowed the layout qualifier to be used with 'varying' and 'attribute'. 2130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * These extensions and all following extensions that add the 'layout' 2131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * keyword have been modified to require the use of 'in' or 'out'. 2132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The following extension do not allow the deprecated keywords: 2134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GL_AMD_conservative_depth 2136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GL_ARB_conservative_depth 2137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GL_ARB_gpu_shader5 2138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GL_ARB_separate_shader_objects 2139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GL_ARB_tesselation_shader 2140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GL_ARB_transform_feedback3 2141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GL_ARB_uniform_buffer_object 2142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * It is unknown whether GL_EXT_shader_image_load_store or GL_NV_gpu_shader5 2144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * allow layout with the deprecated keywords. 2145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const bool relaxed_layout_qualifier_checking = 2147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->ARB_fragment_coord_conventions_enable; 2148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (uses_layout && uses_deprecated_qualifier) { 2150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (relaxed_layout_qualifier_checking) { 2151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_warning(loc, state, 2152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`layout' qualifier may not be used with " 2153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`attribute' or `varying'"); 2154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 2156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`layout' qualifier may not be used with " 2157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`attribute' or `varying'"); 2158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Layout qualifiers for gl_FragDepth, which are enabled by extension 2162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AMD_conservative_depth. 2163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int depth_layout_count = qual->flags.q.depth_any 2165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org + qual->flags.q.depth_greater 2166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org + qual->flags.q.depth_less 2167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org + qual->flags.q.depth_unchanged; 2168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (depth_layout_count > 0 2169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !state->AMD_conservative_depth_enable 2170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !state->ARB_conservative_depth_enable) { 2171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 2172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "extension GL_AMD_conservative_depth or " 2173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "GL_ARB_conservative_depth must be enabled " 2174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "to use depth layout qualifiers"); 2175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (depth_layout_count > 0 2176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && strcmp(var->name, "gl_FragDepth") != 0) { 2177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 2178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "depth layout qualifiers can be applied only to " 2179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "gl_FragDepth"); 2180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (depth_layout_count > 1 2181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && strcmp(var->name, "gl_FragDepth") == 0) { 2182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 2183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "at most one depth layout qualifier can be applied to " 2184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "gl_FragDepth"); 2185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qual->flags.q.depth_any) 2187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->depth_layout = ir_depth_layout_any; 2188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (qual->flags.q.depth_greater) 2189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->depth_layout = ir_depth_layout_greater; 2190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (qual->flags.q.depth_less) 2191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->depth_layout = ir_depth_layout_less; 2192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (qual->flags.q.depth_unchanged) 2193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->depth_layout = ir_depth_layout_unchanged; 2194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 2195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->depth_layout = ir_depth_layout_none; 2196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qual->flags.q.std140 || 2198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qual->flags.q.packed || 2199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qual->flags.q.shared) { 2200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 2201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "uniform block layout qualifiers std140, packed, and " 2202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "shared can only be applied to uniform blocks, not " 2203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "members"); 2204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ubo_qualifiers_valid && 2207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (qual->flags.q.row_major || qual->flags.q.column_major)) { 2208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(loc, state, 2209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "uniform block layout qualifiers row_major and " 2210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "column_major can only be applied to uniform block " 2211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "members"); 2212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 2216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Get the variable that is being redeclared by this declaration 2217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Semantic checks to verify the validity of the redeclaration are also 2219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * performed. If semantic checks fail, compilation error will be emitted via 2220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \c _mesa_glsl_error, but a non-\c NULL pointer will still be returned. 2221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \returns 2223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * A pointer to an existing variable in the current scope if the declaration 2224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is a redeclaration, \c NULL otherwise. 2225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_variable * 2227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_variable_being_redeclared(ir_variable *var, ast_declaration *decl, 2228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 2229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Check if this declaration is actually a re-declaration, either to 2231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * resize an array or add qualifiers to an existing variable. 2232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is allowed for variables in the current scope, or when at 2234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * global scope (for built-ins in the implicit outer scope). 2235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *earlier = state->symbols->get_variable(decl->identifier); 2237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (earlier == NULL || 2238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (state->current_function != NULL && 2239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !state->symbols->name_declared_this_scope(decl->identifier))) { 2240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 2241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = decl->get_location(); 2245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec, 2247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "It is legal to declare an array without a size and then 2249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * later re-declare the same name as an array of the same 2250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * type and specify a size." 2251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((earlier->type->array_size() == 0) 2253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && var->type->is_array() 2254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && (var->type->element_type() == earlier->type->element_type())) { 2255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* FINISHME: This doesn't match the qualifiers on the two 2256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FINISHME: declarations. It's not 100% clear whether this is 2257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FINISHME: required or not. 2258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned size = unsigned(var->type->array_size()); 2261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org check_builtin_array_max_size(var->name, size, loc, state); 2262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((size > 0) && (size <= earlier->max_array_access)) { 2263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "array size must be > %u due to " 2264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "previous access", 2265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org earlier->max_array_access); 2266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org earlier->type = var->type; 2269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete var; 2270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var = NULL; 2271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (state->ARB_fragment_coord_conventions_enable 2272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && strcmp(var->name, "gl_FragCoord") == 0 2273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && earlier->type == var->type 2274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && earlier->mode == var->mode) { 2275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Allow redeclaration of gl_FragCoord for ARB_fcc layout 2276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * qualifiers. 2277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org earlier->origin_upper_left = var->origin_upper_left; 2279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org earlier->pixel_center_integer = var->pixel_center_integer; 2280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* According to section 4.3.7 of the GLSL 1.30 spec, 2282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following built-in varaibles can be redeclared with an 2283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * interpolation qualifier: 2284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * * gl_FrontColor 2285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * * gl_BackColor 2286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * * gl_FrontSecondaryColor 2287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * * gl_BackSecondaryColor 2288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * * gl_Color 2289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * * gl_SecondaryColor 2290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (state->language_version >= 130 2292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && (strcmp(var->name, "gl_FrontColor") == 0 2293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || strcmp(var->name, "gl_BackColor") == 0 2294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || strcmp(var->name, "gl_FrontSecondaryColor") == 0 2295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || strcmp(var->name, "gl_BackSecondaryColor") == 0 2296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || strcmp(var->name, "gl_Color") == 0 2297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || strcmp(var->name, "gl_SecondaryColor") == 0) 2298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && earlier->type == var->type 2299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && earlier->mode == var->mode) { 2300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org earlier->interpolation = var->interpolation; 2301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Layout qualifiers for gl_FragDepth. */ 2303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if ((state->AMD_conservative_depth_enable || 2304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->ARB_conservative_depth_enable) 2305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && strcmp(var->name, "gl_FragDepth") == 0 2306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && earlier->type == var->type 2307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && earlier->mode == var->mode) { 2308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** From the AMD_conservative_depth spec: 2310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Within any shader, the first redeclarations of gl_FragDepth 2311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * must appear before any use of gl_FragDepth. 2312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (earlier->used) { 2314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 2315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "the first redeclaration of gl_FragDepth " 2316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "must appear before any use of gl_FragDepth"); 2317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Prevent inconsistent redeclaration of depth layout qualifier. */ 2320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (earlier->depth_layout != ir_depth_layout_none 2321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && earlier->depth_layout != var->depth_layout) { 2322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 2323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "gl_FragDepth: depth layout is declared here " 2324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "as '%s, but it was previously declared as " 2325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "'%s'", 2326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org depth_layout_string(var->depth_layout), 2327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org depth_layout_string(earlier->depth_layout)); 2328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org earlier->depth_layout = var->depth_layout; 2331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "`%s' redeclared", decl->identifier); 2334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return earlier; 2337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 2340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Generate the IR for an initializer in a variable declaration 2341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 2343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprocess_initializer(ir_variable *var, ast_declaration *decl, 2344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ast_fully_specified_type *type, 2345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list *initializer_instructions, 2346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 2347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *result = NULL; 2349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE initializer_loc = decl->initializer->get_location(); 2351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 24 (page 30 of the PDF) of the GLSL 1.10 spec: 2353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "All uniform variables are read-only and are initialized either 2355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * directly by an application via API commands, or indirectly by 2356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OpenGL." 2357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((state->language_version <= 110) 2359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && (var->mode == ir_var_uniform)) { 2360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& initializer_loc, state, 2361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "cannot initialize uniforms in GLSL 1.10"); 2362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var->type->is_sampler()) { 2365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& initializer_loc, state, 2366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "cannot initialize samplers"); 2367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((var->mode == ir_var_in) && (state->current_function == NULL)) { 2370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& initializer_loc, state, 2371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "cannot initialize %s shader input / %s", 2372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_shader_target_name(state->target), 2373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (state->target == vertex_shader) 2374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ? "attribute" : "varying"); 2375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference *const lhs = new(state) ir_dereference_variable(var); 2378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *rhs = decl->initializer->hir(initializer_instructions, 2379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state); 2380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Calculate the constant value if this is a const or uniform 2382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * declaration. 2383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type->qualifier.flags.q.constant 2385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || type->qualifier.flags.q.uniform) { 2386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *new_rhs = validate_assignment(state, var->type, rhs, true); 2387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (new_rhs != NULL) { 2388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rhs = new_rhs; 2389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant *constant_value = rhs->constant_expression_value(); 2391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!constant_value) { 2392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& initializer_loc, state, 2393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "initializer of %s variable `%s' must be a " 2394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "constant expression", 2395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (type->qualifier.flags.q.constant) 2396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ? "const" : "uniform", 2397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl->identifier); 2398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var->type->is_numeric()) { 2399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Reduce cascading errors. */ 2400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->constant_value = ir_constant::zero(state, var->type); 2401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rhs = constant_value; 2404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->constant_value = constant_value; 2405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&initializer_loc, state, 2408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "initializer of type %s cannot be assigned to " 2409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "variable of type %s", 2410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rhs->type->name, var->type->name); 2411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var->type->is_numeric()) { 2412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Reduce cascading errors. */ 2413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->constant_value = ir_constant::zero(state, var->type); 2414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rhs && !rhs->type->is_error()) { 2419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool temp = var->read_only; 2420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type->qualifier.flags.q.constant) 2421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->read_only = false; 2422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Never emit code to initialize a uniform. 2424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *initializer_type; 2426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!type->qualifier.flags.q.uniform) { 2427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = do_assignment(initializer_instructions, state, 2428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NULL, 2429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lhs, rhs, true, 2430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type->get_location()); 2431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org initializer_type = result->type; 2432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else 2433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org initializer_type = rhs->type; 2434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->constant_initializer = rhs->constant_expression_value(); 2436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->has_initializer = true; 2437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If the declared variable is an unsized array, it must inherrit 2439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * its full type from the initializer. A declaration such as 2440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * uniform float a[] = float[](1.0, 2.0, 3.0, 3.0); 2442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * becomes 2444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * uniform float a[4] = float[](1.0, 2.0, 3.0, 3.0); 2446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The assignment generated in the if-statement (below) will also 2448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * automatically handle this case for non-uniforms. 2449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If the declared variable is not an array, the types must 2451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * already match exactly. As a result, the type assignment 2452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * here can be done unconditionally. For non-uniforms the call 2453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to do_assignment can change the type of the initializer (via 2454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the implicit conversion rules). For uniforms the initializer 2455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * must be a constant expression, and the type of that expression 2456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * was validated above. 2457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->type = initializer_type; 2459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->read_only = temp; 2461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return result; 2464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 2467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_declarator_list::hir(exec_list *instructions, 2468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 2469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ctx = state; 2471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct glsl_type *decl_type; 2472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *type_name = NULL; 2473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *result = NULL; 2474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 2475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 46 (page 52 of the PDF) of the GLSL 1.50 spec: 2477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "To ensure that a particular output variable is invariant, it is 2479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * necessary to use the invariant qualifier. It can either be used to 2480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * qualify a previously declared variable as being invariant 2481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * invariant gl_Position; // make existing gl_Position be invariant" 2483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In these cases the parser will set the 'invariant' flag in the declarator 2485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * list, and the type will be NULL. 2486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->invariant) { 2488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(this->type == NULL); 2489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->current_function != NULL) { 2491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "All uses of `invariant' keyword must be at global " 2493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "scope\n"); 2494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_typed (ast_declaration, decl, link, &this->declarations) { 2497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!decl->is_array); 2498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(decl->array_size == NULL); 2499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(decl->initializer == NULL); 2500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *const earlier = 2502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->get_variable(decl->identifier); 2503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (earlier == NULL) { 2504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "Undeclared variable `%s' cannot be marked " 2506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "invariant\n", decl->identifier); 2507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if ((state->target == vertex_shader) 2508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && (earlier->mode != ir_var_out)) { 2509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`%s' cannot be marked invariant, vertex shader " 2511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "outputs only\n", decl->identifier); 2512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if ((state->target == fragment_shader) 2513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && (earlier->mode != ir_var_in)) { 2514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`%s' cannot be marked invariant, fragment shader " 2516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "inputs only\n", decl->identifier); 2517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (earlier->used) { 2518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "variable `%s' may not be redeclared " 2520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`invariant' after being used", 2521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org earlier->name); 2522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org earlier->invariant = true; 2524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Invariant redeclarations do not have r-values. 2528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 2530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(this->type != NULL); 2533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!this->invariant); 2534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The type specifier may contain a structure definition. Process that 2536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * before any of the variable declarations. 2537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void) this->type->specifier->hir(instructions, state); 2539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl_type = this->type->specifier->glsl_type(& type_name, state); 2541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->declarations.is_empty()) { 2542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If there is no structure involved in the program text, there are two 2543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * possible scenarios: 2544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - The program text contained something like 'vec4;'. This is an 2546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * empty declaration. It is valid but weird. Emit a warning. 2547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - The program text contained something like 'S;' and 'S' is not the 2549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * name of a known structure type. This is both invalid and weird. 2550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emit an error. 2551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note that if decl_type is NULL and there is a structure involved, 2553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * there must have been some sort of error with the structure. In this 2554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * case we assume that an error was already generated on this line of 2555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * code for the structure. There is no need to generate an additional, 2556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * confusing error. 2557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(this->type->specifier->structure == NULL || decl_type != NULL 2559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || state->error); 2560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->type->specifier->structure == NULL) { 2561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (decl_type != NULL) { 2562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_warning(&loc, state, "empty declaration"); 2563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 2565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "invalid type `%s' in empty declaration", 2566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_name); 2567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_typed (ast_declaration, decl, link, &this->declarations) { 2572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct glsl_type *var_type; 2573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *var; 2574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* FINISHME: Emit a warning if a variable declaration shadows a 2576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FINISHME: declaration at a higher scope. 2577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((decl_type == NULL) || decl_type->is_void()) { 2580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type_name != NULL) { 2581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "invalid type `%s' in declaration of `%s'", 2583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_name, decl->identifier); 2584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "invalid type in declaration of `%s'", 2587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl->identifier); 2588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 2590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (decl->is_array) { 2593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var_type = process_array_type(&loc, decl_type, decl->array_size, 2594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state); 2595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var_type->is_error()) 2596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 2597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var_type = decl_type; 2599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var = new(ctx) ir_variable(var_type, decl->identifier, ir_var_auto); 2602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification; 2604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Global variables can only use the qualifiers const, 2606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * attribute, uni form, or varying. Only one may be 2607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * specified. 2608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Local variables can only use the qualifier const." 2610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is relaxed in GLSL 1.30. It is also relaxed by any extension 2612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * that adds the 'layout' keyword. 2613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((state->language_version < 130) 2615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !state->ARB_explicit_attrib_location_enable 2616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !state->ARB_fragment_coord_conventions_enable) { 2617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->type->qualifier.flags.q.out) { 2618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`out' qualifier in declaration of `%s' " 2620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "only valid for function parameters in %s.", 2621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl->identifier, state->version_string); 2622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->type->qualifier.flags.q.in) { 2624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`in' qualifier in declaration of `%s' " 2626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "only valid for function parameters in %s.", 2627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl->identifier, state->version_string); 2628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* FINISHME: Test for other invalid qualifiers. */ 2630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org apply_type_qualifier_to_variable(& this->type->qualifier, var, state, 2633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org & loc, this->ubo_qualifiers_valid); 2634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->type->qualifier.flags.q.invariant) { 2636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((state->target == vertex_shader) && !(var->mode == ir_var_out || 2637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->mode == ir_var_inout)) { 2638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* FINISHME: Note that this doesn't work for invariant on 2639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a function signature outval 2640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`%s' cannot be marked invariant, vertex shader " 2643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "outputs only\n", var->name); 2644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if ((state->target == fragment_shader) && 2645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !(var->mode == ir_var_in || var->mode == ir_var_inout)) { 2646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* FINISHME: Note that this doesn't work for invariant on 2647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a function signature inval 2648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`%s' cannot be marked invariant, fragment shader " 2651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "inputs only\n", var->name); 2652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->current_function != NULL) { 2656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *mode = NULL; 2657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *extra = ""; 2658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* There is no need to check for 'inout' here because the parser will 2660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * only allow that in function parameter lists. 2661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->type->qualifier.flags.q.attribute) { 2663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mode = "attribute"; 2664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (this->type->qualifier.flags.q.uniform) { 2665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mode = "uniform"; 2666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (this->type->qualifier.flags.q.varying) { 2667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mode = "varying"; 2668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (this->type->qualifier.flags.q.in) { 2669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mode = "in"; 2670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org extra = " or in function parameter list"; 2671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (this->type->qualifier.flags.q.out) { 2672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mode = "out"; 2673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org extra = " or in function parameter list"; 2674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (mode) { 2677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "%s variable `%s' must be declared at " 2679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "global scope%s", 2680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mode, var->name, extra); 2681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (var->mode == ir_var_in) { 2683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->read_only = true; 2684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->target == vertex_shader) { 2686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool error_emitted = false; 2687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec: 2689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Vertex shader inputs can only be float, floating-point 2691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * vectors, matrices, signed and unsigned integers and integer 2692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * vectors. Vertex shader inputs can also form arrays of these 2693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * types, but not structures." 2694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * From page 31 (page 27 of the PDF) of the GLSL 1.30 spec: 2696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Vertex shader inputs can only be float, floating-point 2698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * vectors, matrices, signed and unsigned integers and integer 2699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * vectors. They cannot be arrays or structures." 2700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * From page 23 (page 29 of the PDF) of the GLSL 1.20 spec: 2702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The attribute qualifier can be used only with float, 2704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * floating-point vectors, and matrices. Attribute variables 2705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * cannot be declared as arrays or structures." 2706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *check_type = var->type->is_array() 2708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ? var->type->fields.array : var->type; 2709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (check_type->base_type) { 2711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_FLOAT: 2712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_UINT: 2714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_INT: 2715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->language_version > 120) 2716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* FALLTHROUGH */ 2718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 2719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "vertex shader input / attribute cannot have " 2721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "type %s`%s'", 2722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->type->is_array() ? "array of " : "", 2723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org check_type->name); 2724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 2725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!error_emitted && (state->language_version <= 130) 2728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && var->type->is_array()) { 2729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "vertex shader input / attribute cannot have " 2731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "array type"); 2732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org error_emitted = true; 2733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Integer vertex outputs must be qualified with 'flat'. 2738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * From section 4.3.6 of the GLSL 1.30 spec: 2740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "If a vertex output is a signed or unsigned integer or integer 2741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * vector, then it must be qualified with the interpolation qualifier 2742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * flat." 2743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->language_version >= 130 2745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && state->target == vertex_shader 2746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && state->current_function == NULL 2747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && var->type->is_integer() 2748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && var->mode == ir_var_out 2749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && var->interpolation != INTERP_QUALIFIER_FLAT) { 2750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "If a vertex output is an integer, " 2752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "then it must be qualified with 'flat'"); 2753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Interpolation qualifiers cannot be applied to 'centroid' and 2757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 'centroid varying'. 2758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * From page 29 (page 35 of the PDF) of the GLSL 1.30 spec: 2760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "interpolation qualifiers may only precede the qualifiers in, 2761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * centroid in, out, or centroid out in a declaration. They do not apply 2762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to the deprecated storage qualifiers varying or centroid varying." 2763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->language_version >= 130 2765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && this->type->qualifier.has_interpolation() 2766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && this->type->qualifier.flags.q.varying) { 2767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *i = this->type->qualifier.interpolation_string(); 2769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(i != NULL); 2770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *s; 2771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->type->qualifier.flags.q.centroid) 2772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s = "centroid varying"; 2773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 2774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s = "varying"; 2775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 2777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "qualifier '%s' cannot be applied to the " 2778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "deprecated storage qualifier '%s'", i, s); 2779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Interpolation qualifiers can only apply to vertex shader outputs and 2783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * fragment shader inputs. 2784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * From page 29 (page 35 of the PDF) of the GLSL 1.30 spec: 2786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Outputs from a vertex shader (out) and inputs to a fragment 2787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * shader (in) can be further qualified with one or more of these 2788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * interpolation qualifiers" 2789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->language_version >= 130 2791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && this->type->qualifier.has_interpolation()) { 2792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *i = this->type->qualifier.interpolation_string(); 2794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(i != NULL); 2795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (state->target) { 2797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case vertex_shader: 2798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->type->qualifier.flags.q.in) { 2799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 2800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "qualifier '%s' cannot be applied to vertex " 2801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "shader inputs", i); 2802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case fragment_shader: 2805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->type->qualifier.flags.q.out) { 2806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 2807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "qualifier '%s' cannot be applied to fragment " 2808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "shader outputs", i); 2809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 2812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 2813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From section 4.3.4 of the GLSL 1.30 spec: 2818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "It is an error to use centroid in in a vertex shader." 2819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->language_version >= 130 2821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && this->type->qualifier.flags.q.centroid 2822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && this->type->qualifier.flags.q.in 2823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && state->target == vertex_shader) { 2824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 2826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "'centroid in' cannot be used in a vertex shader"); 2827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30. 2831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->type->specifier->precision != ast_precision_none 2833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && state->language_version != 100 2834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && state->language_version < 130) { 2835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 2837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "precision qualifiers are supported only in GLSL ES " 2838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "1.00, and GLSL 1.30 and later"); 2839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Precision qualifiers only apply to floating point and integer types. 2843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * From section 4.5.2 of the GLSL 1.30 spec: 2845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Any floating point or any integer declaration can have the type 2846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * preceded by one of these precision qualifiers [...] Literal 2847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * constants do not have precision qualifiers. Neither do Boolean 2848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * variables. 2849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In GLSL ES, sampler types are also allowed. 2851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * From page 87 of the GLSL ES spec: 2853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "RESOLUTION: Allow sampler types to take a precision qualifier." 2854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->type->specifier->precision != ast_precision_none 2856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !var->type->is_float() 2857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !var->type->is_integer() 2858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !(var->type->is_sampler() && state->es_shader) 2859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !(var->type->is_array() 2860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && (var->type->fields.array->is_float() 2861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || var->type->fields.array->is_integer()))) { 2862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 2864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "precision qualifiers apply only to floating point" 2865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "%s types", state->es_shader ? ", integer, and sampler" 2866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : "and integer"); 2867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec: 2870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "[Sampler types] can only be declared as function 2872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * parameters or uniform variables (see Section 4.3.5 2873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Uniform")". 2874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var_type->contains_sampler() && 2876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !this->type->qualifier.flags.q.uniform) { 2877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "samplers must be declared uniform"); 2878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Process the initializer and add its instructions to a temporary 2881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * list. This list will be added to the instruction stream (below) after 2882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the declaration is added. This is done because in some cases (such as 2883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * redeclarations) the declaration may not actually be added to the 2884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instruction stream. 2885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list initializer_instructions; 2887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *earlier = get_variable_being_redeclared(var, decl, state); 2888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (decl->initializer != NULL) { 2890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = process_initializer((earlier == NULL) ? var : earlier, 2891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl, this->type, 2892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &initializer_instructions, state); 2893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 23 (page 29 of the PDF) of the GLSL 1.10 spec: 2896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "It is an error to write to a const variable outside of 2898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * its declaration, so they must be initialized when 2899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * declared." 2900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->type->qualifier.flags.q.constant && decl->initializer == NULL) { 2902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "const declaration of `%s' must be initialized", 2904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl->identifier); 2905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If the declaration is not a redeclaration, there are a few additional 2908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * semantic checks that must be applied. In addition, variable that was 2909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * created for the declaration should be added to the IR stream. 2910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (earlier == NULL) { 2912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec, 2913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Identifiers starting with "gl_" are reserved for use by 2915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OpenGL, and may not be declared in a shader as either a 2916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * variable or a function." 2917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (strncmp(decl->identifier, "gl_", 3) == 0) 2919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "identifier `%s' uses reserved `gl_' prefix", 2921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl->identifier); 2922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (strstr(decl->identifier, "__")) { 2923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 14 (page 20 of the PDF) of the GLSL 1.10 2924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * spec: 2925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "In addition, all identifiers containing two 2927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * consecutive underscores (__) are reserved as 2928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * possible future keywords." 2929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "identifier `%s' uses reserved `__' string", 2932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl->identifier); 2933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Add the variable to the symbol table. Note that the initializer's 2936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IR was already processed earlier (though it hasn't been emitted 2937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * yet), without the variable in scope. 2938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This differs from most C-like languages, but it follows the GLSL 2940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * specification. From page 28 (page 34 of the PDF) of the GLSL 1.50 2941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * spec: 2942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Within a declaration, the scope of a name starts immediately 2944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * after the initializer if present or immediately after the name 2945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * being declared if not." 2946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!state->symbols->add_variable(var)) { 2948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 2949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "name `%s' already taken in the " 2950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "current scope", decl->identifier); 2951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 2952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Push the variable declaration to the top. It means that all the 2955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * variable declarations will appear in a funny last-to-first order, 2956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * but otherwise we run into trouble if a function is prototyped, a 2957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * global var is decled, then the function is defined with usage of 2958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the global var. See glslparsertest's CorrectModule.frag. 2959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_head(var); 2961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->append_list(&initializer_instructions); 2964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Generally, variable declarations do not have r-values. However, 2968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * one is used for the declaration in 2969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * while (bool b = some_condition()) { 2971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ... 2972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * } 2973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * so we return the rvalue from the last seen declaration here. 2975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return result; 2977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 2981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_parameter_declarator::hir(exec_list *instructions, 2982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 2983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ctx = state; 2985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct glsl_type *type; 2986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *name = NULL; 2987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 2988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = this->type->specifier->glsl_type(& name, state); 2990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type == NULL) { 2992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (name != NULL) { 2993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "invalid type `%s' in declaration of `%s'", 2995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org name, this->identifier); 2996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 2998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "invalid type in declaration of `%s'", 2999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->identifier); 3000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = glsl_type::error_type; 3003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 62 (page 68 of the PDF) of the GLSL 1.50 spec: 3006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Functions that accept no input arguments need not use void in the 3008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * argument list because prototypes (or definitions) are required and 3009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * therefore there is no ambiguity when an empty argument list "( )" is 3010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * declared. The idiom "(void)" as a parameter list is provided for 3011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * convenience." 3012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Placing this check here prevents a void parameter being set up 3014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * for a function, which avoids tripping up checks for main taking 3015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * parameters and lookups of an unnamed symbol. 3016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type->is_void()) { 3018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->identifier != NULL) 3019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 3020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "named parameter cannot have type `void'"); 3021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org is_void = true; 3023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (formal_parameter && (this->identifier == NULL)) { 3027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "formal parameter lacks a name"); 3028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This only handles "vec4 foo[..]". The earlier specifier->glsl_type(...) 3032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * call already handled the "vec4[..] foo" case. 3033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->is_array) { 3035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = process_array_type(&loc, type, this->array_size, state); 3036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!type->is_error() && type->array_size() == 0) { 3039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "arrays passed as parameters must have " 3040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "a declared size."); 3041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = glsl_type::error_type; 3042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org is_void = false; 3045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *var = new(ctx) ir_variable(type, this->identifier, ir_var_in); 3046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Apply any specified qualifiers to the parameter declaration. Note that 3048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * for function parameters the default mode is 'in'. 3049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc, 3051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org false); 3052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec: 3054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Samplers cannot be treated as l-values; hence cannot be used 3056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * as out or inout function parameters, nor can they be assigned 3057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * into." 3058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((var->mode == ir_var_inout || var->mode == ir_var_out) 3060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && type->contains_sampler()) { 3061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "out and inout parameters cannot contain samplers"); 3062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = glsl_type::error_type; 3063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 39 (page 45 of the PDF) of the GLSL 1.10 spec: 3066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "When calling a function, expressions that do not evaluate to 3068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * l-values cannot be passed to parameters declared as out or inout." 3069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * From page 32 (page 38 of the PDF) of the GLSL 1.10 spec: 3071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Other binary or unary expressions, non-dereferenced arrays, 3073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * function names, swizzles with repeated fields, and constants 3074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * cannot be l-values." 3075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * So for GLSL 1.10, passing an array as an out or inout parameter is not 3077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * allowed. This restriction is removed in GLSL 1.20, and in GLSL ES. 3078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((var->mode == ir_var_inout || var->mode == ir_var_out) 3080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && type->is_array() && state->language_version == 110) { 3081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "Arrays cannot be out or inout parameters in GLSL 1.10"); 3082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = glsl_type::error_type; 3083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(var); 3086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Parameter declarations do not have r-values. 3088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 3094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters, 3095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool formal, 3096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list *ir_parameters, 3097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_parse_state *state) 3098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ast_parameter_declarator *void_param = NULL; 3100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned count = 0; 3101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_typed (ast_parameter_declarator, param, link, ast_parameters) { 3103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org param->formal_parameter = formal; 3104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org param->hir(ir_parameters, state); 3105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (param->is_void) 3107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void_param = param; 3108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org count++; 3110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((void_param != NULL) && (count > 1)) { 3113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = void_param->get_location(); 3114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 3116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`void' parameter must be only parameter"); 3117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 3122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_function(_mesa_glsl_parse_state *state, ir_function *f) 3123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* IR invariants disallow function declarations or definitions 3125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * nested within other function definitions. But there is no 3126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * requirement about the relative order of function declarations 3127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and definitions with respect to one another. So simply insert 3128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the new ir_function block at the end of the toplevel instruction 3129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * list. 3130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->toplevel_ir->push_tail(f); 3132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 3136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_function::hir(exec_list *instructions, 3137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 3138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ctx = state; 3140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_function *f = NULL; 3141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_function_signature *sig = NULL; 3142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list hir_parameters; 3143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *const name = identifier; 3145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* New functions are always added to the top-level IR instruction stream, 3147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * so this instruction list pointer is ignored. See also emit_function 3148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (called below). 3149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void) instructions; 3151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec, 3153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Function declarations (prototypes) cannot occur inside of functions; 3155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * they must be at global scope, or for the built-in functions, outside 3156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the global scope." 3157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * From page 27 (page 33 of the PDF) of the GLSL ES 1.00.16 spec, 3159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "User defined functions may only be defined within the global scope." 3161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note that this language does not appear in GLSL 1.10. 3163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((state->current_function != NULL) && (state->language_version != 110)) { 3165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 3167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "declaration of function `%s' not allowed within " 3168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "function body", name); 3169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec, 3172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Identifiers starting with "gl_" are reserved for use by 3174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OpenGL, and may not be declared in a shader as either a 3175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * variable or a function." 3176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (strncmp(name, "gl_", 3) == 0) { 3178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 3180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "identifier `%s' uses reserved `gl_' prefix", name); 3181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Convert the list of function parameters to HIR now so that they can be 3184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * used below to compare this function's signature with previously seen 3185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * signatures for functions with the same name. 3186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ast_parameter_declarator::parameters_to_hir(& this->parameters, 3188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org is_definition, 3189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org & hir_parameters, state); 3190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *return_type_name; 3192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *return_type = 3193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->return_type->specifier->glsl_type(& return_type_name, state); 3194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!return_type) { 3196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 3198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "function `%s' has undeclared return type `%s'", 3199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org name, return_type_name); 3200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return_type = glsl_type::error_type; 3201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 56 (page 62 of the PDF) of the GLSL 1.30 spec: 3204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "No qualifier is allowed on the return type of a function." 3205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->return_type->has_qualifiers()) { 3207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 3209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "function `%s' return type has qualifiers", name); 3210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec: 3213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "[Sampler types] can only be declared as function parameters 3215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * or uniform variables (see Section 4.3.5 "Uniform")". 3216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (return_type->contains_sampler()) { 3218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 3220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "function `%s' return type can't contain a sampler", 3221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org name); 3222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Verify that this function's signature either doesn't match a previously 3225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * seen signature for a function with the same name, or, if a match is found, 3226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * that the previously seen signature does not have an associated definition. 3227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org f = state->symbols->get_function(name); 3229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (f != NULL && (state->es_shader || f->has_user_signature())) { 3230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sig = f->exact_matching_signature(&hir_parameters); 3231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sig != NULL) { 3232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *badvar = sig->qualifiers_match(&hir_parameters); 3233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (badvar != NULL) { 3234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "function `%s' parameter `%s' " 3237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "qualifiers don't match prototype", name, badvar); 3238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sig->return_type != return_type) { 3241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "function `%s' return type doesn't " 3244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "match prototype", name); 3245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (is_definition && sig->is_defined) { 3248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "function `%s' redefined", name); 3251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 3254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org f = new(ctx) ir_function(name); 3255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!state->symbols->add_function(f)) { 3256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This function name shadows a non-function use of the same name. */ 3257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "function name `%s' conflicts with " 3260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "non-function", name); 3261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_function(state, f); 3265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Verify the return type of main() */ 3268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (strcmp(name, "main") == 0) { 3269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (! return_type->is_void()) { 3270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "main() must return void"); 3273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!hir_parameters.is_empty()) { 3276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "main() must not take any parameters"); 3279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Finish storing the information about this new function in its signature. 3283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sig == NULL) { 3285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sig = new(ctx) ir_function_signature(return_type); 3286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org f->add_signature(sig); 3287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sig->replace_parameters(&hir_parameters); 3290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org signature = sig; 3291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Function declarations (prototypes) do not have r-values. 3293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 3299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_function_definition::hir(exec_list *instructions, 3300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 3301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prototype->is_definition = true; 3303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prototype->hir(instructions, state); 3304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_function_signature *signature = prototype->signature; 3306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (signature == NULL) 3307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(state->current_function == NULL); 3310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->current_function = signature; 3311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->found_return = false; 3312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Duplicate parameters declared in the prototype as concrete variables. 3314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Add these to the symbol table. 3315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->push_scope(); 3317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, signature->parameters) { 3318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *const var = ((ir_instruction *) iter.get())->as_variable(); 3319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(var != NULL); 3321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The only way a parameter would "exist" is if two parameters have 3323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the same name. 3324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->symbols->name_declared_this_scope(var->name)) { 3326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name); 3329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 3330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->add_variable(var); 3331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Convert the body of the function to HIR. */ 3335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->body->hir(&signature->body, state); 3336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org signature->is_defined = true; 3337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->pop_scope(); 3339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(state->current_function == signature); 3341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->current_function = NULL; 3342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!signature->return_type->is_void() && !state->found_return) { 3344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "function `%s' has non-void return type " 3346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "%s, but no return statement", 3347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org signature->function_name(), 3348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org signature->return_type->name); 3349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Function definitions do not have r-values. 3352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 3358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_jump_statement::hir(exec_list *instructions, 3359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 3360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ctx = state; 3362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (mode) { 3364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_return: { 3365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_return *inst; 3366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(state->current_function); 3367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (opt_return_value) { 3369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *const ret = opt_return_value->hir(instructions, state); 3370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The value of the return type can be NULL if the shader says 3372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 'return foo();' and foo() is a function that returns void. 3373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NOTE: The GLSL spec doesn't say that this is an error. The type 3375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the return value is void. If the return type of the function is 3376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * also void, then this should compile without error. Seriously. 3377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *const ret_type = 3379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (ret == NULL) ? glsl_type::void_type : ret->type; 3380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Implicit conversions are not allowed for return values. */ 3382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->current_function->return_type != ret_type) { 3383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 3386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`return' with wrong type %s, in function `%s' " 3387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "returning %s", 3388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret_type->name, 3389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->current_function->function_name(), 3390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->current_function->return_type->name); 3391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = new(ctx) ir_return(ret); 3394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 3395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->current_function->return_type->base_type != 3396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLSL_TYPE_VOID) { 3397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 3400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`return' with no value, in function %s returning " 3401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "non-void", 3402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->current_function->function_name()); 3403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = new(ctx) ir_return; 3405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->found_return = true; 3408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(inst); 3409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 3410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_discard: 3413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->target != fragment_shader) { 3414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 3417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`discard' may only appear in a fragment shader"); 3418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(new(ctx) ir_discard); 3420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 3421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_break: 3423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ast_continue: 3424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (mode == ast_continue && 3425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->loop_nesting_ast == NULL) { 3426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 3429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "continue may only appear in a loop"); 3430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (mode == ast_break && 3431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->loop_nesting_ast == NULL && 3432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->switch_state.switch_nesting_ast == NULL) { 3433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 3436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "break may only appear in a loop or a switch"); 3437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 3438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* For a loop, inline the for loop expression again, 3439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * since we don't know where near the end of 3440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the loop body the normal copy of it 3441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is going to be placed. 3442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->loop_nesting_ast != NULL && 3444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mode == ast_continue && 3445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->loop_nesting_ast->rest_expression) { 3446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->loop_nesting_ast->rest_expression->hir(instructions, 3447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state); 3448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->switch_state.is_switch_innermost && 3451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mode == ast_break) { 3452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Force break out of switch by setting is_break switch state. 3453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *const is_break_var = state->switch_state.is_break_var; 3455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *const deref_is_break_var = 3456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_dereference_variable(is_break_var); 3457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant *const true_val = new(ctx) ir_constant(true); 3458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_assignment *const set_break_var = 3459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_assignment(deref_is_break_var, true_val); 3460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(set_break_var); 3462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 3464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_loop_jump *const jump = 3465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_loop_jump((mode == ast_break) 3466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ? ir_loop_jump::jump_break 3467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : ir_loop_jump::jump_continue); 3468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(jump); 3469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 3473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Jump instructions do not have r-values. 3476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 3482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_selection_statement::hir(exec_list *instructions, 3483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 3484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ctx = state; 3486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *const condition = this->condition->hir(instructions, state); 3488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 66 (page 72 of the PDF) of the GLSL 1.50 spec: 3490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Any expression whose type evaluates to a Boolean can be used as the 3492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * conditional expression bool-expression. Vector types are not accepted 3493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * as the expression to if." 3494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The checks are separated so that higher quality diagnostics can be 3496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * generated for cases where both rules are violated. 3497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!condition->type->is_boolean() || !condition->type->is_scalar()) { 3499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->condition->get_location(); 3500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "if-statement condition must be scalar " 3502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "boolean"); 3503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_if *const stmt = new(ctx) ir_if(condition); 3506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (then_statement != NULL) { 3508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->push_scope(); 3509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org then_statement->hir(& stmt->then_instructions, state); 3510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->pop_scope(); 3511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (else_statement != NULL) { 3514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->push_scope(); 3515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else_statement->hir(& stmt->else_instructions, state); 3516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->pop_scope(); 3517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(stmt); 3520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* if-statements do not have r-values. 3522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 3528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_switch_statement::hir(exec_list *instructions, 3529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 3530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ctx = state; 3532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *const test_expression = 3534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->test_expression->hir(instructions, state); 3535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From page 66 (page 55 of the PDF) of the GLSL 1.50 spec: 3537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The type of init-expression in a switch statement must be a 3539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * scalar integer." 3540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!test_expression->type->is_scalar() || 3542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !test_expression->type->is_integer()) { 3543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->test_expression->get_location(); 3544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, 3546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state, 3547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "switch-statement expression must be scalar " 3548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "integer"); 3549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Track the switch-statement nesting in a stack-like manner. 3552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct glsl_switch_state saved = state->switch_state; 3554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->switch_state.is_switch_innermost = true; 3556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->switch_state.switch_nesting_ast = this; 3557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->switch_state.labels_ht = hash_table_ctor(0, hash_table_pointer_hash, 3558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hash_table_pointer_compare); 3559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->switch_state.previous_default = NULL; 3560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Initalize is_fallthru state to false. 3562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *const is_fallthru_val = new (ctx) ir_constant(false); 3564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->switch_state.is_fallthru_var = 3565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_variable(glsl_type::bool_type, 3566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "switch_is_fallthru_tmp", 3567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_var_temporary); 3568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(state->switch_state.is_fallthru_var); 3569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *deref_is_fallthru_var = 3571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_dereference_variable(state->switch_state.is_fallthru_var); 3572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(new(ctx) ir_assignment(deref_is_fallthru_var, 3573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org is_fallthru_val)); 3574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Initalize is_break state to false. 3576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *const is_break_val = new (ctx) ir_constant(false); 3578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->switch_state.is_break_var = new(ctx) ir_variable(glsl_type::bool_type, 3579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "switch_is_break_tmp", 3580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_var_temporary); 3581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(state->switch_state.is_break_var); 3582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *deref_is_break_var = 3584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_dereference_variable(state->switch_state.is_break_var); 3585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(new(ctx) ir_assignment(deref_is_break_var, 3586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org is_break_val)); 3587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Cache test expression. 3589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org test_to_hir(instructions, state); 3591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Emit code for body of switch stmt. 3593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org body->hir(instructions, state); 3595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hash_table_dtor(state->switch_state.labels_ht); 3597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->switch_state = saved; 3599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Switch statements do not have r-values. */ 3601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 3606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_switch_statement::test_to_hir(exec_list *instructions, 3607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 3608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ctx = state; 3610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Cache value of test expression. */ 3612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *const test_val = 3613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org test_expression->hir(instructions, 3614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state); 3615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->switch_state.test_var = new(ctx) ir_variable(test_val->type, 3617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "switch_test_tmp", 3618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_var_temporary); 3619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *deref_test_var = 3620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_dereference_variable(state->switch_state.test_var); 3621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(state->switch_state.test_var); 3623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(new(ctx) ir_assignment(deref_test_var, test_val)); 3624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 3628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_switch_body::hir(exec_list *instructions, 3629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 3630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (stmts != NULL) 3632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stmts->hir(instructions, state); 3633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Switch bodies do not have r-values. */ 3635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 3639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_case_statement_list::hir(exec_list *instructions, 3640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 3641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_typed (ast_case_statement, case_stmt, link, & this->cases) 3643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case_stmt->hir(instructions, state); 3644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Case statements do not have r-values. */ 3646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 3650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_case_statement::hir(exec_list *instructions, 3651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 3652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org labels->hir(instructions, state); 3654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Conditionally set fallthru state based on break state. */ 3656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant *const false_val = new(state) ir_constant(false); 3657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *const deref_is_fallthru_var = 3658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(state) ir_dereference_variable(state->switch_state.is_fallthru_var); 3659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *const deref_is_break_var = 3660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(state) ir_dereference_variable(state->switch_state.is_break_var); 3661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_assignment *const reset_fallthru_on_break = 3662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(state) ir_assignment(deref_is_fallthru_var, 3663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org false_val, 3664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org deref_is_break_var); 3665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(reset_fallthru_on_break); 3666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Guard case statements depending on fallthru state. */ 3668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *const deref_fallthru_guard = 3669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(state) ir_dereference_variable(state->switch_state.is_fallthru_var); 3670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_if *const test_fallthru = new(state) ir_if(deref_fallthru_guard); 3671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_typed (ast_node, stmt, link, & this->stmts) 3673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stmt->hir(& test_fallthru->then_instructions, state); 3674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(test_fallthru); 3676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Case statements do not have r-values. */ 3678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 3683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_case_label_list::hir(exec_list *instructions, 3684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 3685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_typed (ast_case_label, label, link, & this->labels) 3687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org label->hir(instructions, state); 3688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Case labels do not have r-values. */ 3690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 3694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_case_label::hir(exec_list *instructions, 3695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 3696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ctx = state; 3698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *deref_fallthru_var = 3700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_dereference_variable(state->switch_state.is_fallthru_var); 3701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *const true_val = new(ctx) ir_constant(true); 3703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If not default case, ... */ 3705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->test_value != NULL) { 3706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Conditionally set fallthru state based on 3707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * comparison of cached test expression value to case label. 3708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *const label_rval = this->test_value->hir(instructions, state); 3710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant *label_const = label_rval->constant_expression_value(); 3711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!label_const) { 3713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->test_value->get_location(); 3714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 3716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "switch statement case label must be a " 3717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "constant expression"); 3718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Stuff a dummy value in to allow processing to continue. */ 3720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org label_const = new(ctx) ir_constant(0); 3721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 3722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ast_expression *previous_label = (ast_expression *) 3723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hash_table_find(state->switch_state.labels_ht, 3724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void *)(uintptr_t)label_const->value.u[0]); 3725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (previous_label) { 3727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->test_value->get_location(); 3728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 3729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "duplicate case value"); 3730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loc = previous_label->get_location(); 3732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 3733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "this is the previous case label"); 3734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 3735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hash_table_insert(state->switch_state.labels_ht, 3736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->test_value, 3737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void *)(uintptr_t)label_const->value.u[0]); 3738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *deref_test_var = 3742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_dereference_variable(state->switch_state.test_var); 3743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *const test_cond = new(ctx) ir_expression(ir_binop_all_equal, 3745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org label_const, 3746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org deref_test_var); 3747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_assignment *set_fallthru_on_test = 3749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_assignment(deref_fallthru_var, 3750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org true_val, 3751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org test_cond); 3752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(set_fallthru_on_test); 3754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { /* default case */ 3755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->switch_state.previous_default) { 3756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 3758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "multiple default labels in one switch"); 3759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loc = state->switch_state.previous_default->get_location(); 3761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 3762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "this is the first default label"); 3763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->switch_state.previous_default = this; 3765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Set falltrhu state. */ 3767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_assignment *set_fallthru = 3768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_assignment(deref_fallthru_var, true_val); 3769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(set_fallthru); 3771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Case statements do not have r-values. */ 3774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 3778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_iteration_statement::condition_to_hir(ir_loop *stmt, 3779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 3780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ctx = state; 3782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (condition != NULL) { 3784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *const cond = 3785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org condition->hir(& stmt->body_instructions, state); 3786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((cond == NULL) 3788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || !cond->type->is_boolean() || !cond->type->is_scalar()) { 3789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = condition->get_location(); 3790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, 3792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "loop condition must be scalar boolean"); 3793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 3794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* As the first code in the loop body, generate a block that looks 3795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * like 'if (!condition) break;' as the loop termination condition. 3796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *const not_cond = 3798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_expression(ir_unop_logic_not, cond); 3799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_if *const if_stmt = new(ctx) ir_if(not_cond); 3801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_jump *const break_stmt = 3803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ctx) ir_loop_jump(ir_loop_jump::jump_break); 3804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if_stmt->then_instructions.push_tail(break_stmt); 3806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stmt->body_instructions.push_tail(if_stmt); 3807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 3813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_iteration_statement::hir(exec_list *instructions, 3814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 3815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ctx = state; 3817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* For-loops and while-loops start a new scope, but do-while loops do not. 3819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (mode != ast_do_while) 3821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->push_scope(); 3822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (init_statement != NULL) 3824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org init_statement->hir(instructions, state); 3825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_loop *const stmt = new(ctx) ir_loop(); 3827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->push_tail(stmt); 3828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Track the current loop nesting. */ 3830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ast_iteration_statement *nesting_ast = state->loop_nesting_ast; 3831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->loop_nesting_ast = this; 3833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Likewise, indicate that following code is closest to a loop, 3835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NOT closest to a switch. 3836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool saved_is_switch_innermost = state->switch_state.is_switch_innermost; 3838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->switch_state.is_switch_innermost = false; 3839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (mode != ast_do_while) 3841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org condition_to_hir(stmt, state); 3842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (body != NULL) 3844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org body->hir(& stmt->body_instructions, state); 3845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rest_expression != NULL) 3847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rest_expression->hir(& stmt->body_instructions, state); 3848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (mode == ast_do_while) 3850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org condition_to_hir(stmt, state); 3851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (mode != ast_do_while) 3853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->symbols->pop_scope(); 3854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Restore previous nesting before returning. */ 3856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->loop_nesting_ast = nesting_ast; 3857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->switch_state.is_switch_innermost = saved_is_switch_innermost; 3858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Loops do not have r-values. 3860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 3866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_type_specifier::hir(exec_list *instructions, 3867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 3868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!this->is_precision_statement && this->structure == NULL) 3870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->precision != ast_precision_none 3875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && state->language_version != 100 3876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && state->language_version < 130) { 3877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 3878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "precision qualifiers exist only in " 3879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "GLSL ES 1.00, and GLSL 1.30 and later"); 3880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->precision != ast_precision_none 3883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && this->structure != NULL) { 3884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 3885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "precision qualifiers do not apply to structures"); 3886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If this is a precision statement, check that the type to which it is 3890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * applied is either float or int. 3891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * From section 4.5.3 of the GLSL 1.30 spec: 3893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "The precision statement 3894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * precision precision-qualifier type; 3895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * can be used to establish a default precision qualifier. The type 3896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * field can be either int or float [...]. Any other types or 3897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * qualifiers will result in an error. 3898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->is_precision_statement) { 3900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(this->precision != ast_precision_none); 3901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(this->structure == NULL); /* The check for structures was 3902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * performed above. */ 3903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->is_array) { 3904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 3905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "default precision statements do not apply to " 3906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "arrays"); 3907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (strcmp(this->type_name, "float") != 0 && 3910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org strcmp(this->type_name, "int") != 0) { 3911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 3912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "default precision statements apply only to types " 3913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "float and int"); 3914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* FINISHME: Translate precision statements into IR. */ 3918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->structure != NULL) 3922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return this->structure->hir(instructions, state); 3923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 3925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 3929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_struct_specifier::hir(exec_list *instructions, 3930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 3931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned decl_count = 0; 3933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Make an initial pass over the list of structure fields to determine how 3935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * many there are. Each element in this list is an ast_declarator_list. 3936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This means that we actually need to count the number of elements in the 3937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 'declarations' list in each of the elements. 3938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_typed (ast_declarator_list, decl_list, link, 3940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &this->declarations) { 3941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_const (decl_ptr, & decl_list->declarations) { 3942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl_count++; 3943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Allocate storage for the structure fields and process the field 3947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * declarations. As the declarations are processed, try to also convert 3948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the types to HIR. This ensures that structure definitions embedded in 3949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * other structure definitions are processed. 3950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_struct_field *const fields = ralloc_array(state, glsl_struct_field, 3952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl_count); 3953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i = 0; 3955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_typed (ast_declarator_list, decl_list, link, 3956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &this->declarations) { 3957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *type_name; 3958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl_list->type->specifier->hir(instructions, state); 3960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Section 10.9 of the GLSL ES 1.00 specification states that 3962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * embedded structure definitions have been removed from the language. 3963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->es_shader && decl_list->type->specifier->structure != NULL) { 3965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "Embedded structure definitions are " 3967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "not allowed in GLSL ES 1.00."); 3968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *decl_type = 3971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl_list->type->specifier->glsl_type(& type_name, state); 3972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_typed (ast_declaration, decl, link, 3974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &decl_list->declarations) { 3975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct glsl_type *field_type = decl_type; 3976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (decl->is_array) { 3977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = decl->get_location(); 3978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org field_type = process_array_type(&loc, decl_type, decl->array_size, 3979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state); 3980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fields[i].type = (field_type != NULL) 3982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ? field_type : glsl_type::error_type; 3983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fields[i].name = decl->identifier; 3984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i++; 3985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(i == decl_count); 3989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *t = 3991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_type::get_record_instance(fields, decl_count, this->name); 3992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 3994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!state->symbols->add_type(name, t)) { 3995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(& loc, state, "struct `%s' previously defined", name); 3996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 3997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type **s = reralloc(state, state->user_structures, 3998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *, 3999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->num_user_structures + 1); 4000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (s != NULL) { 4001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s[state->num_user_structures] = t; 4002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->user_structures = s; 4003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->num_user_structures++; 4004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Structure type definitions do not have r-values. 4008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 4010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct gl_uniform_block * 4013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_next_uniform_block(struct _mesa_glsl_parse_state *state) 4014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->num_uniform_blocks >= state->uniform_block_array_size) { 4016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->uniform_block_array_size *= 2; 4017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->uniform_block_array_size <= 4) 4018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->uniform_block_array_size = 4; 4019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->uniform_blocks = reralloc(state, 4021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->uniform_blocks, 4022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_uniform_block, 4023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state->uniform_block_array_size); 4024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&state->uniform_blocks[state->num_uniform_blocks], 4027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0, sizeof(*state->uniform_blocks)); 4028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &state->uniform_blocks[state->num_uniform_blocks++]; 4029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue * 4032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgast_uniform_block::hir(exec_list *instructions, 4033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct _mesa_glsl_parse_state *state) 4034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The ast_uniform_block has a list of ast_declarator_lists. We 4036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * need to turn those into ir_variables with an association 4037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * with this uniform block. 4038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_uniform_block *ubo = get_next_uniform_block(state); 4040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ubo->Name = ralloc_strdup(state->uniform_blocks, this->block_name); 4041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!state->symbols->add_uniform_block(ubo)) { 4043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = this->get_location(); 4044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "Uniform block name `%s' already taken in " 4045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "the current scope.\n", ubo->Name); 4046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int num_variables = 0; 4049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_typed(ast_declarator_list, decl_list, link, &declarations) { 4050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_const(node, &decl_list->declarations) { 4051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_variables++; 4052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool block_row_major = this->layout.flags.q.row_major; 4056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ubo->Uniforms = rzalloc_array(state->uniform_blocks, 4058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_uniform_buffer_variable, 4059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_variables); 4060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_typed(ast_declarator_list, decl_list, link, &declarations) { 4062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list declared_variables; 4063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl_list->hir(&declared_variables, state); 4065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list_const(node, &declared_variables) { 4067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ir_variable *var = (ir_variable *)node; 4068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_uniform_buffer_variable *ubo_var = 4070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &ubo->Uniforms[ubo->NumUniforms++]; 4071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->uniform_block = ubo - state->uniform_blocks; 4073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ubo_var->Name = ralloc_strdup(state->uniform_blocks, var->name); 4075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ubo_var->Type = var->type; 4076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ubo_var->Buffer = ubo - state->uniform_blocks; 4077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ubo_var->Offset = 0; /* Assigned at link time. */ 4078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var->type->is_matrix() || 4080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (var->type->is_array() && var->type->fields.array->is_matrix())) { 4081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ubo_var->RowMajor = block_row_major; 4082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (decl_list->type->qualifier.flags.q.row_major) 4083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ubo_var->RowMajor = true; 4084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (decl_list->type->qualifier.flags.q.column_major) 4085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ubo_var->RowMajor = false; 4086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From the GL_ARB_uniform_buffer_object spec: 4089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Sampler types are not allowed inside of uniform 4091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * blocks. All other types, arrays, and structures 4092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * allowed for uniforms are allowed within a uniform 4093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * block." 4094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (var->type->contains_sampler()) { 4096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc = decl_list->get_location(); 4097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, 4098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "Uniform in non-default uniform block contains sampler\n"); 4099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions->append_list(&declared_variables); 4103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 4106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 4109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdetect_conflicting_assignments(struct _mesa_glsl_parse_state *state, 4110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list *instructions) 4111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool gl_FragColor_assigned = false; 4113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool gl_FragData_assigned = false; 4114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool user_defined_fs_output_assigned = false; 4115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *user_defined_fs_output = NULL; 4116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* It would be nice to have proper location information. */ 4118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org YYLTYPE loc; 4119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&loc, 0, sizeof(loc)); 4120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_list(node, instructions) { 4122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *var = ((ir_instruction *)node)->as_variable(); 4123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!var || !var->assigned) 4125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 4126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (strcmp(var->name, "gl_FragColor") == 0) 4128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_FragColor_assigned = true; 4129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (strcmp(var->name, "gl_FragData") == 0) 4130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_FragData_assigned = true; 4131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (strncmp(var->name, "gl_", 3) != 0) { 4132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (state->target == fragment_shader && 4133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (var->mode == ir_var_out || var->mode == ir_var_inout)) { 4134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org user_defined_fs_output_assigned = true; 4135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org user_defined_fs_output = var; 4136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From the GLSL 1.30 spec: 4141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "If a shader statically assigns a value to gl_FragColor, it 4143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * may not assign a value to any element of gl_FragData. If a 4144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * shader statically writes a value to any element of 4145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * gl_FragData, it may not assign a value to 4146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * gl_FragColor. That is, a shader may assign values to either 4147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * gl_FragColor or gl_FragData, but not both. Multiple shaders 4148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * linked together must also consistently write just one of 4149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * these variables. Similarly, if user declared output 4150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * variables are in use (statically assigned to), then the 4151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * built-in variables gl_FragColor and gl_FragData may not be 4152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * assigned to. These incorrect usages all generate compile 4153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * time errors." 4154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (gl_FragColor_assigned && gl_FragData_assigned) { 4156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "fragment shader writes to both " 4157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`gl_FragColor' and `gl_FragData'\n"); 4158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (gl_FragColor_assigned && user_defined_fs_output_assigned) { 4159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "fragment shader writes to both " 4160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`gl_FragColor' and `%s'\n", 4161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org user_defined_fs_output->name); 4162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (gl_FragData_assigned && user_defined_fs_output_assigned) { 4163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_glsl_error(&loc, state, "fragment shader writes to both " 4164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "`gl_FragData' and `%s'\n", 4165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org user_defined_fs_output->name); 4166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4168