1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2010 Intel Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci/** 25bf215546Sopenharmony_ci * \file ast_to_hir.c 26bf215546Sopenharmony_ci * Convert abstract syntax to to high-level intermediate reprensentation (HIR). 27bf215546Sopenharmony_ci * 28bf215546Sopenharmony_ci * During the conversion to HIR, the majority of the symantic checking is 29bf215546Sopenharmony_ci * preformed on the program. This includes: 30bf215546Sopenharmony_ci * 31bf215546Sopenharmony_ci * * Symbol table management 32bf215546Sopenharmony_ci * * Type checking 33bf215546Sopenharmony_ci * * Function binding 34bf215546Sopenharmony_ci * 35bf215546Sopenharmony_ci * The majority of this work could be done during parsing, and the parser could 36bf215546Sopenharmony_ci * probably generate HIR directly. However, this results in frequent changes 37bf215546Sopenharmony_ci * to the parser code. Since we do not assume that every system this complier 38bf215546Sopenharmony_ci * is built on will have Flex and Bison installed, we have to store the code 39bf215546Sopenharmony_ci * generated by these tools in our version control system. In other parts of 40bf215546Sopenharmony_ci * the system we've seen problems where a parser was changed but the generated 41bf215546Sopenharmony_ci * code was not committed, merge conflicts where created because two developers 42bf215546Sopenharmony_ci * had slightly different versions of Bison installed, etc. 43bf215546Sopenharmony_ci * 44bf215546Sopenharmony_ci * I have also noticed that running Bison generated parsers in GDB is very 45bf215546Sopenharmony_ci * irritating. When you get a segfault on '$$ = $1->foo', you can't very 46bf215546Sopenharmony_ci * well 'print $1' in GDB. 47bf215546Sopenharmony_ci * 48bf215546Sopenharmony_ci * As a result, my preference is to put as little C code as possible in the 49bf215546Sopenharmony_ci * parser (and lexer) sources. 50bf215546Sopenharmony_ci */ 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci#include "glsl_symbol_table.h" 53bf215546Sopenharmony_ci#include "glsl_parser_extras.h" 54bf215546Sopenharmony_ci#include "ast.h" 55bf215546Sopenharmony_ci#include "compiler/glsl_types.h" 56bf215546Sopenharmony_ci#include "util/hash_table.h" 57bf215546Sopenharmony_ci#include "main/consts_exts.h" 58bf215546Sopenharmony_ci#include "main/macros.h" 59bf215546Sopenharmony_ci#include "main/shaderobj.h" 60bf215546Sopenharmony_ci#include "ir.h" 61bf215546Sopenharmony_ci#include "ir_builder.h" 62bf215546Sopenharmony_ci#include "builtin_functions.h" 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ciusing namespace ir_builder; 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_cistatic void 67bf215546Sopenharmony_cidetect_conflicting_assignments(struct _mesa_glsl_parse_state *state, 68bf215546Sopenharmony_ci exec_list *instructions); 69bf215546Sopenharmony_cistatic void 70bf215546Sopenharmony_civerify_subroutine_associated_funcs(struct _mesa_glsl_parse_state *state); 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_cistatic void 73bf215546Sopenharmony_ciremove_per_vertex_blocks(exec_list *instructions, 74bf215546Sopenharmony_ci _mesa_glsl_parse_state *state, ir_variable_mode mode); 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci/** 77bf215546Sopenharmony_ci * Visitor class that finds the first instance of any write-only variable that 78bf215546Sopenharmony_ci * is ever read, if any 79bf215546Sopenharmony_ci */ 80bf215546Sopenharmony_ciclass read_from_write_only_variable_visitor : public ir_hierarchical_visitor 81bf215546Sopenharmony_ci{ 82bf215546Sopenharmony_cipublic: 83bf215546Sopenharmony_ci read_from_write_only_variable_visitor() : found(NULL) 84bf215546Sopenharmony_ci { 85bf215546Sopenharmony_ci } 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci virtual ir_visitor_status visit(ir_dereference_variable *ir) 88bf215546Sopenharmony_ci { 89bf215546Sopenharmony_ci if (this->in_assignee) 90bf215546Sopenharmony_ci return visit_continue; 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci ir_variable *var = ir->variable_referenced(); 93bf215546Sopenharmony_ci /* We can have memory_write_only set on both images and buffer variables, 94bf215546Sopenharmony_ci * but in the former there is a distinction between reads from 95bf215546Sopenharmony_ci * the variable itself (write_only) and from the memory they point to 96bf215546Sopenharmony_ci * (memory_write_only), while in the case of buffer variables there is 97bf215546Sopenharmony_ci * no such distinction, that is why this check here is limited to 98bf215546Sopenharmony_ci * buffer variables alone. 99bf215546Sopenharmony_ci */ 100bf215546Sopenharmony_ci if (!var || var->data.mode != ir_var_shader_storage) 101bf215546Sopenharmony_ci return visit_continue; 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci if (var->data.memory_write_only) { 104bf215546Sopenharmony_ci found = var; 105bf215546Sopenharmony_ci return visit_stop; 106bf215546Sopenharmony_ci } 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci return visit_continue; 109bf215546Sopenharmony_ci } 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci ir_variable *get_variable() { 112bf215546Sopenharmony_ci return found; 113bf215546Sopenharmony_ci } 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci virtual ir_visitor_status visit_enter(ir_expression *ir) 116bf215546Sopenharmony_ci { 117bf215546Sopenharmony_ci /* .length() doesn't actually read anything */ 118bf215546Sopenharmony_ci if (ir->operation == ir_unop_ssbo_unsized_array_length) 119bf215546Sopenharmony_ci return visit_continue_with_parent; 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ci return visit_continue; 122bf215546Sopenharmony_ci } 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ciprivate: 125bf215546Sopenharmony_ci ir_variable *found; 126bf215546Sopenharmony_ci}; 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_civoid 129bf215546Sopenharmony_ci_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) 130bf215546Sopenharmony_ci{ 131bf215546Sopenharmony_ci _mesa_glsl_initialize_variables(instructions, state); 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci state->symbols->separate_function_namespace = state->language_version == 110; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci state->current_function = NULL; 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci state->toplevel_ir = instructions; 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci state->gs_input_prim_type_specified = false; 140bf215546Sopenharmony_ci state->tcs_output_vertices_specified = false; 141bf215546Sopenharmony_ci state->cs_input_local_size_specified = false; 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci /* Section 4.2 of the GLSL 1.20 specification states: 144bf215546Sopenharmony_ci * "The built-in functions are scoped in a scope outside the global scope 145bf215546Sopenharmony_ci * users declare global variables in. That is, a shader's global scope, 146bf215546Sopenharmony_ci * available for user-defined functions and global variables, is nested 147bf215546Sopenharmony_ci * inside the scope containing the built-in functions." 148bf215546Sopenharmony_ci * 149bf215546Sopenharmony_ci * Since built-in functions like ftransform() access built-in variables, 150bf215546Sopenharmony_ci * it follows that those must be in the outer scope as well. 151bf215546Sopenharmony_ci * 152bf215546Sopenharmony_ci * We push scope here to create this nesting effect...but don't pop. 153bf215546Sopenharmony_ci * This way, a shader's globals are still in the symbol table for use 154bf215546Sopenharmony_ci * by the linker. 155bf215546Sopenharmony_ci */ 156bf215546Sopenharmony_ci state->symbols->push_scope(); 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci foreach_list_typed (ast_node, ast, link, & state->translation_unit) 159bf215546Sopenharmony_ci ast->hir(instructions, state); 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci verify_subroutine_associated_funcs(state); 162bf215546Sopenharmony_ci detect_recursion_unlinked(state, instructions); 163bf215546Sopenharmony_ci detect_conflicting_assignments(state, instructions); 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci state->toplevel_ir = NULL; 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci /* Move all of the variable declarations to the front of the IR list, and 168bf215546Sopenharmony_ci * reverse the order. This has the (intended!) side effect that vertex 169bf215546Sopenharmony_ci * shader inputs and fragment shader outputs will appear in the IR in the 170bf215546Sopenharmony_ci * same order that they appeared in the shader code. This results in the 171bf215546Sopenharmony_ci * locations being assigned in the declared order. Many (arguably buggy) 172bf215546Sopenharmony_ci * applications depend on this behavior, and it matches what nearly all 173bf215546Sopenharmony_ci * other drivers do. 174bf215546Sopenharmony_ci */ 175bf215546Sopenharmony_ci foreach_in_list_safe(ir_instruction, node, instructions) { 176bf215546Sopenharmony_ci ir_variable *const var = node->as_variable(); 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci if (var == NULL) 179bf215546Sopenharmony_ci continue; 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci var->remove(); 182bf215546Sopenharmony_ci instructions->push_head(var); 183bf215546Sopenharmony_ci } 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci /* Figure out if gl_FragCoord is actually used in fragment shader */ 186bf215546Sopenharmony_ci ir_variable *const var = state->symbols->get_variable("gl_FragCoord"); 187bf215546Sopenharmony_ci if (var != NULL) 188bf215546Sopenharmony_ci state->fs_uses_gl_fragcoord = var->data.used; 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci /* From section 7.1 (Built-In Language Variables) of the GLSL 4.10 spec: 191bf215546Sopenharmony_ci * 192bf215546Sopenharmony_ci * If multiple shaders using members of a built-in block belonging to 193bf215546Sopenharmony_ci * the same interface are linked together in the same program, they 194bf215546Sopenharmony_ci * must all redeclare the built-in block in the same way, as described 195bf215546Sopenharmony_ci * in section 4.3.7 "Interface Blocks" for interface block matching, or 196bf215546Sopenharmony_ci * a link error will result. 197bf215546Sopenharmony_ci * 198bf215546Sopenharmony_ci * The phrase "using members of a built-in block" implies that if two 199bf215546Sopenharmony_ci * shaders are linked together and one of them *does not use* any members 200bf215546Sopenharmony_ci * of the built-in block, then that shader does not need to have a matching 201bf215546Sopenharmony_ci * redeclaration of the built-in block. 202bf215546Sopenharmony_ci * 203bf215546Sopenharmony_ci * This appears to be a clarification to the behaviour established for 204bf215546Sopenharmony_ci * gl_PerVertex by GLSL 1.50, therefore implement it regardless of GLSL 205bf215546Sopenharmony_ci * version. 206bf215546Sopenharmony_ci * 207bf215546Sopenharmony_ci * The definition of "interface" in section 4.3.7 that applies here is as 208bf215546Sopenharmony_ci * follows: 209bf215546Sopenharmony_ci * 210bf215546Sopenharmony_ci * The boundary between adjacent programmable pipeline stages: This 211bf215546Sopenharmony_ci * spans all the outputs in all compilation units of the first stage 212bf215546Sopenharmony_ci * and all the inputs in all compilation units of the second stage. 213bf215546Sopenharmony_ci * 214bf215546Sopenharmony_ci * Therefore this rule applies to both inter- and intra-stage linking. 215bf215546Sopenharmony_ci * 216bf215546Sopenharmony_ci * The easiest way to implement this is to check whether the shader uses 217bf215546Sopenharmony_ci * gl_PerVertex right after ast-to-ir conversion, and if it doesn't, simply 218bf215546Sopenharmony_ci * remove all the relevant variable declaration from the IR, so that the 219bf215546Sopenharmony_ci * linker won't see them and complain about mismatches. 220bf215546Sopenharmony_ci */ 221bf215546Sopenharmony_ci remove_per_vertex_blocks(instructions, state, ir_var_shader_in); 222bf215546Sopenharmony_ci remove_per_vertex_blocks(instructions, state, ir_var_shader_out); 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci /* Check that we don't have reads from write-only variables */ 225bf215546Sopenharmony_ci read_from_write_only_variable_visitor v; 226bf215546Sopenharmony_ci v.run(instructions); 227bf215546Sopenharmony_ci ir_variable *error_var = v.get_variable(); 228bf215546Sopenharmony_ci if (error_var) { 229bf215546Sopenharmony_ci /* It would be nice to have proper location information, but for that 230bf215546Sopenharmony_ci * we would need to check this as we process each kind of AST node 231bf215546Sopenharmony_ci */ 232bf215546Sopenharmony_ci YYLTYPE loc; 233bf215546Sopenharmony_ci memset(&loc, 0, sizeof(loc)); 234bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "Read from write-only variable `%s'", 235bf215546Sopenharmony_ci error_var->name); 236bf215546Sopenharmony_ci } 237bf215546Sopenharmony_ci} 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_cistatic ir_expression_operation 241bf215546Sopenharmony_ciget_implicit_conversion_operation(const glsl_type *to, const glsl_type *from, 242bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 243bf215546Sopenharmony_ci{ 244bf215546Sopenharmony_ci switch (to->base_type) { 245bf215546Sopenharmony_ci case GLSL_TYPE_FLOAT: 246bf215546Sopenharmony_ci switch (from->base_type) { 247bf215546Sopenharmony_ci case GLSL_TYPE_INT: return ir_unop_i2f; 248bf215546Sopenharmony_ci case GLSL_TYPE_UINT: return ir_unop_u2f; 249bf215546Sopenharmony_ci default: return (ir_expression_operation)0; 250bf215546Sopenharmony_ci } 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci case GLSL_TYPE_UINT: 253bf215546Sopenharmony_ci if (!state->has_implicit_int_to_uint_conversion()) 254bf215546Sopenharmony_ci return (ir_expression_operation)0; 255bf215546Sopenharmony_ci switch (from->base_type) { 256bf215546Sopenharmony_ci case GLSL_TYPE_INT: return ir_unop_i2u; 257bf215546Sopenharmony_ci default: return (ir_expression_operation)0; 258bf215546Sopenharmony_ci } 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci case GLSL_TYPE_DOUBLE: 261bf215546Sopenharmony_ci if (!state->has_double()) 262bf215546Sopenharmony_ci return (ir_expression_operation)0; 263bf215546Sopenharmony_ci switch (from->base_type) { 264bf215546Sopenharmony_ci case GLSL_TYPE_INT: return ir_unop_i2d; 265bf215546Sopenharmony_ci case GLSL_TYPE_UINT: return ir_unop_u2d; 266bf215546Sopenharmony_ci case GLSL_TYPE_FLOAT: return ir_unop_f2d; 267bf215546Sopenharmony_ci case GLSL_TYPE_INT64: return ir_unop_i642d; 268bf215546Sopenharmony_ci case GLSL_TYPE_UINT64: return ir_unop_u642d; 269bf215546Sopenharmony_ci default: return (ir_expression_operation)0; 270bf215546Sopenharmony_ci } 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci case GLSL_TYPE_UINT64: 273bf215546Sopenharmony_ci if (!state->has_int64()) 274bf215546Sopenharmony_ci return (ir_expression_operation)0; 275bf215546Sopenharmony_ci switch (from->base_type) { 276bf215546Sopenharmony_ci case GLSL_TYPE_INT: return ir_unop_i2u64; 277bf215546Sopenharmony_ci case GLSL_TYPE_UINT: return ir_unop_u2u64; 278bf215546Sopenharmony_ci case GLSL_TYPE_INT64: return ir_unop_i642u64; 279bf215546Sopenharmony_ci default: return (ir_expression_operation)0; 280bf215546Sopenharmony_ci } 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci case GLSL_TYPE_INT64: 283bf215546Sopenharmony_ci if (!state->has_int64()) 284bf215546Sopenharmony_ci return (ir_expression_operation)0; 285bf215546Sopenharmony_ci switch (from->base_type) { 286bf215546Sopenharmony_ci case GLSL_TYPE_INT: return ir_unop_i2i64; 287bf215546Sopenharmony_ci default: return (ir_expression_operation)0; 288bf215546Sopenharmony_ci } 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci default: return (ir_expression_operation)0; 291bf215546Sopenharmony_ci } 292bf215546Sopenharmony_ci} 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci 295bf215546Sopenharmony_ci/** 296bf215546Sopenharmony_ci * If a conversion is available, convert one operand to a different type 297bf215546Sopenharmony_ci * 298bf215546Sopenharmony_ci * The \c from \c ir_rvalue is converted "in place". 299bf215546Sopenharmony_ci * 300bf215546Sopenharmony_ci * \param to Type that the operand it to be converted to 301bf215546Sopenharmony_ci * \param from Operand that is being converted 302bf215546Sopenharmony_ci * \param state GLSL compiler state 303bf215546Sopenharmony_ci * 304bf215546Sopenharmony_ci * \return 305bf215546Sopenharmony_ci * If a conversion is possible (or unnecessary), \c true is returned. 306bf215546Sopenharmony_ci * Otherwise \c false is returned. 307bf215546Sopenharmony_ci */ 308bf215546Sopenharmony_cistatic bool 309bf215546Sopenharmony_ciapply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, 310bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 311bf215546Sopenharmony_ci{ 312bf215546Sopenharmony_ci void *ctx = state; 313bf215546Sopenharmony_ci if (to->base_type == from->type->base_type) 314bf215546Sopenharmony_ci return true; 315bf215546Sopenharmony_ci 316bf215546Sopenharmony_ci /* Prior to GLSL 1.20, there are no implicit conversions */ 317bf215546Sopenharmony_ci if (!state->has_implicit_conversions()) 318bf215546Sopenharmony_ci return false; 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci /* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec: 321bf215546Sopenharmony_ci * 322bf215546Sopenharmony_ci * "There are no implicit array or structure conversions. For 323bf215546Sopenharmony_ci * example, an array of int cannot be implicitly converted to an 324bf215546Sopenharmony_ci * array of float. 325bf215546Sopenharmony_ci */ 326bf215546Sopenharmony_ci if (!to->is_numeric() || !from->type->is_numeric()) 327bf215546Sopenharmony_ci return false; 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci /* We don't actually want the specific type `to`, we want a type 330bf215546Sopenharmony_ci * with the same base type as `to`, but the same vector width as 331bf215546Sopenharmony_ci * `from`. 332bf215546Sopenharmony_ci */ 333bf215546Sopenharmony_ci to = glsl_type::get_instance(to->base_type, from->type->vector_elements, 334bf215546Sopenharmony_ci from->type->matrix_columns); 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci ir_expression_operation op = get_implicit_conversion_operation(to, from->type, state); 337bf215546Sopenharmony_ci if (op) { 338bf215546Sopenharmony_ci from = new(ctx) ir_expression(op, to, from, NULL); 339bf215546Sopenharmony_ci return true; 340bf215546Sopenharmony_ci } else { 341bf215546Sopenharmony_ci return false; 342bf215546Sopenharmony_ci } 343bf215546Sopenharmony_ci} 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_cistatic const struct glsl_type * 347bf215546Sopenharmony_ciarithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, 348bf215546Sopenharmony_ci bool multiply, 349bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, YYLTYPE *loc) 350bf215546Sopenharmony_ci{ 351bf215546Sopenharmony_ci const glsl_type *type_a = value_a->type; 352bf215546Sopenharmony_ci const glsl_type *type_b = value_b->type; 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci /* From GLSL 1.50 spec, page 56: 355bf215546Sopenharmony_ci * 356bf215546Sopenharmony_ci * "The arithmetic binary operators add (+), subtract (-), 357bf215546Sopenharmony_ci * multiply (*), and divide (/) operate on integer and 358bf215546Sopenharmony_ci * floating-point scalars, vectors, and matrices." 359bf215546Sopenharmony_ci */ 360bf215546Sopenharmony_ci if (!type_a->is_numeric() || !type_b->is_numeric()) { 361bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 362bf215546Sopenharmony_ci "operands to arithmetic operators must be numeric"); 363bf215546Sopenharmony_ci return glsl_type::error_type; 364bf215546Sopenharmony_ci } 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_ci /* "If one operand is floating-point based and the other is 368bf215546Sopenharmony_ci * not, then the conversions from Section 4.1.10 "Implicit 369bf215546Sopenharmony_ci * Conversions" are applied to the non-floating-point-based operand." 370bf215546Sopenharmony_ci */ 371bf215546Sopenharmony_ci if (!apply_implicit_conversion(type_a, value_b, state) 372bf215546Sopenharmony_ci && !apply_implicit_conversion(type_b, value_a, state)) { 373bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 374bf215546Sopenharmony_ci "could not implicitly convert operands to " 375bf215546Sopenharmony_ci "arithmetic operator"); 376bf215546Sopenharmony_ci return glsl_type::error_type; 377bf215546Sopenharmony_ci } 378bf215546Sopenharmony_ci type_a = value_a->type; 379bf215546Sopenharmony_ci type_b = value_b->type; 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_ci /* "If the operands are integer types, they must both be signed or 382bf215546Sopenharmony_ci * both be unsigned." 383bf215546Sopenharmony_ci * 384bf215546Sopenharmony_ci * From this rule and the preceeding conversion it can be inferred that 385bf215546Sopenharmony_ci * both types must be GLSL_TYPE_FLOAT, or GLSL_TYPE_UINT, or GLSL_TYPE_INT. 386bf215546Sopenharmony_ci * The is_numeric check above already filtered out the case where either 387bf215546Sopenharmony_ci * type is not one of these, so now the base types need only be tested for 388bf215546Sopenharmony_ci * equality. 389bf215546Sopenharmony_ci */ 390bf215546Sopenharmony_ci if (type_a->base_type != type_b->base_type) { 391bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 392bf215546Sopenharmony_ci "base type mismatch for arithmetic operator"); 393bf215546Sopenharmony_ci return glsl_type::error_type; 394bf215546Sopenharmony_ci } 395bf215546Sopenharmony_ci 396bf215546Sopenharmony_ci /* "All arithmetic binary operators result in the same fundamental type 397bf215546Sopenharmony_ci * (signed integer, unsigned integer, or floating-point) as the 398bf215546Sopenharmony_ci * operands they operate on, after operand type conversion. After 399bf215546Sopenharmony_ci * conversion, the following cases are valid 400bf215546Sopenharmony_ci * 401bf215546Sopenharmony_ci * * The two operands are scalars. In this case the operation is 402bf215546Sopenharmony_ci * applied, resulting in a scalar." 403bf215546Sopenharmony_ci */ 404bf215546Sopenharmony_ci if (type_a->is_scalar() && type_b->is_scalar()) 405bf215546Sopenharmony_ci return type_a; 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci /* "* One operand is a scalar, and the other is a vector or matrix. 408bf215546Sopenharmony_ci * In this case, the scalar operation is applied independently to each 409bf215546Sopenharmony_ci * component of the vector or matrix, resulting in the same size 410bf215546Sopenharmony_ci * vector or matrix." 411bf215546Sopenharmony_ci */ 412bf215546Sopenharmony_ci if (type_a->is_scalar()) { 413bf215546Sopenharmony_ci if (!type_b->is_scalar()) 414bf215546Sopenharmony_ci return type_b; 415bf215546Sopenharmony_ci } else if (type_b->is_scalar()) { 416bf215546Sopenharmony_ci return type_a; 417bf215546Sopenharmony_ci } 418bf215546Sopenharmony_ci 419bf215546Sopenharmony_ci /* All of the combinations of <scalar, scalar>, <vector, scalar>, 420bf215546Sopenharmony_ci * <scalar, vector>, <scalar, matrix>, and <matrix, scalar> have been 421bf215546Sopenharmony_ci * handled. 422bf215546Sopenharmony_ci */ 423bf215546Sopenharmony_ci assert(!type_a->is_scalar()); 424bf215546Sopenharmony_ci assert(!type_b->is_scalar()); 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci /* "* The two operands are vectors of the same size. In this case, the 427bf215546Sopenharmony_ci * operation is done component-wise resulting in the same size 428bf215546Sopenharmony_ci * vector." 429bf215546Sopenharmony_ci */ 430bf215546Sopenharmony_ci if (type_a->is_vector() && type_b->is_vector()) { 431bf215546Sopenharmony_ci if (type_a == type_b) { 432bf215546Sopenharmony_ci return type_a; 433bf215546Sopenharmony_ci } else { 434bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 435bf215546Sopenharmony_ci "vector size mismatch for arithmetic operator"); 436bf215546Sopenharmony_ci return glsl_type::error_type; 437bf215546Sopenharmony_ci } 438bf215546Sopenharmony_ci } 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci /* All of the combinations of <scalar, scalar>, <vector, scalar>, 441bf215546Sopenharmony_ci * <scalar, vector>, <scalar, matrix>, <matrix, scalar>, and 442bf215546Sopenharmony_ci * <vector, vector> have been handled. At least one of the operands must 443bf215546Sopenharmony_ci * be matrix. Further, since there are no integer matrix types, the base 444bf215546Sopenharmony_ci * type of both operands must be float. 445bf215546Sopenharmony_ci */ 446bf215546Sopenharmony_ci assert(type_a->is_matrix() || type_b->is_matrix()); 447bf215546Sopenharmony_ci assert(type_a->is_float() || type_a->is_double()); 448bf215546Sopenharmony_ci assert(type_b->is_float() || type_b->is_double()); 449bf215546Sopenharmony_ci 450bf215546Sopenharmony_ci /* "* The operator is add (+), subtract (-), or divide (/), and the 451bf215546Sopenharmony_ci * operands are matrices with the same number of rows and the same 452bf215546Sopenharmony_ci * number of columns. In this case, the operation is done component- 453bf215546Sopenharmony_ci * wise resulting in the same size matrix." 454bf215546Sopenharmony_ci * * The operator is multiply (*), where both operands are matrices or 455bf215546Sopenharmony_ci * one operand is a vector and the other a matrix. A right vector 456bf215546Sopenharmony_ci * operand is treated as a column vector and a left vector operand as a 457bf215546Sopenharmony_ci * row vector. In all these cases, it is required that the number of 458bf215546Sopenharmony_ci * columns of the left operand is equal to the number of rows of the 459bf215546Sopenharmony_ci * right operand. Then, the multiply (*) operation does a linear 460bf215546Sopenharmony_ci * algebraic multiply, yielding an object that has the same number of 461bf215546Sopenharmony_ci * rows as the left operand and the same number of columns as the right 462bf215546Sopenharmony_ci * operand. Section 5.10 "Vector and Matrix Operations" explains in 463bf215546Sopenharmony_ci * more detail how vectors and matrices are operated on." 464bf215546Sopenharmony_ci */ 465bf215546Sopenharmony_ci if (! multiply) { 466bf215546Sopenharmony_ci if (type_a == type_b) 467bf215546Sopenharmony_ci return type_a; 468bf215546Sopenharmony_ci } else { 469bf215546Sopenharmony_ci const glsl_type *type = glsl_type::get_mul_type(type_a, type_b); 470bf215546Sopenharmony_ci 471bf215546Sopenharmony_ci if (type == glsl_type::error_type) { 472bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 473bf215546Sopenharmony_ci "size mismatch for matrix multiplication"); 474bf215546Sopenharmony_ci } 475bf215546Sopenharmony_ci 476bf215546Sopenharmony_ci return type; 477bf215546Sopenharmony_ci } 478bf215546Sopenharmony_ci 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_ci /* "All other cases are illegal." 481bf215546Sopenharmony_ci */ 482bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "type mismatch"); 483bf215546Sopenharmony_ci return glsl_type::error_type; 484bf215546Sopenharmony_ci} 485bf215546Sopenharmony_ci 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_cistatic const struct glsl_type * 488bf215546Sopenharmony_ciunary_arithmetic_result_type(const struct glsl_type *type, 489bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, YYLTYPE *loc) 490bf215546Sopenharmony_ci{ 491bf215546Sopenharmony_ci /* From GLSL 1.50 spec, page 57: 492bf215546Sopenharmony_ci * 493bf215546Sopenharmony_ci * "The arithmetic unary operators negate (-), post- and pre-increment 494bf215546Sopenharmony_ci * and decrement (-- and ++) operate on integer or floating-point 495bf215546Sopenharmony_ci * values (including vectors and matrices). All unary operators work 496bf215546Sopenharmony_ci * component-wise on their operands. These result with the same type 497bf215546Sopenharmony_ci * they operated on." 498bf215546Sopenharmony_ci */ 499bf215546Sopenharmony_ci if (!type->is_numeric()) { 500bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 501bf215546Sopenharmony_ci "operands to arithmetic operators must be numeric"); 502bf215546Sopenharmony_ci return glsl_type::error_type; 503bf215546Sopenharmony_ci } 504bf215546Sopenharmony_ci 505bf215546Sopenharmony_ci return type; 506bf215546Sopenharmony_ci} 507bf215546Sopenharmony_ci 508bf215546Sopenharmony_ci/** 509bf215546Sopenharmony_ci * \brief Return the result type of a bit-logic operation. 510bf215546Sopenharmony_ci * 511bf215546Sopenharmony_ci * If the given types to the bit-logic operator are invalid, return 512bf215546Sopenharmony_ci * glsl_type::error_type. 513bf215546Sopenharmony_ci * 514bf215546Sopenharmony_ci * \param value_a LHS of bit-logic op 515bf215546Sopenharmony_ci * \param value_b RHS of bit-logic op 516bf215546Sopenharmony_ci */ 517bf215546Sopenharmony_cistatic const struct glsl_type * 518bf215546Sopenharmony_cibit_logic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, 519bf215546Sopenharmony_ci ast_operators op, 520bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, YYLTYPE *loc) 521bf215546Sopenharmony_ci{ 522bf215546Sopenharmony_ci const glsl_type *type_a = value_a->type; 523bf215546Sopenharmony_ci const glsl_type *type_b = value_b->type; 524bf215546Sopenharmony_ci 525bf215546Sopenharmony_ci if (!state->check_bitwise_operations_allowed(loc)) { 526bf215546Sopenharmony_ci return glsl_type::error_type; 527bf215546Sopenharmony_ci } 528bf215546Sopenharmony_ci 529bf215546Sopenharmony_ci /* From page 50 (page 56 of PDF) of GLSL 1.30 spec: 530bf215546Sopenharmony_ci * 531bf215546Sopenharmony_ci * "The bitwise operators and (&), exclusive-or (^), and inclusive-or 532bf215546Sopenharmony_ci * (|). The operands must be of type signed or unsigned integers or 533bf215546Sopenharmony_ci * integer vectors." 534bf215546Sopenharmony_ci */ 535bf215546Sopenharmony_ci if (!type_a->is_integer_32_64()) { 536bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "LHS of `%s' must be an integer", 537bf215546Sopenharmony_ci ast_expression::operator_string(op)); 538bf215546Sopenharmony_ci return glsl_type::error_type; 539bf215546Sopenharmony_ci } 540bf215546Sopenharmony_ci if (!type_b->is_integer_32_64()) { 541bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "RHS of `%s' must be an integer", 542bf215546Sopenharmony_ci ast_expression::operator_string(op)); 543bf215546Sopenharmony_ci return glsl_type::error_type; 544bf215546Sopenharmony_ci } 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci /* Prior to GLSL 4.0 / GL_ARB_gpu_shader5, implicit conversions didn't 547bf215546Sopenharmony_ci * make sense for bitwise operations, as they don't operate on floats. 548bf215546Sopenharmony_ci * 549bf215546Sopenharmony_ci * GLSL 4.0 added implicit int -> uint conversions, which are relevant 550bf215546Sopenharmony_ci * here. It wasn't clear whether or not we should apply them to bitwise 551bf215546Sopenharmony_ci * operations. However, Khronos has decided that they should in future 552bf215546Sopenharmony_ci * language revisions. Applications also rely on this behavior. We opt 553bf215546Sopenharmony_ci * to apply them in general, but issue a portability warning. 554bf215546Sopenharmony_ci * 555bf215546Sopenharmony_ci * See https://www.khronos.org/bugzilla/show_bug.cgi?id=1405 556bf215546Sopenharmony_ci */ 557bf215546Sopenharmony_ci if (type_a->base_type != type_b->base_type) { 558bf215546Sopenharmony_ci if (!apply_implicit_conversion(type_a, value_b, state) 559bf215546Sopenharmony_ci && !apply_implicit_conversion(type_b, value_a, state)) { 560bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 561bf215546Sopenharmony_ci "could not implicitly convert operands to " 562bf215546Sopenharmony_ci "`%s` operator", 563bf215546Sopenharmony_ci ast_expression::operator_string(op)); 564bf215546Sopenharmony_ci return glsl_type::error_type; 565bf215546Sopenharmony_ci } else { 566bf215546Sopenharmony_ci _mesa_glsl_warning(loc, state, 567bf215546Sopenharmony_ci "some implementations may not support implicit " 568bf215546Sopenharmony_ci "int -> uint conversions for `%s' operators; " 569bf215546Sopenharmony_ci "consider casting explicitly for portability", 570bf215546Sopenharmony_ci ast_expression::operator_string(op)); 571bf215546Sopenharmony_ci } 572bf215546Sopenharmony_ci type_a = value_a->type; 573bf215546Sopenharmony_ci type_b = value_b->type; 574bf215546Sopenharmony_ci } 575bf215546Sopenharmony_ci 576bf215546Sopenharmony_ci /* "The fundamental types of the operands (signed or unsigned) must 577bf215546Sopenharmony_ci * match," 578bf215546Sopenharmony_ci */ 579bf215546Sopenharmony_ci if (type_a->base_type != type_b->base_type) { 580bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "operands of `%s' must have the same " 581bf215546Sopenharmony_ci "base type", ast_expression::operator_string(op)); 582bf215546Sopenharmony_ci return glsl_type::error_type; 583bf215546Sopenharmony_ci } 584bf215546Sopenharmony_ci 585bf215546Sopenharmony_ci /* "The operands cannot be vectors of differing size." */ 586bf215546Sopenharmony_ci if (type_a->is_vector() && 587bf215546Sopenharmony_ci type_b->is_vector() && 588bf215546Sopenharmony_ci type_a->vector_elements != type_b->vector_elements) { 589bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "operands of `%s' cannot be vectors of " 590bf215546Sopenharmony_ci "different sizes", ast_expression::operator_string(op)); 591bf215546Sopenharmony_ci return glsl_type::error_type; 592bf215546Sopenharmony_ci } 593bf215546Sopenharmony_ci 594bf215546Sopenharmony_ci /* "If one operand is a scalar and the other a vector, the scalar is 595bf215546Sopenharmony_ci * applied component-wise to the vector, resulting in the same type as 596bf215546Sopenharmony_ci * the vector. The fundamental types of the operands [...] will be the 597bf215546Sopenharmony_ci * resulting fundamental type." 598bf215546Sopenharmony_ci */ 599bf215546Sopenharmony_ci if (type_a->is_scalar()) 600bf215546Sopenharmony_ci return type_b; 601bf215546Sopenharmony_ci else 602bf215546Sopenharmony_ci return type_a; 603bf215546Sopenharmony_ci} 604bf215546Sopenharmony_ci 605bf215546Sopenharmony_cistatic const struct glsl_type * 606bf215546Sopenharmony_cimodulus_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, 607bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, YYLTYPE *loc) 608bf215546Sopenharmony_ci{ 609bf215546Sopenharmony_ci const glsl_type *type_a = value_a->type; 610bf215546Sopenharmony_ci const glsl_type *type_b = value_b->type; 611bf215546Sopenharmony_ci 612bf215546Sopenharmony_ci if (!state->EXT_gpu_shader4_enable && 613bf215546Sopenharmony_ci !state->check_version(130, 300, loc, "operator '%%' is reserved")) { 614bf215546Sopenharmony_ci return glsl_type::error_type; 615bf215546Sopenharmony_ci } 616bf215546Sopenharmony_ci 617bf215546Sopenharmony_ci /* Section 5.9 (Expressions) of the GLSL 4.00 specification says: 618bf215546Sopenharmony_ci * 619bf215546Sopenharmony_ci * "The operator modulus (%) operates on signed or unsigned integers or 620bf215546Sopenharmony_ci * integer vectors." 621bf215546Sopenharmony_ci */ 622bf215546Sopenharmony_ci if (!type_a->is_integer_32_64()) { 623bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "LHS of operator %% must be an integer"); 624bf215546Sopenharmony_ci return glsl_type::error_type; 625bf215546Sopenharmony_ci } 626bf215546Sopenharmony_ci if (!type_b->is_integer_32_64()) { 627bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "RHS of operator %% must be an integer"); 628bf215546Sopenharmony_ci return glsl_type::error_type; 629bf215546Sopenharmony_ci } 630bf215546Sopenharmony_ci 631bf215546Sopenharmony_ci /* "If the fundamental types in the operands do not match, then the 632bf215546Sopenharmony_ci * conversions from section 4.1.10 "Implicit Conversions" are applied 633bf215546Sopenharmony_ci * to create matching types." 634bf215546Sopenharmony_ci * 635bf215546Sopenharmony_ci * Note that GLSL 4.00 (and GL_ARB_gpu_shader5) introduced implicit 636bf215546Sopenharmony_ci * int -> uint conversion rules. Prior to that, there were no implicit 637bf215546Sopenharmony_ci * conversions. So it's harmless to apply them universally - no implicit 638bf215546Sopenharmony_ci * conversions will exist. If the types don't match, we'll receive false, 639bf215546Sopenharmony_ci * and raise an error, satisfying the GLSL 1.50 spec, page 56: 640bf215546Sopenharmony_ci * 641bf215546Sopenharmony_ci * "The operand types must both be signed or unsigned." 642bf215546Sopenharmony_ci */ 643bf215546Sopenharmony_ci if (!apply_implicit_conversion(type_a, value_b, state) && 644bf215546Sopenharmony_ci !apply_implicit_conversion(type_b, value_a, state)) { 645bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 646bf215546Sopenharmony_ci "could not implicitly convert operands to " 647bf215546Sopenharmony_ci "modulus (%%) operator"); 648bf215546Sopenharmony_ci return glsl_type::error_type; 649bf215546Sopenharmony_ci } 650bf215546Sopenharmony_ci type_a = value_a->type; 651bf215546Sopenharmony_ci type_b = value_b->type; 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_ci /* "The operands cannot be vectors of differing size. If one operand is 654bf215546Sopenharmony_ci * a scalar and the other vector, then the scalar is applied component- 655bf215546Sopenharmony_ci * wise to the vector, resulting in the same type as the vector. If both 656bf215546Sopenharmony_ci * are vectors of the same size, the result is computed component-wise." 657bf215546Sopenharmony_ci */ 658bf215546Sopenharmony_ci if (type_a->is_vector()) { 659bf215546Sopenharmony_ci if (!type_b->is_vector() 660bf215546Sopenharmony_ci || (type_a->vector_elements == type_b->vector_elements)) 661bf215546Sopenharmony_ci return type_a; 662bf215546Sopenharmony_ci } else 663bf215546Sopenharmony_ci return type_b; 664bf215546Sopenharmony_ci 665bf215546Sopenharmony_ci /* "The operator modulus (%) is not defined for any other data types 666bf215546Sopenharmony_ci * (non-integer types)." 667bf215546Sopenharmony_ci */ 668bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "type mismatch"); 669bf215546Sopenharmony_ci return glsl_type::error_type; 670bf215546Sopenharmony_ci} 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_ci 673bf215546Sopenharmony_cistatic const struct glsl_type * 674bf215546Sopenharmony_cirelational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, 675bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, YYLTYPE *loc) 676bf215546Sopenharmony_ci{ 677bf215546Sopenharmony_ci const glsl_type *type_a = value_a->type; 678bf215546Sopenharmony_ci const glsl_type *type_b = value_b->type; 679bf215546Sopenharmony_ci 680bf215546Sopenharmony_ci /* From GLSL 1.50 spec, page 56: 681bf215546Sopenharmony_ci * "The relational operators greater than (>), less than (<), greater 682bf215546Sopenharmony_ci * than or equal (>=), and less than or equal (<=) operate only on 683bf215546Sopenharmony_ci * scalar integer and scalar floating-point expressions." 684bf215546Sopenharmony_ci */ 685bf215546Sopenharmony_ci if (!type_a->is_numeric() 686bf215546Sopenharmony_ci || !type_b->is_numeric() 687bf215546Sopenharmony_ci || !type_a->is_scalar() 688bf215546Sopenharmony_ci || !type_b->is_scalar()) { 689bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 690bf215546Sopenharmony_ci "operands to relational operators must be scalar and " 691bf215546Sopenharmony_ci "numeric"); 692bf215546Sopenharmony_ci return glsl_type::error_type; 693bf215546Sopenharmony_ci } 694bf215546Sopenharmony_ci 695bf215546Sopenharmony_ci /* "Either the operands' types must match, or the conversions from 696bf215546Sopenharmony_ci * Section 4.1.10 "Implicit Conversions" will be applied to the integer 697bf215546Sopenharmony_ci * operand, after which the types must match." 698bf215546Sopenharmony_ci */ 699bf215546Sopenharmony_ci if (!apply_implicit_conversion(type_a, value_b, state) 700bf215546Sopenharmony_ci && !apply_implicit_conversion(type_b, value_a, state)) { 701bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 702bf215546Sopenharmony_ci "could not implicitly convert operands to " 703bf215546Sopenharmony_ci "relational operator"); 704bf215546Sopenharmony_ci return glsl_type::error_type; 705bf215546Sopenharmony_ci } 706bf215546Sopenharmony_ci type_a = value_a->type; 707bf215546Sopenharmony_ci type_b = value_b->type; 708bf215546Sopenharmony_ci 709bf215546Sopenharmony_ci if (type_a->base_type != type_b->base_type) { 710bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "base type mismatch"); 711bf215546Sopenharmony_ci return glsl_type::error_type; 712bf215546Sopenharmony_ci } 713bf215546Sopenharmony_ci 714bf215546Sopenharmony_ci /* "The result is scalar Boolean." 715bf215546Sopenharmony_ci */ 716bf215546Sopenharmony_ci return glsl_type::bool_type; 717bf215546Sopenharmony_ci} 718bf215546Sopenharmony_ci 719bf215546Sopenharmony_ci/** 720bf215546Sopenharmony_ci * \brief Return the result type of a bit-shift operation. 721bf215546Sopenharmony_ci * 722bf215546Sopenharmony_ci * If the given types to the bit-shift operator are invalid, return 723bf215546Sopenharmony_ci * glsl_type::error_type. 724bf215546Sopenharmony_ci * 725bf215546Sopenharmony_ci * \param type_a Type of LHS of bit-shift op 726bf215546Sopenharmony_ci * \param type_b Type of RHS of bit-shift op 727bf215546Sopenharmony_ci */ 728bf215546Sopenharmony_cistatic const struct glsl_type * 729bf215546Sopenharmony_cishift_result_type(const struct glsl_type *type_a, 730bf215546Sopenharmony_ci const struct glsl_type *type_b, 731bf215546Sopenharmony_ci ast_operators op, 732bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, YYLTYPE *loc) 733bf215546Sopenharmony_ci{ 734bf215546Sopenharmony_ci if (!state->check_bitwise_operations_allowed(loc)) { 735bf215546Sopenharmony_ci return glsl_type::error_type; 736bf215546Sopenharmony_ci } 737bf215546Sopenharmony_ci 738bf215546Sopenharmony_ci /* From page 50 (page 56 of the PDF) of the GLSL 1.30 spec: 739bf215546Sopenharmony_ci * 740bf215546Sopenharmony_ci * "The shift operators (<<) and (>>). For both operators, the operands 741bf215546Sopenharmony_ci * must be signed or unsigned integers or integer vectors. One operand 742bf215546Sopenharmony_ci * can be signed while the other is unsigned." 743bf215546Sopenharmony_ci */ 744bf215546Sopenharmony_ci if (!type_a->is_integer_32_64()) { 745bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "LHS of operator %s must be an integer or " 746bf215546Sopenharmony_ci "integer vector", ast_expression::operator_string(op)); 747bf215546Sopenharmony_ci return glsl_type::error_type; 748bf215546Sopenharmony_ci 749bf215546Sopenharmony_ci } 750bf215546Sopenharmony_ci if (!type_b->is_integer_32()) { 751bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "RHS of operator %s must be an integer or " 752bf215546Sopenharmony_ci "integer vector", ast_expression::operator_string(op)); 753bf215546Sopenharmony_ci return glsl_type::error_type; 754bf215546Sopenharmony_ci } 755bf215546Sopenharmony_ci 756bf215546Sopenharmony_ci /* "If the first operand is a scalar, the second operand has to be 757bf215546Sopenharmony_ci * a scalar as well." 758bf215546Sopenharmony_ci */ 759bf215546Sopenharmony_ci if (type_a->is_scalar() && !type_b->is_scalar()) { 760bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "if the first operand of %s is scalar, the " 761bf215546Sopenharmony_ci "second must be scalar as well", 762bf215546Sopenharmony_ci ast_expression::operator_string(op)); 763bf215546Sopenharmony_ci return glsl_type::error_type; 764bf215546Sopenharmony_ci } 765bf215546Sopenharmony_ci 766bf215546Sopenharmony_ci /* If both operands are vectors, check that they have same number of 767bf215546Sopenharmony_ci * elements. 768bf215546Sopenharmony_ci */ 769bf215546Sopenharmony_ci if (type_a->is_vector() && 770bf215546Sopenharmony_ci type_b->is_vector() && 771bf215546Sopenharmony_ci type_a->vector_elements != type_b->vector_elements) { 772bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "vector operands to operator %s must " 773bf215546Sopenharmony_ci "have same number of elements", 774bf215546Sopenharmony_ci ast_expression::operator_string(op)); 775bf215546Sopenharmony_ci return glsl_type::error_type; 776bf215546Sopenharmony_ci } 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci /* "In all cases, the resulting type will be the same type as the left 779bf215546Sopenharmony_ci * operand." 780bf215546Sopenharmony_ci */ 781bf215546Sopenharmony_ci return type_a; 782bf215546Sopenharmony_ci} 783bf215546Sopenharmony_ci 784bf215546Sopenharmony_ci/** 785bf215546Sopenharmony_ci * Returns the innermost array index expression in an rvalue tree. 786bf215546Sopenharmony_ci * This is the largest indexing level -- if an array of blocks, then 787bf215546Sopenharmony_ci * it is the block index rather than an indexing expression for an 788bf215546Sopenharmony_ci * array-typed member of an array of blocks. 789bf215546Sopenharmony_ci */ 790bf215546Sopenharmony_cistatic ir_rvalue * 791bf215546Sopenharmony_cifind_innermost_array_index(ir_rvalue *rv) 792bf215546Sopenharmony_ci{ 793bf215546Sopenharmony_ci ir_dereference_array *last = NULL; 794bf215546Sopenharmony_ci while (rv) { 795bf215546Sopenharmony_ci if (rv->as_dereference_array()) { 796bf215546Sopenharmony_ci last = rv->as_dereference_array(); 797bf215546Sopenharmony_ci rv = last->array; 798bf215546Sopenharmony_ci } else if (rv->as_dereference_record()) 799bf215546Sopenharmony_ci rv = rv->as_dereference_record()->record; 800bf215546Sopenharmony_ci else if (rv->as_swizzle()) 801bf215546Sopenharmony_ci rv = rv->as_swizzle()->val; 802bf215546Sopenharmony_ci else 803bf215546Sopenharmony_ci rv = NULL; 804bf215546Sopenharmony_ci } 805bf215546Sopenharmony_ci 806bf215546Sopenharmony_ci if (last) 807bf215546Sopenharmony_ci return last->array_index; 808bf215546Sopenharmony_ci 809bf215546Sopenharmony_ci return NULL; 810bf215546Sopenharmony_ci} 811bf215546Sopenharmony_ci 812bf215546Sopenharmony_ci/** 813bf215546Sopenharmony_ci * Validates that a value can be assigned to a location with a specified type 814bf215546Sopenharmony_ci * 815bf215546Sopenharmony_ci * Validates that \c rhs can be assigned to some location. If the types are 816bf215546Sopenharmony_ci * not an exact match but an automatic conversion is possible, \c rhs will be 817bf215546Sopenharmony_ci * converted. 818bf215546Sopenharmony_ci * 819bf215546Sopenharmony_ci * \return 820bf215546Sopenharmony_ci * \c NULL if \c rhs cannot be assigned to a location with type \c lhs_type. 821bf215546Sopenharmony_ci * Otherwise the actual RHS to be assigned will be returned. This may be 822bf215546Sopenharmony_ci * \c rhs, or it may be \c rhs after some type conversion. 823bf215546Sopenharmony_ci * 824bf215546Sopenharmony_ci * \note 825bf215546Sopenharmony_ci * In addition to being used for assignments, this function is used to 826bf215546Sopenharmony_ci * type-check return values. 827bf215546Sopenharmony_ci */ 828bf215546Sopenharmony_cistatic ir_rvalue * 829bf215546Sopenharmony_civalidate_assignment(struct _mesa_glsl_parse_state *state, 830bf215546Sopenharmony_ci YYLTYPE loc, ir_rvalue *lhs, 831bf215546Sopenharmony_ci ir_rvalue *rhs, bool is_initializer) 832bf215546Sopenharmony_ci{ 833bf215546Sopenharmony_ci /* If there is already some error in the RHS, just return it. Anything 834bf215546Sopenharmony_ci * else will lead to an avalanche of error message back to the user. 835bf215546Sopenharmony_ci */ 836bf215546Sopenharmony_ci if (rhs->type->is_error()) 837bf215546Sopenharmony_ci return rhs; 838bf215546Sopenharmony_ci 839bf215546Sopenharmony_ci /* In the Tessellation Control Shader: 840bf215546Sopenharmony_ci * If a per-vertex output variable is used as an l-value, it is an error 841bf215546Sopenharmony_ci * if the expression indicating the vertex number is not the identifier 842bf215546Sopenharmony_ci * `gl_InvocationID`. 843bf215546Sopenharmony_ci */ 844bf215546Sopenharmony_ci if (state->stage == MESA_SHADER_TESS_CTRL && !lhs->type->is_error()) { 845bf215546Sopenharmony_ci ir_variable *var = lhs->variable_referenced(); 846bf215546Sopenharmony_ci if (var && var->data.mode == ir_var_shader_out && !var->data.patch) { 847bf215546Sopenharmony_ci ir_rvalue *index = find_innermost_array_index(lhs); 848bf215546Sopenharmony_ci ir_variable *index_var = index ? index->variable_referenced() : NULL; 849bf215546Sopenharmony_ci if (!index_var || strcmp(index_var->name, "gl_InvocationID") != 0) { 850bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 851bf215546Sopenharmony_ci "Tessellation control shader outputs can only " 852bf215546Sopenharmony_ci "be indexed by gl_InvocationID"); 853bf215546Sopenharmony_ci return NULL; 854bf215546Sopenharmony_ci } 855bf215546Sopenharmony_ci } 856bf215546Sopenharmony_ci } 857bf215546Sopenharmony_ci 858bf215546Sopenharmony_ci /* If the types are identical, the assignment can trivially proceed. 859bf215546Sopenharmony_ci */ 860bf215546Sopenharmony_ci if (rhs->type == lhs->type) 861bf215546Sopenharmony_ci return rhs; 862bf215546Sopenharmony_ci 863bf215546Sopenharmony_ci /* If the array element types are the same and the LHS is unsized, 864bf215546Sopenharmony_ci * the assignment is okay for initializers embedded in variable 865bf215546Sopenharmony_ci * declarations. 866bf215546Sopenharmony_ci * 867bf215546Sopenharmony_ci * Note: Whole-array assignments are not permitted in GLSL 1.10, but this 868bf215546Sopenharmony_ci * is handled by ir_dereference::is_lvalue. 869bf215546Sopenharmony_ci */ 870bf215546Sopenharmony_ci const glsl_type *lhs_t = lhs->type; 871bf215546Sopenharmony_ci const glsl_type *rhs_t = rhs->type; 872bf215546Sopenharmony_ci bool unsized_array = false; 873bf215546Sopenharmony_ci while(lhs_t->is_array()) { 874bf215546Sopenharmony_ci if (rhs_t == lhs_t) 875bf215546Sopenharmony_ci break; /* the rest of the inner arrays match so break out early */ 876bf215546Sopenharmony_ci if (!rhs_t->is_array()) { 877bf215546Sopenharmony_ci unsized_array = false; 878bf215546Sopenharmony_ci break; /* number of dimensions mismatch */ 879bf215546Sopenharmony_ci } 880bf215546Sopenharmony_ci if (lhs_t->length == rhs_t->length) { 881bf215546Sopenharmony_ci lhs_t = lhs_t->fields.array; 882bf215546Sopenharmony_ci rhs_t = rhs_t->fields.array; 883bf215546Sopenharmony_ci continue; 884bf215546Sopenharmony_ci } else if (lhs_t->is_unsized_array()) { 885bf215546Sopenharmony_ci unsized_array = true; 886bf215546Sopenharmony_ci } else { 887bf215546Sopenharmony_ci unsized_array = false; 888bf215546Sopenharmony_ci break; /* sized array mismatch */ 889bf215546Sopenharmony_ci } 890bf215546Sopenharmony_ci lhs_t = lhs_t->fields.array; 891bf215546Sopenharmony_ci rhs_t = rhs_t->fields.array; 892bf215546Sopenharmony_ci } 893bf215546Sopenharmony_ci if (unsized_array) { 894bf215546Sopenharmony_ci if (is_initializer) { 895bf215546Sopenharmony_ci if (rhs->type->get_scalar_type() == lhs->type->get_scalar_type()) 896bf215546Sopenharmony_ci return rhs; 897bf215546Sopenharmony_ci } else { 898bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 899bf215546Sopenharmony_ci "implicitly sized arrays cannot be assigned"); 900bf215546Sopenharmony_ci return NULL; 901bf215546Sopenharmony_ci } 902bf215546Sopenharmony_ci } 903bf215546Sopenharmony_ci 904bf215546Sopenharmony_ci /* Check for implicit conversion in GLSL 1.20 */ 905bf215546Sopenharmony_ci if (apply_implicit_conversion(lhs->type, rhs, state)) { 906bf215546Sopenharmony_ci if (rhs->type == lhs->type) 907bf215546Sopenharmony_ci return rhs; 908bf215546Sopenharmony_ci } 909bf215546Sopenharmony_ci 910bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 911bf215546Sopenharmony_ci "%s of type %s cannot be assigned to " 912bf215546Sopenharmony_ci "variable of type %s", 913bf215546Sopenharmony_ci is_initializer ? "initializer" : "value", 914bf215546Sopenharmony_ci rhs->type->name, lhs->type->name); 915bf215546Sopenharmony_ci 916bf215546Sopenharmony_ci return NULL; 917bf215546Sopenharmony_ci} 918bf215546Sopenharmony_ci 919bf215546Sopenharmony_cistatic void 920bf215546Sopenharmony_cimark_whole_array_access(ir_rvalue *access) 921bf215546Sopenharmony_ci{ 922bf215546Sopenharmony_ci ir_dereference_variable *deref = access->as_dereference_variable(); 923bf215546Sopenharmony_ci 924bf215546Sopenharmony_ci if (deref && deref->var) { 925bf215546Sopenharmony_ci deref->var->data.max_array_access = deref->type->length - 1; 926bf215546Sopenharmony_ci } 927bf215546Sopenharmony_ci} 928bf215546Sopenharmony_ci 929bf215546Sopenharmony_cistatic bool 930bf215546Sopenharmony_cido_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, 931bf215546Sopenharmony_ci const char *non_lvalue_description, 932bf215546Sopenharmony_ci ir_rvalue *lhs, ir_rvalue *rhs, 933bf215546Sopenharmony_ci ir_rvalue **out_rvalue, bool needs_rvalue, 934bf215546Sopenharmony_ci bool is_initializer, 935bf215546Sopenharmony_ci YYLTYPE lhs_loc) 936bf215546Sopenharmony_ci{ 937bf215546Sopenharmony_ci void *ctx = state; 938bf215546Sopenharmony_ci bool error_emitted = (lhs->type->is_error() || rhs->type->is_error()); 939bf215546Sopenharmony_ci 940bf215546Sopenharmony_ci ir_variable *lhs_var = lhs->variable_referenced(); 941bf215546Sopenharmony_ci if (lhs_var) 942bf215546Sopenharmony_ci lhs_var->data.assigned = true; 943bf215546Sopenharmony_ci 944bf215546Sopenharmony_ci bool omit_assignment = false; 945bf215546Sopenharmony_ci if (!error_emitted) { 946bf215546Sopenharmony_ci if (non_lvalue_description != NULL) { 947bf215546Sopenharmony_ci _mesa_glsl_error(&lhs_loc, state, 948bf215546Sopenharmony_ci "assignment to %s", 949bf215546Sopenharmony_ci non_lvalue_description); 950bf215546Sopenharmony_ci error_emitted = true; 951bf215546Sopenharmony_ci } else if (lhs_var != NULL && (lhs_var->data.read_only || 952bf215546Sopenharmony_ci (lhs_var->data.mode == ir_var_shader_storage && 953bf215546Sopenharmony_ci lhs_var->data.memory_read_only))) { 954bf215546Sopenharmony_ci /* We can have memory_read_only set on both images and buffer variables, 955bf215546Sopenharmony_ci * but in the former there is a distinction between assignments to 956bf215546Sopenharmony_ci * the variable itself (read_only) and to the memory they point to 957bf215546Sopenharmony_ci * (memory_read_only), while in the case of buffer variables there is 958bf215546Sopenharmony_ci * no such distinction, that is why this check here is limited to 959bf215546Sopenharmony_ci * buffer variables alone. 960bf215546Sopenharmony_ci */ 961bf215546Sopenharmony_ci 962bf215546Sopenharmony_ci if (state->ignore_write_to_readonly_var) 963bf215546Sopenharmony_ci omit_assignment = true; 964bf215546Sopenharmony_ci else { 965bf215546Sopenharmony_ci _mesa_glsl_error(&lhs_loc, state, 966bf215546Sopenharmony_ci "assignment to read-only variable '%s'", 967bf215546Sopenharmony_ci lhs_var->name); 968bf215546Sopenharmony_ci error_emitted = true; 969bf215546Sopenharmony_ci } 970bf215546Sopenharmony_ci } else if (lhs->type->is_array() && 971bf215546Sopenharmony_ci !state->check_version(state->allow_glsl_120_subset_in_110 ? 110 : 120, 972bf215546Sopenharmony_ci 300, &lhs_loc, 973bf215546Sopenharmony_ci "whole array assignment forbidden")) { 974bf215546Sopenharmony_ci /* From page 32 (page 38 of the PDF) of the GLSL 1.10 spec: 975bf215546Sopenharmony_ci * 976bf215546Sopenharmony_ci * "Other binary or unary expressions, non-dereferenced 977bf215546Sopenharmony_ci * arrays, function names, swizzles with repeated fields, 978bf215546Sopenharmony_ci * and constants cannot be l-values." 979bf215546Sopenharmony_ci * 980bf215546Sopenharmony_ci * The restriction on arrays is lifted in GLSL 1.20 and GLSL ES 3.00. 981bf215546Sopenharmony_ci */ 982bf215546Sopenharmony_ci error_emitted = true; 983bf215546Sopenharmony_ci } else if (!lhs->is_lvalue(state)) { 984bf215546Sopenharmony_ci _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment"); 985bf215546Sopenharmony_ci error_emitted = true; 986bf215546Sopenharmony_ci } 987bf215546Sopenharmony_ci } 988bf215546Sopenharmony_ci 989bf215546Sopenharmony_ci ir_rvalue *new_rhs = 990bf215546Sopenharmony_ci validate_assignment(state, lhs_loc, lhs, rhs, is_initializer); 991bf215546Sopenharmony_ci if (new_rhs != NULL) { 992bf215546Sopenharmony_ci rhs = new_rhs; 993bf215546Sopenharmony_ci 994bf215546Sopenharmony_ci /* If the LHS array was not declared with a size, it takes it size from 995bf215546Sopenharmony_ci * the RHS. If the LHS is an l-value and a whole array, it must be a 996bf215546Sopenharmony_ci * dereference of a variable. Any other case would require that the LHS 997bf215546Sopenharmony_ci * is either not an l-value or not a whole array. 998bf215546Sopenharmony_ci */ 999bf215546Sopenharmony_ci if (lhs->type->is_unsized_array()) { 1000bf215546Sopenharmony_ci ir_dereference *const d = lhs->as_dereference(); 1001bf215546Sopenharmony_ci 1002bf215546Sopenharmony_ci assert(d != NULL); 1003bf215546Sopenharmony_ci 1004bf215546Sopenharmony_ci ir_variable *const var = d->variable_referenced(); 1005bf215546Sopenharmony_ci 1006bf215546Sopenharmony_ci assert(var != NULL); 1007bf215546Sopenharmony_ci 1008bf215546Sopenharmony_ci if (var->data.max_array_access >= rhs->type->array_size()) { 1009bf215546Sopenharmony_ci /* FINISHME: This should actually log the location of the RHS. */ 1010bf215546Sopenharmony_ci _mesa_glsl_error(& lhs_loc, state, "array size must be > %u due to " 1011bf215546Sopenharmony_ci "previous access", 1012bf215546Sopenharmony_ci var->data.max_array_access); 1013bf215546Sopenharmony_ci } 1014bf215546Sopenharmony_ci 1015bf215546Sopenharmony_ci var->type = glsl_type::get_array_instance(lhs->type->fields.array, 1016bf215546Sopenharmony_ci rhs->type->array_size()); 1017bf215546Sopenharmony_ci d->type = var->type; 1018bf215546Sopenharmony_ci } 1019bf215546Sopenharmony_ci if (lhs->type->is_array()) { 1020bf215546Sopenharmony_ci mark_whole_array_access(rhs); 1021bf215546Sopenharmony_ci mark_whole_array_access(lhs); 1022bf215546Sopenharmony_ci } 1023bf215546Sopenharmony_ci } else { 1024bf215546Sopenharmony_ci error_emitted = true; 1025bf215546Sopenharmony_ci } 1026bf215546Sopenharmony_ci 1027bf215546Sopenharmony_ci if (omit_assignment) { 1028bf215546Sopenharmony_ci *out_rvalue = needs_rvalue ? ir_rvalue::error_value(ctx) : NULL; 1029bf215546Sopenharmony_ci return error_emitted; 1030bf215546Sopenharmony_ci } 1031bf215546Sopenharmony_ci 1032bf215546Sopenharmony_ci /* Most callers of do_assignment (assign, add_assign, pre_inc/dec, 1033bf215546Sopenharmony_ci * but not post_inc) need the converted assigned value as an rvalue 1034bf215546Sopenharmony_ci * to handle things like: 1035bf215546Sopenharmony_ci * 1036bf215546Sopenharmony_ci * i = j += 1; 1037bf215546Sopenharmony_ci */ 1038bf215546Sopenharmony_ci if (needs_rvalue) { 1039bf215546Sopenharmony_ci ir_rvalue *rvalue; 1040bf215546Sopenharmony_ci if (!error_emitted) { 1041bf215546Sopenharmony_ci ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp", 1042bf215546Sopenharmony_ci ir_var_temporary); 1043bf215546Sopenharmony_ci instructions->push_tail(var); 1044bf215546Sopenharmony_ci instructions->push_tail(assign(var, rhs)); 1045bf215546Sopenharmony_ci 1046bf215546Sopenharmony_ci ir_dereference_variable *deref_var = 1047bf215546Sopenharmony_ci new(ctx) ir_dereference_variable(var); 1048bf215546Sopenharmony_ci instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var)); 1049bf215546Sopenharmony_ci rvalue = new(ctx) ir_dereference_variable(var); 1050bf215546Sopenharmony_ci } else { 1051bf215546Sopenharmony_ci rvalue = ir_rvalue::error_value(ctx); 1052bf215546Sopenharmony_ci } 1053bf215546Sopenharmony_ci *out_rvalue = rvalue; 1054bf215546Sopenharmony_ci } else { 1055bf215546Sopenharmony_ci if (!error_emitted) 1056bf215546Sopenharmony_ci instructions->push_tail(new(ctx) ir_assignment(lhs, rhs)); 1057bf215546Sopenharmony_ci *out_rvalue = NULL; 1058bf215546Sopenharmony_ci } 1059bf215546Sopenharmony_ci 1060bf215546Sopenharmony_ci return error_emitted; 1061bf215546Sopenharmony_ci} 1062bf215546Sopenharmony_ci 1063bf215546Sopenharmony_cistatic ir_rvalue * 1064bf215546Sopenharmony_ciget_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue) 1065bf215546Sopenharmony_ci{ 1066bf215546Sopenharmony_ci void *ctx = ralloc_parent(lvalue); 1067bf215546Sopenharmony_ci ir_variable *var; 1068bf215546Sopenharmony_ci 1069bf215546Sopenharmony_ci var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp", 1070bf215546Sopenharmony_ci ir_var_temporary); 1071bf215546Sopenharmony_ci instructions->push_tail(var); 1072bf215546Sopenharmony_ci 1073bf215546Sopenharmony_ci instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var), 1074bf215546Sopenharmony_ci lvalue)); 1075bf215546Sopenharmony_ci 1076bf215546Sopenharmony_ci return new(ctx) ir_dereference_variable(var); 1077bf215546Sopenharmony_ci} 1078bf215546Sopenharmony_ci 1079bf215546Sopenharmony_ci 1080bf215546Sopenharmony_ciir_rvalue * 1081bf215546Sopenharmony_ciast_node::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) 1082bf215546Sopenharmony_ci{ 1083bf215546Sopenharmony_ci (void) instructions; 1084bf215546Sopenharmony_ci (void) state; 1085bf215546Sopenharmony_ci 1086bf215546Sopenharmony_ci return NULL; 1087bf215546Sopenharmony_ci} 1088bf215546Sopenharmony_ci 1089bf215546Sopenharmony_cibool 1090bf215546Sopenharmony_ciast_node::has_sequence_subexpression() const 1091bf215546Sopenharmony_ci{ 1092bf215546Sopenharmony_ci return false; 1093bf215546Sopenharmony_ci} 1094bf215546Sopenharmony_ci 1095bf215546Sopenharmony_civoid 1096bf215546Sopenharmony_ciast_node::set_is_lhs(bool /* new_value */) 1097bf215546Sopenharmony_ci{ 1098bf215546Sopenharmony_ci} 1099bf215546Sopenharmony_ci 1100bf215546Sopenharmony_civoid 1101bf215546Sopenharmony_ciast_function_expression::hir_no_rvalue(exec_list *instructions, 1102bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 1103bf215546Sopenharmony_ci{ 1104bf215546Sopenharmony_ci (void)hir(instructions, state); 1105bf215546Sopenharmony_ci} 1106bf215546Sopenharmony_ci 1107bf215546Sopenharmony_civoid 1108bf215546Sopenharmony_ciast_aggregate_initializer::hir_no_rvalue(exec_list *instructions, 1109bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 1110bf215546Sopenharmony_ci{ 1111bf215546Sopenharmony_ci (void)hir(instructions, state); 1112bf215546Sopenharmony_ci} 1113bf215546Sopenharmony_ci 1114bf215546Sopenharmony_cistatic ir_rvalue * 1115bf215546Sopenharmony_cido_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1) 1116bf215546Sopenharmony_ci{ 1117bf215546Sopenharmony_ci int join_op; 1118bf215546Sopenharmony_ci ir_rvalue *cmp = NULL; 1119bf215546Sopenharmony_ci 1120bf215546Sopenharmony_ci if (operation == ir_binop_all_equal) 1121bf215546Sopenharmony_ci join_op = ir_binop_logic_and; 1122bf215546Sopenharmony_ci else 1123bf215546Sopenharmony_ci join_op = ir_binop_logic_or; 1124bf215546Sopenharmony_ci 1125bf215546Sopenharmony_ci switch (op0->type->base_type) { 1126bf215546Sopenharmony_ci case GLSL_TYPE_FLOAT: 1127bf215546Sopenharmony_ci case GLSL_TYPE_FLOAT16: 1128bf215546Sopenharmony_ci case GLSL_TYPE_UINT: 1129bf215546Sopenharmony_ci case GLSL_TYPE_INT: 1130bf215546Sopenharmony_ci case GLSL_TYPE_BOOL: 1131bf215546Sopenharmony_ci case GLSL_TYPE_DOUBLE: 1132bf215546Sopenharmony_ci case GLSL_TYPE_UINT64: 1133bf215546Sopenharmony_ci case GLSL_TYPE_INT64: 1134bf215546Sopenharmony_ci case GLSL_TYPE_UINT16: 1135bf215546Sopenharmony_ci case GLSL_TYPE_INT16: 1136bf215546Sopenharmony_ci case GLSL_TYPE_UINT8: 1137bf215546Sopenharmony_ci case GLSL_TYPE_INT8: 1138bf215546Sopenharmony_ci return new(mem_ctx) ir_expression(operation, op0, op1); 1139bf215546Sopenharmony_ci 1140bf215546Sopenharmony_ci case GLSL_TYPE_ARRAY: { 1141bf215546Sopenharmony_ci for (unsigned int i = 0; i < op0->type->length; i++) { 1142bf215546Sopenharmony_ci ir_rvalue *e0, *e1, *result; 1143bf215546Sopenharmony_ci 1144bf215546Sopenharmony_ci e0 = new(mem_ctx) ir_dereference_array(op0->clone(mem_ctx, NULL), 1145bf215546Sopenharmony_ci new(mem_ctx) ir_constant(i)); 1146bf215546Sopenharmony_ci e1 = new(mem_ctx) ir_dereference_array(op1->clone(mem_ctx, NULL), 1147bf215546Sopenharmony_ci new(mem_ctx) ir_constant(i)); 1148bf215546Sopenharmony_ci result = do_comparison(mem_ctx, operation, e0, e1); 1149bf215546Sopenharmony_ci 1150bf215546Sopenharmony_ci if (cmp) { 1151bf215546Sopenharmony_ci cmp = new(mem_ctx) ir_expression(join_op, cmp, result); 1152bf215546Sopenharmony_ci } else { 1153bf215546Sopenharmony_ci cmp = result; 1154bf215546Sopenharmony_ci } 1155bf215546Sopenharmony_ci } 1156bf215546Sopenharmony_ci 1157bf215546Sopenharmony_ci mark_whole_array_access(op0); 1158bf215546Sopenharmony_ci mark_whole_array_access(op1); 1159bf215546Sopenharmony_ci break; 1160bf215546Sopenharmony_ci } 1161bf215546Sopenharmony_ci 1162bf215546Sopenharmony_ci case GLSL_TYPE_STRUCT: { 1163bf215546Sopenharmony_ci for (unsigned int i = 0; i < op0->type->length; i++) { 1164bf215546Sopenharmony_ci ir_rvalue *e0, *e1, *result; 1165bf215546Sopenharmony_ci const char *field_name = op0->type->fields.structure[i].name; 1166bf215546Sopenharmony_ci 1167bf215546Sopenharmony_ci e0 = new(mem_ctx) ir_dereference_record(op0->clone(mem_ctx, NULL), 1168bf215546Sopenharmony_ci field_name); 1169bf215546Sopenharmony_ci e1 = new(mem_ctx) ir_dereference_record(op1->clone(mem_ctx, NULL), 1170bf215546Sopenharmony_ci field_name); 1171bf215546Sopenharmony_ci result = do_comparison(mem_ctx, operation, e0, e1); 1172bf215546Sopenharmony_ci 1173bf215546Sopenharmony_ci if (cmp) { 1174bf215546Sopenharmony_ci cmp = new(mem_ctx) ir_expression(join_op, cmp, result); 1175bf215546Sopenharmony_ci } else { 1176bf215546Sopenharmony_ci cmp = result; 1177bf215546Sopenharmony_ci } 1178bf215546Sopenharmony_ci } 1179bf215546Sopenharmony_ci break; 1180bf215546Sopenharmony_ci } 1181bf215546Sopenharmony_ci 1182bf215546Sopenharmony_ci case GLSL_TYPE_ERROR: 1183bf215546Sopenharmony_ci case GLSL_TYPE_VOID: 1184bf215546Sopenharmony_ci case GLSL_TYPE_SAMPLER: 1185bf215546Sopenharmony_ci case GLSL_TYPE_TEXTURE: 1186bf215546Sopenharmony_ci case GLSL_TYPE_IMAGE: 1187bf215546Sopenharmony_ci case GLSL_TYPE_INTERFACE: 1188bf215546Sopenharmony_ci case GLSL_TYPE_ATOMIC_UINT: 1189bf215546Sopenharmony_ci case GLSL_TYPE_SUBROUTINE: 1190bf215546Sopenharmony_ci case GLSL_TYPE_FUNCTION: 1191bf215546Sopenharmony_ci /* I assume a comparison of a struct containing a sampler just 1192bf215546Sopenharmony_ci * ignores the sampler present in the type. 1193bf215546Sopenharmony_ci */ 1194bf215546Sopenharmony_ci break; 1195bf215546Sopenharmony_ci } 1196bf215546Sopenharmony_ci 1197bf215546Sopenharmony_ci if (cmp == NULL) 1198bf215546Sopenharmony_ci cmp = new(mem_ctx) ir_constant(true); 1199bf215546Sopenharmony_ci 1200bf215546Sopenharmony_ci return cmp; 1201bf215546Sopenharmony_ci} 1202bf215546Sopenharmony_ci 1203bf215546Sopenharmony_ci/* For logical operations, we want to ensure that the operands are 1204bf215546Sopenharmony_ci * scalar booleans. If it isn't, emit an error and return a constant 1205bf215546Sopenharmony_ci * boolean to avoid triggering cascading error messages. 1206bf215546Sopenharmony_ci */ 1207bf215546Sopenharmony_cistatic ir_rvalue * 1208bf215546Sopenharmony_ciget_scalar_boolean_operand(exec_list *instructions, 1209bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, 1210bf215546Sopenharmony_ci ast_expression *parent_expr, 1211bf215546Sopenharmony_ci int operand, 1212bf215546Sopenharmony_ci const char *operand_name, 1213bf215546Sopenharmony_ci bool *error_emitted) 1214bf215546Sopenharmony_ci{ 1215bf215546Sopenharmony_ci ast_expression *expr = parent_expr->subexpressions[operand]; 1216bf215546Sopenharmony_ci void *ctx = state; 1217bf215546Sopenharmony_ci ir_rvalue *val = expr->hir(instructions, state); 1218bf215546Sopenharmony_ci 1219bf215546Sopenharmony_ci if (val->type->is_boolean() && val->type->is_scalar()) 1220bf215546Sopenharmony_ci return val; 1221bf215546Sopenharmony_ci 1222bf215546Sopenharmony_ci if (!*error_emitted) { 1223bf215546Sopenharmony_ci YYLTYPE loc = expr->get_location(); 1224bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "%s of `%s' must be scalar boolean", 1225bf215546Sopenharmony_ci operand_name, 1226bf215546Sopenharmony_ci parent_expr->operator_string(parent_expr->oper)); 1227bf215546Sopenharmony_ci *error_emitted = true; 1228bf215546Sopenharmony_ci } 1229bf215546Sopenharmony_ci 1230bf215546Sopenharmony_ci return new(ctx) ir_constant(true); 1231bf215546Sopenharmony_ci} 1232bf215546Sopenharmony_ci 1233bf215546Sopenharmony_ci/** 1234bf215546Sopenharmony_ci * If name refers to a builtin array whose maximum allowed size is less than 1235bf215546Sopenharmony_ci * size, report an error and return true. Otherwise return false. 1236bf215546Sopenharmony_ci */ 1237bf215546Sopenharmony_civoid 1238bf215546Sopenharmony_cicheck_builtin_array_max_size(const char *name, unsigned size, 1239bf215546Sopenharmony_ci YYLTYPE loc, struct _mesa_glsl_parse_state *state) 1240bf215546Sopenharmony_ci{ 1241bf215546Sopenharmony_ci if ((strcmp("gl_TexCoord", name) == 0) 1242bf215546Sopenharmony_ci && (size > state->Const.MaxTextureCoords)) { 1243bf215546Sopenharmony_ci /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec: 1244bf215546Sopenharmony_ci * 1245bf215546Sopenharmony_ci * "The size [of gl_TexCoord] can be at most 1246bf215546Sopenharmony_ci * gl_MaxTextureCoords." 1247bf215546Sopenharmony_ci */ 1248bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "`gl_TexCoord' array size cannot " 1249bf215546Sopenharmony_ci "be larger than gl_MaxTextureCoords (%u)", 1250bf215546Sopenharmony_ci state->Const.MaxTextureCoords); 1251bf215546Sopenharmony_ci } else if (strcmp("gl_ClipDistance", name) == 0) { 1252bf215546Sopenharmony_ci state->clip_dist_size = size; 1253bf215546Sopenharmony_ci if (size + state->cull_dist_size > state->Const.MaxClipPlanes) { 1254bf215546Sopenharmony_ci /* From section 7.1 (Vertex Shader Special Variables) of the 1255bf215546Sopenharmony_ci * GLSL 1.30 spec: 1256bf215546Sopenharmony_ci * 1257bf215546Sopenharmony_ci * "The gl_ClipDistance array is predeclared as unsized and 1258bf215546Sopenharmony_ci * must be sized by the shader either redeclaring it with a 1259bf215546Sopenharmony_ci * size or indexing it only with integral constant 1260bf215546Sopenharmony_ci * expressions. ... The size can be at most 1261bf215546Sopenharmony_ci * gl_MaxClipDistances." 1262bf215546Sopenharmony_ci */ 1263bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "`gl_ClipDistance' array size cannot " 1264bf215546Sopenharmony_ci "be larger than gl_MaxClipDistances (%u)", 1265bf215546Sopenharmony_ci state->Const.MaxClipPlanes); 1266bf215546Sopenharmony_ci } 1267bf215546Sopenharmony_ci } else if (strcmp("gl_CullDistance", name) == 0) { 1268bf215546Sopenharmony_ci state->cull_dist_size = size; 1269bf215546Sopenharmony_ci if (size + state->clip_dist_size > state->Const.MaxClipPlanes) { 1270bf215546Sopenharmony_ci /* From the ARB_cull_distance spec: 1271bf215546Sopenharmony_ci * 1272bf215546Sopenharmony_ci * "The gl_CullDistance array is predeclared as unsized and 1273bf215546Sopenharmony_ci * must be sized by the shader either redeclaring it with 1274bf215546Sopenharmony_ci * a size or indexing it only with integral constant 1275bf215546Sopenharmony_ci * expressions. The size determines the number and set of 1276bf215546Sopenharmony_ci * enabled cull distances and can be at most 1277bf215546Sopenharmony_ci * gl_MaxCullDistances." 1278bf215546Sopenharmony_ci */ 1279bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "`gl_CullDistance' array size cannot " 1280bf215546Sopenharmony_ci "be larger than gl_MaxCullDistances (%u)", 1281bf215546Sopenharmony_ci state->Const.MaxClipPlanes); 1282bf215546Sopenharmony_ci } 1283bf215546Sopenharmony_ci } 1284bf215546Sopenharmony_ci} 1285bf215546Sopenharmony_ci 1286bf215546Sopenharmony_ci/** 1287bf215546Sopenharmony_ci * Create the constant 1, of a which is appropriate for incrementing and 1288bf215546Sopenharmony_ci * decrementing values of the given GLSL type. For example, if type is vec4, 1289bf215546Sopenharmony_ci * this creates a constant value of 1.0 having type float. 1290bf215546Sopenharmony_ci * 1291bf215546Sopenharmony_ci * If the given type is invalid for increment and decrement operators, return 1292bf215546Sopenharmony_ci * a floating point 1--the error will be detected later. 1293bf215546Sopenharmony_ci */ 1294bf215546Sopenharmony_cistatic ir_rvalue * 1295bf215546Sopenharmony_ciconstant_one_for_inc_dec(void *ctx, const glsl_type *type) 1296bf215546Sopenharmony_ci{ 1297bf215546Sopenharmony_ci switch (type->base_type) { 1298bf215546Sopenharmony_ci case GLSL_TYPE_UINT: 1299bf215546Sopenharmony_ci return new(ctx) ir_constant((unsigned) 1); 1300bf215546Sopenharmony_ci case GLSL_TYPE_INT: 1301bf215546Sopenharmony_ci return new(ctx) ir_constant(1); 1302bf215546Sopenharmony_ci case GLSL_TYPE_UINT64: 1303bf215546Sopenharmony_ci return new(ctx) ir_constant((uint64_t) 1); 1304bf215546Sopenharmony_ci case GLSL_TYPE_INT64: 1305bf215546Sopenharmony_ci return new(ctx) ir_constant((int64_t) 1); 1306bf215546Sopenharmony_ci default: 1307bf215546Sopenharmony_ci case GLSL_TYPE_FLOAT: 1308bf215546Sopenharmony_ci return new(ctx) ir_constant(1.0f); 1309bf215546Sopenharmony_ci } 1310bf215546Sopenharmony_ci} 1311bf215546Sopenharmony_ci 1312bf215546Sopenharmony_ciir_rvalue * 1313bf215546Sopenharmony_ciast_expression::hir(exec_list *instructions, 1314bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 1315bf215546Sopenharmony_ci{ 1316bf215546Sopenharmony_ci return do_hir(instructions, state, true); 1317bf215546Sopenharmony_ci} 1318bf215546Sopenharmony_ci 1319bf215546Sopenharmony_civoid 1320bf215546Sopenharmony_ciast_expression::hir_no_rvalue(exec_list *instructions, 1321bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 1322bf215546Sopenharmony_ci{ 1323bf215546Sopenharmony_ci do_hir(instructions, state, false); 1324bf215546Sopenharmony_ci} 1325bf215546Sopenharmony_ci 1326bf215546Sopenharmony_civoid 1327bf215546Sopenharmony_ciast_expression::set_is_lhs(bool new_value) 1328bf215546Sopenharmony_ci{ 1329bf215546Sopenharmony_ci /* is_lhs is tracked only to print "variable used uninitialized" warnings, 1330bf215546Sopenharmony_ci * if we lack an identifier we can just skip it. 1331bf215546Sopenharmony_ci */ 1332bf215546Sopenharmony_ci if (this->primary_expression.identifier == NULL) 1333bf215546Sopenharmony_ci return; 1334bf215546Sopenharmony_ci 1335bf215546Sopenharmony_ci this->is_lhs = new_value; 1336bf215546Sopenharmony_ci 1337bf215546Sopenharmony_ci /* We need to go through the subexpressions tree to cover cases like 1338bf215546Sopenharmony_ci * ast_field_selection 1339bf215546Sopenharmony_ci */ 1340bf215546Sopenharmony_ci if (this->subexpressions[0] != NULL) 1341bf215546Sopenharmony_ci this->subexpressions[0]->set_is_lhs(new_value); 1342bf215546Sopenharmony_ci} 1343bf215546Sopenharmony_ci 1344bf215546Sopenharmony_ciir_rvalue * 1345bf215546Sopenharmony_ciast_expression::do_hir(exec_list *instructions, 1346bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, 1347bf215546Sopenharmony_ci bool needs_rvalue) 1348bf215546Sopenharmony_ci{ 1349bf215546Sopenharmony_ci void *ctx = state; 1350bf215546Sopenharmony_ci static const int operations[AST_NUM_OPERATORS] = { 1351bf215546Sopenharmony_ci -1, /* ast_assign doesn't convert to ir_expression. */ 1352bf215546Sopenharmony_ci -1, /* ast_plus doesn't convert to ir_expression. */ 1353bf215546Sopenharmony_ci ir_unop_neg, 1354bf215546Sopenharmony_ci ir_binop_add, 1355bf215546Sopenharmony_ci ir_binop_sub, 1356bf215546Sopenharmony_ci ir_binop_mul, 1357bf215546Sopenharmony_ci ir_binop_div, 1358bf215546Sopenharmony_ci ir_binop_mod, 1359bf215546Sopenharmony_ci ir_binop_lshift, 1360bf215546Sopenharmony_ci ir_binop_rshift, 1361bf215546Sopenharmony_ci ir_binop_less, 1362bf215546Sopenharmony_ci ir_binop_less, /* This is correct. See the ast_greater case below. */ 1363bf215546Sopenharmony_ci ir_binop_gequal, /* This is correct. See the ast_lequal case below. */ 1364bf215546Sopenharmony_ci ir_binop_gequal, 1365bf215546Sopenharmony_ci ir_binop_all_equal, 1366bf215546Sopenharmony_ci ir_binop_any_nequal, 1367bf215546Sopenharmony_ci ir_binop_bit_and, 1368bf215546Sopenharmony_ci ir_binop_bit_xor, 1369bf215546Sopenharmony_ci ir_binop_bit_or, 1370bf215546Sopenharmony_ci ir_unop_bit_not, 1371bf215546Sopenharmony_ci ir_binop_logic_and, 1372bf215546Sopenharmony_ci ir_binop_logic_xor, 1373bf215546Sopenharmony_ci ir_binop_logic_or, 1374bf215546Sopenharmony_ci ir_unop_logic_not, 1375bf215546Sopenharmony_ci 1376bf215546Sopenharmony_ci /* Note: The following block of expression types actually convert 1377bf215546Sopenharmony_ci * to multiple IR instructions. 1378bf215546Sopenharmony_ci */ 1379bf215546Sopenharmony_ci ir_binop_mul, /* ast_mul_assign */ 1380bf215546Sopenharmony_ci ir_binop_div, /* ast_div_assign */ 1381bf215546Sopenharmony_ci ir_binop_mod, /* ast_mod_assign */ 1382bf215546Sopenharmony_ci ir_binop_add, /* ast_add_assign */ 1383bf215546Sopenharmony_ci ir_binop_sub, /* ast_sub_assign */ 1384bf215546Sopenharmony_ci ir_binop_lshift, /* ast_ls_assign */ 1385bf215546Sopenharmony_ci ir_binop_rshift, /* ast_rs_assign */ 1386bf215546Sopenharmony_ci ir_binop_bit_and, /* ast_and_assign */ 1387bf215546Sopenharmony_ci ir_binop_bit_xor, /* ast_xor_assign */ 1388bf215546Sopenharmony_ci ir_binop_bit_or, /* ast_or_assign */ 1389bf215546Sopenharmony_ci 1390bf215546Sopenharmony_ci -1, /* ast_conditional doesn't convert to ir_expression. */ 1391bf215546Sopenharmony_ci ir_binop_add, /* ast_pre_inc. */ 1392bf215546Sopenharmony_ci ir_binop_sub, /* ast_pre_dec. */ 1393bf215546Sopenharmony_ci ir_binop_add, /* ast_post_inc. */ 1394bf215546Sopenharmony_ci ir_binop_sub, /* ast_post_dec. */ 1395bf215546Sopenharmony_ci -1, /* ast_field_selection doesn't conv to ir_expression. */ 1396bf215546Sopenharmony_ci -1, /* ast_array_index doesn't convert to ir_expression. */ 1397bf215546Sopenharmony_ci -1, /* ast_function_call doesn't conv to ir_expression. */ 1398bf215546Sopenharmony_ci -1, /* ast_identifier doesn't convert to ir_expression. */ 1399bf215546Sopenharmony_ci -1, /* ast_int_constant doesn't convert to ir_expression. */ 1400bf215546Sopenharmony_ci -1, /* ast_uint_constant doesn't conv to ir_expression. */ 1401bf215546Sopenharmony_ci -1, /* ast_float_constant doesn't conv to ir_expression. */ 1402bf215546Sopenharmony_ci -1, /* ast_bool_constant doesn't conv to ir_expression. */ 1403bf215546Sopenharmony_ci -1, /* ast_sequence doesn't convert to ir_expression. */ 1404bf215546Sopenharmony_ci -1, /* ast_aggregate shouldn't ever even get here. */ 1405bf215546Sopenharmony_ci }; 1406bf215546Sopenharmony_ci ir_rvalue *result = NULL; 1407bf215546Sopenharmony_ci ir_rvalue *op[3]; 1408bf215546Sopenharmony_ci const struct glsl_type *type, *orig_type; 1409bf215546Sopenharmony_ci bool error_emitted = false; 1410bf215546Sopenharmony_ci YYLTYPE loc; 1411bf215546Sopenharmony_ci 1412bf215546Sopenharmony_ci loc = this->get_location(); 1413bf215546Sopenharmony_ci 1414bf215546Sopenharmony_ci switch (this->oper) { 1415bf215546Sopenharmony_ci case ast_aggregate: 1416bf215546Sopenharmony_ci unreachable("ast_aggregate: Should never get here."); 1417bf215546Sopenharmony_ci 1418bf215546Sopenharmony_ci case ast_assign: { 1419bf215546Sopenharmony_ci this->subexpressions[0]->set_is_lhs(true); 1420bf215546Sopenharmony_ci op[0] = this->subexpressions[0]->hir(instructions, state); 1421bf215546Sopenharmony_ci op[1] = this->subexpressions[1]->hir(instructions, state); 1422bf215546Sopenharmony_ci 1423bf215546Sopenharmony_ci error_emitted = 1424bf215546Sopenharmony_ci do_assignment(instructions, state, 1425bf215546Sopenharmony_ci this->subexpressions[0]->non_lvalue_description, 1426bf215546Sopenharmony_ci op[0], op[1], &result, needs_rvalue, false, 1427bf215546Sopenharmony_ci this->subexpressions[0]->get_location()); 1428bf215546Sopenharmony_ci break; 1429bf215546Sopenharmony_ci } 1430bf215546Sopenharmony_ci 1431bf215546Sopenharmony_ci case ast_plus: 1432bf215546Sopenharmony_ci op[0] = this->subexpressions[0]->hir(instructions, state); 1433bf215546Sopenharmony_ci 1434bf215546Sopenharmony_ci type = unary_arithmetic_result_type(op[0]->type, state, & loc); 1435bf215546Sopenharmony_ci 1436bf215546Sopenharmony_ci error_emitted = type->is_error(); 1437bf215546Sopenharmony_ci 1438bf215546Sopenharmony_ci result = op[0]; 1439bf215546Sopenharmony_ci break; 1440bf215546Sopenharmony_ci 1441bf215546Sopenharmony_ci case ast_neg: 1442bf215546Sopenharmony_ci op[0] = this->subexpressions[0]->hir(instructions, state); 1443bf215546Sopenharmony_ci 1444bf215546Sopenharmony_ci type = unary_arithmetic_result_type(op[0]->type, state, & loc); 1445bf215546Sopenharmony_ci 1446bf215546Sopenharmony_ci error_emitted = type->is_error(); 1447bf215546Sopenharmony_ci 1448bf215546Sopenharmony_ci result = new(ctx) ir_expression(operations[this->oper], type, 1449bf215546Sopenharmony_ci op[0], NULL); 1450bf215546Sopenharmony_ci break; 1451bf215546Sopenharmony_ci 1452bf215546Sopenharmony_ci case ast_add: 1453bf215546Sopenharmony_ci case ast_sub: 1454bf215546Sopenharmony_ci case ast_mul: 1455bf215546Sopenharmony_ci case ast_div: 1456bf215546Sopenharmony_ci op[0] = this->subexpressions[0]->hir(instructions, state); 1457bf215546Sopenharmony_ci op[1] = this->subexpressions[1]->hir(instructions, state); 1458bf215546Sopenharmony_ci 1459bf215546Sopenharmony_ci type = arithmetic_result_type(op[0], op[1], 1460bf215546Sopenharmony_ci (this->oper == ast_mul), 1461bf215546Sopenharmony_ci state, & loc); 1462bf215546Sopenharmony_ci error_emitted = type->is_error(); 1463bf215546Sopenharmony_ci 1464bf215546Sopenharmony_ci result = new(ctx) ir_expression(operations[this->oper], type, 1465bf215546Sopenharmony_ci op[0], op[1]); 1466bf215546Sopenharmony_ci break; 1467bf215546Sopenharmony_ci 1468bf215546Sopenharmony_ci case ast_mod: 1469bf215546Sopenharmony_ci op[0] = this->subexpressions[0]->hir(instructions, state); 1470bf215546Sopenharmony_ci op[1] = this->subexpressions[1]->hir(instructions, state); 1471bf215546Sopenharmony_ci 1472bf215546Sopenharmony_ci type = modulus_result_type(op[0], op[1], state, &loc); 1473bf215546Sopenharmony_ci 1474bf215546Sopenharmony_ci assert(operations[this->oper] == ir_binop_mod); 1475bf215546Sopenharmony_ci 1476bf215546Sopenharmony_ci result = new(ctx) ir_expression(operations[this->oper], type, 1477bf215546Sopenharmony_ci op[0], op[1]); 1478bf215546Sopenharmony_ci error_emitted = type->is_error(); 1479bf215546Sopenharmony_ci break; 1480bf215546Sopenharmony_ci 1481bf215546Sopenharmony_ci case ast_lshift: 1482bf215546Sopenharmony_ci case ast_rshift: 1483bf215546Sopenharmony_ci if (!state->check_bitwise_operations_allowed(&loc)) { 1484bf215546Sopenharmony_ci error_emitted = true; 1485bf215546Sopenharmony_ci } 1486bf215546Sopenharmony_ci 1487bf215546Sopenharmony_ci op[0] = this->subexpressions[0]->hir(instructions, state); 1488bf215546Sopenharmony_ci op[1] = this->subexpressions[1]->hir(instructions, state); 1489bf215546Sopenharmony_ci type = shift_result_type(op[0]->type, op[1]->type, this->oper, state, 1490bf215546Sopenharmony_ci &loc); 1491bf215546Sopenharmony_ci result = new(ctx) ir_expression(operations[this->oper], type, 1492bf215546Sopenharmony_ci op[0], op[1]); 1493bf215546Sopenharmony_ci error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); 1494bf215546Sopenharmony_ci break; 1495bf215546Sopenharmony_ci 1496bf215546Sopenharmony_ci case ast_less: 1497bf215546Sopenharmony_ci case ast_greater: 1498bf215546Sopenharmony_ci case ast_lequal: 1499bf215546Sopenharmony_ci case ast_gequal: 1500bf215546Sopenharmony_ci op[0] = this->subexpressions[0]->hir(instructions, state); 1501bf215546Sopenharmony_ci op[1] = this->subexpressions[1]->hir(instructions, state); 1502bf215546Sopenharmony_ci 1503bf215546Sopenharmony_ci type = relational_result_type(op[0], op[1], state, & loc); 1504bf215546Sopenharmony_ci 1505bf215546Sopenharmony_ci /* The relational operators must either generate an error or result 1506bf215546Sopenharmony_ci * in a scalar boolean. See page 57 of the GLSL 1.50 spec. 1507bf215546Sopenharmony_ci */ 1508bf215546Sopenharmony_ci assert(type->is_error() 1509bf215546Sopenharmony_ci || (type->is_boolean() && type->is_scalar())); 1510bf215546Sopenharmony_ci 1511bf215546Sopenharmony_ci /* Like NIR, GLSL IR does not have opcodes for > or <=. Instead, swap 1512bf215546Sopenharmony_ci * the arguments and use < or >=. 1513bf215546Sopenharmony_ci */ 1514bf215546Sopenharmony_ci if (this->oper == ast_greater || this->oper == ast_lequal) { 1515bf215546Sopenharmony_ci ir_rvalue *const tmp = op[0]; 1516bf215546Sopenharmony_ci op[0] = op[1]; 1517bf215546Sopenharmony_ci op[1] = tmp; 1518bf215546Sopenharmony_ci } 1519bf215546Sopenharmony_ci 1520bf215546Sopenharmony_ci result = new(ctx) ir_expression(operations[this->oper], type, 1521bf215546Sopenharmony_ci op[0], op[1]); 1522bf215546Sopenharmony_ci error_emitted = type->is_error(); 1523bf215546Sopenharmony_ci break; 1524bf215546Sopenharmony_ci 1525bf215546Sopenharmony_ci case ast_nequal: 1526bf215546Sopenharmony_ci case ast_equal: 1527bf215546Sopenharmony_ci op[0] = this->subexpressions[0]->hir(instructions, state); 1528bf215546Sopenharmony_ci op[1] = this->subexpressions[1]->hir(instructions, state); 1529bf215546Sopenharmony_ci 1530bf215546Sopenharmony_ci /* From page 58 (page 64 of the PDF) of the GLSL 1.50 spec: 1531bf215546Sopenharmony_ci * 1532bf215546Sopenharmony_ci * "The equality operators equal (==), and not equal (!=) 1533bf215546Sopenharmony_ci * operate on all types. They result in a scalar Boolean. If 1534bf215546Sopenharmony_ci * the operand types do not match, then there must be a 1535bf215546Sopenharmony_ci * conversion from Section 4.1.10 "Implicit Conversions" 1536bf215546Sopenharmony_ci * applied to one operand that can make them match, in which 1537bf215546Sopenharmony_ci * case this conversion is done." 1538bf215546Sopenharmony_ci */ 1539bf215546Sopenharmony_ci 1540bf215546Sopenharmony_ci if (op[0]->type == glsl_type::void_type || op[1]->type == glsl_type::void_type) { 1541bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "`%s': wrong operand types: " 1542bf215546Sopenharmony_ci "no operation `%1$s' exists that takes a left-hand " 1543bf215546Sopenharmony_ci "operand of type 'void' or a right operand of type " 1544bf215546Sopenharmony_ci "'void'", (this->oper == ast_equal) ? "==" : "!="); 1545bf215546Sopenharmony_ci error_emitted = true; 1546bf215546Sopenharmony_ci } else if ((!apply_implicit_conversion(op[0]->type, op[1], state) 1547bf215546Sopenharmony_ci && !apply_implicit_conversion(op[1]->type, op[0], state)) 1548bf215546Sopenharmony_ci || (op[0]->type != op[1]->type)) { 1549bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "operands of `%s' must have the same " 1550bf215546Sopenharmony_ci "type", (this->oper == ast_equal) ? "==" : "!="); 1551bf215546Sopenharmony_ci error_emitted = true; 1552bf215546Sopenharmony_ci } else if ((op[0]->type->is_array() || op[1]->type->is_array()) && 1553bf215546Sopenharmony_ci !state->check_version(120, 300, &loc, 1554bf215546Sopenharmony_ci "array comparisons forbidden")) { 1555bf215546Sopenharmony_ci error_emitted = true; 1556bf215546Sopenharmony_ci } else if ((op[0]->type->contains_subroutine() || 1557bf215546Sopenharmony_ci op[1]->type->contains_subroutine())) { 1558bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "subroutine comparisons forbidden"); 1559bf215546Sopenharmony_ci error_emitted = true; 1560bf215546Sopenharmony_ci } else if ((op[0]->type->contains_opaque() || 1561bf215546Sopenharmony_ci op[1]->type->contains_opaque())) { 1562bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "opaque type comparisons forbidden"); 1563bf215546Sopenharmony_ci error_emitted = true; 1564bf215546Sopenharmony_ci } 1565bf215546Sopenharmony_ci 1566bf215546Sopenharmony_ci if (error_emitted) { 1567bf215546Sopenharmony_ci result = new(ctx) ir_constant(false); 1568bf215546Sopenharmony_ci } else { 1569bf215546Sopenharmony_ci result = do_comparison(ctx, operations[this->oper], op[0], op[1]); 1570bf215546Sopenharmony_ci assert(result->type == glsl_type::bool_type); 1571bf215546Sopenharmony_ci } 1572bf215546Sopenharmony_ci break; 1573bf215546Sopenharmony_ci 1574bf215546Sopenharmony_ci case ast_bit_and: 1575bf215546Sopenharmony_ci case ast_bit_xor: 1576bf215546Sopenharmony_ci case ast_bit_or: 1577bf215546Sopenharmony_ci op[0] = this->subexpressions[0]->hir(instructions, state); 1578bf215546Sopenharmony_ci op[1] = this->subexpressions[1]->hir(instructions, state); 1579bf215546Sopenharmony_ci type = bit_logic_result_type(op[0], op[1], this->oper, state, &loc); 1580bf215546Sopenharmony_ci result = new(ctx) ir_expression(operations[this->oper], type, 1581bf215546Sopenharmony_ci op[0], op[1]); 1582bf215546Sopenharmony_ci error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); 1583bf215546Sopenharmony_ci break; 1584bf215546Sopenharmony_ci 1585bf215546Sopenharmony_ci case ast_bit_not: 1586bf215546Sopenharmony_ci op[0] = this->subexpressions[0]->hir(instructions, state); 1587bf215546Sopenharmony_ci 1588bf215546Sopenharmony_ci if (!state->check_bitwise_operations_allowed(&loc)) { 1589bf215546Sopenharmony_ci error_emitted = true; 1590bf215546Sopenharmony_ci } 1591bf215546Sopenharmony_ci 1592bf215546Sopenharmony_ci if (!op[0]->type->is_integer_32_64()) { 1593bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "operand of `~' must be an integer"); 1594bf215546Sopenharmony_ci error_emitted = true; 1595bf215546Sopenharmony_ci } 1596bf215546Sopenharmony_ci 1597bf215546Sopenharmony_ci type = error_emitted ? glsl_type::error_type : op[0]->type; 1598bf215546Sopenharmony_ci result = new(ctx) ir_expression(ir_unop_bit_not, type, op[0], NULL); 1599bf215546Sopenharmony_ci break; 1600bf215546Sopenharmony_ci 1601bf215546Sopenharmony_ci case ast_logic_and: { 1602bf215546Sopenharmony_ci exec_list rhs_instructions; 1603bf215546Sopenharmony_ci op[0] = get_scalar_boolean_operand(instructions, state, this, 0, 1604bf215546Sopenharmony_ci "LHS", &error_emitted); 1605bf215546Sopenharmony_ci op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1, 1606bf215546Sopenharmony_ci "RHS", &error_emitted); 1607bf215546Sopenharmony_ci 1608bf215546Sopenharmony_ci if (rhs_instructions.is_empty()) { 1609bf215546Sopenharmony_ci result = new(ctx) ir_expression(ir_binop_logic_and, op[0], op[1]); 1610bf215546Sopenharmony_ci } else { 1611bf215546Sopenharmony_ci ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, 1612bf215546Sopenharmony_ci "and_tmp", 1613bf215546Sopenharmony_ci ir_var_temporary); 1614bf215546Sopenharmony_ci instructions->push_tail(tmp); 1615bf215546Sopenharmony_ci 1616bf215546Sopenharmony_ci ir_if *const stmt = new(ctx) ir_if(op[0]); 1617bf215546Sopenharmony_ci instructions->push_tail(stmt); 1618bf215546Sopenharmony_ci 1619bf215546Sopenharmony_ci stmt->then_instructions.append_list(&rhs_instructions); 1620bf215546Sopenharmony_ci ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); 1621bf215546Sopenharmony_ci ir_assignment *const then_assign = 1622bf215546Sopenharmony_ci new(ctx) ir_assignment(then_deref, op[1]); 1623bf215546Sopenharmony_ci stmt->then_instructions.push_tail(then_assign); 1624bf215546Sopenharmony_ci 1625bf215546Sopenharmony_ci ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp); 1626bf215546Sopenharmony_ci ir_assignment *const else_assign = 1627bf215546Sopenharmony_ci new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false)); 1628bf215546Sopenharmony_ci stmt->else_instructions.push_tail(else_assign); 1629bf215546Sopenharmony_ci 1630bf215546Sopenharmony_ci result = new(ctx) ir_dereference_variable(tmp); 1631bf215546Sopenharmony_ci } 1632bf215546Sopenharmony_ci break; 1633bf215546Sopenharmony_ci } 1634bf215546Sopenharmony_ci 1635bf215546Sopenharmony_ci case ast_logic_or: { 1636bf215546Sopenharmony_ci exec_list rhs_instructions; 1637bf215546Sopenharmony_ci op[0] = get_scalar_boolean_operand(instructions, state, this, 0, 1638bf215546Sopenharmony_ci "LHS", &error_emitted); 1639bf215546Sopenharmony_ci op[1] = get_scalar_boolean_operand(&rhs_instructions, state, this, 1, 1640bf215546Sopenharmony_ci "RHS", &error_emitted); 1641bf215546Sopenharmony_ci 1642bf215546Sopenharmony_ci if (rhs_instructions.is_empty()) { 1643bf215546Sopenharmony_ci result = new(ctx) ir_expression(ir_binop_logic_or, op[0], op[1]); 1644bf215546Sopenharmony_ci } else { 1645bf215546Sopenharmony_ci ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, 1646bf215546Sopenharmony_ci "or_tmp", 1647bf215546Sopenharmony_ci ir_var_temporary); 1648bf215546Sopenharmony_ci instructions->push_tail(tmp); 1649bf215546Sopenharmony_ci 1650bf215546Sopenharmony_ci ir_if *const stmt = new(ctx) ir_if(op[0]); 1651bf215546Sopenharmony_ci instructions->push_tail(stmt); 1652bf215546Sopenharmony_ci 1653bf215546Sopenharmony_ci ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); 1654bf215546Sopenharmony_ci ir_assignment *const then_assign = 1655bf215546Sopenharmony_ci new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true)); 1656bf215546Sopenharmony_ci stmt->then_instructions.push_tail(then_assign); 1657bf215546Sopenharmony_ci 1658bf215546Sopenharmony_ci stmt->else_instructions.append_list(&rhs_instructions); 1659bf215546Sopenharmony_ci ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp); 1660bf215546Sopenharmony_ci ir_assignment *const else_assign = 1661bf215546Sopenharmony_ci new(ctx) ir_assignment(else_deref, op[1]); 1662bf215546Sopenharmony_ci stmt->else_instructions.push_tail(else_assign); 1663bf215546Sopenharmony_ci 1664bf215546Sopenharmony_ci result = new(ctx) ir_dereference_variable(tmp); 1665bf215546Sopenharmony_ci } 1666bf215546Sopenharmony_ci break; 1667bf215546Sopenharmony_ci } 1668bf215546Sopenharmony_ci 1669bf215546Sopenharmony_ci case ast_logic_xor: 1670bf215546Sopenharmony_ci /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec: 1671bf215546Sopenharmony_ci * 1672bf215546Sopenharmony_ci * "The logical binary operators and (&&), or ( | | ), and 1673bf215546Sopenharmony_ci * exclusive or (^^). They operate only on two Boolean 1674bf215546Sopenharmony_ci * expressions and result in a Boolean expression." 1675bf215546Sopenharmony_ci */ 1676bf215546Sopenharmony_ci op[0] = get_scalar_boolean_operand(instructions, state, this, 0, "LHS", 1677bf215546Sopenharmony_ci &error_emitted); 1678bf215546Sopenharmony_ci op[1] = get_scalar_boolean_operand(instructions, state, this, 1, "RHS", 1679bf215546Sopenharmony_ci &error_emitted); 1680bf215546Sopenharmony_ci 1681bf215546Sopenharmony_ci result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type, 1682bf215546Sopenharmony_ci op[0], op[1]); 1683bf215546Sopenharmony_ci break; 1684bf215546Sopenharmony_ci 1685bf215546Sopenharmony_ci case ast_logic_not: 1686bf215546Sopenharmony_ci op[0] = get_scalar_boolean_operand(instructions, state, this, 0, 1687bf215546Sopenharmony_ci "operand", &error_emitted); 1688bf215546Sopenharmony_ci 1689bf215546Sopenharmony_ci result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type, 1690bf215546Sopenharmony_ci op[0], NULL); 1691bf215546Sopenharmony_ci break; 1692bf215546Sopenharmony_ci 1693bf215546Sopenharmony_ci case ast_mul_assign: 1694bf215546Sopenharmony_ci case ast_div_assign: 1695bf215546Sopenharmony_ci case ast_add_assign: 1696bf215546Sopenharmony_ci case ast_sub_assign: { 1697bf215546Sopenharmony_ci this->subexpressions[0]->set_is_lhs(true); 1698bf215546Sopenharmony_ci op[0] = this->subexpressions[0]->hir(instructions, state); 1699bf215546Sopenharmony_ci op[1] = this->subexpressions[1]->hir(instructions, state); 1700bf215546Sopenharmony_ci 1701bf215546Sopenharmony_ci orig_type = op[0]->type; 1702bf215546Sopenharmony_ci 1703bf215546Sopenharmony_ci /* Break out if operand types were not parsed successfully. */ 1704bf215546Sopenharmony_ci if ((op[0]->type == glsl_type::error_type || 1705bf215546Sopenharmony_ci op[1]->type == glsl_type::error_type)) { 1706bf215546Sopenharmony_ci error_emitted = true; 1707bf215546Sopenharmony_ci result = ir_rvalue::error_value(ctx); 1708bf215546Sopenharmony_ci break; 1709bf215546Sopenharmony_ci } 1710bf215546Sopenharmony_ci 1711bf215546Sopenharmony_ci type = arithmetic_result_type(op[0], op[1], 1712bf215546Sopenharmony_ci (this->oper == ast_mul_assign), 1713bf215546Sopenharmony_ci state, & loc); 1714bf215546Sopenharmony_ci 1715bf215546Sopenharmony_ci if (type != orig_type) { 1716bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 1717bf215546Sopenharmony_ci "could not implicitly convert " 1718bf215546Sopenharmony_ci "%s to %s", type->name, orig_type->name); 1719bf215546Sopenharmony_ci type = glsl_type::error_type; 1720bf215546Sopenharmony_ci } 1721bf215546Sopenharmony_ci 1722bf215546Sopenharmony_ci ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type, 1723bf215546Sopenharmony_ci op[0], op[1]); 1724bf215546Sopenharmony_ci 1725bf215546Sopenharmony_ci error_emitted = 1726bf215546Sopenharmony_ci do_assignment(instructions, state, 1727bf215546Sopenharmony_ci this->subexpressions[0]->non_lvalue_description, 1728bf215546Sopenharmony_ci op[0]->clone(ctx, NULL), temp_rhs, 1729bf215546Sopenharmony_ci &result, needs_rvalue, false, 1730bf215546Sopenharmony_ci this->subexpressions[0]->get_location()); 1731bf215546Sopenharmony_ci 1732bf215546Sopenharmony_ci /* GLSL 1.10 does not allow array assignment. However, we don't have to 1733bf215546Sopenharmony_ci * explicitly test for this because none of the binary expression 1734bf215546Sopenharmony_ci * operators allow array operands either. 1735bf215546Sopenharmony_ci */ 1736bf215546Sopenharmony_ci 1737bf215546Sopenharmony_ci break; 1738bf215546Sopenharmony_ci } 1739bf215546Sopenharmony_ci 1740bf215546Sopenharmony_ci case ast_mod_assign: { 1741bf215546Sopenharmony_ci this->subexpressions[0]->set_is_lhs(true); 1742bf215546Sopenharmony_ci op[0] = this->subexpressions[0]->hir(instructions, state); 1743bf215546Sopenharmony_ci op[1] = this->subexpressions[1]->hir(instructions, state); 1744bf215546Sopenharmony_ci 1745bf215546Sopenharmony_ci /* Break out if operand types were not parsed successfully. */ 1746bf215546Sopenharmony_ci if ((op[0]->type == glsl_type::error_type || 1747bf215546Sopenharmony_ci op[1]->type == glsl_type::error_type)) { 1748bf215546Sopenharmony_ci error_emitted = true; 1749bf215546Sopenharmony_ci result = ir_rvalue::error_value(ctx); 1750bf215546Sopenharmony_ci break; 1751bf215546Sopenharmony_ci } 1752bf215546Sopenharmony_ci 1753bf215546Sopenharmony_ci orig_type = op[0]->type; 1754bf215546Sopenharmony_ci type = modulus_result_type(op[0], op[1], state, &loc); 1755bf215546Sopenharmony_ci 1756bf215546Sopenharmony_ci if (type != orig_type) { 1757bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 1758bf215546Sopenharmony_ci "could not implicitly convert " 1759bf215546Sopenharmony_ci "%s to %s", type->name, orig_type->name); 1760bf215546Sopenharmony_ci type = glsl_type::error_type; 1761bf215546Sopenharmony_ci } 1762bf215546Sopenharmony_ci 1763bf215546Sopenharmony_ci assert(operations[this->oper] == ir_binop_mod); 1764bf215546Sopenharmony_ci 1765bf215546Sopenharmony_ci ir_rvalue *temp_rhs; 1766bf215546Sopenharmony_ci temp_rhs = new(ctx) ir_expression(operations[this->oper], type, 1767bf215546Sopenharmony_ci op[0], op[1]); 1768bf215546Sopenharmony_ci 1769bf215546Sopenharmony_ci error_emitted = 1770bf215546Sopenharmony_ci do_assignment(instructions, state, 1771bf215546Sopenharmony_ci this->subexpressions[0]->non_lvalue_description, 1772bf215546Sopenharmony_ci op[0]->clone(ctx, NULL), temp_rhs, 1773bf215546Sopenharmony_ci &result, needs_rvalue, false, 1774bf215546Sopenharmony_ci this->subexpressions[0]->get_location()); 1775bf215546Sopenharmony_ci break; 1776bf215546Sopenharmony_ci } 1777bf215546Sopenharmony_ci 1778bf215546Sopenharmony_ci case ast_ls_assign: 1779bf215546Sopenharmony_ci case ast_rs_assign: { 1780bf215546Sopenharmony_ci this->subexpressions[0]->set_is_lhs(true); 1781bf215546Sopenharmony_ci op[0] = this->subexpressions[0]->hir(instructions, state); 1782bf215546Sopenharmony_ci op[1] = this->subexpressions[1]->hir(instructions, state); 1783bf215546Sopenharmony_ci 1784bf215546Sopenharmony_ci /* Break out if operand types were not parsed successfully. */ 1785bf215546Sopenharmony_ci if ((op[0]->type == glsl_type::error_type || 1786bf215546Sopenharmony_ci op[1]->type == glsl_type::error_type)) { 1787bf215546Sopenharmony_ci error_emitted = true; 1788bf215546Sopenharmony_ci result = ir_rvalue::error_value(ctx); 1789bf215546Sopenharmony_ci break; 1790bf215546Sopenharmony_ci } 1791bf215546Sopenharmony_ci 1792bf215546Sopenharmony_ci type = shift_result_type(op[0]->type, op[1]->type, this->oper, state, 1793bf215546Sopenharmony_ci &loc); 1794bf215546Sopenharmony_ci ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], 1795bf215546Sopenharmony_ci type, op[0], op[1]); 1796bf215546Sopenharmony_ci error_emitted = 1797bf215546Sopenharmony_ci do_assignment(instructions, state, 1798bf215546Sopenharmony_ci this->subexpressions[0]->non_lvalue_description, 1799bf215546Sopenharmony_ci op[0]->clone(ctx, NULL), temp_rhs, 1800bf215546Sopenharmony_ci &result, needs_rvalue, false, 1801bf215546Sopenharmony_ci this->subexpressions[0]->get_location()); 1802bf215546Sopenharmony_ci break; 1803bf215546Sopenharmony_ci } 1804bf215546Sopenharmony_ci 1805bf215546Sopenharmony_ci case ast_and_assign: 1806bf215546Sopenharmony_ci case ast_xor_assign: 1807bf215546Sopenharmony_ci case ast_or_assign: { 1808bf215546Sopenharmony_ci this->subexpressions[0]->set_is_lhs(true); 1809bf215546Sopenharmony_ci op[0] = this->subexpressions[0]->hir(instructions, state); 1810bf215546Sopenharmony_ci op[1] = this->subexpressions[1]->hir(instructions, state); 1811bf215546Sopenharmony_ci 1812bf215546Sopenharmony_ci /* Break out if operand types were not parsed successfully. */ 1813bf215546Sopenharmony_ci if ((op[0]->type == glsl_type::error_type || 1814bf215546Sopenharmony_ci op[1]->type == glsl_type::error_type)) { 1815bf215546Sopenharmony_ci error_emitted = true; 1816bf215546Sopenharmony_ci result = ir_rvalue::error_value(ctx); 1817bf215546Sopenharmony_ci break; 1818bf215546Sopenharmony_ci } 1819bf215546Sopenharmony_ci 1820bf215546Sopenharmony_ci orig_type = op[0]->type; 1821bf215546Sopenharmony_ci type = bit_logic_result_type(op[0], op[1], this->oper, state, &loc); 1822bf215546Sopenharmony_ci 1823bf215546Sopenharmony_ci if (type != orig_type) { 1824bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 1825bf215546Sopenharmony_ci "could not implicitly convert " 1826bf215546Sopenharmony_ci "%s to %s", type->name, orig_type->name); 1827bf215546Sopenharmony_ci type = glsl_type::error_type; 1828bf215546Sopenharmony_ci } 1829bf215546Sopenharmony_ci 1830bf215546Sopenharmony_ci ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], 1831bf215546Sopenharmony_ci type, op[0], op[1]); 1832bf215546Sopenharmony_ci error_emitted = 1833bf215546Sopenharmony_ci do_assignment(instructions, state, 1834bf215546Sopenharmony_ci this->subexpressions[0]->non_lvalue_description, 1835bf215546Sopenharmony_ci op[0]->clone(ctx, NULL), temp_rhs, 1836bf215546Sopenharmony_ci &result, needs_rvalue, false, 1837bf215546Sopenharmony_ci this->subexpressions[0]->get_location()); 1838bf215546Sopenharmony_ci break; 1839bf215546Sopenharmony_ci } 1840bf215546Sopenharmony_ci 1841bf215546Sopenharmony_ci case ast_conditional: { 1842bf215546Sopenharmony_ci /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec: 1843bf215546Sopenharmony_ci * 1844bf215546Sopenharmony_ci * "The ternary selection operator (?:). It operates on three 1845bf215546Sopenharmony_ci * expressions (exp1 ? exp2 : exp3). This operator evaluates the 1846bf215546Sopenharmony_ci * first expression, which must result in a scalar Boolean." 1847bf215546Sopenharmony_ci */ 1848bf215546Sopenharmony_ci op[0] = get_scalar_boolean_operand(instructions, state, this, 0, 1849bf215546Sopenharmony_ci "condition", &error_emitted); 1850bf215546Sopenharmony_ci 1851bf215546Sopenharmony_ci /* The :? operator is implemented by generating an anonymous temporary 1852bf215546Sopenharmony_ci * followed by an if-statement. The last instruction in each branch of 1853bf215546Sopenharmony_ci * the if-statement assigns a value to the anonymous temporary. This 1854bf215546Sopenharmony_ci * temporary is the r-value of the expression. 1855bf215546Sopenharmony_ci */ 1856bf215546Sopenharmony_ci exec_list then_instructions; 1857bf215546Sopenharmony_ci exec_list else_instructions; 1858bf215546Sopenharmony_ci 1859bf215546Sopenharmony_ci op[1] = this->subexpressions[1]->hir(&then_instructions, state); 1860bf215546Sopenharmony_ci op[2] = this->subexpressions[2]->hir(&else_instructions, state); 1861bf215546Sopenharmony_ci 1862bf215546Sopenharmony_ci /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec: 1863bf215546Sopenharmony_ci * 1864bf215546Sopenharmony_ci * "The second and third expressions can be any type, as 1865bf215546Sopenharmony_ci * long their types match, or there is a conversion in 1866bf215546Sopenharmony_ci * Section 4.1.10 "Implicit Conversions" that can be applied 1867bf215546Sopenharmony_ci * to one of the expressions to make their types match. This 1868bf215546Sopenharmony_ci * resulting matching type is the type of the entire 1869bf215546Sopenharmony_ci * expression." 1870bf215546Sopenharmony_ci */ 1871bf215546Sopenharmony_ci if ((!apply_implicit_conversion(op[1]->type, op[2], state) 1872bf215546Sopenharmony_ci && !apply_implicit_conversion(op[2]->type, op[1], state)) 1873bf215546Sopenharmony_ci || (op[1]->type != op[2]->type)) { 1874bf215546Sopenharmony_ci YYLTYPE loc = this->subexpressions[1]->get_location(); 1875bf215546Sopenharmony_ci 1876bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "second and third operands of ?: " 1877bf215546Sopenharmony_ci "operator must have matching types"); 1878bf215546Sopenharmony_ci error_emitted = true; 1879bf215546Sopenharmony_ci type = glsl_type::error_type; 1880bf215546Sopenharmony_ci } else { 1881bf215546Sopenharmony_ci type = op[1]->type; 1882bf215546Sopenharmony_ci } 1883bf215546Sopenharmony_ci 1884bf215546Sopenharmony_ci /* From page 33 (page 39 of the PDF) of the GLSL 1.10 spec: 1885bf215546Sopenharmony_ci * 1886bf215546Sopenharmony_ci * "The second and third expressions must be the same type, but can 1887bf215546Sopenharmony_ci * be of any type other than an array." 1888bf215546Sopenharmony_ci */ 1889bf215546Sopenharmony_ci if (type->is_array() && 1890bf215546Sopenharmony_ci !state->check_version(120, 300, &loc, 1891bf215546Sopenharmony_ci "second and third operands of ?: operator " 1892bf215546Sopenharmony_ci "cannot be arrays")) { 1893bf215546Sopenharmony_ci error_emitted = true; 1894bf215546Sopenharmony_ci } 1895bf215546Sopenharmony_ci 1896bf215546Sopenharmony_ci /* From section 4.1.7 of the GLSL 4.50 spec (Opaque Types): 1897bf215546Sopenharmony_ci * 1898bf215546Sopenharmony_ci * "Except for array indexing, structure member selection, and 1899bf215546Sopenharmony_ci * parentheses, opaque variables are not allowed to be operands in 1900bf215546Sopenharmony_ci * expressions; such use results in a compile-time error." 1901bf215546Sopenharmony_ci */ 1902bf215546Sopenharmony_ci if (type->contains_opaque()) { 1903bf215546Sopenharmony_ci if (!(state->has_bindless() && (type->is_image() || type->is_sampler()))) { 1904bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "variables of type %s cannot be " 1905bf215546Sopenharmony_ci "operands of the ?: operator", type->name); 1906bf215546Sopenharmony_ci error_emitted = true; 1907bf215546Sopenharmony_ci } 1908bf215546Sopenharmony_ci } 1909bf215546Sopenharmony_ci 1910bf215546Sopenharmony_ci ir_constant *cond_val = op[0]->constant_expression_value(ctx); 1911bf215546Sopenharmony_ci 1912bf215546Sopenharmony_ci if (then_instructions.is_empty() 1913bf215546Sopenharmony_ci && else_instructions.is_empty() 1914bf215546Sopenharmony_ci && cond_val != NULL) { 1915bf215546Sopenharmony_ci result = cond_val->value.b[0] ? op[1] : op[2]; 1916bf215546Sopenharmony_ci } else { 1917bf215546Sopenharmony_ci /* The copy to conditional_tmp reads the whole array. */ 1918bf215546Sopenharmony_ci if (type->is_array()) { 1919bf215546Sopenharmony_ci mark_whole_array_access(op[1]); 1920bf215546Sopenharmony_ci mark_whole_array_access(op[2]); 1921bf215546Sopenharmony_ci } 1922bf215546Sopenharmony_ci 1923bf215546Sopenharmony_ci ir_variable *const tmp = 1924bf215546Sopenharmony_ci new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary); 1925bf215546Sopenharmony_ci instructions->push_tail(tmp); 1926bf215546Sopenharmony_ci 1927bf215546Sopenharmony_ci ir_if *const stmt = new(ctx) ir_if(op[0]); 1928bf215546Sopenharmony_ci instructions->push_tail(stmt); 1929bf215546Sopenharmony_ci 1930bf215546Sopenharmony_ci then_instructions.move_nodes_to(& stmt->then_instructions); 1931bf215546Sopenharmony_ci ir_dereference *const then_deref = 1932bf215546Sopenharmony_ci new(ctx) ir_dereference_variable(tmp); 1933bf215546Sopenharmony_ci ir_assignment *const then_assign = 1934bf215546Sopenharmony_ci new(ctx) ir_assignment(then_deref, op[1]); 1935bf215546Sopenharmony_ci stmt->then_instructions.push_tail(then_assign); 1936bf215546Sopenharmony_ci 1937bf215546Sopenharmony_ci else_instructions.move_nodes_to(& stmt->else_instructions); 1938bf215546Sopenharmony_ci ir_dereference *const else_deref = 1939bf215546Sopenharmony_ci new(ctx) ir_dereference_variable(tmp); 1940bf215546Sopenharmony_ci ir_assignment *const else_assign = 1941bf215546Sopenharmony_ci new(ctx) ir_assignment(else_deref, op[2]); 1942bf215546Sopenharmony_ci stmt->else_instructions.push_tail(else_assign); 1943bf215546Sopenharmony_ci 1944bf215546Sopenharmony_ci result = new(ctx) ir_dereference_variable(tmp); 1945bf215546Sopenharmony_ci } 1946bf215546Sopenharmony_ci break; 1947bf215546Sopenharmony_ci } 1948bf215546Sopenharmony_ci 1949bf215546Sopenharmony_ci case ast_pre_inc: 1950bf215546Sopenharmony_ci case ast_pre_dec: { 1951bf215546Sopenharmony_ci this->non_lvalue_description = (this->oper == ast_pre_inc) 1952bf215546Sopenharmony_ci ? "pre-increment operation" : "pre-decrement operation"; 1953bf215546Sopenharmony_ci 1954bf215546Sopenharmony_ci op[0] = this->subexpressions[0]->hir(instructions, state); 1955bf215546Sopenharmony_ci op[1] = constant_one_for_inc_dec(ctx, op[0]->type); 1956bf215546Sopenharmony_ci 1957bf215546Sopenharmony_ci type = arithmetic_result_type(op[0], op[1], false, state, & loc); 1958bf215546Sopenharmony_ci 1959bf215546Sopenharmony_ci ir_rvalue *temp_rhs; 1960bf215546Sopenharmony_ci temp_rhs = new(ctx) ir_expression(operations[this->oper], type, 1961bf215546Sopenharmony_ci op[0], op[1]); 1962bf215546Sopenharmony_ci 1963bf215546Sopenharmony_ci error_emitted = 1964bf215546Sopenharmony_ci do_assignment(instructions, state, 1965bf215546Sopenharmony_ci this->subexpressions[0]->non_lvalue_description, 1966bf215546Sopenharmony_ci op[0]->clone(ctx, NULL), temp_rhs, 1967bf215546Sopenharmony_ci &result, needs_rvalue, false, 1968bf215546Sopenharmony_ci this->subexpressions[0]->get_location()); 1969bf215546Sopenharmony_ci break; 1970bf215546Sopenharmony_ci } 1971bf215546Sopenharmony_ci 1972bf215546Sopenharmony_ci case ast_post_inc: 1973bf215546Sopenharmony_ci case ast_post_dec: { 1974bf215546Sopenharmony_ci this->non_lvalue_description = (this->oper == ast_post_inc) 1975bf215546Sopenharmony_ci ? "post-increment operation" : "post-decrement operation"; 1976bf215546Sopenharmony_ci op[0] = this->subexpressions[0]->hir(instructions, state); 1977bf215546Sopenharmony_ci op[1] = constant_one_for_inc_dec(ctx, op[0]->type); 1978bf215546Sopenharmony_ci 1979bf215546Sopenharmony_ci error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); 1980bf215546Sopenharmony_ci 1981bf215546Sopenharmony_ci if (error_emitted) { 1982bf215546Sopenharmony_ci result = ir_rvalue::error_value(ctx); 1983bf215546Sopenharmony_ci break; 1984bf215546Sopenharmony_ci } 1985bf215546Sopenharmony_ci 1986bf215546Sopenharmony_ci type = arithmetic_result_type(op[0], op[1], false, state, & loc); 1987bf215546Sopenharmony_ci 1988bf215546Sopenharmony_ci ir_rvalue *temp_rhs; 1989bf215546Sopenharmony_ci temp_rhs = new(ctx) ir_expression(operations[this->oper], type, 1990bf215546Sopenharmony_ci op[0], op[1]); 1991bf215546Sopenharmony_ci 1992bf215546Sopenharmony_ci /* Get a temporary of a copy of the lvalue before it's modified. 1993bf215546Sopenharmony_ci * This may get thrown away later. 1994bf215546Sopenharmony_ci */ 1995bf215546Sopenharmony_ci result = get_lvalue_copy(instructions, op[0]->clone(ctx, NULL)); 1996bf215546Sopenharmony_ci 1997bf215546Sopenharmony_ci ir_rvalue *junk_rvalue; 1998bf215546Sopenharmony_ci error_emitted = 1999bf215546Sopenharmony_ci do_assignment(instructions, state, 2000bf215546Sopenharmony_ci this->subexpressions[0]->non_lvalue_description, 2001bf215546Sopenharmony_ci op[0]->clone(ctx, NULL), temp_rhs, 2002bf215546Sopenharmony_ci &junk_rvalue, false, false, 2003bf215546Sopenharmony_ci this->subexpressions[0]->get_location()); 2004bf215546Sopenharmony_ci 2005bf215546Sopenharmony_ci break; 2006bf215546Sopenharmony_ci } 2007bf215546Sopenharmony_ci 2008bf215546Sopenharmony_ci case ast_field_selection: 2009bf215546Sopenharmony_ci result = _mesa_ast_field_selection_to_hir(this, instructions, state); 2010bf215546Sopenharmony_ci break; 2011bf215546Sopenharmony_ci 2012bf215546Sopenharmony_ci case ast_array_index: { 2013bf215546Sopenharmony_ci YYLTYPE index_loc = subexpressions[1]->get_location(); 2014bf215546Sopenharmony_ci 2015bf215546Sopenharmony_ci /* Getting if an array is being used uninitialized is beyond what we get 2016bf215546Sopenharmony_ci * from ir_value.data.assigned. Setting is_lhs as true would force to 2017bf215546Sopenharmony_ci * not raise a uninitialized warning when using an array 2018bf215546Sopenharmony_ci */ 2019bf215546Sopenharmony_ci subexpressions[0]->set_is_lhs(true); 2020bf215546Sopenharmony_ci op[0] = subexpressions[0]->hir(instructions, state); 2021bf215546Sopenharmony_ci op[1] = subexpressions[1]->hir(instructions, state); 2022bf215546Sopenharmony_ci 2023bf215546Sopenharmony_ci result = _mesa_ast_array_index_to_hir(ctx, state, op[0], op[1], 2024bf215546Sopenharmony_ci loc, index_loc); 2025bf215546Sopenharmony_ci 2026bf215546Sopenharmony_ci if (result->type->is_error()) 2027bf215546Sopenharmony_ci error_emitted = true; 2028bf215546Sopenharmony_ci 2029bf215546Sopenharmony_ci break; 2030bf215546Sopenharmony_ci } 2031bf215546Sopenharmony_ci 2032bf215546Sopenharmony_ci case ast_unsized_array_dim: 2033bf215546Sopenharmony_ci unreachable("ast_unsized_array_dim: Should never get here."); 2034bf215546Sopenharmony_ci 2035bf215546Sopenharmony_ci case ast_function_call: 2036bf215546Sopenharmony_ci /* Should *NEVER* get here. ast_function_call should always be handled 2037bf215546Sopenharmony_ci * by ast_function_expression::hir. 2038bf215546Sopenharmony_ci */ 2039bf215546Sopenharmony_ci unreachable("ast_function_call: handled elsewhere "); 2040bf215546Sopenharmony_ci 2041bf215546Sopenharmony_ci case ast_identifier: { 2042bf215546Sopenharmony_ci /* ast_identifier can appear several places in a full abstract syntax 2043bf215546Sopenharmony_ci * tree. This particular use must be at location specified in the grammar 2044bf215546Sopenharmony_ci * as 'variable_identifier'. 2045bf215546Sopenharmony_ci */ 2046bf215546Sopenharmony_ci ir_variable *var = 2047bf215546Sopenharmony_ci state->symbols->get_variable(this->primary_expression.identifier); 2048bf215546Sopenharmony_ci 2049bf215546Sopenharmony_ci if (var == NULL) { 2050bf215546Sopenharmony_ci /* the identifier might be a subroutine name */ 2051bf215546Sopenharmony_ci char *sub_name; 2052bf215546Sopenharmony_ci sub_name = ralloc_asprintf(ctx, "%s_%s", _mesa_shader_stage_to_subroutine_prefix(state->stage), this->primary_expression.identifier); 2053bf215546Sopenharmony_ci var = state->symbols->get_variable(sub_name); 2054bf215546Sopenharmony_ci ralloc_free(sub_name); 2055bf215546Sopenharmony_ci } 2056bf215546Sopenharmony_ci 2057bf215546Sopenharmony_ci if (var != NULL) { 2058bf215546Sopenharmony_ci var->data.used = true; 2059bf215546Sopenharmony_ci result = new(ctx) ir_dereference_variable(var); 2060bf215546Sopenharmony_ci 2061bf215546Sopenharmony_ci if ((var->data.mode == ir_var_auto || var->data.mode == ir_var_shader_out) 2062bf215546Sopenharmony_ci && !this->is_lhs 2063bf215546Sopenharmony_ci && result->variable_referenced()->data.assigned != true 2064bf215546Sopenharmony_ci && !is_gl_identifier(var->name)) { 2065bf215546Sopenharmony_ci _mesa_glsl_warning(&loc, state, "`%s' used uninitialized", 2066bf215546Sopenharmony_ci this->primary_expression.identifier); 2067bf215546Sopenharmony_ci } 2068bf215546Sopenharmony_ci 2069bf215546Sopenharmony_ci if (var->is_fb_fetch_color_output()) { 2070bf215546Sopenharmony_ci /* From the EXT_shader_framebuffer_fetch spec: 2071bf215546Sopenharmony_ci * 2072bf215546Sopenharmony_ci * "Unless the GL_EXT_shader_framebuffer_fetch extension has been 2073bf215546Sopenharmony_ci * enabled in addition, it's an error to use gl_LastFragData if it 2074bf215546Sopenharmony_ci * hasn't been explicitly redeclared with layout(noncoherent)." 2075bf215546Sopenharmony_ci */ 2076bf215546Sopenharmony_ci if (var->data.memory_coherent && !state->EXT_shader_framebuffer_fetch_enable) { 2077bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 2078bf215546Sopenharmony_ci "invalid use of framebuffer fetch output not " 2079bf215546Sopenharmony_ci "qualified with layout(noncoherent)"); 2080bf215546Sopenharmony_ci } 2081bf215546Sopenharmony_ci } else if (var->data.fb_fetch_output) { 2082bf215546Sopenharmony_ci /* From the ARM_shader_framebuffer_fetch_depth_stencil spec: 2083bf215546Sopenharmony_ci * 2084bf215546Sopenharmony_ci * "It is not legal for a fragment shader to read from gl_LastFragDepthARM 2085bf215546Sopenharmony_ci * and gl_LastFragStencilARM if the early_fragment_tests layout qualifier 2086bf215546Sopenharmony_ci * is specified. This will result in a compile-time error." 2087bf215546Sopenharmony_ci */ 2088bf215546Sopenharmony_ci if (state->fs_early_fragment_tests) { 2089bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 2090bf215546Sopenharmony_ci "invalid use of depth or stencil fetch " 2091bf215546Sopenharmony_ci "with early fragment tests enabled"); 2092bf215546Sopenharmony_ci } 2093bf215546Sopenharmony_ci } 2094bf215546Sopenharmony_ci 2095bf215546Sopenharmony_ci } else { 2096bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "`%s' undeclared", 2097bf215546Sopenharmony_ci this->primary_expression.identifier); 2098bf215546Sopenharmony_ci 2099bf215546Sopenharmony_ci result = ir_rvalue::error_value(ctx); 2100bf215546Sopenharmony_ci error_emitted = true; 2101bf215546Sopenharmony_ci } 2102bf215546Sopenharmony_ci break; 2103bf215546Sopenharmony_ci } 2104bf215546Sopenharmony_ci 2105bf215546Sopenharmony_ci case ast_int_constant: 2106bf215546Sopenharmony_ci result = new(ctx) ir_constant(this->primary_expression.int_constant); 2107bf215546Sopenharmony_ci break; 2108bf215546Sopenharmony_ci 2109bf215546Sopenharmony_ci case ast_uint_constant: 2110bf215546Sopenharmony_ci result = new(ctx) ir_constant(this->primary_expression.uint_constant); 2111bf215546Sopenharmony_ci break; 2112bf215546Sopenharmony_ci 2113bf215546Sopenharmony_ci case ast_float_constant: 2114bf215546Sopenharmony_ci result = new(ctx) ir_constant(this->primary_expression.float_constant); 2115bf215546Sopenharmony_ci break; 2116bf215546Sopenharmony_ci 2117bf215546Sopenharmony_ci case ast_bool_constant: 2118bf215546Sopenharmony_ci result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant)); 2119bf215546Sopenharmony_ci break; 2120bf215546Sopenharmony_ci 2121bf215546Sopenharmony_ci case ast_double_constant: 2122bf215546Sopenharmony_ci result = new(ctx) ir_constant(this->primary_expression.double_constant); 2123bf215546Sopenharmony_ci break; 2124bf215546Sopenharmony_ci 2125bf215546Sopenharmony_ci case ast_uint64_constant: 2126bf215546Sopenharmony_ci result = new(ctx) ir_constant(this->primary_expression.uint64_constant); 2127bf215546Sopenharmony_ci break; 2128bf215546Sopenharmony_ci 2129bf215546Sopenharmony_ci case ast_int64_constant: 2130bf215546Sopenharmony_ci result = new(ctx) ir_constant(this->primary_expression.int64_constant); 2131bf215546Sopenharmony_ci break; 2132bf215546Sopenharmony_ci 2133bf215546Sopenharmony_ci case ast_sequence: { 2134bf215546Sopenharmony_ci /* It should not be possible to generate a sequence in the AST without 2135bf215546Sopenharmony_ci * any expressions in it. 2136bf215546Sopenharmony_ci */ 2137bf215546Sopenharmony_ci assert(!this->expressions.is_empty()); 2138bf215546Sopenharmony_ci 2139bf215546Sopenharmony_ci /* The r-value of a sequence is the last expression in the sequence. If 2140bf215546Sopenharmony_ci * the other expressions in the sequence do not have side-effects (and 2141bf215546Sopenharmony_ci * therefore add instructions to the instruction list), they get dropped 2142bf215546Sopenharmony_ci * on the floor. 2143bf215546Sopenharmony_ci */ 2144bf215546Sopenharmony_ci exec_node *previous_tail = NULL; 2145bf215546Sopenharmony_ci YYLTYPE previous_operand_loc = loc; 2146bf215546Sopenharmony_ci 2147bf215546Sopenharmony_ci foreach_list_typed (ast_node, ast, link, &this->expressions) { 2148bf215546Sopenharmony_ci /* If one of the operands of comma operator does not generate any 2149bf215546Sopenharmony_ci * code, we want to emit a warning. At each pass through the loop 2150bf215546Sopenharmony_ci * previous_tail will point to the last instruction in the stream 2151bf215546Sopenharmony_ci * *before* processing the previous operand. Naturally, 2152bf215546Sopenharmony_ci * instructions->get_tail_raw() will point to the last instruction in 2153bf215546Sopenharmony_ci * the stream *after* processing the previous operand. If the two 2154bf215546Sopenharmony_ci * pointers match, then the previous operand had no effect. 2155bf215546Sopenharmony_ci * 2156bf215546Sopenharmony_ci * The warning behavior here differs slightly from GCC. GCC will 2157bf215546Sopenharmony_ci * only emit a warning if none of the left-hand operands have an 2158bf215546Sopenharmony_ci * effect. However, it will emit a warning for each. I believe that 2159bf215546Sopenharmony_ci * there are some cases in C (especially with GCC extensions) where 2160bf215546Sopenharmony_ci * it is useful to have an intermediate step in a sequence have no 2161bf215546Sopenharmony_ci * effect, but I don't think these cases exist in GLSL. Either way, 2162bf215546Sopenharmony_ci * it would be a giant hassle to replicate that behavior. 2163bf215546Sopenharmony_ci */ 2164bf215546Sopenharmony_ci if (previous_tail == instructions->get_tail_raw()) { 2165bf215546Sopenharmony_ci _mesa_glsl_warning(&previous_operand_loc, state, 2166bf215546Sopenharmony_ci "left-hand operand of comma expression has " 2167bf215546Sopenharmony_ci "no effect"); 2168bf215546Sopenharmony_ci } 2169bf215546Sopenharmony_ci 2170bf215546Sopenharmony_ci /* The tail is directly accessed instead of using the get_tail() 2171bf215546Sopenharmony_ci * method for performance reasons. get_tail() has extra code to 2172bf215546Sopenharmony_ci * return NULL when the list is empty. We don't care about that 2173bf215546Sopenharmony_ci * here, so using get_tail_raw() is fine. 2174bf215546Sopenharmony_ci */ 2175bf215546Sopenharmony_ci previous_tail = instructions->get_tail_raw(); 2176bf215546Sopenharmony_ci previous_operand_loc = ast->get_location(); 2177bf215546Sopenharmony_ci 2178bf215546Sopenharmony_ci result = ast->hir(instructions, state); 2179bf215546Sopenharmony_ci } 2180bf215546Sopenharmony_ci 2181bf215546Sopenharmony_ci /* Any errors should have already been emitted in the loop above. 2182bf215546Sopenharmony_ci */ 2183bf215546Sopenharmony_ci error_emitted = true; 2184bf215546Sopenharmony_ci break; 2185bf215546Sopenharmony_ci } 2186bf215546Sopenharmony_ci } 2187bf215546Sopenharmony_ci type = NULL; /* use result->type, not type. */ 2188bf215546Sopenharmony_ci assert(error_emitted || (result != NULL || !needs_rvalue)); 2189bf215546Sopenharmony_ci 2190bf215546Sopenharmony_ci if (result && result->type->is_error() && !error_emitted) 2191bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "type mismatch"); 2192bf215546Sopenharmony_ci 2193bf215546Sopenharmony_ci return result; 2194bf215546Sopenharmony_ci} 2195bf215546Sopenharmony_ci 2196bf215546Sopenharmony_cibool 2197bf215546Sopenharmony_ciast_expression::has_sequence_subexpression() const 2198bf215546Sopenharmony_ci{ 2199bf215546Sopenharmony_ci switch (this->oper) { 2200bf215546Sopenharmony_ci case ast_plus: 2201bf215546Sopenharmony_ci case ast_neg: 2202bf215546Sopenharmony_ci case ast_bit_not: 2203bf215546Sopenharmony_ci case ast_logic_not: 2204bf215546Sopenharmony_ci case ast_pre_inc: 2205bf215546Sopenharmony_ci case ast_pre_dec: 2206bf215546Sopenharmony_ci case ast_post_inc: 2207bf215546Sopenharmony_ci case ast_post_dec: 2208bf215546Sopenharmony_ci return this->subexpressions[0]->has_sequence_subexpression(); 2209bf215546Sopenharmony_ci 2210bf215546Sopenharmony_ci case ast_assign: 2211bf215546Sopenharmony_ci case ast_add: 2212bf215546Sopenharmony_ci case ast_sub: 2213bf215546Sopenharmony_ci case ast_mul: 2214bf215546Sopenharmony_ci case ast_div: 2215bf215546Sopenharmony_ci case ast_mod: 2216bf215546Sopenharmony_ci case ast_lshift: 2217bf215546Sopenharmony_ci case ast_rshift: 2218bf215546Sopenharmony_ci case ast_less: 2219bf215546Sopenharmony_ci case ast_greater: 2220bf215546Sopenharmony_ci case ast_lequal: 2221bf215546Sopenharmony_ci case ast_gequal: 2222bf215546Sopenharmony_ci case ast_nequal: 2223bf215546Sopenharmony_ci case ast_equal: 2224bf215546Sopenharmony_ci case ast_bit_and: 2225bf215546Sopenharmony_ci case ast_bit_xor: 2226bf215546Sopenharmony_ci case ast_bit_or: 2227bf215546Sopenharmony_ci case ast_logic_and: 2228bf215546Sopenharmony_ci case ast_logic_or: 2229bf215546Sopenharmony_ci case ast_logic_xor: 2230bf215546Sopenharmony_ci case ast_array_index: 2231bf215546Sopenharmony_ci case ast_mul_assign: 2232bf215546Sopenharmony_ci case ast_div_assign: 2233bf215546Sopenharmony_ci case ast_add_assign: 2234bf215546Sopenharmony_ci case ast_sub_assign: 2235bf215546Sopenharmony_ci case ast_mod_assign: 2236bf215546Sopenharmony_ci case ast_ls_assign: 2237bf215546Sopenharmony_ci case ast_rs_assign: 2238bf215546Sopenharmony_ci case ast_and_assign: 2239bf215546Sopenharmony_ci case ast_xor_assign: 2240bf215546Sopenharmony_ci case ast_or_assign: 2241bf215546Sopenharmony_ci return this->subexpressions[0]->has_sequence_subexpression() || 2242bf215546Sopenharmony_ci this->subexpressions[1]->has_sequence_subexpression(); 2243bf215546Sopenharmony_ci 2244bf215546Sopenharmony_ci case ast_conditional: 2245bf215546Sopenharmony_ci return this->subexpressions[0]->has_sequence_subexpression() || 2246bf215546Sopenharmony_ci this->subexpressions[1]->has_sequence_subexpression() || 2247bf215546Sopenharmony_ci this->subexpressions[2]->has_sequence_subexpression(); 2248bf215546Sopenharmony_ci 2249bf215546Sopenharmony_ci case ast_sequence: 2250bf215546Sopenharmony_ci return true; 2251bf215546Sopenharmony_ci 2252bf215546Sopenharmony_ci case ast_field_selection: 2253bf215546Sopenharmony_ci case ast_identifier: 2254bf215546Sopenharmony_ci case ast_int_constant: 2255bf215546Sopenharmony_ci case ast_uint_constant: 2256bf215546Sopenharmony_ci case ast_float_constant: 2257bf215546Sopenharmony_ci case ast_bool_constant: 2258bf215546Sopenharmony_ci case ast_double_constant: 2259bf215546Sopenharmony_ci case ast_int64_constant: 2260bf215546Sopenharmony_ci case ast_uint64_constant: 2261bf215546Sopenharmony_ci return false; 2262bf215546Sopenharmony_ci 2263bf215546Sopenharmony_ci case ast_aggregate: 2264bf215546Sopenharmony_ci return false; 2265bf215546Sopenharmony_ci 2266bf215546Sopenharmony_ci case ast_function_call: 2267bf215546Sopenharmony_ci unreachable("should be handled by ast_function_expression::hir"); 2268bf215546Sopenharmony_ci 2269bf215546Sopenharmony_ci case ast_unsized_array_dim: 2270bf215546Sopenharmony_ci unreachable("ast_unsized_array_dim: Should never get here."); 2271bf215546Sopenharmony_ci } 2272bf215546Sopenharmony_ci 2273bf215546Sopenharmony_ci return false; 2274bf215546Sopenharmony_ci} 2275bf215546Sopenharmony_ci 2276bf215546Sopenharmony_ciir_rvalue * 2277bf215546Sopenharmony_ciast_expression_statement::hir(exec_list *instructions, 2278bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 2279bf215546Sopenharmony_ci{ 2280bf215546Sopenharmony_ci /* It is possible to have expression statements that don't have an 2281bf215546Sopenharmony_ci * expression. This is the solitary semicolon: 2282bf215546Sopenharmony_ci * 2283bf215546Sopenharmony_ci * for (i = 0; i < 5; i++) 2284bf215546Sopenharmony_ci * ; 2285bf215546Sopenharmony_ci * 2286bf215546Sopenharmony_ci * In this case the expression will be NULL. Test for NULL and don't do 2287bf215546Sopenharmony_ci * anything in that case. 2288bf215546Sopenharmony_ci */ 2289bf215546Sopenharmony_ci if (expression != NULL) 2290bf215546Sopenharmony_ci expression->hir_no_rvalue(instructions, state); 2291bf215546Sopenharmony_ci 2292bf215546Sopenharmony_ci /* Statements do not have r-values. 2293bf215546Sopenharmony_ci */ 2294bf215546Sopenharmony_ci return NULL; 2295bf215546Sopenharmony_ci} 2296bf215546Sopenharmony_ci 2297bf215546Sopenharmony_ci 2298bf215546Sopenharmony_ciir_rvalue * 2299bf215546Sopenharmony_ciast_compound_statement::hir(exec_list *instructions, 2300bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 2301bf215546Sopenharmony_ci{ 2302bf215546Sopenharmony_ci if (new_scope) 2303bf215546Sopenharmony_ci state->symbols->push_scope(); 2304bf215546Sopenharmony_ci 2305bf215546Sopenharmony_ci foreach_list_typed (ast_node, ast, link, &this->statements) 2306bf215546Sopenharmony_ci ast->hir(instructions, state); 2307bf215546Sopenharmony_ci 2308bf215546Sopenharmony_ci if (new_scope) 2309bf215546Sopenharmony_ci state->symbols->pop_scope(); 2310bf215546Sopenharmony_ci 2311bf215546Sopenharmony_ci /* Compound statements do not have r-values. 2312bf215546Sopenharmony_ci */ 2313bf215546Sopenharmony_ci return NULL; 2314bf215546Sopenharmony_ci} 2315bf215546Sopenharmony_ci 2316bf215546Sopenharmony_ci/** 2317bf215546Sopenharmony_ci * Evaluate the given exec_node (which should be an ast_node representing 2318bf215546Sopenharmony_ci * a single array dimension) and return its integer value. 2319bf215546Sopenharmony_ci */ 2320bf215546Sopenharmony_cistatic unsigned 2321bf215546Sopenharmony_ciprocess_array_size(exec_node *node, 2322bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 2323bf215546Sopenharmony_ci{ 2324bf215546Sopenharmony_ci void *mem_ctx = state; 2325bf215546Sopenharmony_ci 2326bf215546Sopenharmony_ci exec_list dummy_instructions; 2327bf215546Sopenharmony_ci 2328bf215546Sopenharmony_ci ast_node *array_size = exec_node_data(ast_node, node, link); 2329bf215546Sopenharmony_ci 2330bf215546Sopenharmony_ci /** 2331bf215546Sopenharmony_ci * Dimensions other than the outermost dimension can by unsized if they 2332bf215546Sopenharmony_ci * are immediately sized by a constructor or initializer. 2333bf215546Sopenharmony_ci */ 2334bf215546Sopenharmony_ci if (((ast_expression*)array_size)->oper == ast_unsized_array_dim) 2335bf215546Sopenharmony_ci return 0; 2336bf215546Sopenharmony_ci 2337bf215546Sopenharmony_ci ir_rvalue *const ir = array_size->hir(& dummy_instructions, state); 2338bf215546Sopenharmony_ci YYLTYPE loc = array_size->get_location(); 2339bf215546Sopenharmony_ci 2340bf215546Sopenharmony_ci if (ir == NULL) { 2341bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 2342bf215546Sopenharmony_ci "array size could not be resolved"); 2343bf215546Sopenharmony_ci return 0; 2344bf215546Sopenharmony_ci } 2345bf215546Sopenharmony_ci 2346bf215546Sopenharmony_ci if (!ir->type->is_integer_32()) { 2347bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 2348bf215546Sopenharmony_ci "array size must be integer type"); 2349bf215546Sopenharmony_ci return 0; 2350bf215546Sopenharmony_ci } 2351bf215546Sopenharmony_ci 2352bf215546Sopenharmony_ci if (!ir->type->is_scalar()) { 2353bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 2354bf215546Sopenharmony_ci "array size must be scalar type"); 2355bf215546Sopenharmony_ci return 0; 2356bf215546Sopenharmony_ci } 2357bf215546Sopenharmony_ci 2358bf215546Sopenharmony_ci ir_constant *const size = ir->constant_expression_value(mem_ctx); 2359bf215546Sopenharmony_ci if (size == NULL || 2360bf215546Sopenharmony_ci (state->is_version(120, 300) && 2361bf215546Sopenharmony_ci array_size->has_sequence_subexpression())) { 2362bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "array size must be a " 2363bf215546Sopenharmony_ci "constant valued expression"); 2364bf215546Sopenharmony_ci return 0; 2365bf215546Sopenharmony_ci } 2366bf215546Sopenharmony_ci 2367bf215546Sopenharmony_ci if (size->value.i[0] <= 0) { 2368bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "array size must be > 0"); 2369bf215546Sopenharmony_ci return 0; 2370bf215546Sopenharmony_ci } 2371bf215546Sopenharmony_ci 2372bf215546Sopenharmony_ci assert(size->type == ir->type); 2373bf215546Sopenharmony_ci 2374bf215546Sopenharmony_ci /* If the array size is const (and we've verified that 2375bf215546Sopenharmony_ci * it is) then no instructions should have been emitted 2376bf215546Sopenharmony_ci * when we converted it to HIR. If they were emitted, 2377bf215546Sopenharmony_ci * then either the array size isn't const after all, or 2378bf215546Sopenharmony_ci * we are emitting unnecessary instructions. 2379bf215546Sopenharmony_ci */ 2380bf215546Sopenharmony_ci assert(dummy_instructions.is_empty()); 2381bf215546Sopenharmony_ci 2382bf215546Sopenharmony_ci return size->value.u[0]; 2383bf215546Sopenharmony_ci} 2384bf215546Sopenharmony_ci 2385bf215546Sopenharmony_cistatic const glsl_type * 2386bf215546Sopenharmony_ciprocess_array_type(YYLTYPE *loc, const glsl_type *base, 2387bf215546Sopenharmony_ci ast_array_specifier *array_specifier, 2388bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 2389bf215546Sopenharmony_ci{ 2390bf215546Sopenharmony_ci const glsl_type *array_type = base; 2391bf215546Sopenharmony_ci 2392bf215546Sopenharmony_ci if (array_specifier != NULL) { 2393bf215546Sopenharmony_ci if (base->is_array()) { 2394bf215546Sopenharmony_ci 2395bf215546Sopenharmony_ci /* From page 19 (page 25) of the GLSL 1.20 spec: 2396bf215546Sopenharmony_ci * 2397bf215546Sopenharmony_ci * "Only one-dimensional arrays may be declared." 2398bf215546Sopenharmony_ci */ 2399bf215546Sopenharmony_ci if (!state->check_arrays_of_arrays_allowed(loc)) { 2400bf215546Sopenharmony_ci return glsl_type::error_type; 2401bf215546Sopenharmony_ci } 2402bf215546Sopenharmony_ci } 2403bf215546Sopenharmony_ci 2404bf215546Sopenharmony_ci for (exec_node *node = array_specifier->array_dimensions.get_tail_raw(); 2405bf215546Sopenharmony_ci !node->is_head_sentinel(); node = node->prev) { 2406bf215546Sopenharmony_ci unsigned array_size = process_array_size(node, state); 2407bf215546Sopenharmony_ci array_type = glsl_type::get_array_instance(array_type, array_size); 2408bf215546Sopenharmony_ci } 2409bf215546Sopenharmony_ci } 2410bf215546Sopenharmony_ci 2411bf215546Sopenharmony_ci return array_type; 2412bf215546Sopenharmony_ci} 2413bf215546Sopenharmony_ci 2414bf215546Sopenharmony_cistatic bool 2415bf215546Sopenharmony_ciprecision_qualifier_allowed(const glsl_type *type) 2416bf215546Sopenharmony_ci{ 2417bf215546Sopenharmony_ci /* Precision qualifiers apply to floating point, integer and opaque 2418bf215546Sopenharmony_ci * types. 2419bf215546Sopenharmony_ci * 2420bf215546Sopenharmony_ci * Section 4.5.2 (Precision Qualifiers) of the GLSL 1.30 spec says: 2421bf215546Sopenharmony_ci * "Any floating point or any integer declaration can have the type 2422bf215546Sopenharmony_ci * preceded by one of these precision qualifiers [...] Literal 2423bf215546Sopenharmony_ci * constants do not have precision qualifiers. Neither do Boolean 2424bf215546Sopenharmony_ci * variables. 2425bf215546Sopenharmony_ci * 2426bf215546Sopenharmony_ci * Section 4.5 (Precision and Precision Qualifiers) of the GLSL 1.30 2427bf215546Sopenharmony_ci * spec also says: 2428bf215546Sopenharmony_ci * 2429bf215546Sopenharmony_ci * "Precision qualifiers are added for code portability with OpenGL 2430bf215546Sopenharmony_ci * ES, not for functionality. They have the same syntax as in OpenGL 2431bf215546Sopenharmony_ci * ES." 2432bf215546Sopenharmony_ci * 2433bf215546Sopenharmony_ci * Section 8 (Built-In Functions) of the GLSL ES 1.00 spec says: 2434bf215546Sopenharmony_ci * 2435bf215546Sopenharmony_ci * "uniform lowp sampler2D sampler; 2436bf215546Sopenharmony_ci * highp vec2 coord; 2437bf215546Sopenharmony_ci * ... 2438bf215546Sopenharmony_ci * lowp vec4 col = texture2D (sampler, coord); 2439bf215546Sopenharmony_ci * // texture2D returns lowp" 2440bf215546Sopenharmony_ci * 2441bf215546Sopenharmony_ci * From this, we infer that GLSL 1.30 (and later) should allow precision 2442bf215546Sopenharmony_ci * qualifiers on sampler types just like float and integer types. 2443bf215546Sopenharmony_ci */ 2444bf215546Sopenharmony_ci const glsl_type *const t = type->without_array(); 2445bf215546Sopenharmony_ci 2446bf215546Sopenharmony_ci return (t->is_float() || t->is_integer_32() || t->contains_opaque()) && 2447bf215546Sopenharmony_ci !t->is_struct(); 2448bf215546Sopenharmony_ci} 2449bf215546Sopenharmony_ci 2450bf215546Sopenharmony_ciconst glsl_type * 2451bf215546Sopenharmony_ciast_type_specifier::glsl_type(const char **name, 2452bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) const 2453bf215546Sopenharmony_ci{ 2454bf215546Sopenharmony_ci const struct glsl_type *type; 2455bf215546Sopenharmony_ci 2456bf215546Sopenharmony_ci if (this->type != NULL) 2457bf215546Sopenharmony_ci type = this->type; 2458bf215546Sopenharmony_ci else if (structure) 2459bf215546Sopenharmony_ci type = structure->type; 2460bf215546Sopenharmony_ci else 2461bf215546Sopenharmony_ci type = state->symbols->get_type(this->type_name); 2462bf215546Sopenharmony_ci *name = this->type_name; 2463bf215546Sopenharmony_ci 2464bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 2465bf215546Sopenharmony_ci type = process_array_type(&loc, type, this->array_specifier, state); 2466bf215546Sopenharmony_ci 2467bf215546Sopenharmony_ci return type; 2468bf215546Sopenharmony_ci} 2469bf215546Sopenharmony_ci 2470bf215546Sopenharmony_ci/** 2471bf215546Sopenharmony_ci * From the OpenGL ES 3.0 spec, 4.5.4 Default Precision Qualifiers: 2472bf215546Sopenharmony_ci * 2473bf215546Sopenharmony_ci * "The precision statement 2474bf215546Sopenharmony_ci * 2475bf215546Sopenharmony_ci * precision precision-qualifier type; 2476bf215546Sopenharmony_ci * 2477bf215546Sopenharmony_ci * can be used to establish a default precision qualifier. The type field can 2478bf215546Sopenharmony_ci * be either int or float or any of the sampler types, (...) If type is float, 2479bf215546Sopenharmony_ci * the directive applies to non-precision-qualified floating point type 2480bf215546Sopenharmony_ci * (scalar, vector, and matrix) declarations. If type is int, the directive 2481bf215546Sopenharmony_ci * applies to all non-precision-qualified integer type (scalar, vector, signed, 2482bf215546Sopenharmony_ci * and unsigned) declarations." 2483bf215546Sopenharmony_ci * 2484bf215546Sopenharmony_ci * We use the symbol table to keep the values of the default precisions for 2485bf215546Sopenharmony_ci * each 'type' in each scope and we use the 'type' string from the precision 2486bf215546Sopenharmony_ci * statement as key in the symbol table. When we want to retrieve the default 2487bf215546Sopenharmony_ci * precision associated with a given glsl_type we need to know the type string 2488bf215546Sopenharmony_ci * associated with it. This is what this function returns. 2489bf215546Sopenharmony_ci */ 2490bf215546Sopenharmony_cistatic const char * 2491bf215546Sopenharmony_ciget_type_name_for_precision_qualifier(const glsl_type *type) 2492bf215546Sopenharmony_ci{ 2493bf215546Sopenharmony_ci switch (type->base_type) { 2494bf215546Sopenharmony_ci case GLSL_TYPE_FLOAT: 2495bf215546Sopenharmony_ci return "float"; 2496bf215546Sopenharmony_ci case GLSL_TYPE_UINT: 2497bf215546Sopenharmony_ci case GLSL_TYPE_INT: 2498bf215546Sopenharmony_ci return "int"; 2499bf215546Sopenharmony_ci case GLSL_TYPE_ATOMIC_UINT: 2500bf215546Sopenharmony_ci return "atomic_uint"; 2501bf215546Sopenharmony_ci case GLSL_TYPE_IMAGE: 2502bf215546Sopenharmony_ci FALLTHROUGH; 2503bf215546Sopenharmony_ci case GLSL_TYPE_SAMPLER: { 2504bf215546Sopenharmony_ci const unsigned type_idx = 2505bf215546Sopenharmony_ci type->sampler_array + 2 * type->sampler_shadow; 2506bf215546Sopenharmony_ci const unsigned offset = type->is_sampler() ? 0 : 4; 2507bf215546Sopenharmony_ci assert(type_idx < 4); 2508bf215546Sopenharmony_ci switch (type->sampled_type) { 2509bf215546Sopenharmony_ci case GLSL_TYPE_FLOAT: 2510bf215546Sopenharmony_ci switch (type->sampler_dimensionality) { 2511bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_1D: { 2512bf215546Sopenharmony_ci assert(type->is_sampler()); 2513bf215546Sopenharmony_ci static const char *const names[4] = { 2514bf215546Sopenharmony_ci "sampler1D", "sampler1DArray", 2515bf215546Sopenharmony_ci "sampler1DShadow", "sampler1DArrayShadow" 2516bf215546Sopenharmony_ci }; 2517bf215546Sopenharmony_ci return names[type_idx]; 2518bf215546Sopenharmony_ci } 2519bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_2D: { 2520bf215546Sopenharmony_ci static const char *const names[8] = { 2521bf215546Sopenharmony_ci "sampler2D", "sampler2DArray", 2522bf215546Sopenharmony_ci "sampler2DShadow", "sampler2DArrayShadow", 2523bf215546Sopenharmony_ci "image2D", "image2DArray", NULL, NULL 2524bf215546Sopenharmony_ci }; 2525bf215546Sopenharmony_ci return names[offset + type_idx]; 2526bf215546Sopenharmony_ci } 2527bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_3D: { 2528bf215546Sopenharmony_ci static const char *const names[8] = { 2529bf215546Sopenharmony_ci "sampler3D", NULL, NULL, NULL, 2530bf215546Sopenharmony_ci "image3D", NULL, NULL, NULL 2531bf215546Sopenharmony_ci }; 2532bf215546Sopenharmony_ci return names[offset + type_idx]; 2533bf215546Sopenharmony_ci } 2534bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_CUBE: { 2535bf215546Sopenharmony_ci static const char *const names[8] = { 2536bf215546Sopenharmony_ci "samplerCube", "samplerCubeArray", 2537bf215546Sopenharmony_ci "samplerCubeShadow", "samplerCubeArrayShadow", 2538bf215546Sopenharmony_ci "imageCube", NULL, NULL, NULL 2539bf215546Sopenharmony_ci }; 2540bf215546Sopenharmony_ci return names[offset + type_idx]; 2541bf215546Sopenharmony_ci } 2542bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_MS: { 2543bf215546Sopenharmony_ci assert(type->is_sampler()); 2544bf215546Sopenharmony_ci static const char *const names[4] = { 2545bf215546Sopenharmony_ci "sampler2DMS", "sampler2DMSArray", NULL, NULL 2546bf215546Sopenharmony_ci }; 2547bf215546Sopenharmony_ci return names[type_idx]; 2548bf215546Sopenharmony_ci } 2549bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_RECT: { 2550bf215546Sopenharmony_ci assert(type->is_sampler()); 2551bf215546Sopenharmony_ci static const char *const names[4] = { 2552bf215546Sopenharmony_ci "samplerRect", NULL, "samplerRectShadow", NULL 2553bf215546Sopenharmony_ci }; 2554bf215546Sopenharmony_ci return names[type_idx]; 2555bf215546Sopenharmony_ci } 2556bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_BUF: { 2557bf215546Sopenharmony_ci static const char *const names[8] = { 2558bf215546Sopenharmony_ci "samplerBuffer", NULL, NULL, NULL, 2559bf215546Sopenharmony_ci "imageBuffer", NULL, NULL, NULL 2560bf215546Sopenharmony_ci }; 2561bf215546Sopenharmony_ci return names[offset + type_idx]; 2562bf215546Sopenharmony_ci } 2563bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_EXTERNAL: { 2564bf215546Sopenharmony_ci assert(type->is_sampler()); 2565bf215546Sopenharmony_ci static const char *const names[4] = { 2566bf215546Sopenharmony_ci "samplerExternalOES", NULL, NULL, NULL 2567bf215546Sopenharmony_ci }; 2568bf215546Sopenharmony_ci return names[type_idx]; 2569bf215546Sopenharmony_ci } 2570bf215546Sopenharmony_ci default: 2571bf215546Sopenharmony_ci unreachable("Unsupported sampler/image dimensionality"); 2572bf215546Sopenharmony_ci } /* sampler/image float dimensionality */ 2573bf215546Sopenharmony_ci break; 2574bf215546Sopenharmony_ci case GLSL_TYPE_INT: 2575bf215546Sopenharmony_ci switch (type->sampler_dimensionality) { 2576bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_1D: { 2577bf215546Sopenharmony_ci assert(type->is_sampler()); 2578bf215546Sopenharmony_ci static const char *const names[4] = { 2579bf215546Sopenharmony_ci "isampler1D", "isampler1DArray", NULL, NULL 2580bf215546Sopenharmony_ci }; 2581bf215546Sopenharmony_ci return names[type_idx]; 2582bf215546Sopenharmony_ci } 2583bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_2D: { 2584bf215546Sopenharmony_ci static const char *const names[8] = { 2585bf215546Sopenharmony_ci "isampler2D", "isampler2DArray", NULL, NULL, 2586bf215546Sopenharmony_ci "iimage2D", "iimage2DArray", NULL, NULL 2587bf215546Sopenharmony_ci }; 2588bf215546Sopenharmony_ci return names[offset + type_idx]; 2589bf215546Sopenharmony_ci } 2590bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_3D: { 2591bf215546Sopenharmony_ci static const char *const names[8] = { 2592bf215546Sopenharmony_ci "isampler3D", NULL, NULL, NULL, 2593bf215546Sopenharmony_ci "iimage3D", NULL, NULL, NULL 2594bf215546Sopenharmony_ci }; 2595bf215546Sopenharmony_ci return names[offset + type_idx]; 2596bf215546Sopenharmony_ci } 2597bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_CUBE: { 2598bf215546Sopenharmony_ci static const char *const names[8] = { 2599bf215546Sopenharmony_ci "isamplerCube", "isamplerCubeArray", NULL, NULL, 2600bf215546Sopenharmony_ci "iimageCube", NULL, NULL, NULL 2601bf215546Sopenharmony_ci }; 2602bf215546Sopenharmony_ci return names[offset + type_idx]; 2603bf215546Sopenharmony_ci } 2604bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_MS: { 2605bf215546Sopenharmony_ci assert(type->is_sampler()); 2606bf215546Sopenharmony_ci static const char *const names[4] = { 2607bf215546Sopenharmony_ci "isampler2DMS", "isampler2DMSArray", NULL, NULL 2608bf215546Sopenharmony_ci }; 2609bf215546Sopenharmony_ci return names[type_idx]; 2610bf215546Sopenharmony_ci } 2611bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_RECT: { 2612bf215546Sopenharmony_ci assert(type->is_sampler()); 2613bf215546Sopenharmony_ci static const char *const names[4] = { 2614bf215546Sopenharmony_ci "isamplerRect", NULL, "isamplerRectShadow", NULL 2615bf215546Sopenharmony_ci }; 2616bf215546Sopenharmony_ci return names[type_idx]; 2617bf215546Sopenharmony_ci } 2618bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_BUF: { 2619bf215546Sopenharmony_ci static const char *const names[8] = { 2620bf215546Sopenharmony_ci "isamplerBuffer", NULL, NULL, NULL, 2621bf215546Sopenharmony_ci "iimageBuffer", NULL, NULL, NULL 2622bf215546Sopenharmony_ci }; 2623bf215546Sopenharmony_ci return names[offset + type_idx]; 2624bf215546Sopenharmony_ci } 2625bf215546Sopenharmony_ci default: 2626bf215546Sopenharmony_ci unreachable("Unsupported isampler/iimage dimensionality"); 2627bf215546Sopenharmony_ci } /* sampler/image int dimensionality */ 2628bf215546Sopenharmony_ci break; 2629bf215546Sopenharmony_ci case GLSL_TYPE_UINT: 2630bf215546Sopenharmony_ci switch (type->sampler_dimensionality) { 2631bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_1D: { 2632bf215546Sopenharmony_ci assert(type->is_sampler()); 2633bf215546Sopenharmony_ci static const char *const names[4] = { 2634bf215546Sopenharmony_ci "usampler1D", "usampler1DArray", NULL, NULL 2635bf215546Sopenharmony_ci }; 2636bf215546Sopenharmony_ci return names[type_idx]; 2637bf215546Sopenharmony_ci } 2638bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_2D: { 2639bf215546Sopenharmony_ci static const char *const names[8] = { 2640bf215546Sopenharmony_ci "usampler2D", "usampler2DArray", NULL, NULL, 2641bf215546Sopenharmony_ci "uimage2D", "uimage2DArray", NULL, NULL 2642bf215546Sopenharmony_ci }; 2643bf215546Sopenharmony_ci return names[offset + type_idx]; 2644bf215546Sopenharmony_ci } 2645bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_3D: { 2646bf215546Sopenharmony_ci static const char *const names[8] = { 2647bf215546Sopenharmony_ci "usampler3D", NULL, NULL, NULL, 2648bf215546Sopenharmony_ci "uimage3D", NULL, NULL, NULL 2649bf215546Sopenharmony_ci }; 2650bf215546Sopenharmony_ci return names[offset + type_idx]; 2651bf215546Sopenharmony_ci } 2652bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_CUBE: { 2653bf215546Sopenharmony_ci static const char *const names[8] = { 2654bf215546Sopenharmony_ci "usamplerCube", "usamplerCubeArray", NULL, NULL, 2655bf215546Sopenharmony_ci "uimageCube", NULL, NULL, NULL 2656bf215546Sopenharmony_ci }; 2657bf215546Sopenharmony_ci return names[offset + type_idx]; 2658bf215546Sopenharmony_ci } 2659bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_MS: { 2660bf215546Sopenharmony_ci assert(type->is_sampler()); 2661bf215546Sopenharmony_ci static const char *const names[4] = { 2662bf215546Sopenharmony_ci "usampler2DMS", "usampler2DMSArray", NULL, NULL 2663bf215546Sopenharmony_ci }; 2664bf215546Sopenharmony_ci return names[type_idx]; 2665bf215546Sopenharmony_ci } 2666bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_RECT: { 2667bf215546Sopenharmony_ci assert(type->is_sampler()); 2668bf215546Sopenharmony_ci static const char *const names[4] = { 2669bf215546Sopenharmony_ci "usamplerRect", NULL, "usamplerRectShadow", NULL 2670bf215546Sopenharmony_ci }; 2671bf215546Sopenharmony_ci return names[type_idx]; 2672bf215546Sopenharmony_ci } 2673bf215546Sopenharmony_ci case GLSL_SAMPLER_DIM_BUF: { 2674bf215546Sopenharmony_ci static const char *const names[8] = { 2675bf215546Sopenharmony_ci "usamplerBuffer", NULL, NULL, NULL, 2676bf215546Sopenharmony_ci "uimageBuffer", NULL, NULL, NULL 2677bf215546Sopenharmony_ci }; 2678bf215546Sopenharmony_ci return names[offset + type_idx]; 2679bf215546Sopenharmony_ci } 2680bf215546Sopenharmony_ci default: 2681bf215546Sopenharmony_ci unreachable("Unsupported usampler/uimage dimensionality"); 2682bf215546Sopenharmony_ci } /* sampler/image uint dimensionality */ 2683bf215546Sopenharmony_ci break; 2684bf215546Sopenharmony_ci default: 2685bf215546Sopenharmony_ci unreachable("Unsupported sampler/image type"); 2686bf215546Sopenharmony_ci } /* sampler/image type */ 2687bf215546Sopenharmony_ci break; 2688bf215546Sopenharmony_ci } /* GLSL_TYPE_SAMPLER/GLSL_TYPE_IMAGE */ 2689bf215546Sopenharmony_ci break; 2690bf215546Sopenharmony_ci default: 2691bf215546Sopenharmony_ci unreachable("Unsupported type"); 2692bf215546Sopenharmony_ci } /* base type */ 2693bf215546Sopenharmony_ci} 2694bf215546Sopenharmony_ci 2695bf215546Sopenharmony_cistatic unsigned 2696bf215546Sopenharmony_ciselect_gles_precision(unsigned qual_precision, 2697bf215546Sopenharmony_ci const glsl_type *type, 2698bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, YYLTYPE *loc) 2699bf215546Sopenharmony_ci{ 2700bf215546Sopenharmony_ci /* Precision qualifiers do not have any meaning in Desktop GLSL. 2701bf215546Sopenharmony_ci * In GLES we take the precision from the type qualifier if present, 2702bf215546Sopenharmony_ci * otherwise, if the type of the variable allows precision qualifiers at 2703bf215546Sopenharmony_ci * all, we look for the default precision qualifier for that type in the 2704bf215546Sopenharmony_ci * current scope. 2705bf215546Sopenharmony_ci */ 2706bf215546Sopenharmony_ci assert(state->es_shader); 2707bf215546Sopenharmony_ci 2708bf215546Sopenharmony_ci unsigned precision = GLSL_PRECISION_NONE; 2709bf215546Sopenharmony_ci if (qual_precision) { 2710bf215546Sopenharmony_ci precision = qual_precision; 2711bf215546Sopenharmony_ci } else if (precision_qualifier_allowed(type)) { 2712bf215546Sopenharmony_ci const char *type_name = 2713bf215546Sopenharmony_ci get_type_name_for_precision_qualifier(type->without_array()); 2714bf215546Sopenharmony_ci assert(type_name != NULL); 2715bf215546Sopenharmony_ci 2716bf215546Sopenharmony_ci precision = 2717bf215546Sopenharmony_ci state->symbols->get_default_precision_qualifier(type_name); 2718bf215546Sopenharmony_ci if (precision == ast_precision_none) { 2719bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 2720bf215546Sopenharmony_ci "No precision specified in this scope for type `%s'", 2721bf215546Sopenharmony_ci type->name); 2722bf215546Sopenharmony_ci } 2723bf215546Sopenharmony_ci } 2724bf215546Sopenharmony_ci 2725bf215546Sopenharmony_ci 2726bf215546Sopenharmony_ci /* Section 4.1.7.3 (Atomic Counters) of the GLSL ES 3.10 spec says: 2727bf215546Sopenharmony_ci * 2728bf215546Sopenharmony_ci * "The default precision of all atomic types is highp. It is an error to 2729bf215546Sopenharmony_ci * declare an atomic type with a different precision or to specify the 2730bf215546Sopenharmony_ci * default precision for an atomic type to be lowp or mediump." 2731bf215546Sopenharmony_ci */ 2732bf215546Sopenharmony_ci if (type->is_atomic_uint() && precision != ast_precision_high) { 2733bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 2734bf215546Sopenharmony_ci "atomic_uint can only have highp precision qualifier"); 2735bf215546Sopenharmony_ci } 2736bf215546Sopenharmony_ci 2737bf215546Sopenharmony_ci return precision; 2738bf215546Sopenharmony_ci} 2739bf215546Sopenharmony_ci 2740bf215546Sopenharmony_ciconst glsl_type * 2741bf215546Sopenharmony_ciast_fully_specified_type::glsl_type(const char **name, 2742bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) const 2743bf215546Sopenharmony_ci{ 2744bf215546Sopenharmony_ci return this->specifier->glsl_type(name, state); 2745bf215546Sopenharmony_ci} 2746bf215546Sopenharmony_ci 2747bf215546Sopenharmony_ci/** 2748bf215546Sopenharmony_ci * Determine whether a toplevel variable declaration declares a varying. This 2749bf215546Sopenharmony_ci * function operates by examining the variable's mode and the shader target, 2750bf215546Sopenharmony_ci * so it correctly identifies linkage variables regardless of whether they are 2751bf215546Sopenharmony_ci * declared using the deprecated "varying" syntax or the new "in/out" syntax. 2752bf215546Sopenharmony_ci * 2753bf215546Sopenharmony_ci * Passing a non-toplevel variable declaration (e.g. a function parameter) to 2754bf215546Sopenharmony_ci * this function will produce undefined results. 2755bf215546Sopenharmony_ci */ 2756bf215546Sopenharmony_cistatic bool 2757bf215546Sopenharmony_ciis_varying_var(ir_variable *var, gl_shader_stage target) 2758bf215546Sopenharmony_ci{ 2759bf215546Sopenharmony_ci switch (target) { 2760bf215546Sopenharmony_ci case MESA_SHADER_VERTEX: 2761bf215546Sopenharmony_ci return var->data.mode == ir_var_shader_out; 2762bf215546Sopenharmony_ci case MESA_SHADER_FRAGMENT: 2763bf215546Sopenharmony_ci return var->data.mode == ir_var_shader_in || 2764bf215546Sopenharmony_ci (var->data.mode == ir_var_system_value && 2765bf215546Sopenharmony_ci var->data.location == SYSTEM_VALUE_FRAG_COORD); 2766bf215546Sopenharmony_ci default: 2767bf215546Sopenharmony_ci return var->data.mode == ir_var_shader_out || var->data.mode == ir_var_shader_in; 2768bf215546Sopenharmony_ci } 2769bf215546Sopenharmony_ci} 2770bf215546Sopenharmony_ci 2771bf215546Sopenharmony_cistatic bool 2772bf215546Sopenharmony_ciis_allowed_invariant(ir_variable *var, struct _mesa_glsl_parse_state *state) 2773bf215546Sopenharmony_ci{ 2774bf215546Sopenharmony_ci if (is_varying_var(var, state->stage)) 2775bf215546Sopenharmony_ci return true; 2776bf215546Sopenharmony_ci 2777bf215546Sopenharmony_ci /* From Section 4.6.1 ("The Invariant Qualifier") GLSL 1.20 spec: 2778bf215546Sopenharmony_ci * "Only variables output from a vertex shader can be candidates 2779bf215546Sopenharmony_ci * for invariance". 2780bf215546Sopenharmony_ci */ 2781bf215546Sopenharmony_ci if (!state->is_version(130, 100)) 2782bf215546Sopenharmony_ci return false; 2783bf215546Sopenharmony_ci 2784bf215546Sopenharmony_ci /* 2785bf215546Sopenharmony_ci * Later specs remove this language - so allowed invariant 2786bf215546Sopenharmony_ci * on fragment shader outputs as well. 2787bf215546Sopenharmony_ci */ 2788bf215546Sopenharmony_ci if (state->stage == MESA_SHADER_FRAGMENT && 2789bf215546Sopenharmony_ci var->data.mode == ir_var_shader_out) 2790bf215546Sopenharmony_ci return true; 2791bf215546Sopenharmony_ci return false; 2792bf215546Sopenharmony_ci} 2793bf215546Sopenharmony_ci 2794bf215546Sopenharmony_cistatic void 2795bf215546Sopenharmony_civalidate_component_layout_for_type(struct _mesa_glsl_parse_state *state, 2796bf215546Sopenharmony_ci YYLTYPE *loc, const glsl_type *type, 2797bf215546Sopenharmony_ci unsigned qual_component) 2798bf215546Sopenharmony_ci{ 2799bf215546Sopenharmony_ci type = type->without_array(); 2800bf215546Sopenharmony_ci unsigned components = type->component_slots(); 2801bf215546Sopenharmony_ci 2802bf215546Sopenharmony_ci if (type->is_matrix() || type->is_struct()) { 2803bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "component layout qualifier " 2804bf215546Sopenharmony_ci "cannot be applied to a matrix, a structure, " 2805bf215546Sopenharmony_ci "a block, or an array containing any of these."); 2806bf215546Sopenharmony_ci } else if (components > 4 && type->is_64bit()) { 2807bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "component layout qualifier " 2808bf215546Sopenharmony_ci "cannot be applied to dvec%u.", 2809bf215546Sopenharmony_ci components / 2); 2810bf215546Sopenharmony_ci } else if (qual_component != 0 && (qual_component + components - 1) > 3) { 2811bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "component overflow (%u > 3)", 2812bf215546Sopenharmony_ci (qual_component + components - 1)); 2813bf215546Sopenharmony_ci } else if (qual_component == 1 && type->is_64bit()) { 2814bf215546Sopenharmony_ci /* We don't bother checking for 3 as it should be caught by the 2815bf215546Sopenharmony_ci * overflow check above. 2816bf215546Sopenharmony_ci */ 2817bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "doubles cannot begin at component 1 or 3"); 2818bf215546Sopenharmony_ci } 2819bf215546Sopenharmony_ci} 2820bf215546Sopenharmony_ci 2821bf215546Sopenharmony_ci/** 2822bf215546Sopenharmony_ci * Matrix layout qualifiers are only allowed on certain types 2823bf215546Sopenharmony_ci */ 2824bf215546Sopenharmony_cistatic void 2825bf215546Sopenharmony_civalidate_matrix_layout_for_type(struct _mesa_glsl_parse_state *state, 2826bf215546Sopenharmony_ci YYLTYPE *loc, 2827bf215546Sopenharmony_ci const glsl_type *type, 2828bf215546Sopenharmony_ci ir_variable *var) 2829bf215546Sopenharmony_ci{ 2830bf215546Sopenharmony_ci if (var && !var->is_in_buffer_block()) { 2831bf215546Sopenharmony_ci /* Layout qualifiers may only apply to interface blocks and fields in 2832bf215546Sopenharmony_ci * them. 2833bf215546Sopenharmony_ci */ 2834bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 2835bf215546Sopenharmony_ci "uniform block layout qualifiers row_major and " 2836bf215546Sopenharmony_ci "column_major may not be applied to variables " 2837bf215546Sopenharmony_ci "outside of uniform blocks"); 2838bf215546Sopenharmony_ci } else if (!type->without_array()->is_matrix()) { 2839bf215546Sopenharmony_ci /* The OpenGL ES 3.0 conformance tests did not originally allow 2840bf215546Sopenharmony_ci * matrix layout qualifiers on non-matrices. However, the OpenGL 2841bf215546Sopenharmony_ci * 4.4 and OpenGL ES 3.0 (revision TBD) specifications were 2842bf215546Sopenharmony_ci * amended to specifically allow these layouts on all types. Emit 2843bf215546Sopenharmony_ci * a warning so that people know their code may not be portable. 2844bf215546Sopenharmony_ci */ 2845bf215546Sopenharmony_ci _mesa_glsl_warning(loc, state, 2846bf215546Sopenharmony_ci "uniform block layout qualifiers row_major and " 2847bf215546Sopenharmony_ci "column_major applied to non-matrix types may " 2848bf215546Sopenharmony_ci "be rejected by older compilers"); 2849bf215546Sopenharmony_ci } 2850bf215546Sopenharmony_ci} 2851bf215546Sopenharmony_ci 2852bf215546Sopenharmony_cistatic bool 2853bf215546Sopenharmony_civalidate_xfb_buffer_qualifier(YYLTYPE *loc, 2854bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, 2855bf215546Sopenharmony_ci unsigned xfb_buffer) { 2856bf215546Sopenharmony_ci if (xfb_buffer >= state->Const.MaxTransformFeedbackBuffers) { 2857bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 2858bf215546Sopenharmony_ci "invalid xfb_buffer specified %d is larger than " 2859bf215546Sopenharmony_ci "MAX_TRANSFORM_FEEDBACK_BUFFERS - 1 (%d).", 2860bf215546Sopenharmony_ci xfb_buffer, 2861bf215546Sopenharmony_ci state->Const.MaxTransformFeedbackBuffers - 1); 2862bf215546Sopenharmony_ci return false; 2863bf215546Sopenharmony_ci } 2864bf215546Sopenharmony_ci 2865bf215546Sopenharmony_ci return true; 2866bf215546Sopenharmony_ci} 2867bf215546Sopenharmony_ci 2868bf215546Sopenharmony_ci/* From the ARB_enhanced_layouts spec: 2869bf215546Sopenharmony_ci * 2870bf215546Sopenharmony_ci * "Variables and block members qualified with *xfb_offset* can be 2871bf215546Sopenharmony_ci * scalars, vectors, matrices, structures, and (sized) arrays of these. 2872bf215546Sopenharmony_ci * The offset must be a multiple of the size of the first component of 2873bf215546Sopenharmony_ci * the first qualified variable or block member, or a compile-time error 2874bf215546Sopenharmony_ci * results. Further, if applied to an aggregate containing a double, 2875bf215546Sopenharmony_ci * the offset must also be a multiple of 8, and the space taken in the 2876bf215546Sopenharmony_ci * buffer will be a multiple of 8. 2877bf215546Sopenharmony_ci */ 2878bf215546Sopenharmony_cistatic bool 2879bf215546Sopenharmony_civalidate_xfb_offset_qualifier(YYLTYPE *loc, 2880bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, 2881bf215546Sopenharmony_ci int xfb_offset, const glsl_type *type, 2882bf215546Sopenharmony_ci unsigned component_size) { 2883bf215546Sopenharmony_ci const glsl_type *t_without_array = type->without_array(); 2884bf215546Sopenharmony_ci 2885bf215546Sopenharmony_ci if (xfb_offset != -1 && type->is_unsized_array()) { 2886bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 2887bf215546Sopenharmony_ci "xfb_offset can't be used with unsized arrays."); 2888bf215546Sopenharmony_ci return false; 2889bf215546Sopenharmony_ci } 2890bf215546Sopenharmony_ci 2891bf215546Sopenharmony_ci /* Make sure nested structs don't contain unsized arrays, and validate 2892bf215546Sopenharmony_ci * any xfb_offsets on interface members. 2893bf215546Sopenharmony_ci */ 2894bf215546Sopenharmony_ci if (t_without_array->is_struct() || t_without_array->is_interface()) 2895bf215546Sopenharmony_ci for (unsigned int i = 0; i < t_without_array->length; i++) { 2896bf215546Sopenharmony_ci const glsl_type *member_t = t_without_array->fields.structure[i].type; 2897bf215546Sopenharmony_ci 2898bf215546Sopenharmony_ci /* When the interface block doesn't have an xfb_offset qualifier then 2899bf215546Sopenharmony_ci * we apply the component size rules at the member level. 2900bf215546Sopenharmony_ci */ 2901bf215546Sopenharmony_ci if (xfb_offset == -1) 2902bf215546Sopenharmony_ci component_size = member_t->contains_double() ? 8 : 4; 2903bf215546Sopenharmony_ci 2904bf215546Sopenharmony_ci int xfb_offset = t_without_array->fields.structure[i].offset; 2905bf215546Sopenharmony_ci validate_xfb_offset_qualifier(loc, state, xfb_offset, member_t, 2906bf215546Sopenharmony_ci component_size); 2907bf215546Sopenharmony_ci } 2908bf215546Sopenharmony_ci 2909bf215546Sopenharmony_ci /* Nested structs or interface block without offset may not have had an 2910bf215546Sopenharmony_ci * offset applied yet so return. 2911bf215546Sopenharmony_ci */ 2912bf215546Sopenharmony_ci if (xfb_offset == -1) { 2913bf215546Sopenharmony_ci return true; 2914bf215546Sopenharmony_ci } 2915bf215546Sopenharmony_ci 2916bf215546Sopenharmony_ci if (xfb_offset % component_size) { 2917bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 2918bf215546Sopenharmony_ci "invalid qualifier xfb_offset=%d must be a multiple " 2919bf215546Sopenharmony_ci "of the first component size of the first qualified " 2920bf215546Sopenharmony_ci "variable or block member. Or double if an aggregate " 2921bf215546Sopenharmony_ci "that contains a double (%d).", 2922bf215546Sopenharmony_ci xfb_offset, component_size); 2923bf215546Sopenharmony_ci return false; 2924bf215546Sopenharmony_ci } 2925bf215546Sopenharmony_ci 2926bf215546Sopenharmony_ci return true; 2927bf215546Sopenharmony_ci} 2928bf215546Sopenharmony_ci 2929bf215546Sopenharmony_cistatic bool 2930bf215546Sopenharmony_civalidate_stream_qualifier(YYLTYPE *loc, struct _mesa_glsl_parse_state *state, 2931bf215546Sopenharmony_ci unsigned stream) 2932bf215546Sopenharmony_ci{ 2933bf215546Sopenharmony_ci if (stream >= state->consts->MaxVertexStreams) { 2934bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 2935bf215546Sopenharmony_ci "invalid stream specified %d is larger than " 2936bf215546Sopenharmony_ci "MAX_VERTEX_STREAMS - 1 (%d).", 2937bf215546Sopenharmony_ci stream, state->consts->MaxVertexStreams - 1); 2938bf215546Sopenharmony_ci return false; 2939bf215546Sopenharmony_ci } 2940bf215546Sopenharmony_ci 2941bf215546Sopenharmony_ci return true; 2942bf215546Sopenharmony_ci} 2943bf215546Sopenharmony_ci 2944bf215546Sopenharmony_cistatic void 2945bf215546Sopenharmony_ciapply_explicit_binding(struct _mesa_glsl_parse_state *state, 2946bf215546Sopenharmony_ci YYLTYPE *loc, 2947bf215546Sopenharmony_ci ir_variable *var, 2948bf215546Sopenharmony_ci const glsl_type *type, 2949bf215546Sopenharmony_ci const ast_type_qualifier *qual) 2950bf215546Sopenharmony_ci{ 2951bf215546Sopenharmony_ci if (!qual->flags.q.uniform && !qual->flags.q.buffer) { 2952bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 2953bf215546Sopenharmony_ci "the \"binding\" qualifier only applies to uniforms and " 2954bf215546Sopenharmony_ci "shader storage buffer objects"); 2955bf215546Sopenharmony_ci return; 2956bf215546Sopenharmony_ci } 2957bf215546Sopenharmony_ci 2958bf215546Sopenharmony_ci unsigned qual_binding; 2959bf215546Sopenharmony_ci if (!process_qualifier_constant(state, loc, "binding", qual->binding, 2960bf215546Sopenharmony_ci &qual_binding)) { 2961bf215546Sopenharmony_ci return; 2962bf215546Sopenharmony_ci } 2963bf215546Sopenharmony_ci 2964bf215546Sopenharmony_ci const struct gl_constants *consts = state->consts; 2965bf215546Sopenharmony_ci unsigned elements = type->is_array() ? type->arrays_of_arrays_size() : 1; 2966bf215546Sopenharmony_ci unsigned max_index = qual_binding + elements - 1; 2967bf215546Sopenharmony_ci const glsl_type *base_type = type->without_array(); 2968bf215546Sopenharmony_ci 2969bf215546Sopenharmony_ci if (base_type->is_interface()) { 2970bf215546Sopenharmony_ci /* UBOs. From page 60 of the GLSL 4.20 specification: 2971bf215546Sopenharmony_ci * "If the binding point for any uniform block instance is less than zero, 2972bf215546Sopenharmony_ci * or greater than or equal to the implementation-dependent maximum 2973bf215546Sopenharmony_ci * number of uniform buffer bindings, a compilation error will occur. 2974bf215546Sopenharmony_ci * When the binding identifier is used with a uniform block instanced as 2975bf215546Sopenharmony_ci * an array of size N, all elements of the array from binding through 2976bf215546Sopenharmony_ci * binding + N – 1 must be within this range." 2977bf215546Sopenharmony_ci * 2978bf215546Sopenharmony_ci * The implementation-dependent maximum is GL_MAX_UNIFORM_BUFFER_BINDINGS. 2979bf215546Sopenharmony_ci */ 2980bf215546Sopenharmony_ci if (qual->flags.q.uniform && 2981bf215546Sopenharmony_ci max_index >= consts->MaxUniformBufferBindings) { 2982bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "layout(binding = %u) for %d UBOs exceeds " 2983bf215546Sopenharmony_ci "the maximum number of UBO binding points (%d)", 2984bf215546Sopenharmony_ci qual_binding, elements, 2985bf215546Sopenharmony_ci consts->MaxUniformBufferBindings); 2986bf215546Sopenharmony_ci return; 2987bf215546Sopenharmony_ci } 2988bf215546Sopenharmony_ci 2989bf215546Sopenharmony_ci /* SSBOs. From page 67 of the GLSL 4.30 specification: 2990bf215546Sopenharmony_ci * "If the binding point for any uniform or shader storage block instance 2991bf215546Sopenharmony_ci * is less than zero, or greater than or equal to the 2992bf215546Sopenharmony_ci * implementation-dependent maximum number of uniform buffer bindings, a 2993bf215546Sopenharmony_ci * compile-time error will occur. When the binding identifier is used 2994bf215546Sopenharmony_ci * with a uniform or shader storage block instanced as an array of size 2995bf215546Sopenharmony_ci * N, all elements of the array from binding through binding + N – 1 must 2996bf215546Sopenharmony_ci * be within this range." 2997bf215546Sopenharmony_ci */ 2998bf215546Sopenharmony_ci if (qual->flags.q.buffer && 2999bf215546Sopenharmony_ci max_index >= consts->MaxShaderStorageBufferBindings) { 3000bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "layout(binding = %u) for %d SSBOs exceeds " 3001bf215546Sopenharmony_ci "the maximum number of SSBO binding points (%d)", 3002bf215546Sopenharmony_ci qual_binding, elements, 3003bf215546Sopenharmony_ci consts->MaxShaderStorageBufferBindings); 3004bf215546Sopenharmony_ci return; 3005bf215546Sopenharmony_ci } 3006bf215546Sopenharmony_ci } else if (base_type->is_sampler()) { 3007bf215546Sopenharmony_ci /* Samplers. From page 63 of the GLSL 4.20 specification: 3008bf215546Sopenharmony_ci * "If the binding is less than zero, or greater than or equal to the 3009bf215546Sopenharmony_ci * implementation-dependent maximum supported number of units, a 3010bf215546Sopenharmony_ci * compilation error will occur. When the binding identifier is used 3011bf215546Sopenharmony_ci * with an array of size N, all elements of the array from binding 3012bf215546Sopenharmony_ci * through binding + N - 1 must be within this range." 3013bf215546Sopenharmony_ci */ 3014bf215546Sopenharmony_ci unsigned limit = consts->MaxCombinedTextureImageUnits; 3015bf215546Sopenharmony_ci 3016bf215546Sopenharmony_ci if (max_index >= limit) { 3017bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "layout(binding = %d) for %d samplers " 3018bf215546Sopenharmony_ci "exceeds the maximum number of texture image units " 3019bf215546Sopenharmony_ci "(%u)", qual_binding, elements, limit); 3020bf215546Sopenharmony_ci 3021bf215546Sopenharmony_ci return; 3022bf215546Sopenharmony_ci } 3023bf215546Sopenharmony_ci } else if (base_type->contains_atomic()) { 3024bf215546Sopenharmony_ci assert(consts->MaxAtomicBufferBindings <= MAX_COMBINED_ATOMIC_BUFFERS); 3025bf215546Sopenharmony_ci if (qual_binding >= consts->MaxAtomicBufferBindings) { 3026bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "layout(binding = %d) exceeds the " 3027bf215546Sopenharmony_ci "maximum number of atomic counter buffer bindings " 3028bf215546Sopenharmony_ci "(%u)", qual_binding, 3029bf215546Sopenharmony_ci consts->MaxAtomicBufferBindings); 3030bf215546Sopenharmony_ci 3031bf215546Sopenharmony_ci return; 3032bf215546Sopenharmony_ci } 3033bf215546Sopenharmony_ci } else if ((state->is_version(420, 310) || 3034bf215546Sopenharmony_ci state->ARB_shading_language_420pack_enable) && 3035bf215546Sopenharmony_ci base_type->is_image()) { 3036bf215546Sopenharmony_ci assert(consts->MaxImageUnits <= MAX_IMAGE_UNITS); 3037bf215546Sopenharmony_ci if (max_index >= consts->MaxImageUnits) { 3038bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "Image binding %d exceeds the " 3039bf215546Sopenharmony_ci "maximum number of image units (%d)", max_index, 3040bf215546Sopenharmony_ci consts->MaxImageUnits); 3041bf215546Sopenharmony_ci return; 3042bf215546Sopenharmony_ci } 3043bf215546Sopenharmony_ci 3044bf215546Sopenharmony_ci } else { 3045bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3046bf215546Sopenharmony_ci "the \"binding\" qualifier only applies to uniform " 3047bf215546Sopenharmony_ci "blocks, storage blocks, opaque variables, or arrays " 3048bf215546Sopenharmony_ci "thereof"); 3049bf215546Sopenharmony_ci return; 3050bf215546Sopenharmony_ci } 3051bf215546Sopenharmony_ci 3052bf215546Sopenharmony_ci var->data.explicit_binding = true; 3053bf215546Sopenharmony_ci var->data.binding = qual_binding; 3054bf215546Sopenharmony_ci 3055bf215546Sopenharmony_ci return; 3056bf215546Sopenharmony_ci} 3057bf215546Sopenharmony_ci 3058bf215546Sopenharmony_cistatic void 3059bf215546Sopenharmony_civalidate_fragment_flat_interpolation_input(struct _mesa_glsl_parse_state *state, 3060bf215546Sopenharmony_ci YYLTYPE *loc, 3061bf215546Sopenharmony_ci const glsl_interp_mode interpolation, 3062bf215546Sopenharmony_ci const struct glsl_type *var_type, 3063bf215546Sopenharmony_ci ir_variable_mode mode) 3064bf215546Sopenharmony_ci{ 3065bf215546Sopenharmony_ci if (state->stage != MESA_SHADER_FRAGMENT || 3066bf215546Sopenharmony_ci interpolation == INTERP_MODE_FLAT || 3067bf215546Sopenharmony_ci mode != ir_var_shader_in) 3068bf215546Sopenharmony_ci return; 3069bf215546Sopenharmony_ci 3070bf215546Sopenharmony_ci /* Integer fragment inputs must be qualified with 'flat'. In GLSL ES, 3071bf215546Sopenharmony_ci * so must integer vertex outputs. 3072bf215546Sopenharmony_ci * 3073bf215546Sopenharmony_ci * From section 4.3.4 ("Inputs") of the GLSL 1.50 spec: 3074bf215546Sopenharmony_ci * "Fragment shader inputs that are signed or unsigned integers or 3075bf215546Sopenharmony_ci * integer vectors must be qualified with the interpolation qualifier 3076bf215546Sopenharmony_ci * flat." 3077bf215546Sopenharmony_ci * 3078bf215546Sopenharmony_ci * From section 4.3.4 ("Input Variables") of the GLSL 3.00 ES spec: 3079bf215546Sopenharmony_ci * "Fragment shader inputs that are, or contain, signed or unsigned 3080bf215546Sopenharmony_ci * integers or integer vectors must be qualified with the 3081bf215546Sopenharmony_ci * interpolation qualifier flat." 3082bf215546Sopenharmony_ci * 3083bf215546Sopenharmony_ci * From section 4.3.6 ("Output Variables") of the GLSL 3.00 ES spec: 3084bf215546Sopenharmony_ci * "Vertex shader outputs that are, or contain, signed or unsigned 3085bf215546Sopenharmony_ci * integers or integer vectors must be qualified with the 3086bf215546Sopenharmony_ci * interpolation qualifier flat." 3087bf215546Sopenharmony_ci * 3088bf215546Sopenharmony_ci * Note that prior to GLSL 1.50, this requirement applied to vertex 3089bf215546Sopenharmony_ci * outputs rather than fragment inputs. That creates problems in the 3090bf215546Sopenharmony_ci * presence of geometry shaders, so we adopt the GLSL 1.50 rule for all 3091bf215546Sopenharmony_ci * desktop GL shaders. For GLSL ES shaders, we follow the spec and 3092bf215546Sopenharmony_ci * apply the restriction to both vertex outputs and fragment inputs. 3093bf215546Sopenharmony_ci * 3094bf215546Sopenharmony_ci * Note also that the desktop GLSL specs are missing the text "or 3095bf215546Sopenharmony_ci * contain"; this is presumably an oversight, since there is no 3096bf215546Sopenharmony_ci * reasonable way to interpolate a fragment shader input that contains 3097bf215546Sopenharmony_ci * an integer. See Khronos bug #15671. 3098bf215546Sopenharmony_ci */ 3099bf215546Sopenharmony_ci if ((state->is_version(130, 300) || state->EXT_gpu_shader4_enable) 3100bf215546Sopenharmony_ci && var_type->contains_integer()) { 3101bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "if a fragment input is (or contains) " 3102bf215546Sopenharmony_ci "an integer, then it must be qualified with 'flat'"); 3103bf215546Sopenharmony_ci } 3104bf215546Sopenharmony_ci 3105bf215546Sopenharmony_ci /* Double fragment inputs must be qualified with 'flat'. 3106bf215546Sopenharmony_ci * 3107bf215546Sopenharmony_ci * From the "Overview" of the ARB_gpu_shader_fp64 extension spec: 3108bf215546Sopenharmony_ci * "This extension does not support interpolation of double-precision 3109bf215546Sopenharmony_ci * values; doubles used as fragment shader inputs must be qualified as 3110bf215546Sopenharmony_ci * "flat"." 3111bf215546Sopenharmony_ci * 3112bf215546Sopenharmony_ci * From section 4.3.4 ("Inputs") of the GLSL 4.00 spec: 3113bf215546Sopenharmony_ci * "Fragment shader inputs that are signed or unsigned integers, integer 3114bf215546Sopenharmony_ci * vectors, or any double-precision floating-point type must be 3115bf215546Sopenharmony_ci * qualified with the interpolation qualifier flat." 3116bf215546Sopenharmony_ci * 3117bf215546Sopenharmony_ci * Note that the GLSL specs are missing the text "or contain"; this is 3118bf215546Sopenharmony_ci * presumably an oversight. See Khronos bug #15671. 3119bf215546Sopenharmony_ci * 3120bf215546Sopenharmony_ci * The 'double' type does not exist in GLSL ES so far. 3121bf215546Sopenharmony_ci */ 3122bf215546Sopenharmony_ci if (state->has_double() 3123bf215546Sopenharmony_ci && var_type->contains_double()) { 3124bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "if a fragment input is (or contains) " 3125bf215546Sopenharmony_ci "a double, then it must be qualified with 'flat'"); 3126bf215546Sopenharmony_ci } 3127bf215546Sopenharmony_ci 3128bf215546Sopenharmony_ci /* Bindless sampler/image fragment inputs must be qualified with 'flat'. 3129bf215546Sopenharmony_ci * 3130bf215546Sopenharmony_ci * From section 4.3.4 of the ARB_bindless_texture spec: 3131bf215546Sopenharmony_ci * 3132bf215546Sopenharmony_ci * "(modify last paragraph, p. 35, allowing samplers and images as 3133bf215546Sopenharmony_ci * fragment shader inputs) ... Fragment inputs can only be signed and 3134bf215546Sopenharmony_ci * unsigned integers and integer vectors, floating point scalars, 3135bf215546Sopenharmony_ci * floating-point vectors, matrices, sampler and image types, or arrays 3136bf215546Sopenharmony_ci * or structures of these. Fragment shader inputs that are signed or 3137bf215546Sopenharmony_ci * unsigned integers, integer vectors, or any double-precision floating- 3138bf215546Sopenharmony_ci * point type, or any sampler or image type must be qualified with the 3139bf215546Sopenharmony_ci * interpolation qualifier "flat"." 3140bf215546Sopenharmony_ci */ 3141bf215546Sopenharmony_ci if (state->has_bindless() 3142bf215546Sopenharmony_ci && (var_type->contains_sampler() || var_type->contains_image())) { 3143bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "if a fragment input is (or contains) " 3144bf215546Sopenharmony_ci "a bindless sampler (or image), then it must be " 3145bf215546Sopenharmony_ci "qualified with 'flat'"); 3146bf215546Sopenharmony_ci } 3147bf215546Sopenharmony_ci} 3148bf215546Sopenharmony_ci 3149bf215546Sopenharmony_cistatic void 3150bf215546Sopenharmony_civalidate_interpolation_qualifier(struct _mesa_glsl_parse_state *state, 3151bf215546Sopenharmony_ci YYLTYPE *loc, 3152bf215546Sopenharmony_ci const glsl_interp_mode interpolation, 3153bf215546Sopenharmony_ci const struct ast_type_qualifier *qual, 3154bf215546Sopenharmony_ci const struct glsl_type *var_type, 3155bf215546Sopenharmony_ci ir_variable_mode mode) 3156bf215546Sopenharmony_ci{ 3157bf215546Sopenharmony_ci /* Interpolation qualifiers can only apply to shader inputs or outputs, but 3158bf215546Sopenharmony_ci * not to vertex shader inputs nor fragment shader outputs. 3159bf215546Sopenharmony_ci * 3160bf215546Sopenharmony_ci * From section 4.3 ("Storage Qualifiers") of the GLSL 1.30 spec: 3161bf215546Sopenharmony_ci * "Outputs from a vertex shader (out) and inputs to a fragment 3162bf215546Sopenharmony_ci * shader (in) can be further qualified with one or more of these 3163bf215546Sopenharmony_ci * interpolation qualifiers" 3164bf215546Sopenharmony_ci * ... 3165bf215546Sopenharmony_ci * "These interpolation qualifiers may only precede the qualifiers in, 3166bf215546Sopenharmony_ci * centroid in, out, or centroid out in a declaration. They do not apply 3167bf215546Sopenharmony_ci * to the deprecated storage qualifiers varying or centroid 3168bf215546Sopenharmony_ci * varying. They also do not apply to inputs into a vertex shader or 3169bf215546Sopenharmony_ci * outputs from a fragment shader." 3170bf215546Sopenharmony_ci * 3171bf215546Sopenharmony_ci * From section 4.3 ("Storage Qualifiers") of the GLSL ES 3.00 spec: 3172bf215546Sopenharmony_ci * "Outputs from a shader (out) and inputs to a shader (in) can be 3173bf215546Sopenharmony_ci * further qualified with one of these interpolation qualifiers." 3174bf215546Sopenharmony_ci * ... 3175bf215546Sopenharmony_ci * "These interpolation qualifiers may only precede the qualifiers 3176bf215546Sopenharmony_ci * in, centroid in, out, or centroid out in a declaration. They do 3177bf215546Sopenharmony_ci * not apply to inputs into a vertex shader or outputs from a 3178bf215546Sopenharmony_ci * fragment shader." 3179bf215546Sopenharmony_ci */ 3180bf215546Sopenharmony_ci if ((state->is_version(130, 300) || state->EXT_gpu_shader4_enable) 3181bf215546Sopenharmony_ci && interpolation != INTERP_MODE_NONE) { 3182bf215546Sopenharmony_ci const char *i = interpolation_string(interpolation); 3183bf215546Sopenharmony_ci if (mode != ir_var_shader_in && mode != ir_var_shader_out) 3184bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3185bf215546Sopenharmony_ci "interpolation qualifier `%s' can only be applied to " 3186bf215546Sopenharmony_ci "shader inputs or outputs.", i); 3187bf215546Sopenharmony_ci 3188bf215546Sopenharmony_ci switch (state->stage) { 3189bf215546Sopenharmony_ci case MESA_SHADER_VERTEX: 3190bf215546Sopenharmony_ci if (mode == ir_var_shader_in) { 3191bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3192bf215546Sopenharmony_ci "interpolation qualifier '%s' cannot be applied to " 3193bf215546Sopenharmony_ci "vertex shader inputs", i); 3194bf215546Sopenharmony_ci } 3195bf215546Sopenharmony_ci break; 3196bf215546Sopenharmony_ci case MESA_SHADER_FRAGMENT: 3197bf215546Sopenharmony_ci if (mode == ir_var_shader_out) { 3198bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3199bf215546Sopenharmony_ci "interpolation qualifier '%s' cannot be applied to " 3200bf215546Sopenharmony_ci "fragment shader outputs", i); 3201bf215546Sopenharmony_ci } 3202bf215546Sopenharmony_ci break; 3203bf215546Sopenharmony_ci default: 3204bf215546Sopenharmony_ci break; 3205bf215546Sopenharmony_ci } 3206bf215546Sopenharmony_ci } 3207bf215546Sopenharmony_ci 3208bf215546Sopenharmony_ci /* Interpolation qualifiers cannot be applied to 'centroid' and 3209bf215546Sopenharmony_ci * 'centroid varying'. 3210bf215546Sopenharmony_ci * 3211bf215546Sopenharmony_ci * From section 4.3 ("Storage Qualifiers") of the GLSL 1.30 spec: 3212bf215546Sopenharmony_ci * "interpolation qualifiers may only precede the qualifiers in, 3213bf215546Sopenharmony_ci * centroid in, out, or centroid out in a declaration. They do not apply 3214bf215546Sopenharmony_ci * to the deprecated storage qualifiers varying or centroid varying." 3215bf215546Sopenharmony_ci * 3216bf215546Sopenharmony_ci * These deprecated storage qualifiers do not exist in GLSL ES 3.00. 3217bf215546Sopenharmony_ci * 3218bf215546Sopenharmony_ci * GL_EXT_gpu_shader4 allows this. 3219bf215546Sopenharmony_ci */ 3220bf215546Sopenharmony_ci if (state->is_version(130, 0) && !state->EXT_gpu_shader4_enable 3221bf215546Sopenharmony_ci && interpolation != INTERP_MODE_NONE 3222bf215546Sopenharmony_ci && qual->flags.q.varying) { 3223bf215546Sopenharmony_ci 3224bf215546Sopenharmony_ci const char *i = interpolation_string(interpolation); 3225bf215546Sopenharmony_ci const char *s; 3226bf215546Sopenharmony_ci if (qual->flags.q.centroid) 3227bf215546Sopenharmony_ci s = "centroid varying"; 3228bf215546Sopenharmony_ci else 3229bf215546Sopenharmony_ci s = "varying"; 3230bf215546Sopenharmony_ci 3231bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3232bf215546Sopenharmony_ci "qualifier '%s' cannot be applied to the " 3233bf215546Sopenharmony_ci "deprecated storage qualifier '%s'", i, s); 3234bf215546Sopenharmony_ci } 3235bf215546Sopenharmony_ci 3236bf215546Sopenharmony_ci validate_fragment_flat_interpolation_input(state, loc, interpolation, 3237bf215546Sopenharmony_ci var_type, mode); 3238bf215546Sopenharmony_ci} 3239bf215546Sopenharmony_ci 3240bf215546Sopenharmony_cistatic glsl_interp_mode 3241bf215546Sopenharmony_ciinterpret_interpolation_qualifier(const struct ast_type_qualifier *qual, 3242bf215546Sopenharmony_ci const struct glsl_type *var_type, 3243bf215546Sopenharmony_ci ir_variable_mode mode, 3244bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, 3245bf215546Sopenharmony_ci YYLTYPE *loc) 3246bf215546Sopenharmony_ci{ 3247bf215546Sopenharmony_ci glsl_interp_mode interpolation; 3248bf215546Sopenharmony_ci if (qual->flags.q.flat) 3249bf215546Sopenharmony_ci interpolation = INTERP_MODE_FLAT; 3250bf215546Sopenharmony_ci else if (qual->flags.q.noperspective) 3251bf215546Sopenharmony_ci interpolation = INTERP_MODE_NOPERSPECTIVE; 3252bf215546Sopenharmony_ci else if (qual->flags.q.smooth) 3253bf215546Sopenharmony_ci interpolation = INTERP_MODE_SMOOTH; 3254bf215546Sopenharmony_ci else 3255bf215546Sopenharmony_ci interpolation = INTERP_MODE_NONE; 3256bf215546Sopenharmony_ci 3257bf215546Sopenharmony_ci validate_interpolation_qualifier(state, loc, 3258bf215546Sopenharmony_ci interpolation, 3259bf215546Sopenharmony_ci qual, var_type, mode); 3260bf215546Sopenharmony_ci 3261bf215546Sopenharmony_ci return interpolation; 3262bf215546Sopenharmony_ci} 3263bf215546Sopenharmony_ci 3264bf215546Sopenharmony_ci 3265bf215546Sopenharmony_cistatic void 3266bf215546Sopenharmony_ciapply_explicit_location(const struct ast_type_qualifier *qual, 3267bf215546Sopenharmony_ci ir_variable *var, 3268bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, 3269bf215546Sopenharmony_ci YYLTYPE *loc) 3270bf215546Sopenharmony_ci{ 3271bf215546Sopenharmony_ci bool fail = false; 3272bf215546Sopenharmony_ci 3273bf215546Sopenharmony_ci unsigned qual_location; 3274bf215546Sopenharmony_ci if (!process_qualifier_constant(state, loc, "location", qual->location, 3275bf215546Sopenharmony_ci &qual_location)) { 3276bf215546Sopenharmony_ci return; 3277bf215546Sopenharmony_ci } 3278bf215546Sopenharmony_ci 3279bf215546Sopenharmony_ci /* Checks for GL_ARB_explicit_uniform_location. */ 3280bf215546Sopenharmony_ci if (qual->flags.q.uniform) { 3281bf215546Sopenharmony_ci if (!state->check_explicit_uniform_location_allowed(loc, var)) 3282bf215546Sopenharmony_ci return; 3283bf215546Sopenharmony_ci 3284bf215546Sopenharmony_ci const struct gl_constants *consts = state->consts; 3285bf215546Sopenharmony_ci unsigned max_loc = qual_location + var->type->uniform_locations() - 1; 3286bf215546Sopenharmony_ci 3287bf215546Sopenharmony_ci if (max_loc >= consts->MaxUserAssignableUniformLocations) { 3288bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "location(s) consumed by uniform %s " 3289bf215546Sopenharmony_ci ">= MAX_UNIFORM_LOCATIONS (%u)", var->name, 3290bf215546Sopenharmony_ci consts->MaxUserAssignableUniformLocations); 3291bf215546Sopenharmony_ci return; 3292bf215546Sopenharmony_ci } 3293bf215546Sopenharmony_ci 3294bf215546Sopenharmony_ci var->data.explicit_location = true; 3295bf215546Sopenharmony_ci var->data.location = qual_location; 3296bf215546Sopenharmony_ci return; 3297bf215546Sopenharmony_ci } 3298bf215546Sopenharmony_ci 3299bf215546Sopenharmony_ci /* Between GL_ARB_explicit_attrib_location an 3300bf215546Sopenharmony_ci * GL_ARB_separate_shader_objects, the inputs and outputs of any shader 3301bf215546Sopenharmony_ci * stage can be assigned explicit locations. The checking here associates 3302bf215546Sopenharmony_ci * the correct extension with the correct stage's input / output: 3303bf215546Sopenharmony_ci * 3304bf215546Sopenharmony_ci * input output 3305bf215546Sopenharmony_ci * ----- ------ 3306bf215546Sopenharmony_ci * vertex explicit_loc sso 3307bf215546Sopenharmony_ci * tess control sso sso 3308bf215546Sopenharmony_ci * tess eval sso sso 3309bf215546Sopenharmony_ci * geometry sso sso 3310bf215546Sopenharmony_ci * fragment sso explicit_loc 3311bf215546Sopenharmony_ci */ 3312bf215546Sopenharmony_ci switch (state->stage) { 3313bf215546Sopenharmony_ci case MESA_SHADER_VERTEX: 3314bf215546Sopenharmony_ci if (var->data.mode == ir_var_shader_in) { 3315bf215546Sopenharmony_ci if (!state->check_explicit_attrib_location_allowed(loc, var)) 3316bf215546Sopenharmony_ci return; 3317bf215546Sopenharmony_ci 3318bf215546Sopenharmony_ci break; 3319bf215546Sopenharmony_ci } 3320bf215546Sopenharmony_ci 3321bf215546Sopenharmony_ci if (var->data.mode == ir_var_shader_out) { 3322bf215546Sopenharmony_ci if (!state->check_separate_shader_objects_allowed(loc, var)) 3323bf215546Sopenharmony_ci return; 3324bf215546Sopenharmony_ci 3325bf215546Sopenharmony_ci break; 3326bf215546Sopenharmony_ci } 3327bf215546Sopenharmony_ci 3328bf215546Sopenharmony_ci fail = true; 3329bf215546Sopenharmony_ci break; 3330bf215546Sopenharmony_ci 3331bf215546Sopenharmony_ci case MESA_SHADER_TESS_CTRL: 3332bf215546Sopenharmony_ci case MESA_SHADER_TESS_EVAL: 3333bf215546Sopenharmony_ci case MESA_SHADER_GEOMETRY: 3334bf215546Sopenharmony_ci if (var->data.mode == ir_var_shader_in || var->data.mode == ir_var_shader_out) { 3335bf215546Sopenharmony_ci if (!state->check_separate_shader_objects_allowed(loc, var)) 3336bf215546Sopenharmony_ci return; 3337bf215546Sopenharmony_ci 3338bf215546Sopenharmony_ci break; 3339bf215546Sopenharmony_ci } 3340bf215546Sopenharmony_ci 3341bf215546Sopenharmony_ci fail = true; 3342bf215546Sopenharmony_ci break; 3343bf215546Sopenharmony_ci 3344bf215546Sopenharmony_ci case MESA_SHADER_FRAGMENT: 3345bf215546Sopenharmony_ci if (var->data.mode == ir_var_shader_in) { 3346bf215546Sopenharmony_ci if (!state->check_separate_shader_objects_allowed(loc, var)) 3347bf215546Sopenharmony_ci return; 3348bf215546Sopenharmony_ci 3349bf215546Sopenharmony_ci break; 3350bf215546Sopenharmony_ci } 3351bf215546Sopenharmony_ci 3352bf215546Sopenharmony_ci if (var->data.mode == ir_var_shader_out) { 3353bf215546Sopenharmony_ci if (!state->check_explicit_attrib_location_allowed(loc, var)) 3354bf215546Sopenharmony_ci return; 3355bf215546Sopenharmony_ci 3356bf215546Sopenharmony_ci break; 3357bf215546Sopenharmony_ci } 3358bf215546Sopenharmony_ci 3359bf215546Sopenharmony_ci fail = true; 3360bf215546Sopenharmony_ci break; 3361bf215546Sopenharmony_ci 3362bf215546Sopenharmony_ci case MESA_SHADER_COMPUTE: 3363bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3364bf215546Sopenharmony_ci "compute shader variables cannot be given " 3365bf215546Sopenharmony_ci "explicit locations"); 3366bf215546Sopenharmony_ci return; 3367bf215546Sopenharmony_ci default: 3368bf215546Sopenharmony_ci fail = true; 3369bf215546Sopenharmony_ci break; 3370bf215546Sopenharmony_ci }; 3371bf215546Sopenharmony_ci 3372bf215546Sopenharmony_ci if (fail) { 3373bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3374bf215546Sopenharmony_ci "%s cannot be given an explicit location in %s shader", 3375bf215546Sopenharmony_ci mode_string(var), 3376bf215546Sopenharmony_ci _mesa_shader_stage_to_string(state->stage)); 3377bf215546Sopenharmony_ci } else { 3378bf215546Sopenharmony_ci var->data.explicit_location = true; 3379bf215546Sopenharmony_ci 3380bf215546Sopenharmony_ci switch (state->stage) { 3381bf215546Sopenharmony_ci case MESA_SHADER_VERTEX: 3382bf215546Sopenharmony_ci var->data.location = (var->data.mode == ir_var_shader_in) 3383bf215546Sopenharmony_ci ? (qual_location + VERT_ATTRIB_GENERIC0) 3384bf215546Sopenharmony_ci : (qual_location + VARYING_SLOT_VAR0); 3385bf215546Sopenharmony_ci break; 3386bf215546Sopenharmony_ci 3387bf215546Sopenharmony_ci case MESA_SHADER_TESS_CTRL: 3388bf215546Sopenharmony_ci case MESA_SHADER_TESS_EVAL: 3389bf215546Sopenharmony_ci case MESA_SHADER_GEOMETRY: 3390bf215546Sopenharmony_ci if (var->data.patch) 3391bf215546Sopenharmony_ci var->data.location = qual_location + VARYING_SLOT_PATCH0; 3392bf215546Sopenharmony_ci else 3393bf215546Sopenharmony_ci var->data.location = qual_location + VARYING_SLOT_VAR0; 3394bf215546Sopenharmony_ci break; 3395bf215546Sopenharmony_ci 3396bf215546Sopenharmony_ci case MESA_SHADER_FRAGMENT: 3397bf215546Sopenharmony_ci var->data.location = (var->data.mode == ir_var_shader_out) 3398bf215546Sopenharmony_ci ? (qual_location + FRAG_RESULT_DATA0) 3399bf215546Sopenharmony_ci : (qual_location + VARYING_SLOT_VAR0); 3400bf215546Sopenharmony_ci break; 3401bf215546Sopenharmony_ci default: 3402bf215546Sopenharmony_ci assert(!"Unexpected shader type"); 3403bf215546Sopenharmony_ci break; 3404bf215546Sopenharmony_ci } 3405bf215546Sopenharmony_ci 3406bf215546Sopenharmony_ci /* Check if index was set for the uniform instead of the function */ 3407bf215546Sopenharmony_ci if (qual->flags.q.explicit_index && qual->is_subroutine_decl()) { 3408bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "an index qualifier can only be " 3409bf215546Sopenharmony_ci "used with subroutine functions"); 3410bf215546Sopenharmony_ci return; 3411bf215546Sopenharmony_ci } 3412bf215546Sopenharmony_ci 3413bf215546Sopenharmony_ci unsigned qual_index; 3414bf215546Sopenharmony_ci if (qual->flags.q.explicit_index && 3415bf215546Sopenharmony_ci process_qualifier_constant(state, loc, "index", qual->index, 3416bf215546Sopenharmony_ci &qual_index)) { 3417bf215546Sopenharmony_ci /* From the GLSL 4.30 specification, section 4.4.2 (Output 3418bf215546Sopenharmony_ci * Layout Qualifiers): 3419bf215546Sopenharmony_ci * 3420bf215546Sopenharmony_ci * "It is also a compile-time error if a fragment shader 3421bf215546Sopenharmony_ci * sets a layout index to less than 0 or greater than 1." 3422bf215546Sopenharmony_ci * 3423bf215546Sopenharmony_ci * Older specifications don't mandate a behavior; we take 3424bf215546Sopenharmony_ci * this as a clarification and always generate the error. 3425bf215546Sopenharmony_ci */ 3426bf215546Sopenharmony_ci if (qual_index > 1) { 3427bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3428bf215546Sopenharmony_ci "explicit index may only be 0 or 1"); 3429bf215546Sopenharmony_ci } else { 3430bf215546Sopenharmony_ci var->data.explicit_index = true; 3431bf215546Sopenharmony_ci var->data.index = qual_index; 3432bf215546Sopenharmony_ci } 3433bf215546Sopenharmony_ci } 3434bf215546Sopenharmony_ci } 3435bf215546Sopenharmony_ci} 3436bf215546Sopenharmony_ci 3437bf215546Sopenharmony_cistatic bool 3438bf215546Sopenharmony_civalidate_storage_for_sampler_image_types(ir_variable *var, 3439bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, 3440bf215546Sopenharmony_ci YYLTYPE *loc) 3441bf215546Sopenharmony_ci{ 3442bf215546Sopenharmony_ci /* From section 4.1.7 of the GLSL 4.40 spec: 3443bf215546Sopenharmony_ci * 3444bf215546Sopenharmony_ci * "[Opaque types] can only be declared as function 3445bf215546Sopenharmony_ci * parameters or uniform-qualified variables." 3446bf215546Sopenharmony_ci * 3447bf215546Sopenharmony_ci * From section 4.1.7 of the ARB_bindless_texture spec: 3448bf215546Sopenharmony_ci * 3449bf215546Sopenharmony_ci * "Samplers may be declared as shader inputs and outputs, as uniform 3450bf215546Sopenharmony_ci * variables, as temporary variables, and as function parameters." 3451bf215546Sopenharmony_ci * 3452bf215546Sopenharmony_ci * From section 4.1.X of the ARB_bindless_texture spec: 3453bf215546Sopenharmony_ci * 3454bf215546Sopenharmony_ci * "Images may be declared as shader inputs and outputs, as uniform 3455bf215546Sopenharmony_ci * variables, as temporary variables, and as function parameters." 3456bf215546Sopenharmony_ci */ 3457bf215546Sopenharmony_ci if (state->has_bindless()) { 3458bf215546Sopenharmony_ci if (var->data.mode != ir_var_auto && 3459bf215546Sopenharmony_ci var->data.mode != ir_var_uniform && 3460bf215546Sopenharmony_ci var->data.mode != ir_var_shader_in && 3461bf215546Sopenharmony_ci var->data.mode != ir_var_shader_out && 3462bf215546Sopenharmony_ci var->data.mode != ir_var_function_in && 3463bf215546Sopenharmony_ci var->data.mode != ir_var_function_out && 3464bf215546Sopenharmony_ci var->data.mode != ir_var_function_inout) { 3465bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "bindless image/sampler variables may " 3466bf215546Sopenharmony_ci "only be declared as shader inputs and outputs, as " 3467bf215546Sopenharmony_ci "uniform variables, as temporary variables and as " 3468bf215546Sopenharmony_ci "function parameters"); 3469bf215546Sopenharmony_ci return false; 3470bf215546Sopenharmony_ci } 3471bf215546Sopenharmony_ci } else { 3472bf215546Sopenharmony_ci if (var->data.mode != ir_var_uniform && 3473bf215546Sopenharmony_ci var->data.mode != ir_var_function_in) { 3474bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "image/sampler variables may only be " 3475bf215546Sopenharmony_ci "declared as function parameters or " 3476bf215546Sopenharmony_ci "uniform-qualified global variables"); 3477bf215546Sopenharmony_ci return false; 3478bf215546Sopenharmony_ci } 3479bf215546Sopenharmony_ci } 3480bf215546Sopenharmony_ci return true; 3481bf215546Sopenharmony_ci} 3482bf215546Sopenharmony_ci 3483bf215546Sopenharmony_cistatic bool 3484bf215546Sopenharmony_civalidate_memory_qualifier_for_type(struct _mesa_glsl_parse_state *state, 3485bf215546Sopenharmony_ci YYLTYPE *loc, 3486bf215546Sopenharmony_ci const struct ast_type_qualifier *qual, 3487bf215546Sopenharmony_ci const glsl_type *type) 3488bf215546Sopenharmony_ci{ 3489bf215546Sopenharmony_ci /* From Section 4.10 (Memory Qualifiers) of the GLSL 4.50 spec: 3490bf215546Sopenharmony_ci * 3491bf215546Sopenharmony_ci * "Memory qualifiers are only supported in the declarations of image 3492bf215546Sopenharmony_ci * variables, buffer variables, and shader storage blocks; it is an error 3493bf215546Sopenharmony_ci * to use such qualifiers in any other declarations. 3494bf215546Sopenharmony_ci */ 3495bf215546Sopenharmony_ci if (!type->is_image() && !qual->flags.q.buffer) { 3496bf215546Sopenharmony_ci if (qual->flags.q.read_only || 3497bf215546Sopenharmony_ci qual->flags.q.write_only || 3498bf215546Sopenharmony_ci qual->flags.q.coherent || 3499bf215546Sopenharmony_ci qual->flags.q._volatile || 3500bf215546Sopenharmony_ci qual->flags.q.restrict_flag) { 3501bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "memory qualifiers may only be applied " 3502bf215546Sopenharmony_ci "in the declarations of image variables, buffer " 3503bf215546Sopenharmony_ci "variables, and shader storage blocks"); 3504bf215546Sopenharmony_ci return false; 3505bf215546Sopenharmony_ci } 3506bf215546Sopenharmony_ci } 3507bf215546Sopenharmony_ci return true; 3508bf215546Sopenharmony_ci} 3509bf215546Sopenharmony_ci 3510bf215546Sopenharmony_cistatic bool 3511bf215546Sopenharmony_civalidate_image_format_qualifier_for_type(struct _mesa_glsl_parse_state *state, 3512bf215546Sopenharmony_ci YYLTYPE *loc, 3513bf215546Sopenharmony_ci const struct ast_type_qualifier *qual, 3514bf215546Sopenharmony_ci const glsl_type *type) 3515bf215546Sopenharmony_ci{ 3516bf215546Sopenharmony_ci /* From section 4.4.6.2 (Format Layout Qualifiers) of the GLSL 4.50 spec: 3517bf215546Sopenharmony_ci * 3518bf215546Sopenharmony_ci * "Format layout qualifiers can be used on image variable declarations 3519bf215546Sopenharmony_ci * (those declared with a basic type having “image ” in its keyword)." 3520bf215546Sopenharmony_ci */ 3521bf215546Sopenharmony_ci if (!type->is_image() && qual->flags.q.explicit_image_format) { 3522bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "format layout qualifiers may only be " 3523bf215546Sopenharmony_ci "applied to images"); 3524bf215546Sopenharmony_ci return false; 3525bf215546Sopenharmony_ci } 3526bf215546Sopenharmony_ci return true; 3527bf215546Sopenharmony_ci} 3528bf215546Sopenharmony_ci 3529bf215546Sopenharmony_cistatic void 3530bf215546Sopenharmony_ciapply_image_qualifier_to_variable(const struct ast_type_qualifier *qual, 3531bf215546Sopenharmony_ci ir_variable *var, 3532bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, 3533bf215546Sopenharmony_ci YYLTYPE *loc) 3534bf215546Sopenharmony_ci{ 3535bf215546Sopenharmony_ci const glsl_type *base_type = var->type->without_array(); 3536bf215546Sopenharmony_ci 3537bf215546Sopenharmony_ci if (!validate_image_format_qualifier_for_type(state, loc, qual, base_type) || 3538bf215546Sopenharmony_ci !validate_memory_qualifier_for_type(state, loc, qual, base_type)) 3539bf215546Sopenharmony_ci return; 3540bf215546Sopenharmony_ci 3541bf215546Sopenharmony_ci if (!base_type->is_image()) 3542bf215546Sopenharmony_ci return; 3543bf215546Sopenharmony_ci 3544bf215546Sopenharmony_ci if (!validate_storage_for_sampler_image_types(var, state, loc)) 3545bf215546Sopenharmony_ci return; 3546bf215546Sopenharmony_ci 3547bf215546Sopenharmony_ci var->data.memory_read_only |= qual->flags.q.read_only; 3548bf215546Sopenharmony_ci var->data.memory_write_only |= qual->flags.q.write_only; 3549bf215546Sopenharmony_ci var->data.memory_coherent |= qual->flags.q.coherent; 3550bf215546Sopenharmony_ci var->data.memory_volatile |= qual->flags.q._volatile; 3551bf215546Sopenharmony_ci var->data.memory_restrict |= qual->flags.q.restrict_flag; 3552bf215546Sopenharmony_ci 3553bf215546Sopenharmony_ci if (qual->flags.q.explicit_image_format) { 3554bf215546Sopenharmony_ci if (var->data.mode == ir_var_function_in) { 3555bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "format qualifiers cannot be used on " 3556bf215546Sopenharmony_ci "image function parameters"); 3557bf215546Sopenharmony_ci } 3558bf215546Sopenharmony_ci 3559bf215546Sopenharmony_ci if (qual->image_base_type != base_type->sampled_type) { 3560bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "format qualifier doesn't match the base " 3561bf215546Sopenharmony_ci "data type of the image"); 3562bf215546Sopenharmony_ci } 3563bf215546Sopenharmony_ci 3564bf215546Sopenharmony_ci var->data.image_format = qual->image_format; 3565bf215546Sopenharmony_ci } else if (state->has_image_load_formatted()) { 3566bf215546Sopenharmony_ci if (var->data.mode == ir_var_uniform && 3567bf215546Sopenharmony_ci state->EXT_shader_image_load_formatted_warn) { 3568bf215546Sopenharmony_ci _mesa_glsl_warning(loc, state, "GL_EXT_image_load_formatted used"); 3569bf215546Sopenharmony_ci } 3570bf215546Sopenharmony_ci } else { 3571bf215546Sopenharmony_ci if (var->data.mode == ir_var_uniform) { 3572bf215546Sopenharmony_ci if (state->es_shader || 3573bf215546Sopenharmony_ci !(state->is_version(420, 310) || state->ARB_shader_image_load_store_enable)) { 3574bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "all image uniforms must have a " 3575bf215546Sopenharmony_ci "format layout qualifier"); 3576bf215546Sopenharmony_ci } else if (!qual->flags.q.write_only) { 3577bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "image uniforms not qualified with " 3578bf215546Sopenharmony_ci "`writeonly' must have a format layout qualifier"); 3579bf215546Sopenharmony_ci } 3580bf215546Sopenharmony_ci } 3581bf215546Sopenharmony_ci var->data.image_format = PIPE_FORMAT_NONE; 3582bf215546Sopenharmony_ci } 3583bf215546Sopenharmony_ci 3584bf215546Sopenharmony_ci /* From page 70 of the GLSL ES 3.1 specification: 3585bf215546Sopenharmony_ci * 3586bf215546Sopenharmony_ci * "Except for image variables qualified with the format qualifiers r32f, 3587bf215546Sopenharmony_ci * r32i, and r32ui, image variables must specify either memory qualifier 3588bf215546Sopenharmony_ci * readonly or the memory qualifier writeonly." 3589bf215546Sopenharmony_ci */ 3590bf215546Sopenharmony_ci if (state->es_shader && 3591bf215546Sopenharmony_ci var->data.image_format != PIPE_FORMAT_R32_FLOAT && 3592bf215546Sopenharmony_ci var->data.image_format != PIPE_FORMAT_R32_SINT && 3593bf215546Sopenharmony_ci var->data.image_format != PIPE_FORMAT_R32_UINT && 3594bf215546Sopenharmony_ci !var->data.memory_read_only && 3595bf215546Sopenharmony_ci !var->data.memory_write_only) { 3596bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "image variables of format other than r32f, " 3597bf215546Sopenharmony_ci "r32i or r32ui must be qualified `readonly' or " 3598bf215546Sopenharmony_ci "`writeonly'"); 3599bf215546Sopenharmony_ci } 3600bf215546Sopenharmony_ci} 3601bf215546Sopenharmony_ci 3602bf215546Sopenharmony_cistatic inline const char* 3603bf215546Sopenharmony_ciget_layout_qualifier_string(bool origin_upper_left, bool pixel_center_integer) 3604bf215546Sopenharmony_ci{ 3605bf215546Sopenharmony_ci if (origin_upper_left && pixel_center_integer) 3606bf215546Sopenharmony_ci return "origin_upper_left, pixel_center_integer"; 3607bf215546Sopenharmony_ci else if (origin_upper_left) 3608bf215546Sopenharmony_ci return "origin_upper_left"; 3609bf215546Sopenharmony_ci else if (pixel_center_integer) 3610bf215546Sopenharmony_ci return "pixel_center_integer"; 3611bf215546Sopenharmony_ci else 3612bf215546Sopenharmony_ci return " "; 3613bf215546Sopenharmony_ci} 3614bf215546Sopenharmony_ci 3615bf215546Sopenharmony_cistatic inline bool 3616bf215546Sopenharmony_ciis_conflicting_fragcoord_redeclaration(struct _mesa_glsl_parse_state *state, 3617bf215546Sopenharmony_ci const struct ast_type_qualifier *qual) 3618bf215546Sopenharmony_ci{ 3619bf215546Sopenharmony_ci /* If gl_FragCoord was previously declared, and the qualifiers were 3620bf215546Sopenharmony_ci * different in any way, return true. 3621bf215546Sopenharmony_ci */ 3622bf215546Sopenharmony_ci if (state->fs_redeclares_gl_fragcoord) { 3623bf215546Sopenharmony_ci return (state->fs_pixel_center_integer != qual->flags.q.pixel_center_integer 3624bf215546Sopenharmony_ci || state->fs_origin_upper_left != qual->flags.q.origin_upper_left); 3625bf215546Sopenharmony_ci } 3626bf215546Sopenharmony_ci 3627bf215546Sopenharmony_ci return false; 3628bf215546Sopenharmony_ci} 3629bf215546Sopenharmony_ci 3630bf215546Sopenharmony_cistatic inline bool 3631bf215546Sopenharmony_ciis_conflicting_layer_redeclaration(struct _mesa_glsl_parse_state *state, 3632bf215546Sopenharmony_ci const struct ast_type_qualifier *qual) 3633bf215546Sopenharmony_ci{ 3634bf215546Sopenharmony_ci if (state->redeclares_gl_layer) { 3635bf215546Sopenharmony_ci return state->layer_viewport_relative != qual->flags.q.viewport_relative; 3636bf215546Sopenharmony_ci } 3637bf215546Sopenharmony_ci return false; 3638bf215546Sopenharmony_ci} 3639bf215546Sopenharmony_ci 3640bf215546Sopenharmony_cistatic inline void 3641bf215546Sopenharmony_civalidate_array_dimensions(const glsl_type *t, 3642bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, 3643bf215546Sopenharmony_ci YYLTYPE *loc) { 3644bf215546Sopenharmony_ci if (t->is_array()) { 3645bf215546Sopenharmony_ci t = t->fields.array; 3646bf215546Sopenharmony_ci while (t->is_array()) { 3647bf215546Sopenharmony_ci if (t->is_unsized_array()) { 3648bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3649bf215546Sopenharmony_ci "only the outermost array dimension can " 3650bf215546Sopenharmony_ci "be unsized", 3651bf215546Sopenharmony_ci t->name); 3652bf215546Sopenharmony_ci break; 3653bf215546Sopenharmony_ci } 3654bf215546Sopenharmony_ci t = t->fields.array; 3655bf215546Sopenharmony_ci } 3656bf215546Sopenharmony_ci } 3657bf215546Sopenharmony_ci} 3658bf215546Sopenharmony_ci 3659bf215546Sopenharmony_cistatic void 3660bf215546Sopenharmony_ciapply_bindless_qualifier_to_variable(const struct ast_type_qualifier *qual, 3661bf215546Sopenharmony_ci ir_variable *var, 3662bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, 3663bf215546Sopenharmony_ci YYLTYPE *loc) 3664bf215546Sopenharmony_ci{ 3665bf215546Sopenharmony_ci bool has_local_qualifiers = qual->flags.q.bindless_sampler || 3666bf215546Sopenharmony_ci qual->flags.q.bindless_image || 3667bf215546Sopenharmony_ci qual->flags.q.bound_sampler || 3668bf215546Sopenharmony_ci qual->flags.q.bound_image; 3669bf215546Sopenharmony_ci 3670bf215546Sopenharmony_ci /* The ARB_bindless_texture spec says: 3671bf215546Sopenharmony_ci * 3672bf215546Sopenharmony_ci * "Modify Section 4.4.6 Opaque-Uniform Layout Qualifiers of the GLSL 4.30 3673bf215546Sopenharmony_ci * spec" 3674bf215546Sopenharmony_ci * 3675bf215546Sopenharmony_ci * "If these layout qualifiers are applied to other types of default block 3676bf215546Sopenharmony_ci * uniforms, or variables with non-uniform storage, a compile-time error 3677bf215546Sopenharmony_ci * will be generated." 3678bf215546Sopenharmony_ci */ 3679bf215546Sopenharmony_ci if (has_local_qualifiers && !qual->flags.q.uniform) { 3680bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "ARB_bindless_texture layout qualifiers " 3681bf215546Sopenharmony_ci "can only be applied to default block uniforms or " 3682bf215546Sopenharmony_ci "variables with uniform storage"); 3683bf215546Sopenharmony_ci return; 3684bf215546Sopenharmony_ci } 3685bf215546Sopenharmony_ci 3686bf215546Sopenharmony_ci /* The ARB_bindless_texture spec doesn't state anything in this situation, 3687bf215546Sopenharmony_ci * but it makes sense to only allow bindless_sampler/bound_sampler for 3688bf215546Sopenharmony_ci * sampler types, and respectively bindless_image/bound_image for image 3689bf215546Sopenharmony_ci * types. 3690bf215546Sopenharmony_ci */ 3691bf215546Sopenharmony_ci if ((qual->flags.q.bindless_sampler || qual->flags.q.bound_sampler) && 3692bf215546Sopenharmony_ci !var->type->contains_sampler()) { 3693bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "bindless_sampler or bound_sampler can only " 3694bf215546Sopenharmony_ci "be applied to sampler types"); 3695bf215546Sopenharmony_ci return; 3696bf215546Sopenharmony_ci } 3697bf215546Sopenharmony_ci 3698bf215546Sopenharmony_ci if ((qual->flags.q.bindless_image || qual->flags.q.bound_image) && 3699bf215546Sopenharmony_ci !var->type->contains_image()) { 3700bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "bindless_image or bound_image can only be " 3701bf215546Sopenharmony_ci "applied to image types"); 3702bf215546Sopenharmony_ci return; 3703bf215546Sopenharmony_ci } 3704bf215546Sopenharmony_ci 3705bf215546Sopenharmony_ci /* The bindless_sampler/bindless_image (and respectively 3706bf215546Sopenharmony_ci * bound_sampler/bound_image) layout qualifiers can be set at global and at 3707bf215546Sopenharmony_ci * local scope. 3708bf215546Sopenharmony_ci */ 3709bf215546Sopenharmony_ci if (var->type->contains_sampler() || var->type->contains_image()) { 3710bf215546Sopenharmony_ci var->data.bindless = qual->flags.q.bindless_sampler || 3711bf215546Sopenharmony_ci qual->flags.q.bindless_image || 3712bf215546Sopenharmony_ci state->bindless_sampler_specified || 3713bf215546Sopenharmony_ci state->bindless_image_specified; 3714bf215546Sopenharmony_ci 3715bf215546Sopenharmony_ci var->data.bound = qual->flags.q.bound_sampler || 3716bf215546Sopenharmony_ci qual->flags.q.bound_image || 3717bf215546Sopenharmony_ci state->bound_sampler_specified || 3718bf215546Sopenharmony_ci state->bound_image_specified; 3719bf215546Sopenharmony_ci } 3720bf215546Sopenharmony_ci} 3721bf215546Sopenharmony_ci 3722bf215546Sopenharmony_cistatic void 3723bf215546Sopenharmony_ciapply_layout_qualifier_to_variable(const struct ast_type_qualifier *qual, 3724bf215546Sopenharmony_ci ir_variable *var, 3725bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, 3726bf215546Sopenharmony_ci YYLTYPE *loc) 3727bf215546Sopenharmony_ci{ 3728bf215546Sopenharmony_ci if (var->name != NULL && strcmp(var->name, "gl_FragCoord") == 0) { 3729bf215546Sopenharmony_ci 3730bf215546Sopenharmony_ci /* Section 4.3.8.1, page 39 of GLSL 1.50 spec says: 3731bf215546Sopenharmony_ci * 3732bf215546Sopenharmony_ci * "Within any shader, the first redeclarations of gl_FragCoord 3733bf215546Sopenharmony_ci * must appear before any use of gl_FragCoord." 3734bf215546Sopenharmony_ci * 3735bf215546Sopenharmony_ci * Generate a compiler error if above condition is not met by the 3736bf215546Sopenharmony_ci * fragment shader. 3737bf215546Sopenharmony_ci */ 3738bf215546Sopenharmony_ci ir_variable *earlier = state->symbols->get_variable("gl_FragCoord"); 3739bf215546Sopenharmony_ci if (earlier != NULL && 3740bf215546Sopenharmony_ci earlier->data.used && 3741bf215546Sopenharmony_ci !state->fs_redeclares_gl_fragcoord) { 3742bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3743bf215546Sopenharmony_ci "gl_FragCoord used before its first redeclaration " 3744bf215546Sopenharmony_ci "in fragment shader"); 3745bf215546Sopenharmony_ci } 3746bf215546Sopenharmony_ci 3747bf215546Sopenharmony_ci /* Make sure all gl_FragCoord redeclarations specify the same layout 3748bf215546Sopenharmony_ci * qualifiers. 3749bf215546Sopenharmony_ci */ 3750bf215546Sopenharmony_ci if (is_conflicting_fragcoord_redeclaration(state, qual)) { 3751bf215546Sopenharmony_ci const char *const qual_string = 3752bf215546Sopenharmony_ci get_layout_qualifier_string(qual->flags.q.origin_upper_left, 3753bf215546Sopenharmony_ci qual->flags.q.pixel_center_integer); 3754bf215546Sopenharmony_ci 3755bf215546Sopenharmony_ci const char *const state_string = 3756bf215546Sopenharmony_ci get_layout_qualifier_string(state->fs_origin_upper_left, 3757bf215546Sopenharmony_ci state->fs_pixel_center_integer); 3758bf215546Sopenharmony_ci 3759bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3760bf215546Sopenharmony_ci "gl_FragCoord redeclared with different layout " 3761bf215546Sopenharmony_ci "qualifiers (%s) and (%s) ", 3762bf215546Sopenharmony_ci state_string, 3763bf215546Sopenharmony_ci qual_string); 3764bf215546Sopenharmony_ci } 3765bf215546Sopenharmony_ci state->fs_origin_upper_left = qual->flags.q.origin_upper_left; 3766bf215546Sopenharmony_ci state->fs_pixel_center_integer = qual->flags.q.pixel_center_integer; 3767bf215546Sopenharmony_ci state->fs_redeclares_gl_fragcoord_with_no_layout_qualifiers = 3768bf215546Sopenharmony_ci !qual->flags.q.origin_upper_left && !qual->flags.q.pixel_center_integer; 3769bf215546Sopenharmony_ci state->fs_redeclares_gl_fragcoord = 3770bf215546Sopenharmony_ci state->fs_origin_upper_left || 3771bf215546Sopenharmony_ci state->fs_pixel_center_integer || 3772bf215546Sopenharmony_ci state->fs_redeclares_gl_fragcoord_with_no_layout_qualifiers; 3773bf215546Sopenharmony_ci } 3774bf215546Sopenharmony_ci 3775bf215546Sopenharmony_ci if ((qual->flags.q.origin_upper_left || qual->flags.q.pixel_center_integer) 3776bf215546Sopenharmony_ci && (strcmp(var->name, "gl_FragCoord") != 0)) { 3777bf215546Sopenharmony_ci const char *const qual_string = (qual->flags.q.origin_upper_left) 3778bf215546Sopenharmony_ci ? "origin_upper_left" : "pixel_center_integer"; 3779bf215546Sopenharmony_ci 3780bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3781bf215546Sopenharmony_ci "layout qualifier `%s' can only be applied to " 3782bf215546Sopenharmony_ci "fragment shader input `gl_FragCoord'", 3783bf215546Sopenharmony_ci qual_string); 3784bf215546Sopenharmony_ci } 3785bf215546Sopenharmony_ci 3786bf215546Sopenharmony_ci if (qual->flags.q.explicit_location) { 3787bf215546Sopenharmony_ci apply_explicit_location(qual, var, state, loc); 3788bf215546Sopenharmony_ci 3789bf215546Sopenharmony_ci if (qual->flags.q.explicit_component) { 3790bf215546Sopenharmony_ci unsigned qual_component; 3791bf215546Sopenharmony_ci if (process_qualifier_constant(state, loc, "component", 3792bf215546Sopenharmony_ci qual->component, &qual_component)) { 3793bf215546Sopenharmony_ci validate_component_layout_for_type(state, loc, var->type, 3794bf215546Sopenharmony_ci qual_component); 3795bf215546Sopenharmony_ci var->data.explicit_component = true; 3796bf215546Sopenharmony_ci var->data.location_frac = qual_component; 3797bf215546Sopenharmony_ci } 3798bf215546Sopenharmony_ci } 3799bf215546Sopenharmony_ci } else if (qual->flags.q.explicit_index) { 3800bf215546Sopenharmony_ci if (!qual->subroutine_list) 3801bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3802bf215546Sopenharmony_ci "explicit index requires explicit location"); 3803bf215546Sopenharmony_ci } else if (qual->flags.q.explicit_component) { 3804bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3805bf215546Sopenharmony_ci "explicit component requires explicit location"); 3806bf215546Sopenharmony_ci } 3807bf215546Sopenharmony_ci 3808bf215546Sopenharmony_ci if (qual->flags.q.explicit_binding) { 3809bf215546Sopenharmony_ci apply_explicit_binding(state, loc, var, var->type, qual); 3810bf215546Sopenharmony_ci } 3811bf215546Sopenharmony_ci 3812bf215546Sopenharmony_ci if (state->stage == MESA_SHADER_GEOMETRY && 3813bf215546Sopenharmony_ci qual->flags.q.out && qual->flags.q.stream) { 3814bf215546Sopenharmony_ci unsigned qual_stream; 3815bf215546Sopenharmony_ci if (process_qualifier_constant(state, loc, "stream", qual->stream, 3816bf215546Sopenharmony_ci &qual_stream) && 3817bf215546Sopenharmony_ci validate_stream_qualifier(loc, state, qual_stream)) { 3818bf215546Sopenharmony_ci var->data.stream = qual_stream; 3819bf215546Sopenharmony_ci } 3820bf215546Sopenharmony_ci } 3821bf215546Sopenharmony_ci 3822bf215546Sopenharmony_ci if (qual->flags.q.out && qual->flags.q.xfb_buffer) { 3823bf215546Sopenharmony_ci unsigned qual_xfb_buffer; 3824bf215546Sopenharmony_ci if (process_qualifier_constant(state, loc, "xfb_buffer", 3825bf215546Sopenharmony_ci qual->xfb_buffer, &qual_xfb_buffer) && 3826bf215546Sopenharmony_ci validate_xfb_buffer_qualifier(loc, state, qual_xfb_buffer)) { 3827bf215546Sopenharmony_ci var->data.xfb_buffer = qual_xfb_buffer; 3828bf215546Sopenharmony_ci if (qual->flags.q.explicit_xfb_buffer) 3829bf215546Sopenharmony_ci var->data.explicit_xfb_buffer = true; 3830bf215546Sopenharmony_ci } 3831bf215546Sopenharmony_ci } 3832bf215546Sopenharmony_ci 3833bf215546Sopenharmony_ci if (qual->flags.q.explicit_xfb_offset) { 3834bf215546Sopenharmony_ci unsigned qual_xfb_offset; 3835bf215546Sopenharmony_ci unsigned component_size = var->type->contains_double() ? 8 : 4; 3836bf215546Sopenharmony_ci 3837bf215546Sopenharmony_ci if (process_qualifier_constant(state, loc, "xfb_offset", 3838bf215546Sopenharmony_ci qual->offset, &qual_xfb_offset) && 3839bf215546Sopenharmony_ci validate_xfb_offset_qualifier(loc, state, (int) qual_xfb_offset, 3840bf215546Sopenharmony_ci var->type, component_size)) { 3841bf215546Sopenharmony_ci var->data.offset = qual_xfb_offset; 3842bf215546Sopenharmony_ci var->data.explicit_xfb_offset = true; 3843bf215546Sopenharmony_ci } 3844bf215546Sopenharmony_ci } 3845bf215546Sopenharmony_ci 3846bf215546Sopenharmony_ci if (qual->flags.q.explicit_xfb_stride) { 3847bf215546Sopenharmony_ci unsigned qual_xfb_stride; 3848bf215546Sopenharmony_ci if (process_qualifier_constant(state, loc, "xfb_stride", 3849bf215546Sopenharmony_ci qual->xfb_stride, &qual_xfb_stride)) { 3850bf215546Sopenharmony_ci var->data.xfb_stride = qual_xfb_stride; 3851bf215546Sopenharmony_ci var->data.explicit_xfb_stride = true; 3852bf215546Sopenharmony_ci } 3853bf215546Sopenharmony_ci } 3854bf215546Sopenharmony_ci 3855bf215546Sopenharmony_ci if (var->type->contains_atomic()) { 3856bf215546Sopenharmony_ci if (var->data.mode == ir_var_uniform) { 3857bf215546Sopenharmony_ci if (var->data.explicit_binding) { 3858bf215546Sopenharmony_ci unsigned *offset = 3859bf215546Sopenharmony_ci &state->atomic_counter_offsets[var->data.binding]; 3860bf215546Sopenharmony_ci 3861bf215546Sopenharmony_ci if (*offset % ATOMIC_COUNTER_SIZE) 3862bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3863bf215546Sopenharmony_ci "misaligned atomic counter offset"); 3864bf215546Sopenharmony_ci 3865bf215546Sopenharmony_ci var->data.offset = *offset; 3866bf215546Sopenharmony_ci *offset += var->type->atomic_size(); 3867bf215546Sopenharmony_ci 3868bf215546Sopenharmony_ci } else { 3869bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3870bf215546Sopenharmony_ci "atomic counters require explicit binding point"); 3871bf215546Sopenharmony_ci } 3872bf215546Sopenharmony_ci } else if (var->data.mode != ir_var_function_in) { 3873bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "atomic counters may only be declared as " 3874bf215546Sopenharmony_ci "function parameters or uniform-qualified " 3875bf215546Sopenharmony_ci "global variables"); 3876bf215546Sopenharmony_ci } 3877bf215546Sopenharmony_ci } 3878bf215546Sopenharmony_ci 3879bf215546Sopenharmony_ci if (var->type->contains_sampler() && 3880bf215546Sopenharmony_ci !validate_storage_for_sampler_image_types(var, state, loc)) 3881bf215546Sopenharmony_ci return; 3882bf215546Sopenharmony_ci 3883bf215546Sopenharmony_ci /* Is the 'layout' keyword used with parameters that allow relaxed checking. 3884bf215546Sopenharmony_ci * Many implementations of GL_ARB_fragment_coord_conventions_enable and some 3885bf215546Sopenharmony_ci * implementations (only Mesa?) GL_ARB_explicit_attrib_location_enable 3886bf215546Sopenharmony_ci * allowed the layout qualifier to be used with 'varying' and 'attribute'. 3887bf215546Sopenharmony_ci * These extensions and all following extensions that add the 'layout' 3888bf215546Sopenharmony_ci * keyword have been modified to require the use of 'in' or 'out'. 3889bf215546Sopenharmony_ci * 3890bf215546Sopenharmony_ci * The following extension do not allow the deprecated keywords: 3891bf215546Sopenharmony_ci * 3892bf215546Sopenharmony_ci * GL_AMD_conservative_depth 3893bf215546Sopenharmony_ci * GL_ARB_conservative_depth 3894bf215546Sopenharmony_ci * GL_ARB_gpu_shader5 3895bf215546Sopenharmony_ci * GL_ARB_separate_shader_objects 3896bf215546Sopenharmony_ci * GL_ARB_tessellation_shader 3897bf215546Sopenharmony_ci * GL_ARB_transform_feedback3 3898bf215546Sopenharmony_ci * GL_ARB_uniform_buffer_object 3899bf215546Sopenharmony_ci * 3900bf215546Sopenharmony_ci * It is unknown whether GL_EXT_shader_image_load_store or GL_NV_gpu_shader5 3901bf215546Sopenharmony_ci * allow layout with the deprecated keywords. 3902bf215546Sopenharmony_ci */ 3903bf215546Sopenharmony_ci const bool relaxed_layout_qualifier_checking = 3904bf215546Sopenharmony_ci state->ARB_fragment_coord_conventions_enable; 3905bf215546Sopenharmony_ci 3906bf215546Sopenharmony_ci const bool uses_deprecated_qualifier = qual->flags.q.attribute 3907bf215546Sopenharmony_ci || qual->flags.q.varying; 3908bf215546Sopenharmony_ci if (qual->has_layout() && uses_deprecated_qualifier) { 3909bf215546Sopenharmony_ci if (relaxed_layout_qualifier_checking) { 3910bf215546Sopenharmony_ci _mesa_glsl_warning(loc, state, 3911bf215546Sopenharmony_ci "`layout' qualifier may not be used with " 3912bf215546Sopenharmony_ci "`attribute' or `varying'"); 3913bf215546Sopenharmony_ci } else { 3914bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3915bf215546Sopenharmony_ci "`layout' qualifier may not be used with " 3916bf215546Sopenharmony_ci "`attribute' or `varying'"); 3917bf215546Sopenharmony_ci } 3918bf215546Sopenharmony_ci } 3919bf215546Sopenharmony_ci 3920bf215546Sopenharmony_ci /* Layout qualifiers for gl_FragDepth, which are enabled by extension 3921bf215546Sopenharmony_ci * AMD_conservative_depth. 3922bf215546Sopenharmony_ci */ 3923bf215546Sopenharmony_ci if (qual->flags.q.depth_type 3924bf215546Sopenharmony_ci && !state->is_version(420, 0) 3925bf215546Sopenharmony_ci && !state->AMD_conservative_depth_enable 3926bf215546Sopenharmony_ci && !state->ARB_conservative_depth_enable) { 3927bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3928bf215546Sopenharmony_ci "extension GL_AMD_conservative_depth or " 3929bf215546Sopenharmony_ci "GL_ARB_conservative_depth must be enabled " 3930bf215546Sopenharmony_ci "to use depth layout qualifiers"); 3931bf215546Sopenharmony_ci } else if (qual->flags.q.depth_type 3932bf215546Sopenharmony_ci && strcmp(var->name, "gl_FragDepth") != 0) { 3933bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3934bf215546Sopenharmony_ci "depth layout qualifiers can be applied only to " 3935bf215546Sopenharmony_ci "gl_FragDepth"); 3936bf215546Sopenharmony_ci } 3937bf215546Sopenharmony_ci 3938bf215546Sopenharmony_ci switch (qual->depth_type) { 3939bf215546Sopenharmony_ci case ast_depth_any: 3940bf215546Sopenharmony_ci var->data.depth_layout = ir_depth_layout_any; 3941bf215546Sopenharmony_ci break; 3942bf215546Sopenharmony_ci case ast_depth_greater: 3943bf215546Sopenharmony_ci var->data.depth_layout = ir_depth_layout_greater; 3944bf215546Sopenharmony_ci break; 3945bf215546Sopenharmony_ci case ast_depth_less: 3946bf215546Sopenharmony_ci var->data.depth_layout = ir_depth_layout_less; 3947bf215546Sopenharmony_ci break; 3948bf215546Sopenharmony_ci case ast_depth_unchanged: 3949bf215546Sopenharmony_ci var->data.depth_layout = ir_depth_layout_unchanged; 3950bf215546Sopenharmony_ci break; 3951bf215546Sopenharmony_ci default: 3952bf215546Sopenharmony_ci var->data.depth_layout = ir_depth_layout_none; 3953bf215546Sopenharmony_ci break; 3954bf215546Sopenharmony_ci } 3955bf215546Sopenharmony_ci 3956bf215546Sopenharmony_ci if (qual->flags.q.std140 || 3957bf215546Sopenharmony_ci qual->flags.q.std430 || 3958bf215546Sopenharmony_ci qual->flags.q.packed || 3959bf215546Sopenharmony_ci qual->flags.q.shared) { 3960bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 3961bf215546Sopenharmony_ci "uniform and shader storage block layout qualifiers " 3962bf215546Sopenharmony_ci "std140, std430, packed, and shared can only be " 3963bf215546Sopenharmony_ci "applied to uniform or shader storage blocks, not " 3964bf215546Sopenharmony_ci "members"); 3965bf215546Sopenharmony_ci } 3966bf215546Sopenharmony_ci 3967bf215546Sopenharmony_ci if (qual->flags.q.row_major || qual->flags.q.column_major) { 3968bf215546Sopenharmony_ci validate_matrix_layout_for_type(state, loc, var->type, var); 3969bf215546Sopenharmony_ci } 3970bf215546Sopenharmony_ci 3971bf215546Sopenharmony_ci /* From section 4.4.1.3 of the GLSL 4.50 specification (Fragment Shader 3972bf215546Sopenharmony_ci * Inputs): 3973bf215546Sopenharmony_ci * 3974bf215546Sopenharmony_ci * "Fragment shaders also allow the following layout qualifier on in only 3975bf215546Sopenharmony_ci * (not with variable declarations) 3976bf215546Sopenharmony_ci * layout-qualifier-id 3977bf215546Sopenharmony_ci * early_fragment_tests 3978bf215546Sopenharmony_ci * [...]" 3979bf215546Sopenharmony_ci */ 3980bf215546Sopenharmony_ci if (qual->flags.q.early_fragment_tests) { 3981bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "early_fragment_tests layout qualifier only " 3982bf215546Sopenharmony_ci "valid in fragment shader input layout declaration."); 3983bf215546Sopenharmony_ci } 3984bf215546Sopenharmony_ci 3985bf215546Sopenharmony_ci if (qual->flags.q.inner_coverage) { 3986bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "inner_coverage layout qualifier only " 3987bf215546Sopenharmony_ci "valid in fragment shader input layout declaration."); 3988bf215546Sopenharmony_ci } 3989bf215546Sopenharmony_ci 3990bf215546Sopenharmony_ci if (qual->flags.q.post_depth_coverage) { 3991bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "post_depth_coverage layout qualifier only " 3992bf215546Sopenharmony_ci "valid in fragment shader input layout declaration."); 3993bf215546Sopenharmony_ci } 3994bf215546Sopenharmony_ci 3995bf215546Sopenharmony_ci if (state->has_bindless()) 3996bf215546Sopenharmony_ci apply_bindless_qualifier_to_variable(qual, var, state, loc); 3997bf215546Sopenharmony_ci 3998bf215546Sopenharmony_ci if (qual->flags.q.pixel_interlock_ordered || 3999bf215546Sopenharmony_ci qual->flags.q.pixel_interlock_unordered || 4000bf215546Sopenharmony_ci qual->flags.q.sample_interlock_ordered || 4001bf215546Sopenharmony_ci qual->flags.q.sample_interlock_unordered) { 4002bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "interlock layout qualifiers: " 4003bf215546Sopenharmony_ci "pixel_interlock_ordered, pixel_interlock_unordered, " 4004bf215546Sopenharmony_ci "sample_interlock_ordered and sample_interlock_unordered, " 4005bf215546Sopenharmony_ci "only valid in fragment shader input layout declaration."); 4006bf215546Sopenharmony_ci } 4007bf215546Sopenharmony_ci 4008bf215546Sopenharmony_ci if (var->name != NULL && strcmp(var->name, "gl_Layer") == 0) { 4009bf215546Sopenharmony_ci if (is_conflicting_layer_redeclaration(state, qual)) { 4010bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "gl_Layer redeclaration with " 4011bf215546Sopenharmony_ci "different viewport_relative setting than earlier"); 4012bf215546Sopenharmony_ci } 4013bf215546Sopenharmony_ci state->redeclares_gl_layer = true; 4014bf215546Sopenharmony_ci if (qual->flags.q.viewport_relative) { 4015bf215546Sopenharmony_ci state->layer_viewport_relative = true; 4016bf215546Sopenharmony_ci } 4017bf215546Sopenharmony_ci } else if (qual->flags.q.viewport_relative) { 4018bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 4019bf215546Sopenharmony_ci "viewport_relative qualifier " 4020bf215546Sopenharmony_ci "can only be applied to gl_Layer."); 4021bf215546Sopenharmony_ci } 4022bf215546Sopenharmony_ci} 4023bf215546Sopenharmony_ci 4024bf215546Sopenharmony_cistatic void 4025bf215546Sopenharmony_ciapply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, 4026bf215546Sopenharmony_ci ir_variable *var, 4027bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, 4028bf215546Sopenharmony_ci YYLTYPE *loc, 4029bf215546Sopenharmony_ci bool is_parameter) 4030bf215546Sopenharmony_ci{ 4031bf215546Sopenharmony_ci STATIC_ASSERT(sizeof(qual->flags.q) <= sizeof(qual->flags.i)); 4032bf215546Sopenharmony_ci 4033bf215546Sopenharmony_ci if (qual->flags.q.invariant) { 4034bf215546Sopenharmony_ci if (var->data.used) { 4035bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 4036bf215546Sopenharmony_ci "variable `%s' may not be redeclared " 4037bf215546Sopenharmony_ci "`invariant' after being used", 4038bf215546Sopenharmony_ci var->name); 4039bf215546Sopenharmony_ci } else { 4040bf215546Sopenharmony_ci var->data.explicit_invariant = true; 4041bf215546Sopenharmony_ci var->data.invariant = true; 4042bf215546Sopenharmony_ci } 4043bf215546Sopenharmony_ci } 4044bf215546Sopenharmony_ci 4045bf215546Sopenharmony_ci if (qual->flags.q.precise) { 4046bf215546Sopenharmony_ci if (var->data.used) { 4047bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 4048bf215546Sopenharmony_ci "variable `%s' may not be redeclared " 4049bf215546Sopenharmony_ci "`precise' after being used", 4050bf215546Sopenharmony_ci var->name); 4051bf215546Sopenharmony_ci } else { 4052bf215546Sopenharmony_ci var->data.precise = 1; 4053bf215546Sopenharmony_ci } 4054bf215546Sopenharmony_ci } 4055bf215546Sopenharmony_ci 4056bf215546Sopenharmony_ci if (qual->is_subroutine_decl() && !qual->flags.q.uniform) { 4057bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 4058bf215546Sopenharmony_ci "`subroutine' may only be applied to uniforms, " 4059bf215546Sopenharmony_ci "subroutine type declarations, or function definitions"); 4060bf215546Sopenharmony_ci } 4061bf215546Sopenharmony_ci 4062bf215546Sopenharmony_ci if (qual->flags.q.constant || qual->flags.q.attribute 4063bf215546Sopenharmony_ci || qual->flags.q.uniform 4064bf215546Sopenharmony_ci || (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT))) 4065bf215546Sopenharmony_ci var->data.read_only = 1; 4066bf215546Sopenharmony_ci 4067bf215546Sopenharmony_ci if (qual->flags.q.centroid) 4068bf215546Sopenharmony_ci var->data.centroid = 1; 4069bf215546Sopenharmony_ci 4070bf215546Sopenharmony_ci if (qual->flags.q.sample) 4071bf215546Sopenharmony_ci var->data.sample = 1; 4072bf215546Sopenharmony_ci 4073bf215546Sopenharmony_ci /* Precision qualifiers do not hold any meaning in Desktop GLSL */ 4074bf215546Sopenharmony_ci if (state->es_shader) { 4075bf215546Sopenharmony_ci var->data.precision = 4076bf215546Sopenharmony_ci select_gles_precision(qual->precision, var->type, state, loc); 4077bf215546Sopenharmony_ci } 4078bf215546Sopenharmony_ci 4079bf215546Sopenharmony_ci if (qual->flags.q.patch) 4080bf215546Sopenharmony_ci var->data.patch = 1; 4081bf215546Sopenharmony_ci 4082bf215546Sopenharmony_ci if (qual->flags.q.attribute && state->stage != MESA_SHADER_VERTEX) { 4083bf215546Sopenharmony_ci var->type = glsl_type::error_type; 4084bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 4085bf215546Sopenharmony_ci "`attribute' variables may not be declared in the " 4086bf215546Sopenharmony_ci "%s shader", 4087bf215546Sopenharmony_ci _mesa_shader_stage_to_string(state->stage)); 4088bf215546Sopenharmony_ci } 4089bf215546Sopenharmony_ci 4090bf215546Sopenharmony_ci /* Disallow layout qualifiers which may only appear on layout declarations. */ 4091bf215546Sopenharmony_ci if (qual->flags.q.prim_type) { 4092bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 4093bf215546Sopenharmony_ci "Primitive type may only be specified on GS input or output " 4094bf215546Sopenharmony_ci "layout declaration, not on variables."); 4095bf215546Sopenharmony_ci } 4096bf215546Sopenharmony_ci 4097bf215546Sopenharmony_ci /* Section 6.1.1 (Function Calling Conventions) of the GLSL 1.10 spec says: 4098bf215546Sopenharmony_ci * 4099bf215546Sopenharmony_ci * "However, the const qualifier cannot be used with out or inout." 4100bf215546Sopenharmony_ci * 4101bf215546Sopenharmony_ci * The same section of the GLSL 4.40 spec further clarifies this saying: 4102bf215546Sopenharmony_ci * 4103bf215546Sopenharmony_ci * "The const qualifier cannot be used with out or inout, or a 4104bf215546Sopenharmony_ci * compile-time error results." 4105bf215546Sopenharmony_ci */ 4106bf215546Sopenharmony_ci if (is_parameter && qual->flags.q.constant && qual->flags.q.out) { 4107bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 4108bf215546Sopenharmony_ci "`const' may not be applied to `out' or `inout' " 4109bf215546Sopenharmony_ci "function parameters"); 4110bf215546Sopenharmony_ci } 4111bf215546Sopenharmony_ci 4112bf215546Sopenharmony_ci /* If there is no qualifier that changes the mode of the variable, leave 4113bf215546Sopenharmony_ci * the setting alone. 4114bf215546Sopenharmony_ci */ 4115bf215546Sopenharmony_ci assert(var->data.mode != ir_var_temporary); 4116bf215546Sopenharmony_ci if (qual->flags.q.in && qual->flags.q.out) 4117bf215546Sopenharmony_ci var->data.mode = is_parameter ? ir_var_function_inout : ir_var_shader_out; 4118bf215546Sopenharmony_ci else if (qual->flags.q.in) 4119bf215546Sopenharmony_ci var->data.mode = is_parameter ? ir_var_function_in : ir_var_shader_in; 4120bf215546Sopenharmony_ci else if (qual->flags.q.attribute 4121bf215546Sopenharmony_ci || (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT))) 4122bf215546Sopenharmony_ci var->data.mode = ir_var_shader_in; 4123bf215546Sopenharmony_ci else if (qual->flags.q.out) 4124bf215546Sopenharmony_ci var->data.mode = is_parameter ? ir_var_function_out : ir_var_shader_out; 4125bf215546Sopenharmony_ci else if (qual->flags.q.varying && (state->stage == MESA_SHADER_VERTEX)) 4126bf215546Sopenharmony_ci var->data.mode = ir_var_shader_out; 4127bf215546Sopenharmony_ci else if (qual->flags.q.uniform) 4128bf215546Sopenharmony_ci var->data.mode = ir_var_uniform; 4129bf215546Sopenharmony_ci else if (qual->flags.q.buffer) 4130bf215546Sopenharmony_ci var->data.mode = ir_var_shader_storage; 4131bf215546Sopenharmony_ci else if (qual->flags.q.shared_storage) 4132bf215546Sopenharmony_ci var->data.mode = ir_var_shader_shared; 4133bf215546Sopenharmony_ci 4134bf215546Sopenharmony_ci if (!is_parameter && state->stage == MESA_SHADER_FRAGMENT) { 4135bf215546Sopenharmony_ci if (state->has_framebuffer_fetch()) { 4136bf215546Sopenharmony_ci if (state->is_version(130, 300)) 4137bf215546Sopenharmony_ci var->data.fb_fetch_output = qual->flags.q.in && qual->flags.q.out; 4138bf215546Sopenharmony_ci else 4139bf215546Sopenharmony_ci var->data.fb_fetch_output = (strcmp(var->name, "gl_LastFragData") == 0); 4140bf215546Sopenharmony_ci } 4141bf215546Sopenharmony_ci 4142bf215546Sopenharmony_ci if (state->has_framebuffer_fetch_zs() && 4143bf215546Sopenharmony_ci (strcmp(var->name, "gl_LastFragDepthARM") == 0 || 4144bf215546Sopenharmony_ci strcmp(var->name, "gl_LastFragStencilARM") == 0)) { 4145bf215546Sopenharmony_ci var->data.fb_fetch_output = 1; 4146bf215546Sopenharmony_ci } 4147bf215546Sopenharmony_ci } 4148bf215546Sopenharmony_ci 4149bf215546Sopenharmony_ci if (var->data.fb_fetch_output) 4150bf215546Sopenharmony_ci var->data.assigned = true; 4151bf215546Sopenharmony_ci 4152bf215546Sopenharmony_ci if (var->is_fb_fetch_color_output()) { 4153bf215546Sopenharmony_ci var->data.memory_coherent = !qual->flags.q.non_coherent; 4154bf215546Sopenharmony_ci 4155bf215546Sopenharmony_ci /* From the EXT_shader_framebuffer_fetch spec: 4156bf215546Sopenharmony_ci * 4157bf215546Sopenharmony_ci * "It is an error to declare an inout fragment output not qualified 4158bf215546Sopenharmony_ci * with layout(noncoherent) if the GL_EXT_shader_framebuffer_fetch 4159bf215546Sopenharmony_ci * extension hasn't been enabled." 4160bf215546Sopenharmony_ci */ 4161bf215546Sopenharmony_ci if (var->data.memory_coherent && 4162bf215546Sopenharmony_ci !state->EXT_shader_framebuffer_fetch_enable) 4163bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 4164bf215546Sopenharmony_ci "invalid declaration of framebuffer fetch output not " 4165bf215546Sopenharmony_ci "qualified with layout(noncoherent)"); 4166bf215546Sopenharmony_ci 4167bf215546Sopenharmony_ci } else { 4168bf215546Sopenharmony_ci /* From the EXT_shader_framebuffer_fetch spec: 4169bf215546Sopenharmony_ci * 4170bf215546Sopenharmony_ci * "Fragment outputs declared inout may specify the following layout 4171bf215546Sopenharmony_ci * qualifier: [...] noncoherent" 4172bf215546Sopenharmony_ci */ 4173bf215546Sopenharmony_ci if (qual->flags.q.non_coherent) 4174bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 4175bf215546Sopenharmony_ci "invalid layout(noncoherent) qualifier not part of " 4176bf215546Sopenharmony_ci "framebuffer fetch output declaration"); 4177bf215546Sopenharmony_ci } 4178bf215546Sopenharmony_ci 4179bf215546Sopenharmony_ci if (!is_parameter && is_varying_var(var, state->stage)) { 4180bf215546Sopenharmony_ci /* User-defined ins/outs are not permitted in compute shaders. */ 4181bf215546Sopenharmony_ci if (state->stage == MESA_SHADER_COMPUTE) { 4182bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 4183bf215546Sopenharmony_ci "user-defined input and output variables are not " 4184bf215546Sopenharmony_ci "permitted in compute shaders"); 4185bf215546Sopenharmony_ci } 4186bf215546Sopenharmony_ci 4187bf215546Sopenharmony_ci /* This variable is being used to link data between shader stages (in 4188bf215546Sopenharmony_ci * pre-glsl-1.30 parlance, it's a "varying"). Check that it has a type 4189bf215546Sopenharmony_ci * that is allowed for such purposes. 4190bf215546Sopenharmony_ci * 4191bf215546Sopenharmony_ci * From page 25 (page 31 of the PDF) of the GLSL 1.10 spec: 4192bf215546Sopenharmony_ci * 4193bf215546Sopenharmony_ci * "The varying qualifier can be used only with the data types 4194bf215546Sopenharmony_ci * float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of 4195bf215546Sopenharmony_ci * these." 4196bf215546Sopenharmony_ci * 4197bf215546Sopenharmony_ci * This was relaxed in GLSL version 1.30 and GLSL ES version 3.00. From 4198bf215546Sopenharmony_ci * page 31 (page 37 of the PDF) of the GLSL 1.30 spec: 4199bf215546Sopenharmony_ci * 4200bf215546Sopenharmony_ci * "Fragment inputs can only be signed and unsigned integers and 4201bf215546Sopenharmony_ci * integer vectors, float, floating-point vectors, matrices, or 4202bf215546Sopenharmony_ci * arrays of these. Structures cannot be input. 4203bf215546Sopenharmony_ci * 4204bf215546Sopenharmony_ci * Similar text exists in the section on vertex shader outputs. 4205bf215546Sopenharmony_ci * 4206bf215546Sopenharmony_ci * Similar text exists in the GLSL ES 3.00 spec, except that the GLSL ES 4207bf215546Sopenharmony_ci * 3.00 spec allows structs as well. Varying structs are also allowed 4208bf215546Sopenharmony_ci * in GLSL 1.50. 4209bf215546Sopenharmony_ci * 4210bf215546Sopenharmony_ci * From section 4.3.4 of the ARB_bindless_texture spec: 4211bf215546Sopenharmony_ci * 4212bf215546Sopenharmony_ci * "(modify third paragraph of the section to allow sampler and image 4213bf215546Sopenharmony_ci * types) ... Vertex shader inputs can only be float, 4214bf215546Sopenharmony_ci * single-precision floating-point scalars, single-precision 4215bf215546Sopenharmony_ci * floating-point vectors, matrices, signed and unsigned integers 4216bf215546Sopenharmony_ci * and integer vectors, sampler and image types." 4217bf215546Sopenharmony_ci * 4218bf215546Sopenharmony_ci * From section 4.3.6 of the ARB_bindless_texture spec: 4219bf215546Sopenharmony_ci * 4220bf215546Sopenharmony_ci * "Output variables can only be floating-point scalars, 4221bf215546Sopenharmony_ci * floating-point vectors, matrices, signed or unsigned integers or 4222bf215546Sopenharmony_ci * integer vectors, sampler or image types, or arrays or structures 4223bf215546Sopenharmony_ci * of any these." 4224bf215546Sopenharmony_ci */ 4225bf215546Sopenharmony_ci switch (var->type->without_array()->base_type) { 4226bf215546Sopenharmony_ci case GLSL_TYPE_FLOAT: 4227bf215546Sopenharmony_ci /* Ok in all GLSL versions */ 4228bf215546Sopenharmony_ci break; 4229bf215546Sopenharmony_ci case GLSL_TYPE_UINT: 4230bf215546Sopenharmony_ci case GLSL_TYPE_INT: 4231bf215546Sopenharmony_ci if (state->is_version(130, 300) || state->EXT_gpu_shader4_enable) 4232bf215546Sopenharmony_ci break; 4233bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 4234bf215546Sopenharmony_ci "varying variables must be of base type float in %s", 4235bf215546Sopenharmony_ci state->get_version_string()); 4236bf215546Sopenharmony_ci break; 4237bf215546Sopenharmony_ci case GLSL_TYPE_STRUCT: 4238bf215546Sopenharmony_ci if (state->is_version(150, 300)) 4239bf215546Sopenharmony_ci break; 4240bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 4241bf215546Sopenharmony_ci "varying variables may not be of type struct"); 4242bf215546Sopenharmony_ci break; 4243bf215546Sopenharmony_ci case GLSL_TYPE_DOUBLE: 4244bf215546Sopenharmony_ci case GLSL_TYPE_UINT64: 4245bf215546Sopenharmony_ci case GLSL_TYPE_INT64: 4246bf215546Sopenharmony_ci break; 4247bf215546Sopenharmony_ci case GLSL_TYPE_SAMPLER: 4248bf215546Sopenharmony_ci case GLSL_TYPE_TEXTURE: 4249bf215546Sopenharmony_ci case GLSL_TYPE_IMAGE: 4250bf215546Sopenharmony_ci if (state->has_bindless()) 4251bf215546Sopenharmony_ci break; 4252bf215546Sopenharmony_ci FALLTHROUGH; 4253bf215546Sopenharmony_ci default: 4254bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, "illegal type for a varying variable"); 4255bf215546Sopenharmony_ci break; 4256bf215546Sopenharmony_ci } 4257bf215546Sopenharmony_ci } 4258bf215546Sopenharmony_ci 4259bf215546Sopenharmony_ci if (state->all_invariant && var->data.mode == ir_var_shader_out) { 4260bf215546Sopenharmony_ci var->data.explicit_invariant = true; 4261bf215546Sopenharmony_ci var->data.invariant = true; 4262bf215546Sopenharmony_ci } 4263bf215546Sopenharmony_ci 4264bf215546Sopenharmony_ci var->data.interpolation = 4265bf215546Sopenharmony_ci interpret_interpolation_qualifier(qual, var->type, 4266bf215546Sopenharmony_ci (ir_variable_mode) var->data.mode, 4267bf215546Sopenharmony_ci state, loc); 4268bf215546Sopenharmony_ci 4269bf215546Sopenharmony_ci /* Does the declaration use the deprecated 'attribute' or 'varying' 4270bf215546Sopenharmony_ci * keywords? 4271bf215546Sopenharmony_ci */ 4272bf215546Sopenharmony_ci const bool uses_deprecated_qualifier = qual->flags.q.attribute 4273bf215546Sopenharmony_ci || qual->flags.q.varying; 4274bf215546Sopenharmony_ci 4275bf215546Sopenharmony_ci 4276bf215546Sopenharmony_ci /* Validate auxiliary storage qualifiers */ 4277bf215546Sopenharmony_ci 4278bf215546Sopenharmony_ci /* From section 4.3.4 of the GLSL 1.30 spec: 4279bf215546Sopenharmony_ci * "It is an error to use centroid in in a vertex shader." 4280bf215546Sopenharmony_ci * 4281bf215546Sopenharmony_ci * From section 4.3.4 of the GLSL ES 3.00 spec: 4282bf215546Sopenharmony_ci * "It is an error to use centroid in or interpolation qualifiers in 4283bf215546Sopenharmony_ci * a vertex shader input." 4284bf215546Sopenharmony_ci */ 4285bf215546Sopenharmony_ci 4286bf215546Sopenharmony_ci /* Section 4.3.6 of the GLSL 1.30 specification states: 4287bf215546Sopenharmony_ci * "It is an error to use centroid out in a fragment shader." 4288bf215546Sopenharmony_ci * 4289bf215546Sopenharmony_ci * The GL_ARB_shading_language_420pack extension specification states: 4290bf215546Sopenharmony_ci * "It is an error to use auxiliary storage qualifiers or interpolation 4291bf215546Sopenharmony_ci * qualifiers on an output in a fragment shader." 4292bf215546Sopenharmony_ci */ 4293bf215546Sopenharmony_ci if (qual->flags.q.sample && (!is_varying_var(var, state->stage) || uses_deprecated_qualifier)) { 4294bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 4295bf215546Sopenharmony_ci "sample qualifier may only be used on `in` or `out` " 4296bf215546Sopenharmony_ci "variables between shader stages"); 4297bf215546Sopenharmony_ci } 4298bf215546Sopenharmony_ci if (qual->flags.q.centroid && !is_varying_var(var, state->stage)) { 4299bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 4300bf215546Sopenharmony_ci "centroid qualifier may only be used with `in', " 4301bf215546Sopenharmony_ci "`out' or `varying' variables between shader stages"); 4302bf215546Sopenharmony_ci } 4303bf215546Sopenharmony_ci 4304bf215546Sopenharmony_ci if (qual->flags.q.shared_storage && state->stage != MESA_SHADER_COMPUTE) { 4305bf215546Sopenharmony_ci _mesa_glsl_error(loc, state, 4306bf215546Sopenharmony_ci "the shared storage qualifiers can only be used with " 4307bf215546Sopenharmony_ci "compute shaders"); 4308bf215546Sopenharmony_ci } 4309bf215546Sopenharmony_ci 4310bf215546Sopenharmony_ci apply_image_qualifier_to_variable(qual, var, state, loc); 4311bf215546Sopenharmony_ci} 4312bf215546Sopenharmony_ci 4313bf215546Sopenharmony_ci/** 4314bf215546Sopenharmony_ci * Get the variable that is being redeclared by this declaration or if it 4315bf215546Sopenharmony_ci * does not exist, the current declared variable. 4316bf215546Sopenharmony_ci * 4317bf215546Sopenharmony_ci * Semantic checks to verify the validity of the redeclaration are also 4318bf215546Sopenharmony_ci * performed. If semantic checks fail, compilation error will be emitted via 4319bf215546Sopenharmony_ci * \c _mesa_glsl_error, but a non-\c NULL pointer will still be returned. 4320bf215546Sopenharmony_ci * 4321bf215546Sopenharmony_ci * \returns 4322bf215546Sopenharmony_ci * A pointer to an existing variable in the current scope if the declaration 4323bf215546Sopenharmony_ci * is a redeclaration, current variable otherwise. \c is_declared boolean 4324bf215546Sopenharmony_ci * will return \c true if the declaration is a redeclaration, \c false 4325bf215546Sopenharmony_ci * otherwise. 4326bf215546Sopenharmony_ci */ 4327bf215546Sopenharmony_cistatic ir_variable * 4328bf215546Sopenharmony_ciget_variable_being_redeclared(ir_variable **var_ptr, YYLTYPE loc, 4329bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, 4330bf215546Sopenharmony_ci bool allow_all_redeclarations, 4331bf215546Sopenharmony_ci bool *is_redeclaration) 4332bf215546Sopenharmony_ci{ 4333bf215546Sopenharmony_ci ir_variable *var = *var_ptr; 4334bf215546Sopenharmony_ci 4335bf215546Sopenharmony_ci /* Check if this declaration is actually a re-declaration, either to 4336bf215546Sopenharmony_ci * resize an array or add qualifiers to an existing variable. 4337bf215546Sopenharmony_ci * 4338bf215546Sopenharmony_ci * This is allowed for variables in the current scope, or when at 4339bf215546Sopenharmony_ci * global scope (for built-ins in the implicit outer scope). 4340bf215546Sopenharmony_ci */ 4341bf215546Sopenharmony_ci ir_variable *earlier = state->symbols->get_variable(var->name); 4342bf215546Sopenharmony_ci if (earlier == NULL || 4343bf215546Sopenharmony_ci (state->current_function != NULL && 4344bf215546Sopenharmony_ci !state->symbols->name_declared_this_scope(var->name))) { 4345bf215546Sopenharmony_ci *is_redeclaration = false; 4346bf215546Sopenharmony_ci return var; 4347bf215546Sopenharmony_ci } 4348bf215546Sopenharmony_ci 4349bf215546Sopenharmony_ci *is_redeclaration = true; 4350bf215546Sopenharmony_ci 4351bf215546Sopenharmony_ci if (earlier->data.how_declared == ir_var_declared_implicitly) { 4352bf215546Sopenharmony_ci /* Verify that the redeclaration of a built-in does not change the 4353bf215546Sopenharmony_ci * storage qualifier. There are a couple special cases. 4354bf215546Sopenharmony_ci * 4355bf215546Sopenharmony_ci * 1. Some built-in variables that are defined as 'in' in the 4356bf215546Sopenharmony_ci * specification are implemented as system values. Allow 4357bf215546Sopenharmony_ci * ir_var_system_value -> ir_var_shader_in. 4358bf215546Sopenharmony_ci * 4359bf215546Sopenharmony_ci * 2. gl_LastFragData is implemented as a ir_var_shader_out, but the 4360bf215546Sopenharmony_ci * specification requires that redeclarations omit any qualifier. 4361bf215546Sopenharmony_ci * Allow ir_var_shader_out -> ir_var_auto for this one variable. 4362bf215546Sopenharmony_ci */ 4363bf215546Sopenharmony_ci if (earlier->data.mode != var->data.mode && 4364bf215546Sopenharmony_ci !(earlier->data.mode == ir_var_system_value && 4365bf215546Sopenharmony_ci var->data.mode == ir_var_shader_in) && 4366bf215546Sopenharmony_ci !(strcmp(var->name, "gl_LastFragData") == 0 && 4367bf215546Sopenharmony_ci var->data.mode == ir_var_auto)) { 4368bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 4369bf215546Sopenharmony_ci "redeclaration cannot change qualification of `%s'", 4370bf215546Sopenharmony_ci var->name); 4371bf215546Sopenharmony_ci } 4372bf215546Sopenharmony_ci } 4373bf215546Sopenharmony_ci 4374bf215546Sopenharmony_ci /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec, 4375bf215546Sopenharmony_ci * 4376bf215546Sopenharmony_ci * "It is legal to declare an array without a size and then 4377bf215546Sopenharmony_ci * later re-declare the same name as an array of the same 4378bf215546Sopenharmony_ci * type and specify a size." 4379bf215546Sopenharmony_ci */ 4380bf215546Sopenharmony_ci if (earlier->type->is_unsized_array() && var->type->is_array() 4381bf215546Sopenharmony_ci && (var->type->fields.array == earlier->type->fields.array)) { 4382bf215546Sopenharmony_ci const int size = var->type->array_size(); 4383bf215546Sopenharmony_ci check_builtin_array_max_size(var->name, size, loc, state); 4384bf215546Sopenharmony_ci if ((size > 0) && (size <= earlier->data.max_array_access)) { 4385bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "array size must be > %u due to " 4386bf215546Sopenharmony_ci "previous access", 4387bf215546Sopenharmony_ci earlier->data.max_array_access); 4388bf215546Sopenharmony_ci } 4389bf215546Sopenharmony_ci 4390bf215546Sopenharmony_ci earlier->type = var->type; 4391bf215546Sopenharmony_ci delete var; 4392bf215546Sopenharmony_ci var = NULL; 4393bf215546Sopenharmony_ci *var_ptr = NULL; 4394bf215546Sopenharmony_ci } else if (earlier->type != var->type) { 4395bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 4396bf215546Sopenharmony_ci "redeclaration of `%s' has incorrect type", 4397bf215546Sopenharmony_ci var->name); 4398bf215546Sopenharmony_ci } else if ((state->ARB_fragment_coord_conventions_enable || 4399bf215546Sopenharmony_ci state->is_version(150, 0)) 4400bf215546Sopenharmony_ci && strcmp(var->name, "gl_FragCoord") == 0) { 4401bf215546Sopenharmony_ci /* Allow redeclaration of gl_FragCoord for ARB_fcc layout 4402bf215546Sopenharmony_ci * qualifiers. 4403bf215546Sopenharmony_ci * 4404bf215546Sopenharmony_ci * We don't really need to do anything here, just allow the 4405bf215546Sopenharmony_ci * redeclaration. Any error on the gl_FragCoord is handled on the ast 4406bf215546Sopenharmony_ci * level at apply_layout_qualifier_to_variable using the 4407bf215546Sopenharmony_ci * ast_type_qualifier and _mesa_glsl_parse_state, or later at 4408bf215546Sopenharmony_ci * linker.cpp. 4409bf215546Sopenharmony_ci */ 4410bf215546Sopenharmony_ci /* According to section 4.3.7 of the GLSL 1.30 spec, 4411bf215546Sopenharmony_ci * the following built-in varaibles can be redeclared with an 4412bf215546Sopenharmony_ci * interpolation qualifier: 4413bf215546Sopenharmony_ci * * gl_FrontColor 4414bf215546Sopenharmony_ci * * gl_BackColor 4415bf215546Sopenharmony_ci * * gl_FrontSecondaryColor 4416bf215546Sopenharmony_ci * * gl_BackSecondaryColor 4417bf215546Sopenharmony_ci * * gl_Color 4418bf215546Sopenharmony_ci * * gl_SecondaryColor 4419bf215546Sopenharmony_ci */ 4420bf215546Sopenharmony_ci } else if (state->is_version(130, 0) 4421bf215546Sopenharmony_ci && (strcmp(var->name, "gl_FrontColor") == 0 4422bf215546Sopenharmony_ci || strcmp(var->name, "gl_BackColor") == 0 4423bf215546Sopenharmony_ci || strcmp(var->name, "gl_FrontSecondaryColor") == 0 4424bf215546Sopenharmony_ci || strcmp(var->name, "gl_BackSecondaryColor") == 0 4425bf215546Sopenharmony_ci || strcmp(var->name, "gl_Color") == 0 4426bf215546Sopenharmony_ci || strcmp(var->name, "gl_SecondaryColor") == 0)) { 4427bf215546Sopenharmony_ci earlier->data.interpolation = var->data.interpolation; 4428bf215546Sopenharmony_ci 4429bf215546Sopenharmony_ci /* Layout qualifiers for gl_FragDepth. */ 4430bf215546Sopenharmony_ci } else if ((state->is_version(420, 0) || 4431bf215546Sopenharmony_ci state->AMD_conservative_depth_enable || 4432bf215546Sopenharmony_ci state->ARB_conservative_depth_enable) 4433bf215546Sopenharmony_ci && strcmp(var->name, "gl_FragDepth") == 0) { 4434bf215546Sopenharmony_ci 4435bf215546Sopenharmony_ci /** From the AMD_conservative_depth spec: 4436bf215546Sopenharmony_ci * Within any shader, the first redeclarations of gl_FragDepth 4437bf215546Sopenharmony_ci * must appear before any use of gl_FragDepth. 4438bf215546Sopenharmony_ci */ 4439bf215546Sopenharmony_ci if (earlier->data.used) { 4440bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 4441bf215546Sopenharmony_ci "the first redeclaration of gl_FragDepth " 4442bf215546Sopenharmony_ci "must appear before any use of gl_FragDepth"); 4443bf215546Sopenharmony_ci } 4444bf215546Sopenharmony_ci 4445bf215546Sopenharmony_ci /* Prevent inconsistent redeclaration of depth layout qualifier. */ 4446bf215546Sopenharmony_ci if (earlier->data.depth_layout != ir_depth_layout_none 4447bf215546Sopenharmony_ci && earlier->data.depth_layout != var->data.depth_layout) { 4448bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 4449bf215546Sopenharmony_ci "gl_FragDepth: depth layout is declared here " 4450bf215546Sopenharmony_ci "as '%s, but it was previously declared as " 4451bf215546Sopenharmony_ci "'%s'", 4452bf215546Sopenharmony_ci depth_layout_string(var->data.depth_layout), 4453bf215546Sopenharmony_ci depth_layout_string(earlier->data.depth_layout)); 4454bf215546Sopenharmony_ci } 4455bf215546Sopenharmony_ci 4456bf215546Sopenharmony_ci earlier->data.depth_layout = var->data.depth_layout; 4457bf215546Sopenharmony_ci 4458bf215546Sopenharmony_ci } else if (state->has_framebuffer_fetch() && 4459bf215546Sopenharmony_ci strcmp(var->name, "gl_LastFragData") == 0 && 4460bf215546Sopenharmony_ci var->data.mode == ir_var_auto) { 4461bf215546Sopenharmony_ci /* According to the EXT_shader_framebuffer_fetch spec: 4462bf215546Sopenharmony_ci * 4463bf215546Sopenharmony_ci * "By default, gl_LastFragData is declared with the mediump precision 4464bf215546Sopenharmony_ci * qualifier. This can be changed by redeclaring the corresponding 4465bf215546Sopenharmony_ci * variables with the desired precision qualifier." 4466bf215546Sopenharmony_ci * 4467bf215546Sopenharmony_ci * "Fragment shaders may specify the following layout qualifier only for 4468bf215546Sopenharmony_ci * redeclaring the built-in gl_LastFragData array [...]: noncoherent" 4469bf215546Sopenharmony_ci */ 4470bf215546Sopenharmony_ci earlier->data.precision = var->data.precision; 4471bf215546Sopenharmony_ci earlier->data.memory_coherent = var->data.memory_coherent; 4472bf215546Sopenharmony_ci 4473bf215546Sopenharmony_ci } else if (state->NV_viewport_array2_enable && 4474bf215546Sopenharmony_ci strcmp(var->name, "gl_Layer") == 0 && 4475bf215546Sopenharmony_ci earlier->data.how_declared == ir_var_declared_implicitly) { 4476bf215546Sopenharmony_ci /* No need to do anything, just allow it. Qualifier is stored in state */ 4477bf215546Sopenharmony_ci 4478bf215546Sopenharmony_ci } else if (state->is_version(0, 300) && 4479bf215546Sopenharmony_ci state->has_separate_shader_objects() && 4480bf215546Sopenharmony_ci (strcmp(var->name, "gl_Position") == 0 || 4481bf215546Sopenharmony_ci strcmp(var->name, "gl_PointSize") == 0)) { 4482bf215546Sopenharmony_ci 4483bf215546Sopenharmony_ci /* EXT_separate_shader_objects spec says: 4484bf215546Sopenharmony_ci * 4485bf215546Sopenharmony_ci * "The following vertex shader outputs may be redeclared 4486bf215546Sopenharmony_ci * at global scope to specify a built-in output interface, 4487bf215546Sopenharmony_ci * with or without special qualifiers: 4488bf215546Sopenharmony_ci * 4489bf215546Sopenharmony_ci * gl_Position 4490bf215546Sopenharmony_ci * gl_PointSize 4491bf215546Sopenharmony_ci * 4492bf215546Sopenharmony_ci * When compiling shaders using either of the above variables, 4493bf215546Sopenharmony_ci * both such variables must be redeclared prior to use." 4494bf215546Sopenharmony_ci */ 4495bf215546Sopenharmony_ci if (earlier->data.used) { 4496bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "the first redeclaration of " 4497bf215546Sopenharmony_ci "%s must appear before any use", var->name); 4498bf215546Sopenharmony_ci } 4499bf215546Sopenharmony_ci } else if ((earlier->data.how_declared == ir_var_declared_implicitly && 4500bf215546Sopenharmony_ci state->allow_builtin_variable_redeclaration) || 4501bf215546Sopenharmony_ci allow_all_redeclarations) { 4502bf215546Sopenharmony_ci /* Allow verbatim redeclarations of built-in variables. Not explicitly 4503bf215546Sopenharmony_ci * valid, but some applications do it. 4504bf215546Sopenharmony_ci */ 4505bf215546Sopenharmony_ci } else { 4506bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "`%s' redeclared", var->name); 4507bf215546Sopenharmony_ci } 4508bf215546Sopenharmony_ci 4509bf215546Sopenharmony_ci return earlier; 4510bf215546Sopenharmony_ci} 4511bf215546Sopenharmony_ci 4512bf215546Sopenharmony_ci/** 4513bf215546Sopenharmony_ci * Generate the IR for an initializer in a variable declaration 4514bf215546Sopenharmony_ci */ 4515bf215546Sopenharmony_cistatic ir_rvalue * 4516bf215546Sopenharmony_ciprocess_initializer(ir_variable *var, ast_declaration *decl, 4517bf215546Sopenharmony_ci ast_fully_specified_type *type, 4518bf215546Sopenharmony_ci exec_list *initializer_instructions, 4519bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 4520bf215546Sopenharmony_ci{ 4521bf215546Sopenharmony_ci void *mem_ctx = state; 4522bf215546Sopenharmony_ci ir_rvalue *result = NULL; 4523bf215546Sopenharmony_ci 4524bf215546Sopenharmony_ci YYLTYPE initializer_loc = decl->initializer->get_location(); 4525bf215546Sopenharmony_ci 4526bf215546Sopenharmony_ci /* From page 24 (page 30 of the PDF) of the GLSL 1.10 spec: 4527bf215546Sopenharmony_ci * 4528bf215546Sopenharmony_ci * "All uniform variables are read-only and are initialized either 4529bf215546Sopenharmony_ci * directly by an application via API commands, or indirectly by 4530bf215546Sopenharmony_ci * OpenGL." 4531bf215546Sopenharmony_ci */ 4532bf215546Sopenharmony_ci if (var->data.mode == ir_var_uniform) { 4533bf215546Sopenharmony_ci state->check_version(120, 0, &initializer_loc, 4534bf215546Sopenharmony_ci "cannot initialize uniform %s", 4535bf215546Sopenharmony_ci var->name); 4536bf215546Sopenharmony_ci } 4537bf215546Sopenharmony_ci 4538bf215546Sopenharmony_ci /* Section 4.3.7 "Buffer Variables" of the GLSL 4.30 spec: 4539bf215546Sopenharmony_ci * 4540bf215546Sopenharmony_ci * "Buffer variables cannot have initializers." 4541bf215546Sopenharmony_ci */ 4542bf215546Sopenharmony_ci if (var->data.mode == ir_var_shader_storage) { 4543bf215546Sopenharmony_ci _mesa_glsl_error(&initializer_loc, state, 4544bf215546Sopenharmony_ci "cannot initialize buffer variable %s", 4545bf215546Sopenharmony_ci var->name); 4546bf215546Sopenharmony_ci } 4547bf215546Sopenharmony_ci 4548bf215546Sopenharmony_ci /* From section 4.1.7 of the GLSL 4.40 spec: 4549bf215546Sopenharmony_ci * 4550bf215546Sopenharmony_ci * "Opaque variables [...] are initialized only through the 4551bf215546Sopenharmony_ci * OpenGL API; they cannot be declared with an initializer in a 4552bf215546Sopenharmony_ci * shader." 4553bf215546Sopenharmony_ci * 4554bf215546Sopenharmony_ci * From section 4.1.7 of the ARB_bindless_texture spec: 4555bf215546Sopenharmony_ci * 4556bf215546Sopenharmony_ci * "Samplers may be declared as shader inputs and outputs, as uniform 4557bf215546Sopenharmony_ci * variables, as temporary variables, and as function parameters." 4558bf215546Sopenharmony_ci * 4559bf215546Sopenharmony_ci * From section 4.1.X of the ARB_bindless_texture spec: 4560bf215546Sopenharmony_ci * 4561bf215546Sopenharmony_ci * "Images may be declared as shader inputs and outputs, as uniform 4562bf215546Sopenharmony_ci * variables, as temporary variables, and as function parameters." 4563bf215546Sopenharmony_ci */ 4564bf215546Sopenharmony_ci if (var->type->contains_atomic() || 4565bf215546Sopenharmony_ci (!state->has_bindless() && var->type->contains_opaque())) { 4566bf215546Sopenharmony_ci _mesa_glsl_error(&initializer_loc, state, 4567bf215546Sopenharmony_ci "cannot initialize %s variable %s", 4568bf215546Sopenharmony_ci var->name, state->has_bindless() ? "atomic" : "opaque"); 4569bf215546Sopenharmony_ci } 4570bf215546Sopenharmony_ci 4571bf215546Sopenharmony_ci if ((var->data.mode == ir_var_shader_in) && (state->current_function == NULL)) { 4572bf215546Sopenharmony_ci _mesa_glsl_error(&initializer_loc, state, 4573bf215546Sopenharmony_ci "cannot initialize %s shader input / %s %s", 4574bf215546Sopenharmony_ci _mesa_shader_stage_to_string(state->stage), 4575bf215546Sopenharmony_ci (state->stage == MESA_SHADER_VERTEX) 4576bf215546Sopenharmony_ci ? "attribute" : "varying", 4577bf215546Sopenharmony_ci var->name); 4578bf215546Sopenharmony_ci } 4579bf215546Sopenharmony_ci 4580bf215546Sopenharmony_ci if (var->data.mode == ir_var_shader_out && state->current_function == NULL) { 4581bf215546Sopenharmony_ci _mesa_glsl_error(&initializer_loc, state, 4582bf215546Sopenharmony_ci "cannot initialize %s shader output %s", 4583bf215546Sopenharmony_ci _mesa_shader_stage_to_string(state->stage), 4584bf215546Sopenharmony_ci var->name); 4585bf215546Sopenharmony_ci } 4586bf215546Sopenharmony_ci 4587bf215546Sopenharmony_ci /* If the initializer is an ast_aggregate_initializer, recursively store 4588bf215546Sopenharmony_ci * type information from the LHS into it, so that its hir() function can do 4589bf215546Sopenharmony_ci * type checking. 4590bf215546Sopenharmony_ci */ 4591bf215546Sopenharmony_ci if (decl->initializer->oper == ast_aggregate) 4592bf215546Sopenharmony_ci _mesa_ast_set_aggregate_type(var->type, decl->initializer); 4593bf215546Sopenharmony_ci 4594bf215546Sopenharmony_ci ir_dereference *const lhs = new(state) ir_dereference_variable(var); 4595bf215546Sopenharmony_ci ir_rvalue *rhs = decl->initializer->hir(initializer_instructions, state); 4596bf215546Sopenharmony_ci 4597bf215546Sopenharmony_ci /* Calculate the constant value if this is a const or uniform 4598bf215546Sopenharmony_ci * declaration. 4599bf215546Sopenharmony_ci * 4600bf215546Sopenharmony_ci * Section 4.3 (Storage Qualifiers) of the GLSL ES 1.00.17 spec says: 4601bf215546Sopenharmony_ci * 4602bf215546Sopenharmony_ci * "Declarations of globals without a storage qualifier, or with 4603bf215546Sopenharmony_ci * just the const qualifier, may include initializers, in which case 4604bf215546Sopenharmony_ci * they will be initialized before the first line of main() is 4605bf215546Sopenharmony_ci * executed. Such initializers must be a constant expression." 4606bf215546Sopenharmony_ci * 4607bf215546Sopenharmony_ci * The same section of the GLSL ES 3.00.4 spec has similar language. 4608bf215546Sopenharmony_ci */ 4609bf215546Sopenharmony_ci if (type->qualifier.flags.q.constant 4610bf215546Sopenharmony_ci || type->qualifier.flags.q.uniform 4611bf215546Sopenharmony_ci || (state->es_shader && state->current_function == NULL)) { 4612bf215546Sopenharmony_ci ir_rvalue *new_rhs = validate_assignment(state, initializer_loc, 4613bf215546Sopenharmony_ci lhs, rhs, true); 4614bf215546Sopenharmony_ci if (new_rhs != NULL) { 4615bf215546Sopenharmony_ci rhs = new_rhs; 4616bf215546Sopenharmony_ci 4617bf215546Sopenharmony_ci /* Section 4.3.3 (Constant Expressions) of the GLSL ES 3.00.4 spec 4618bf215546Sopenharmony_ci * says: 4619bf215546Sopenharmony_ci * 4620bf215546Sopenharmony_ci * "A constant expression is one of 4621bf215546Sopenharmony_ci * 4622bf215546Sopenharmony_ci * ... 4623bf215546Sopenharmony_ci * 4624bf215546Sopenharmony_ci * - an expression formed by an operator on operands that are 4625bf215546Sopenharmony_ci * all constant expressions, including getting an element of 4626bf215546Sopenharmony_ci * a constant array, or a field of a constant structure, or 4627bf215546Sopenharmony_ci * components of a constant vector. However, the sequence 4628bf215546Sopenharmony_ci * operator ( , ) and the assignment operators ( =, +=, ...) 4629bf215546Sopenharmony_ci * are not included in the operators that can create a 4630bf215546Sopenharmony_ci * constant expression." 4631bf215546Sopenharmony_ci * 4632bf215546Sopenharmony_ci * Section 12.43 (Sequence operator and constant expressions) says: 4633bf215546Sopenharmony_ci * 4634bf215546Sopenharmony_ci * "Should the following construct be allowed? 4635bf215546Sopenharmony_ci * 4636bf215546Sopenharmony_ci * float a[2,3]; 4637bf215546Sopenharmony_ci * 4638bf215546Sopenharmony_ci * The expression within the brackets uses the sequence operator 4639bf215546Sopenharmony_ci * (',') and returns the integer 3 so the construct is declaring 4640bf215546Sopenharmony_ci * a single-dimensional array of size 3. In some languages, the 4641bf215546Sopenharmony_ci * construct declares a two-dimensional array. It would be 4642bf215546Sopenharmony_ci * preferable to make this construct illegal to avoid confusion. 4643bf215546Sopenharmony_ci * 4644bf215546Sopenharmony_ci * One possibility is to change the definition of the sequence 4645bf215546Sopenharmony_ci * operator so that it does not return a constant-expression and 4646bf215546Sopenharmony_ci * hence cannot be used to declare an array size. 4647bf215546Sopenharmony_ci * 4648bf215546Sopenharmony_ci * RESOLUTION: The result of a sequence operator is not a 4649bf215546Sopenharmony_ci * constant-expression." 4650bf215546Sopenharmony_ci * 4651bf215546Sopenharmony_ci * Section 4.3.3 (Constant Expressions) of the GLSL 4.30.9 spec 4652bf215546Sopenharmony_ci * contains language almost identical to the section 4.3.3 in the 4653bf215546Sopenharmony_ci * GLSL ES 3.00.4 spec. This is a new limitation for these GLSL 4654bf215546Sopenharmony_ci * versions. 4655bf215546Sopenharmony_ci */ 4656bf215546Sopenharmony_ci ir_constant *constant_value = 4657bf215546Sopenharmony_ci rhs->constant_expression_value(mem_ctx); 4658bf215546Sopenharmony_ci 4659bf215546Sopenharmony_ci if (!constant_value || 4660bf215546Sopenharmony_ci (state->is_version(430, 300) && 4661bf215546Sopenharmony_ci decl->initializer->has_sequence_subexpression())) { 4662bf215546Sopenharmony_ci const char *const variable_mode = 4663bf215546Sopenharmony_ci (type->qualifier.flags.q.constant) 4664bf215546Sopenharmony_ci ? "const" 4665bf215546Sopenharmony_ci : ((type->qualifier.flags.q.uniform) ? "uniform" : "global"); 4666bf215546Sopenharmony_ci 4667bf215546Sopenharmony_ci /* If ARB_shading_language_420pack is enabled, initializers of 4668bf215546Sopenharmony_ci * const-qualified local variables do not have to be constant 4669bf215546Sopenharmony_ci * expressions. Const-qualified global variables must still be 4670bf215546Sopenharmony_ci * initialized with constant expressions. 4671bf215546Sopenharmony_ci */ 4672bf215546Sopenharmony_ci if (!state->has_420pack() 4673bf215546Sopenharmony_ci || state->current_function == NULL) { 4674bf215546Sopenharmony_ci _mesa_glsl_error(& initializer_loc, state, 4675bf215546Sopenharmony_ci "initializer of %s variable `%s' must be a " 4676bf215546Sopenharmony_ci "constant expression", 4677bf215546Sopenharmony_ci variable_mode, 4678bf215546Sopenharmony_ci decl->identifier); 4679bf215546Sopenharmony_ci if (var->type->is_numeric()) { 4680bf215546Sopenharmony_ci /* Reduce cascading errors. */ 4681bf215546Sopenharmony_ci var->constant_value = type->qualifier.flags.q.constant 4682bf215546Sopenharmony_ci ? ir_constant::zero(state, var->type) : NULL; 4683bf215546Sopenharmony_ci } 4684bf215546Sopenharmony_ci } 4685bf215546Sopenharmony_ci } else { 4686bf215546Sopenharmony_ci rhs = constant_value; 4687bf215546Sopenharmony_ci var->constant_value = type->qualifier.flags.q.constant 4688bf215546Sopenharmony_ci ? constant_value : NULL; 4689bf215546Sopenharmony_ci } 4690bf215546Sopenharmony_ci } else { 4691bf215546Sopenharmony_ci if (var->type->is_numeric()) { 4692bf215546Sopenharmony_ci /* Reduce cascading errors. */ 4693bf215546Sopenharmony_ci rhs = var->constant_value = type->qualifier.flags.q.constant 4694bf215546Sopenharmony_ci ? ir_constant::zero(state, var->type) : NULL; 4695bf215546Sopenharmony_ci } 4696bf215546Sopenharmony_ci } 4697bf215546Sopenharmony_ci } 4698bf215546Sopenharmony_ci 4699bf215546Sopenharmony_ci if (rhs && !rhs->type->is_error()) { 4700bf215546Sopenharmony_ci bool temp = var->data.read_only; 4701bf215546Sopenharmony_ci if (type->qualifier.flags.q.constant) 4702bf215546Sopenharmony_ci var->data.read_only = false; 4703bf215546Sopenharmony_ci 4704bf215546Sopenharmony_ci /* Never emit code to initialize a uniform. 4705bf215546Sopenharmony_ci */ 4706bf215546Sopenharmony_ci const glsl_type *initializer_type; 4707bf215546Sopenharmony_ci bool error_emitted = false; 4708bf215546Sopenharmony_ci if (!type->qualifier.flags.q.uniform) { 4709bf215546Sopenharmony_ci error_emitted = 4710bf215546Sopenharmony_ci do_assignment(initializer_instructions, state, 4711bf215546Sopenharmony_ci NULL, lhs, rhs, 4712bf215546Sopenharmony_ci &result, true, true, 4713bf215546Sopenharmony_ci type->get_location()); 4714bf215546Sopenharmony_ci initializer_type = result->type; 4715bf215546Sopenharmony_ci } else 4716bf215546Sopenharmony_ci initializer_type = rhs->type; 4717bf215546Sopenharmony_ci 4718bf215546Sopenharmony_ci if (!error_emitted) { 4719bf215546Sopenharmony_ci var->constant_initializer = rhs->constant_expression_value(mem_ctx); 4720bf215546Sopenharmony_ci var->data.has_initializer = true; 4721bf215546Sopenharmony_ci var->data.is_implicit_initializer = false; 4722bf215546Sopenharmony_ci 4723bf215546Sopenharmony_ci /* If the declared variable is an unsized array, it must inherrit 4724bf215546Sopenharmony_ci * its full type from the initializer. A declaration such as 4725bf215546Sopenharmony_ci * 4726bf215546Sopenharmony_ci * uniform float a[] = float[](1.0, 2.0, 3.0, 3.0); 4727bf215546Sopenharmony_ci * 4728bf215546Sopenharmony_ci * becomes 4729bf215546Sopenharmony_ci * 4730bf215546Sopenharmony_ci * uniform float a[4] = float[](1.0, 2.0, 3.0, 3.0); 4731bf215546Sopenharmony_ci * 4732bf215546Sopenharmony_ci * The assignment generated in the if-statement (below) will also 4733bf215546Sopenharmony_ci * automatically handle this case for non-uniforms. 4734bf215546Sopenharmony_ci * 4735bf215546Sopenharmony_ci * If the declared variable is not an array, the types must 4736bf215546Sopenharmony_ci * already match exactly. As a result, the type assignment 4737bf215546Sopenharmony_ci * here can be done unconditionally. For non-uniforms the call 4738bf215546Sopenharmony_ci * to do_assignment can change the type of the initializer (via 4739bf215546Sopenharmony_ci * the implicit conversion rules). For uniforms the initializer 4740bf215546Sopenharmony_ci * must be a constant expression, and the type of that expression 4741bf215546Sopenharmony_ci * was validated above. 4742bf215546Sopenharmony_ci */ 4743bf215546Sopenharmony_ci var->type = initializer_type; 4744bf215546Sopenharmony_ci } 4745bf215546Sopenharmony_ci 4746bf215546Sopenharmony_ci var->data.read_only = temp; 4747bf215546Sopenharmony_ci } 4748bf215546Sopenharmony_ci 4749bf215546Sopenharmony_ci return result; 4750bf215546Sopenharmony_ci} 4751bf215546Sopenharmony_ci 4752bf215546Sopenharmony_cistatic void 4753bf215546Sopenharmony_civalidate_layout_qualifier_vertex_count(struct _mesa_glsl_parse_state *state, 4754bf215546Sopenharmony_ci YYLTYPE loc, ir_variable *var, 4755bf215546Sopenharmony_ci unsigned num_vertices, 4756bf215546Sopenharmony_ci unsigned *size, 4757bf215546Sopenharmony_ci const char *var_category) 4758bf215546Sopenharmony_ci{ 4759bf215546Sopenharmony_ci if (var->type->is_unsized_array()) { 4760bf215546Sopenharmony_ci /* Section 4.3.8.1 (Input Layout Qualifiers) of the GLSL 1.50 spec says: 4761bf215546Sopenharmony_ci * 4762bf215546Sopenharmony_ci * All geometry shader input unsized array declarations will be 4763bf215546Sopenharmony_ci * sized by an earlier input layout qualifier, when present, as per 4764bf215546Sopenharmony_ci * the following table. 4765bf215546Sopenharmony_ci * 4766bf215546Sopenharmony_ci * Followed by a table mapping each allowed input layout qualifier to 4767bf215546Sopenharmony_ci * the corresponding input length. 4768bf215546Sopenharmony_ci * 4769bf215546Sopenharmony_ci * Similarly for tessellation control shader outputs. 4770bf215546Sopenharmony_ci */ 4771bf215546Sopenharmony_ci if (num_vertices != 0) 4772bf215546Sopenharmony_ci var->type = glsl_type::get_array_instance(var->type->fields.array, 4773bf215546Sopenharmony_ci num_vertices); 4774bf215546Sopenharmony_ci } else { 4775bf215546Sopenharmony_ci /* Section 4.3.8.1 (Input Layout Qualifiers) of the GLSL 1.50 spec 4776bf215546Sopenharmony_ci * includes the following examples of compile-time errors: 4777bf215546Sopenharmony_ci * 4778bf215546Sopenharmony_ci * // code sequence within one shader... 4779bf215546Sopenharmony_ci * in vec4 Color1[]; // size unknown 4780bf215546Sopenharmony_ci * ...Color1.length()...// illegal, length() unknown 4781bf215546Sopenharmony_ci * in vec4 Color2[2]; // size is 2 4782bf215546Sopenharmony_ci * ...Color1.length()...// illegal, Color1 still has no size 4783bf215546Sopenharmony_ci * in vec4 Color3[3]; // illegal, input sizes are inconsistent 4784bf215546Sopenharmony_ci * layout(lines) in; // legal, input size is 2, matching 4785bf215546Sopenharmony_ci * in vec4 Color4[3]; // illegal, contradicts layout 4786bf215546Sopenharmony_ci * ... 4787bf215546Sopenharmony_ci * 4788bf215546Sopenharmony_ci * To detect the case illustrated by Color3, we verify that the size of 4789bf215546Sopenharmony_ci * an explicitly-sized array matches the size of any previously declared 4790bf215546Sopenharmony_ci * explicitly-sized array. To detect the case illustrated by Color4, we 4791bf215546Sopenharmony_ci * verify that the size of an explicitly-sized array is consistent with 4792bf215546Sopenharmony_ci * any previously declared input layout. 4793bf215546Sopenharmony_ci */ 4794bf215546Sopenharmony_ci if (num_vertices != 0 && var->type->length != num_vertices) { 4795bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 4796bf215546Sopenharmony_ci "%s size contradicts previously declared layout " 4797bf215546Sopenharmony_ci "(size is %u, but layout requires a size of %u)", 4798bf215546Sopenharmony_ci var_category, var->type->length, num_vertices); 4799bf215546Sopenharmony_ci } else if (*size != 0 && var->type->length != *size) { 4800bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 4801bf215546Sopenharmony_ci "%s sizes are inconsistent (size is %u, but a " 4802bf215546Sopenharmony_ci "previous declaration has size %u)", 4803bf215546Sopenharmony_ci var_category, var->type->length, *size); 4804bf215546Sopenharmony_ci } else { 4805bf215546Sopenharmony_ci *size = var->type->length; 4806bf215546Sopenharmony_ci } 4807bf215546Sopenharmony_ci } 4808bf215546Sopenharmony_ci} 4809bf215546Sopenharmony_ci 4810bf215546Sopenharmony_cistatic void 4811bf215546Sopenharmony_cihandle_tess_ctrl_shader_output_decl(struct _mesa_glsl_parse_state *state, 4812bf215546Sopenharmony_ci YYLTYPE loc, ir_variable *var) 4813bf215546Sopenharmony_ci{ 4814bf215546Sopenharmony_ci unsigned num_vertices = 0; 4815bf215546Sopenharmony_ci 4816bf215546Sopenharmony_ci if (state->tcs_output_vertices_specified) { 4817bf215546Sopenharmony_ci if (!state->out_qualifier->vertices-> 4818bf215546Sopenharmony_ci process_qualifier_constant(state, "vertices", 4819bf215546Sopenharmony_ci &num_vertices, false)) { 4820bf215546Sopenharmony_ci return; 4821bf215546Sopenharmony_ci } 4822bf215546Sopenharmony_ci 4823bf215546Sopenharmony_ci if (num_vertices > state->Const.MaxPatchVertices) { 4824bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "vertices (%d) exceeds " 4825bf215546Sopenharmony_ci "GL_MAX_PATCH_VERTICES", num_vertices); 4826bf215546Sopenharmony_ci return; 4827bf215546Sopenharmony_ci } 4828bf215546Sopenharmony_ci } 4829bf215546Sopenharmony_ci 4830bf215546Sopenharmony_ci if (!var->type->is_array() && !var->data.patch) { 4831bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 4832bf215546Sopenharmony_ci "tessellation control shader outputs must be arrays"); 4833bf215546Sopenharmony_ci 4834bf215546Sopenharmony_ci /* To avoid cascading failures, short circuit the checks below. */ 4835bf215546Sopenharmony_ci return; 4836bf215546Sopenharmony_ci } 4837bf215546Sopenharmony_ci 4838bf215546Sopenharmony_ci if (var->data.patch) 4839bf215546Sopenharmony_ci return; 4840bf215546Sopenharmony_ci 4841bf215546Sopenharmony_ci validate_layout_qualifier_vertex_count(state, loc, var, num_vertices, 4842bf215546Sopenharmony_ci &state->tcs_output_size, 4843bf215546Sopenharmony_ci "tessellation control shader output"); 4844bf215546Sopenharmony_ci} 4845bf215546Sopenharmony_ci 4846bf215546Sopenharmony_ci/** 4847bf215546Sopenharmony_ci * Do additional processing necessary for tessellation control/evaluation shader 4848bf215546Sopenharmony_ci * input declarations. This covers both interface block arrays and bare input 4849bf215546Sopenharmony_ci * variables. 4850bf215546Sopenharmony_ci */ 4851bf215546Sopenharmony_cistatic void 4852bf215546Sopenharmony_cihandle_tess_shader_input_decl(struct _mesa_glsl_parse_state *state, 4853bf215546Sopenharmony_ci YYLTYPE loc, ir_variable *var) 4854bf215546Sopenharmony_ci{ 4855bf215546Sopenharmony_ci if (!var->type->is_array() && !var->data.patch) { 4856bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 4857bf215546Sopenharmony_ci "per-vertex tessellation shader inputs must be arrays"); 4858bf215546Sopenharmony_ci /* Avoid cascading failures. */ 4859bf215546Sopenharmony_ci return; 4860bf215546Sopenharmony_ci } 4861bf215546Sopenharmony_ci 4862bf215546Sopenharmony_ci if (var->data.patch) 4863bf215546Sopenharmony_ci return; 4864bf215546Sopenharmony_ci 4865bf215546Sopenharmony_ci /* The ARB_tessellation_shader spec says: 4866bf215546Sopenharmony_ci * 4867bf215546Sopenharmony_ci * "Declaring an array size is optional. If no size is specified, it 4868bf215546Sopenharmony_ci * will be taken from the implementation-dependent maximum patch size 4869bf215546Sopenharmony_ci * (gl_MaxPatchVertices). If a size is specified, it must match the 4870bf215546Sopenharmony_ci * maximum patch size; otherwise, a compile or link error will occur." 4871bf215546Sopenharmony_ci * 4872bf215546Sopenharmony_ci * This text appears twice, once for TCS inputs, and again for TES inputs. 4873bf215546Sopenharmony_ci */ 4874bf215546Sopenharmony_ci if (var->type->is_unsized_array()) { 4875bf215546Sopenharmony_ci var->type = glsl_type::get_array_instance(var->type->fields.array, 4876bf215546Sopenharmony_ci state->Const.MaxPatchVertices); 4877bf215546Sopenharmony_ci } else if (var->type->length != state->Const.MaxPatchVertices) { 4878bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 4879bf215546Sopenharmony_ci "per-vertex tessellation shader input arrays must be " 4880bf215546Sopenharmony_ci "sized to gl_MaxPatchVertices (%d).", 4881bf215546Sopenharmony_ci state->Const.MaxPatchVertices); 4882bf215546Sopenharmony_ci } 4883bf215546Sopenharmony_ci} 4884bf215546Sopenharmony_ci 4885bf215546Sopenharmony_ci 4886bf215546Sopenharmony_ci/** 4887bf215546Sopenharmony_ci * Do additional processing necessary for geometry shader input declarations 4888bf215546Sopenharmony_ci * (this covers both interface blocks arrays and bare input variables). 4889bf215546Sopenharmony_ci */ 4890bf215546Sopenharmony_cistatic void 4891bf215546Sopenharmony_cihandle_geometry_shader_input_decl(struct _mesa_glsl_parse_state *state, 4892bf215546Sopenharmony_ci YYLTYPE loc, ir_variable *var) 4893bf215546Sopenharmony_ci{ 4894bf215546Sopenharmony_ci unsigned num_vertices = 0; 4895bf215546Sopenharmony_ci 4896bf215546Sopenharmony_ci if (state->gs_input_prim_type_specified) { 4897bf215546Sopenharmony_ci num_vertices = vertices_per_prim(state->in_qualifier->prim_type); 4898bf215546Sopenharmony_ci } 4899bf215546Sopenharmony_ci 4900bf215546Sopenharmony_ci /* Geometry shader input variables must be arrays. Caller should have 4901bf215546Sopenharmony_ci * reported an error for this. 4902bf215546Sopenharmony_ci */ 4903bf215546Sopenharmony_ci if (!var->type->is_array()) { 4904bf215546Sopenharmony_ci assert(state->error); 4905bf215546Sopenharmony_ci 4906bf215546Sopenharmony_ci /* To avoid cascading failures, short circuit the checks below. */ 4907bf215546Sopenharmony_ci return; 4908bf215546Sopenharmony_ci } 4909bf215546Sopenharmony_ci 4910bf215546Sopenharmony_ci validate_layout_qualifier_vertex_count(state, loc, var, num_vertices, 4911bf215546Sopenharmony_ci &state->gs_input_size, 4912bf215546Sopenharmony_ci "geometry shader input"); 4913bf215546Sopenharmony_ci} 4914bf215546Sopenharmony_ci 4915bf215546Sopenharmony_cistatic void 4916bf215546Sopenharmony_civalidate_identifier(const char *identifier, YYLTYPE loc, 4917bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 4918bf215546Sopenharmony_ci{ 4919bf215546Sopenharmony_ci /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec, 4920bf215546Sopenharmony_ci * 4921bf215546Sopenharmony_ci * "Identifiers starting with "gl_" are reserved for use by 4922bf215546Sopenharmony_ci * OpenGL, and may not be declared in a shader as either a 4923bf215546Sopenharmony_ci * variable or a function." 4924bf215546Sopenharmony_ci */ 4925bf215546Sopenharmony_ci if (is_gl_identifier(identifier)) { 4926bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 4927bf215546Sopenharmony_ci "identifier `%s' uses reserved `gl_' prefix", 4928bf215546Sopenharmony_ci identifier); 4929bf215546Sopenharmony_ci } else if (strstr(identifier, "__")) { 4930bf215546Sopenharmony_ci /* From page 14 (page 20 of the PDF) of the GLSL 1.10 4931bf215546Sopenharmony_ci * spec: 4932bf215546Sopenharmony_ci * 4933bf215546Sopenharmony_ci * "In addition, all identifiers containing two 4934bf215546Sopenharmony_ci * consecutive underscores (__) are reserved as 4935bf215546Sopenharmony_ci * possible future keywords." 4936bf215546Sopenharmony_ci * 4937bf215546Sopenharmony_ci * The intention is that names containing __ are reserved for internal 4938bf215546Sopenharmony_ci * use by the implementation, and names prefixed with GL_ are reserved 4939bf215546Sopenharmony_ci * for use by Khronos. Names simply containing __ are dangerous to use, 4940bf215546Sopenharmony_ci * but should be allowed. 4941bf215546Sopenharmony_ci * 4942bf215546Sopenharmony_ci * A future version of the GLSL specification will clarify this. 4943bf215546Sopenharmony_ci */ 4944bf215546Sopenharmony_ci _mesa_glsl_warning(&loc, state, 4945bf215546Sopenharmony_ci "identifier `%s' uses reserved `__' string", 4946bf215546Sopenharmony_ci identifier); 4947bf215546Sopenharmony_ci } 4948bf215546Sopenharmony_ci} 4949bf215546Sopenharmony_ci 4950bf215546Sopenharmony_ciir_rvalue * 4951bf215546Sopenharmony_ciast_declarator_list::hir(exec_list *instructions, 4952bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 4953bf215546Sopenharmony_ci{ 4954bf215546Sopenharmony_ci void *ctx = state; 4955bf215546Sopenharmony_ci const struct glsl_type *decl_type; 4956bf215546Sopenharmony_ci const char *type_name = NULL; 4957bf215546Sopenharmony_ci ir_rvalue *result = NULL; 4958bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 4959bf215546Sopenharmony_ci 4960bf215546Sopenharmony_ci /* From page 46 (page 52 of the PDF) of the GLSL 1.50 spec: 4961bf215546Sopenharmony_ci * 4962bf215546Sopenharmony_ci * "To ensure that a particular output variable is invariant, it is 4963bf215546Sopenharmony_ci * necessary to use the invariant qualifier. It can either be used to 4964bf215546Sopenharmony_ci * qualify a previously declared variable as being invariant 4965bf215546Sopenharmony_ci * 4966bf215546Sopenharmony_ci * invariant gl_Position; // make existing gl_Position be invariant" 4967bf215546Sopenharmony_ci * 4968bf215546Sopenharmony_ci * In these cases the parser will set the 'invariant' flag in the declarator 4969bf215546Sopenharmony_ci * list, and the type will be NULL. 4970bf215546Sopenharmony_ci */ 4971bf215546Sopenharmony_ci if (this->invariant) { 4972bf215546Sopenharmony_ci assert(this->type == NULL); 4973bf215546Sopenharmony_ci 4974bf215546Sopenharmony_ci if (state->current_function != NULL) { 4975bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 4976bf215546Sopenharmony_ci "all uses of `invariant' keyword must be at global " 4977bf215546Sopenharmony_ci "scope"); 4978bf215546Sopenharmony_ci } 4979bf215546Sopenharmony_ci 4980bf215546Sopenharmony_ci foreach_list_typed (ast_declaration, decl, link, &this->declarations) { 4981bf215546Sopenharmony_ci assert(decl->array_specifier == NULL); 4982bf215546Sopenharmony_ci assert(decl->initializer == NULL); 4983bf215546Sopenharmony_ci 4984bf215546Sopenharmony_ci ir_variable *const earlier = 4985bf215546Sopenharmony_ci state->symbols->get_variable(decl->identifier); 4986bf215546Sopenharmony_ci if (earlier == NULL) { 4987bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 4988bf215546Sopenharmony_ci "undeclared variable `%s' cannot be marked " 4989bf215546Sopenharmony_ci "invariant", decl->identifier); 4990bf215546Sopenharmony_ci } else if (!is_allowed_invariant(earlier, state)) { 4991bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 4992bf215546Sopenharmony_ci "`%s' cannot be marked invariant; interfaces between " 4993bf215546Sopenharmony_ci "shader stages only.", decl->identifier); 4994bf215546Sopenharmony_ci } else if (earlier->data.used) { 4995bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 4996bf215546Sopenharmony_ci "variable `%s' may not be redeclared " 4997bf215546Sopenharmony_ci "`invariant' after being used", 4998bf215546Sopenharmony_ci earlier->name); 4999bf215546Sopenharmony_ci } else { 5000bf215546Sopenharmony_ci earlier->data.explicit_invariant = true; 5001bf215546Sopenharmony_ci earlier->data.invariant = true; 5002bf215546Sopenharmony_ci } 5003bf215546Sopenharmony_ci } 5004bf215546Sopenharmony_ci 5005bf215546Sopenharmony_ci /* Invariant redeclarations do not have r-values. 5006bf215546Sopenharmony_ci */ 5007bf215546Sopenharmony_ci return NULL; 5008bf215546Sopenharmony_ci } 5009bf215546Sopenharmony_ci 5010bf215546Sopenharmony_ci if (this->precise) { 5011bf215546Sopenharmony_ci assert(this->type == NULL); 5012bf215546Sopenharmony_ci 5013bf215546Sopenharmony_ci foreach_list_typed (ast_declaration, decl, link, &this->declarations) { 5014bf215546Sopenharmony_ci assert(decl->array_specifier == NULL); 5015bf215546Sopenharmony_ci assert(decl->initializer == NULL); 5016bf215546Sopenharmony_ci 5017bf215546Sopenharmony_ci ir_variable *const earlier = 5018bf215546Sopenharmony_ci state->symbols->get_variable(decl->identifier); 5019bf215546Sopenharmony_ci if (earlier == NULL) { 5020bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5021bf215546Sopenharmony_ci "undeclared variable `%s' cannot be marked " 5022bf215546Sopenharmony_ci "precise", decl->identifier); 5023bf215546Sopenharmony_ci } else if (state->current_function != NULL && 5024bf215546Sopenharmony_ci !state->symbols->name_declared_this_scope(decl->identifier)) { 5025bf215546Sopenharmony_ci /* Note: we have to check if we're in a function, since 5026bf215546Sopenharmony_ci * builtins are treated as having come from another scope. 5027bf215546Sopenharmony_ci */ 5028bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5029bf215546Sopenharmony_ci "variable `%s' from an outer scope may not be " 5030bf215546Sopenharmony_ci "redeclared `precise' in this scope", 5031bf215546Sopenharmony_ci earlier->name); 5032bf215546Sopenharmony_ci } else if (earlier->data.used) { 5033bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5034bf215546Sopenharmony_ci "variable `%s' may not be redeclared " 5035bf215546Sopenharmony_ci "`precise' after being used", 5036bf215546Sopenharmony_ci earlier->name); 5037bf215546Sopenharmony_ci } else { 5038bf215546Sopenharmony_ci earlier->data.precise = true; 5039bf215546Sopenharmony_ci } 5040bf215546Sopenharmony_ci } 5041bf215546Sopenharmony_ci 5042bf215546Sopenharmony_ci /* Precise redeclarations do not have r-values either. */ 5043bf215546Sopenharmony_ci return NULL; 5044bf215546Sopenharmony_ci } 5045bf215546Sopenharmony_ci 5046bf215546Sopenharmony_ci assert(this->type != NULL); 5047bf215546Sopenharmony_ci assert(!this->invariant); 5048bf215546Sopenharmony_ci assert(!this->precise); 5049bf215546Sopenharmony_ci 5050bf215546Sopenharmony_ci /* GL_EXT_shader_image_load_store base type uses GLSL_TYPE_VOID as a special value to 5051bf215546Sopenharmony_ci * indicate that it needs to be updated later (see glsl_parser.yy). 5052bf215546Sopenharmony_ci * This is done here, based on the layout qualifier and the type of the image var 5053bf215546Sopenharmony_ci */ 5054bf215546Sopenharmony_ci if (this->type->qualifier.flags.q.explicit_image_format && 5055bf215546Sopenharmony_ci this->type->specifier->type->is_image() && 5056bf215546Sopenharmony_ci this->type->qualifier.image_base_type == GLSL_TYPE_VOID) { 5057bf215546Sopenharmony_ci /* "The ARB_shader_image_load_store says: 5058bf215546Sopenharmony_ci * If both extensions are enabled in the shading language, the "size*" layout 5059bf215546Sopenharmony_ci * qualifiers are treated as format qualifiers, and are mapped to equivalent 5060bf215546Sopenharmony_ci * format qualifiers in the table below, according to the type of image 5061bf215546Sopenharmony_ci * variable. 5062bf215546Sopenharmony_ci * image* iimage* uimage* 5063bf215546Sopenharmony_ci * -------- -------- -------- 5064bf215546Sopenharmony_ci * size1x8 n/a r8i r8ui 5065bf215546Sopenharmony_ci * size1x16 r16f r16i r16ui 5066bf215546Sopenharmony_ci * size1x32 r32f r32i r32ui 5067bf215546Sopenharmony_ci * size2x32 rg32f rg32i rg32ui 5068bf215546Sopenharmony_ci * size4x32 rgba32f rgba32i rgba32ui" 5069bf215546Sopenharmony_ci */ 5070bf215546Sopenharmony_ci if (strncmp(this->type->specifier->type_name, "image", strlen("image")) == 0) { 5071bf215546Sopenharmony_ci switch (this->type->qualifier.image_format) { 5072bf215546Sopenharmony_ci case PIPE_FORMAT_R8_SINT: 5073bf215546Sopenharmony_ci /* The GL_EXT_shader_image_load_store spec says: 5074bf215546Sopenharmony_ci * A layout of "size1x8" is illegal for image variables associated 5075bf215546Sopenharmony_ci * with floating-point data types. 5076bf215546Sopenharmony_ci */ 5077bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5078bf215546Sopenharmony_ci "size1x8 is illegal for image variables " 5079bf215546Sopenharmony_ci "with floating-point data types."); 5080bf215546Sopenharmony_ci return NULL; 5081bf215546Sopenharmony_ci case PIPE_FORMAT_R16_SINT: 5082bf215546Sopenharmony_ci this->type->qualifier.image_format = PIPE_FORMAT_R16_FLOAT; 5083bf215546Sopenharmony_ci break; 5084bf215546Sopenharmony_ci case PIPE_FORMAT_R32_SINT: 5085bf215546Sopenharmony_ci this->type->qualifier.image_format = PIPE_FORMAT_R32_FLOAT; 5086bf215546Sopenharmony_ci break; 5087bf215546Sopenharmony_ci case PIPE_FORMAT_R32G32_SINT: 5088bf215546Sopenharmony_ci this->type->qualifier.image_format = PIPE_FORMAT_R32G32_FLOAT; 5089bf215546Sopenharmony_ci break; 5090bf215546Sopenharmony_ci case PIPE_FORMAT_R32G32B32A32_SINT: 5091bf215546Sopenharmony_ci this->type->qualifier.image_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 5092bf215546Sopenharmony_ci break; 5093bf215546Sopenharmony_ci default: 5094bf215546Sopenharmony_ci unreachable("Unknown image format"); 5095bf215546Sopenharmony_ci } 5096bf215546Sopenharmony_ci this->type->qualifier.image_base_type = GLSL_TYPE_FLOAT; 5097bf215546Sopenharmony_ci } else if (strncmp(this->type->specifier->type_name, "uimage", strlen("uimage")) == 0) { 5098bf215546Sopenharmony_ci switch (this->type->qualifier.image_format) { 5099bf215546Sopenharmony_ci case PIPE_FORMAT_R8_SINT: 5100bf215546Sopenharmony_ci this->type->qualifier.image_format = PIPE_FORMAT_R8_UINT; 5101bf215546Sopenharmony_ci break; 5102bf215546Sopenharmony_ci case PIPE_FORMAT_R16_SINT: 5103bf215546Sopenharmony_ci this->type->qualifier.image_format = PIPE_FORMAT_R16_UINT; 5104bf215546Sopenharmony_ci break; 5105bf215546Sopenharmony_ci case PIPE_FORMAT_R32_SINT: 5106bf215546Sopenharmony_ci this->type->qualifier.image_format = PIPE_FORMAT_R32_UINT; 5107bf215546Sopenharmony_ci break; 5108bf215546Sopenharmony_ci case PIPE_FORMAT_R32G32_SINT: 5109bf215546Sopenharmony_ci this->type->qualifier.image_format = PIPE_FORMAT_R32G32_UINT; 5110bf215546Sopenharmony_ci break; 5111bf215546Sopenharmony_ci case PIPE_FORMAT_R32G32B32A32_SINT: 5112bf215546Sopenharmony_ci this->type->qualifier.image_format = PIPE_FORMAT_R32G32B32A32_UINT; 5113bf215546Sopenharmony_ci break; 5114bf215546Sopenharmony_ci default: 5115bf215546Sopenharmony_ci unreachable("Unknown image format"); 5116bf215546Sopenharmony_ci } 5117bf215546Sopenharmony_ci this->type->qualifier.image_base_type = GLSL_TYPE_UINT; 5118bf215546Sopenharmony_ci } else if (strncmp(this->type->specifier->type_name, "iimage", strlen("iimage")) == 0) { 5119bf215546Sopenharmony_ci this->type->qualifier.image_base_type = GLSL_TYPE_INT; 5120bf215546Sopenharmony_ci } else { 5121bf215546Sopenharmony_ci assert(false); 5122bf215546Sopenharmony_ci } 5123bf215546Sopenharmony_ci } 5124bf215546Sopenharmony_ci 5125bf215546Sopenharmony_ci /* The type specifier may contain a structure definition. Process that 5126bf215546Sopenharmony_ci * before any of the variable declarations. 5127bf215546Sopenharmony_ci */ 5128bf215546Sopenharmony_ci (void) this->type->specifier->hir(instructions, state); 5129bf215546Sopenharmony_ci 5130bf215546Sopenharmony_ci decl_type = this->type->glsl_type(& type_name, state); 5131bf215546Sopenharmony_ci 5132bf215546Sopenharmony_ci /* Section 4.3.7 "Buffer Variables" of the GLSL 4.30 spec: 5133bf215546Sopenharmony_ci * "Buffer variables may only be declared inside interface blocks 5134bf215546Sopenharmony_ci * (section 4.3.9 “Interface Blocks”), which are then referred to as 5135bf215546Sopenharmony_ci * shader storage blocks. It is a compile-time error to declare buffer 5136bf215546Sopenharmony_ci * variables at global scope (outside a block)." 5137bf215546Sopenharmony_ci */ 5138bf215546Sopenharmony_ci if (type->qualifier.flags.q.buffer && !decl_type->is_interface()) { 5139bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5140bf215546Sopenharmony_ci "buffer variables cannot be declared outside " 5141bf215546Sopenharmony_ci "interface blocks"); 5142bf215546Sopenharmony_ci } 5143bf215546Sopenharmony_ci 5144bf215546Sopenharmony_ci /* An offset-qualified atomic counter declaration sets the default 5145bf215546Sopenharmony_ci * offset for the next declaration within the same atomic counter 5146bf215546Sopenharmony_ci * buffer. 5147bf215546Sopenharmony_ci */ 5148bf215546Sopenharmony_ci if (decl_type && decl_type->contains_atomic()) { 5149bf215546Sopenharmony_ci if (type->qualifier.flags.q.explicit_binding && 5150bf215546Sopenharmony_ci type->qualifier.flags.q.explicit_offset) { 5151bf215546Sopenharmony_ci unsigned qual_binding; 5152bf215546Sopenharmony_ci unsigned qual_offset; 5153bf215546Sopenharmony_ci if (process_qualifier_constant(state, &loc, "binding", 5154bf215546Sopenharmony_ci type->qualifier.binding, 5155bf215546Sopenharmony_ci &qual_binding) 5156bf215546Sopenharmony_ci && process_qualifier_constant(state, &loc, "offset", 5157bf215546Sopenharmony_ci type->qualifier.offset, 5158bf215546Sopenharmony_ci &qual_offset)) { 5159bf215546Sopenharmony_ci if (qual_binding < ARRAY_SIZE(state->atomic_counter_offsets)) 5160bf215546Sopenharmony_ci state->atomic_counter_offsets[qual_binding] = qual_offset; 5161bf215546Sopenharmony_ci } 5162bf215546Sopenharmony_ci } 5163bf215546Sopenharmony_ci 5164bf215546Sopenharmony_ci ast_type_qualifier allowed_atomic_qual_mask; 5165bf215546Sopenharmony_ci allowed_atomic_qual_mask.flags.i = 0; 5166bf215546Sopenharmony_ci allowed_atomic_qual_mask.flags.q.explicit_binding = 1; 5167bf215546Sopenharmony_ci allowed_atomic_qual_mask.flags.q.explicit_offset = 1; 5168bf215546Sopenharmony_ci allowed_atomic_qual_mask.flags.q.uniform = 1; 5169bf215546Sopenharmony_ci 5170bf215546Sopenharmony_ci type->qualifier.validate_flags(&loc, state, allowed_atomic_qual_mask, 5171bf215546Sopenharmony_ci "invalid layout qualifier for", 5172bf215546Sopenharmony_ci "atomic_uint"); 5173bf215546Sopenharmony_ci } 5174bf215546Sopenharmony_ci 5175bf215546Sopenharmony_ci if (this->declarations.is_empty()) { 5176bf215546Sopenharmony_ci /* If there is no structure involved in the program text, there are two 5177bf215546Sopenharmony_ci * possible scenarios: 5178bf215546Sopenharmony_ci * 5179bf215546Sopenharmony_ci * - The program text contained something like 'vec4;'. This is an 5180bf215546Sopenharmony_ci * empty declaration. It is valid but weird. Emit a warning. 5181bf215546Sopenharmony_ci * 5182bf215546Sopenharmony_ci * - The program text contained something like 'S;' and 'S' is not the 5183bf215546Sopenharmony_ci * name of a known structure type. This is both invalid and weird. 5184bf215546Sopenharmony_ci * Emit an error. 5185bf215546Sopenharmony_ci * 5186bf215546Sopenharmony_ci * - The program text contained something like 'mediump float;' 5187bf215546Sopenharmony_ci * when the programmer probably meant 'precision mediump 5188bf215546Sopenharmony_ci * float;' Emit a warning with a description of what they 5189bf215546Sopenharmony_ci * probably meant to do. 5190bf215546Sopenharmony_ci * 5191bf215546Sopenharmony_ci * Note that if decl_type is NULL and there is a structure involved, 5192bf215546Sopenharmony_ci * there must have been some sort of error with the structure. In this 5193bf215546Sopenharmony_ci * case we assume that an error was already generated on this line of 5194bf215546Sopenharmony_ci * code for the structure. There is no need to generate an additional, 5195bf215546Sopenharmony_ci * confusing error. 5196bf215546Sopenharmony_ci */ 5197bf215546Sopenharmony_ci assert(this->type->specifier->structure == NULL || decl_type != NULL 5198bf215546Sopenharmony_ci || state->error); 5199bf215546Sopenharmony_ci 5200bf215546Sopenharmony_ci if (decl_type == NULL) { 5201bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5202bf215546Sopenharmony_ci "invalid type `%s' in empty declaration", 5203bf215546Sopenharmony_ci type_name); 5204bf215546Sopenharmony_ci } else { 5205bf215546Sopenharmony_ci if (decl_type->is_array()) { 5206bf215546Sopenharmony_ci /* From Section 13.22 (Array Declarations) of the GLSL ES 3.2 5207bf215546Sopenharmony_ci * spec: 5208bf215546Sopenharmony_ci * 5209bf215546Sopenharmony_ci * "... any declaration that leaves the size undefined is 5210bf215546Sopenharmony_ci * disallowed as this would add complexity and there are no 5211bf215546Sopenharmony_ci * use-cases." 5212bf215546Sopenharmony_ci */ 5213bf215546Sopenharmony_ci if (state->es_shader && decl_type->is_unsized_array()) { 5214bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "array size must be explicitly " 5215bf215546Sopenharmony_ci "or implicitly defined"); 5216bf215546Sopenharmony_ci } 5217bf215546Sopenharmony_ci 5218bf215546Sopenharmony_ci /* From Section 4.12 (Empty Declarations) of the GLSL 4.5 spec: 5219bf215546Sopenharmony_ci * 5220bf215546Sopenharmony_ci * "The combinations of types and qualifiers that cause 5221bf215546Sopenharmony_ci * compile-time or link-time errors are the same whether or not 5222bf215546Sopenharmony_ci * the declaration is empty." 5223bf215546Sopenharmony_ci */ 5224bf215546Sopenharmony_ci validate_array_dimensions(decl_type, state, &loc); 5225bf215546Sopenharmony_ci } 5226bf215546Sopenharmony_ci 5227bf215546Sopenharmony_ci if (decl_type->is_atomic_uint()) { 5228bf215546Sopenharmony_ci /* Empty atomic counter declarations are allowed and useful 5229bf215546Sopenharmony_ci * to set the default offset qualifier. 5230bf215546Sopenharmony_ci */ 5231bf215546Sopenharmony_ci return NULL; 5232bf215546Sopenharmony_ci } else if (this->type->qualifier.precision != ast_precision_none) { 5233bf215546Sopenharmony_ci if (this->type->specifier->structure != NULL) { 5234bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5235bf215546Sopenharmony_ci "precision qualifiers can't be applied " 5236bf215546Sopenharmony_ci "to structures"); 5237bf215546Sopenharmony_ci } else { 5238bf215546Sopenharmony_ci static const char *const precision_names[] = { 5239bf215546Sopenharmony_ci "highp", 5240bf215546Sopenharmony_ci "highp", 5241bf215546Sopenharmony_ci "mediump", 5242bf215546Sopenharmony_ci "lowp" 5243bf215546Sopenharmony_ci }; 5244bf215546Sopenharmony_ci 5245bf215546Sopenharmony_ci _mesa_glsl_warning(&loc, state, 5246bf215546Sopenharmony_ci "empty declaration with precision " 5247bf215546Sopenharmony_ci "qualifier, to set the default precision, " 5248bf215546Sopenharmony_ci "use `precision %s %s;'", 5249bf215546Sopenharmony_ci precision_names[this->type-> 5250bf215546Sopenharmony_ci qualifier.precision], 5251bf215546Sopenharmony_ci type_name); 5252bf215546Sopenharmony_ci } 5253bf215546Sopenharmony_ci } else if (this->type->specifier->structure == NULL) { 5254bf215546Sopenharmony_ci _mesa_glsl_warning(&loc, state, "empty declaration"); 5255bf215546Sopenharmony_ci } 5256bf215546Sopenharmony_ci } 5257bf215546Sopenharmony_ci } 5258bf215546Sopenharmony_ci 5259bf215546Sopenharmony_ci foreach_list_typed (ast_declaration, decl, link, &this->declarations) { 5260bf215546Sopenharmony_ci const struct glsl_type *var_type; 5261bf215546Sopenharmony_ci ir_variable *var; 5262bf215546Sopenharmony_ci const char *identifier = decl->identifier; 5263bf215546Sopenharmony_ci /* FINISHME: Emit a warning if a variable declaration shadows a 5264bf215546Sopenharmony_ci * FINISHME: declaration at a higher scope. 5265bf215546Sopenharmony_ci */ 5266bf215546Sopenharmony_ci 5267bf215546Sopenharmony_ci if ((decl_type == NULL) || decl_type->is_void()) { 5268bf215546Sopenharmony_ci if (type_name != NULL) { 5269bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5270bf215546Sopenharmony_ci "invalid type `%s' in declaration of `%s'", 5271bf215546Sopenharmony_ci type_name, decl->identifier); 5272bf215546Sopenharmony_ci } else { 5273bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5274bf215546Sopenharmony_ci "invalid type in declaration of `%s'", 5275bf215546Sopenharmony_ci decl->identifier); 5276bf215546Sopenharmony_ci } 5277bf215546Sopenharmony_ci continue; 5278bf215546Sopenharmony_ci } 5279bf215546Sopenharmony_ci 5280bf215546Sopenharmony_ci if (this->type->qualifier.is_subroutine_decl()) { 5281bf215546Sopenharmony_ci const glsl_type *t; 5282bf215546Sopenharmony_ci const char *name; 5283bf215546Sopenharmony_ci 5284bf215546Sopenharmony_ci t = state->symbols->get_type(this->type->specifier->type_name); 5285bf215546Sopenharmony_ci if (!t) 5286bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5287bf215546Sopenharmony_ci "invalid type in declaration of `%s'", 5288bf215546Sopenharmony_ci decl->identifier); 5289bf215546Sopenharmony_ci name = ralloc_asprintf(ctx, "%s_%s", _mesa_shader_stage_to_subroutine_prefix(state->stage), decl->identifier); 5290bf215546Sopenharmony_ci 5291bf215546Sopenharmony_ci identifier = name; 5292bf215546Sopenharmony_ci 5293bf215546Sopenharmony_ci } 5294bf215546Sopenharmony_ci var_type = process_array_type(&loc, decl_type, decl->array_specifier, 5295bf215546Sopenharmony_ci state); 5296bf215546Sopenharmony_ci 5297bf215546Sopenharmony_ci var = new(ctx) ir_variable(var_type, identifier, ir_var_auto); 5298bf215546Sopenharmony_ci 5299bf215546Sopenharmony_ci /* The 'varying in' and 'varying out' qualifiers can only be used with 5300bf215546Sopenharmony_ci * ARB_geometry_shader4 and EXT_geometry_shader4, which we don't support 5301bf215546Sopenharmony_ci * yet. 5302bf215546Sopenharmony_ci */ 5303bf215546Sopenharmony_ci if (this->type->qualifier.flags.q.varying) { 5304bf215546Sopenharmony_ci if (this->type->qualifier.flags.q.in) { 5305bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5306bf215546Sopenharmony_ci "`varying in' qualifier in declaration of " 5307bf215546Sopenharmony_ci "`%s' only valid for geometry shaders using " 5308bf215546Sopenharmony_ci "ARB_geometry_shader4 or EXT_geometry_shader4", 5309bf215546Sopenharmony_ci decl->identifier); 5310bf215546Sopenharmony_ci } else if (this->type->qualifier.flags.q.out) { 5311bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5312bf215546Sopenharmony_ci "`varying out' qualifier in declaration of " 5313bf215546Sopenharmony_ci "`%s' only valid for geometry shaders using " 5314bf215546Sopenharmony_ci "ARB_geometry_shader4 or EXT_geometry_shader4", 5315bf215546Sopenharmony_ci decl->identifier); 5316bf215546Sopenharmony_ci } 5317bf215546Sopenharmony_ci } 5318bf215546Sopenharmony_ci 5319bf215546Sopenharmony_ci /* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification; 5320bf215546Sopenharmony_ci * 5321bf215546Sopenharmony_ci * "Global variables can only use the qualifiers const, 5322bf215546Sopenharmony_ci * attribute, uniform, or varying. Only one may be 5323bf215546Sopenharmony_ci * specified. 5324bf215546Sopenharmony_ci * 5325bf215546Sopenharmony_ci * Local variables can only use the qualifier const." 5326bf215546Sopenharmony_ci * 5327bf215546Sopenharmony_ci * This is relaxed in GLSL 1.30 and GLSL ES 3.00. It is also relaxed by 5328bf215546Sopenharmony_ci * any extension that adds the 'layout' keyword. 5329bf215546Sopenharmony_ci */ 5330bf215546Sopenharmony_ci if (!state->is_version(130, 300) 5331bf215546Sopenharmony_ci && !state->has_explicit_attrib_location() 5332bf215546Sopenharmony_ci && !state->has_separate_shader_objects() 5333bf215546Sopenharmony_ci && !state->ARB_fragment_coord_conventions_enable) { 5334bf215546Sopenharmony_ci /* GL_EXT_gpu_shader4 only allows "varying out" on fragment shader 5335bf215546Sopenharmony_ci * outputs. (the varying flag is not set by the parser) 5336bf215546Sopenharmony_ci */ 5337bf215546Sopenharmony_ci if (this->type->qualifier.flags.q.out && 5338bf215546Sopenharmony_ci (!state->EXT_gpu_shader4_enable || 5339bf215546Sopenharmony_ci state->stage != MESA_SHADER_FRAGMENT)) { 5340bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5341bf215546Sopenharmony_ci "`out' qualifier in declaration of `%s' " 5342bf215546Sopenharmony_ci "only valid for function parameters in %s", 5343bf215546Sopenharmony_ci decl->identifier, state->get_version_string()); 5344bf215546Sopenharmony_ci } 5345bf215546Sopenharmony_ci if (this->type->qualifier.flags.q.in) { 5346bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5347bf215546Sopenharmony_ci "`in' qualifier in declaration of `%s' " 5348bf215546Sopenharmony_ci "only valid for function parameters in %s", 5349bf215546Sopenharmony_ci decl->identifier, state->get_version_string()); 5350bf215546Sopenharmony_ci } 5351bf215546Sopenharmony_ci /* FINISHME: Test for other invalid qualifiers. */ 5352bf215546Sopenharmony_ci } 5353bf215546Sopenharmony_ci 5354bf215546Sopenharmony_ci apply_type_qualifier_to_variable(& this->type->qualifier, var, state, 5355bf215546Sopenharmony_ci & loc, false); 5356bf215546Sopenharmony_ci apply_layout_qualifier_to_variable(&this->type->qualifier, var, state, 5357bf215546Sopenharmony_ci &loc); 5358bf215546Sopenharmony_ci 5359bf215546Sopenharmony_ci if ((state->zero_init & (1u << var->data.mode)) && 5360bf215546Sopenharmony_ci (var->type->is_numeric() || var->type->is_boolean())) { 5361bf215546Sopenharmony_ci const ir_constant_data data = { { 0 } }; 5362bf215546Sopenharmony_ci var->data.has_initializer = true; 5363bf215546Sopenharmony_ci var->data.is_implicit_initializer = true; 5364bf215546Sopenharmony_ci var->constant_initializer = new(var) ir_constant(var->type, &data); 5365bf215546Sopenharmony_ci } 5366bf215546Sopenharmony_ci 5367bf215546Sopenharmony_ci if (this->type->qualifier.flags.q.invariant) { 5368bf215546Sopenharmony_ci if (!is_allowed_invariant(var, state)) { 5369bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5370bf215546Sopenharmony_ci "`%s' cannot be marked invariant; interfaces between " 5371bf215546Sopenharmony_ci "shader stages only", var->name); 5372bf215546Sopenharmony_ci } 5373bf215546Sopenharmony_ci } 5374bf215546Sopenharmony_ci 5375bf215546Sopenharmony_ci if (state->current_function != NULL) { 5376bf215546Sopenharmony_ci const char *mode = NULL; 5377bf215546Sopenharmony_ci const char *extra = ""; 5378bf215546Sopenharmony_ci 5379bf215546Sopenharmony_ci /* There is no need to check for 'inout' here because the parser will 5380bf215546Sopenharmony_ci * only allow that in function parameter lists. 5381bf215546Sopenharmony_ci */ 5382bf215546Sopenharmony_ci if (this->type->qualifier.flags.q.attribute) { 5383bf215546Sopenharmony_ci mode = "attribute"; 5384bf215546Sopenharmony_ci } else if (this->type->qualifier.is_subroutine_decl()) { 5385bf215546Sopenharmony_ci mode = "subroutine uniform"; 5386bf215546Sopenharmony_ci } else if (this->type->qualifier.flags.q.uniform) { 5387bf215546Sopenharmony_ci mode = "uniform"; 5388bf215546Sopenharmony_ci } else if (this->type->qualifier.flags.q.varying) { 5389bf215546Sopenharmony_ci mode = "varying"; 5390bf215546Sopenharmony_ci } else if (this->type->qualifier.flags.q.in) { 5391bf215546Sopenharmony_ci mode = "in"; 5392bf215546Sopenharmony_ci extra = " or in function parameter list"; 5393bf215546Sopenharmony_ci } else if (this->type->qualifier.flags.q.out) { 5394bf215546Sopenharmony_ci mode = "out"; 5395bf215546Sopenharmony_ci extra = " or in function parameter list"; 5396bf215546Sopenharmony_ci } 5397bf215546Sopenharmony_ci 5398bf215546Sopenharmony_ci if (mode) { 5399bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5400bf215546Sopenharmony_ci "%s variable `%s' must be declared at " 5401bf215546Sopenharmony_ci "global scope%s", 5402bf215546Sopenharmony_ci mode, var->name, extra); 5403bf215546Sopenharmony_ci } 5404bf215546Sopenharmony_ci } else if (var->data.mode == ir_var_shader_in) { 5405bf215546Sopenharmony_ci var->data.read_only = true; 5406bf215546Sopenharmony_ci 5407bf215546Sopenharmony_ci if (state->stage == MESA_SHADER_VERTEX) { 5408bf215546Sopenharmony_ci /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec: 5409bf215546Sopenharmony_ci * 5410bf215546Sopenharmony_ci * "Vertex shader inputs can only be float, floating-point 5411bf215546Sopenharmony_ci * vectors, matrices, signed and unsigned integers and integer 5412bf215546Sopenharmony_ci * vectors. Vertex shader inputs can also form arrays of these 5413bf215546Sopenharmony_ci * types, but not structures." 5414bf215546Sopenharmony_ci * 5415bf215546Sopenharmony_ci * From page 31 (page 27 of the PDF) of the GLSL 1.30 spec: 5416bf215546Sopenharmony_ci * 5417bf215546Sopenharmony_ci * "Vertex shader inputs can only be float, floating-point 5418bf215546Sopenharmony_ci * vectors, matrices, signed and unsigned integers and integer 5419bf215546Sopenharmony_ci * vectors. They cannot be arrays or structures." 5420bf215546Sopenharmony_ci * 5421bf215546Sopenharmony_ci * From page 23 (page 29 of the PDF) of the GLSL 1.20 spec: 5422bf215546Sopenharmony_ci * 5423bf215546Sopenharmony_ci * "The attribute qualifier can be used only with float, 5424bf215546Sopenharmony_ci * floating-point vectors, and matrices. Attribute variables 5425bf215546Sopenharmony_ci * cannot be declared as arrays or structures." 5426bf215546Sopenharmony_ci * 5427bf215546Sopenharmony_ci * From page 33 (page 39 of the PDF) of the GLSL ES 3.00 spec: 5428bf215546Sopenharmony_ci * 5429bf215546Sopenharmony_ci * "Vertex shader inputs can only be float, floating-point 5430bf215546Sopenharmony_ci * vectors, matrices, signed and unsigned integers and integer 5431bf215546Sopenharmony_ci * vectors. Vertex shader inputs cannot be arrays or 5432bf215546Sopenharmony_ci * structures." 5433bf215546Sopenharmony_ci * 5434bf215546Sopenharmony_ci * From section 4.3.4 of the ARB_bindless_texture spec: 5435bf215546Sopenharmony_ci * 5436bf215546Sopenharmony_ci * "(modify third paragraph of the section to allow sampler and 5437bf215546Sopenharmony_ci * image types) ... Vertex shader inputs can only be float, 5438bf215546Sopenharmony_ci * single-precision floating-point scalars, single-precision 5439bf215546Sopenharmony_ci * floating-point vectors, matrices, signed and unsigned 5440bf215546Sopenharmony_ci * integers and integer vectors, sampler and image types." 5441bf215546Sopenharmony_ci */ 5442bf215546Sopenharmony_ci const glsl_type *check_type = var->type->without_array(); 5443bf215546Sopenharmony_ci 5444bf215546Sopenharmony_ci bool error = false; 5445bf215546Sopenharmony_ci switch (check_type->base_type) { 5446bf215546Sopenharmony_ci case GLSL_TYPE_FLOAT: 5447bf215546Sopenharmony_ci break; 5448bf215546Sopenharmony_ci case GLSL_TYPE_UINT64: 5449bf215546Sopenharmony_ci case GLSL_TYPE_INT64: 5450bf215546Sopenharmony_ci break; 5451bf215546Sopenharmony_ci case GLSL_TYPE_UINT: 5452bf215546Sopenharmony_ci case GLSL_TYPE_INT: 5453bf215546Sopenharmony_ci error = !state->is_version(120, 300) && !state->EXT_gpu_shader4_enable; 5454bf215546Sopenharmony_ci break; 5455bf215546Sopenharmony_ci case GLSL_TYPE_DOUBLE: 5456bf215546Sopenharmony_ci error = !state->is_version(410, 0) && !state->ARB_vertex_attrib_64bit_enable; 5457bf215546Sopenharmony_ci break; 5458bf215546Sopenharmony_ci case GLSL_TYPE_SAMPLER: 5459bf215546Sopenharmony_ci case GLSL_TYPE_TEXTURE: 5460bf215546Sopenharmony_ci case GLSL_TYPE_IMAGE: 5461bf215546Sopenharmony_ci error = !state->has_bindless(); 5462bf215546Sopenharmony_ci break; 5463bf215546Sopenharmony_ci default: 5464bf215546Sopenharmony_ci error = true; 5465bf215546Sopenharmony_ci } 5466bf215546Sopenharmony_ci 5467bf215546Sopenharmony_ci if (error) { 5468bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5469bf215546Sopenharmony_ci "vertex shader input / attribute cannot have " 5470bf215546Sopenharmony_ci "type %s`%s'", 5471bf215546Sopenharmony_ci var->type->is_array() ? "array of " : "", 5472bf215546Sopenharmony_ci check_type->name); 5473bf215546Sopenharmony_ci } else if (var->type->is_array() && 5474bf215546Sopenharmony_ci !state->check_version(150, 0, &loc, 5475bf215546Sopenharmony_ci "vertex shader input / attribute " 5476bf215546Sopenharmony_ci "cannot have array type")) { 5477bf215546Sopenharmony_ci } 5478bf215546Sopenharmony_ci } else if (state->stage == MESA_SHADER_GEOMETRY) { 5479bf215546Sopenharmony_ci /* From section 4.3.4 (Inputs) of the GLSL 1.50 spec: 5480bf215546Sopenharmony_ci * 5481bf215546Sopenharmony_ci * Geometry shader input variables get the per-vertex values 5482bf215546Sopenharmony_ci * written out by vertex shader output variables of the same 5483bf215546Sopenharmony_ci * names. Since a geometry shader operates on a set of 5484bf215546Sopenharmony_ci * vertices, each input varying variable (or input block, see 5485bf215546Sopenharmony_ci * interface blocks below) needs to be declared as an array. 5486bf215546Sopenharmony_ci */ 5487bf215546Sopenharmony_ci if (!var->type->is_array()) { 5488bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5489bf215546Sopenharmony_ci "geometry shader inputs must be arrays"); 5490bf215546Sopenharmony_ci } 5491bf215546Sopenharmony_ci 5492bf215546Sopenharmony_ci handle_geometry_shader_input_decl(state, loc, var); 5493bf215546Sopenharmony_ci } else if (state->stage == MESA_SHADER_FRAGMENT) { 5494bf215546Sopenharmony_ci /* From section 4.3.4 (Input Variables) of the GLSL ES 3.10 spec: 5495bf215546Sopenharmony_ci * 5496bf215546Sopenharmony_ci * It is a compile-time error to declare a fragment shader 5497bf215546Sopenharmony_ci * input with, or that contains, any of the following types: 5498bf215546Sopenharmony_ci * 5499bf215546Sopenharmony_ci * * A boolean type 5500bf215546Sopenharmony_ci * * An opaque type 5501bf215546Sopenharmony_ci * * An array of arrays 5502bf215546Sopenharmony_ci * * An array of structures 5503bf215546Sopenharmony_ci * * A structure containing an array 5504bf215546Sopenharmony_ci * * A structure containing a structure 5505bf215546Sopenharmony_ci */ 5506bf215546Sopenharmony_ci if (state->es_shader) { 5507bf215546Sopenharmony_ci const glsl_type *check_type = var->type->without_array(); 5508bf215546Sopenharmony_ci if (check_type->is_boolean() || 5509bf215546Sopenharmony_ci check_type->contains_opaque()) { 5510bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5511bf215546Sopenharmony_ci "fragment shader input cannot have type %s", 5512bf215546Sopenharmony_ci check_type->name); 5513bf215546Sopenharmony_ci } 5514bf215546Sopenharmony_ci if (var->type->is_array() && 5515bf215546Sopenharmony_ci var->type->fields.array->is_array()) { 5516bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5517bf215546Sopenharmony_ci "%s shader output " 5518bf215546Sopenharmony_ci "cannot have an array of arrays", 5519bf215546Sopenharmony_ci _mesa_shader_stage_to_string(state->stage)); 5520bf215546Sopenharmony_ci } 5521bf215546Sopenharmony_ci if (var->type->is_array() && 5522bf215546Sopenharmony_ci var->type->fields.array->is_struct()) { 5523bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5524bf215546Sopenharmony_ci "fragment shader input " 5525bf215546Sopenharmony_ci "cannot have an array of structs"); 5526bf215546Sopenharmony_ci } 5527bf215546Sopenharmony_ci if (var->type->is_struct()) { 5528bf215546Sopenharmony_ci for (unsigned i = 0; i < var->type->length; i++) { 5529bf215546Sopenharmony_ci if (var->type->fields.structure[i].type->is_array() || 5530bf215546Sopenharmony_ci var->type->fields.structure[i].type->is_struct()) 5531bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5532bf215546Sopenharmony_ci "fragment shader input cannot have " 5533bf215546Sopenharmony_ci "a struct that contains an " 5534bf215546Sopenharmony_ci "array or struct"); 5535bf215546Sopenharmony_ci } 5536bf215546Sopenharmony_ci } 5537bf215546Sopenharmony_ci } 5538bf215546Sopenharmony_ci } else if (state->stage == MESA_SHADER_TESS_CTRL || 5539bf215546Sopenharmony_ci state->stage == MESA_SHADER_TESS_EVAL) { 5540bf215546Sopenharmony_ci handle_tess_shader_input_decl(state, loc, var); 5541bf215546Sopenharmony_ci } 5542bf215546Sopenharmony_ci } else if (var->data.mode == ir_var_shader_out) { 5543bf215546Sopenharmony_ci const glsl_type *check_type = var->type->without_array(); 5544bf215546Sopenharmony_ci 5545bf215546Sopenharmony_ci /* From section 4.3.6 (Output variables) of the GLSL 4.40 spec: 5546bf215546Sopenharmony_ci * 5547bf215546Sopenharmony_ci * It is a compile-time error to declare a fragment shader output 5548bf215546Sopenharmony_ci * that contains any of the following: 5549bf215546Sopenharmony_ci * 5550bf215546Sopenharmony_ci * * A Boolean type (bool, bvec2 ...) 5551bf215546Sopenharmony_ci * * A double-precision scalar or vector (double, dvec2 ...) 5552bf215546Sopenharmony_ci * * An opaque type 5553bf215546Sopenharmony_ci * * Any matrix type 5554bf215546Sopenharmony_ci * * A structure 5555bf215546Sopenharmony_ci */ 5556bf215546Sopenharmony_ci if (state->stage == MESA_SHADER_FRAGMENT) { 5557bf215546Sopenharmony_ci if (check_type->is_struct() || check_type->is_matrix()) 5558bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5559bf215546Sopenharmony_ci "fragment shader output " 5560bf215546Sopenharmony_ci "cannot have struct or matrix type"); 5561bf215546Sopenharmony_ci switch (check_type->base_type) { 5562bf215546Sopenharmony_ci case GLSL_TYPE_UINT: 5563bf215546Sopenharmony_ci case GLSL_TYPE_INT: 5564bf215546Sopenharmony_ci case GLSL_TYPE_FLOAT: 5565bf215546Sopenharmony_ci break; 5566bf215546Sopenharmony_ci default: 5567bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5568bf215546Sopenharmony_ci "fragment shader output cannot have " 5569bf215546Sopenharmony_ci "type %s", check_type->name); 5570bf215546Sopenharmony_ci } 5571bf215546Sopenharmony_ci } 5572bf215546Sopenharmony_ci 5573bf215546Sopenharmony_ci /* From section 4.3.6 (Output Variables) of the GLSL ES 3.10 spec: 5574bf215546Sopenharmony_ci * 5575bf215546Sopenharmony_ci * It is a compile-time error to declare a vertex shader output 5576bf215546Sopenharmony_ci * with, or that contains, any of the following types: 5577bf215546Sopenharmony_ci * 5578bf215546Sopenharmony_ci * * A boolean type 5579bf215546Sopenharmony_ci * * An opaque type 5580bf215546Sopenharmony_ci * * An array of arrays 5581bf215546Sopenharmony_ci * * An array of structures 5582bf215546Sopenharmony_ci * * A structure containing an array 5583bf215546Sopenharmony_ci * * A structure containing a structure 5584bf215546Sopenharmony_ci * 5585bf215546Sopenharmony_ci * It is a compile-time error to declare a fragment shader output 5586bf215546Sopenharmony_ci * with, or that contains, any of the following types: 5587bf215546Sopenharmony_ci * 5588bf215546Sopenharmony_ci * * A boolean type 5589bf215546Sopenharmony_ci * * An opaque type 5590bf215546Sopenharmony_ci * * A matrix 5591bf215546Sopenharmony_ci * * A structure 5592bf215546Sopenharmony_ci * * An array of array 5593bf215546Sopenharmony_ci * 5594bf215546Sopenharmony_ci * ES 3.20 updates this to apply to tessellation and geometry shaders 5595bf215546Sopenharmony_ci * as well. Because there are per-vertex arrays in the new stages, 5596bf215546Sopenharmony_ci * it strikes the "array of..." rules and replaces them with these: 5597bf215546Sopenharmony_ci * 5598bf215546Sopenharmony_ci * * For per-vertex-arrayed variables (applies to tessellation 5599bf215546Sopenharmony_ci * control, tessellation evaluation and geometry shaders): 5600bf215546Sopenharmony_ci * 5601bf215546Sopenharmony_ci * * Per-vertex-arrayed arrays of arrays 5602bf215546Sopenharmony_ci * * Per-vertex-arrayed arrays of structures 5603bf215546Sopenharmony_ci * 5604bf215546Sopenharmony_ci * * For non-per-vertex-arrayed variables: 5605bf215546Sopenharmony_ci * 5606bf215546Sopenharmony_ci * * An array of arrays 5607bf215546Sopenharmony_ci * * An array of structures 5608bf215546Sopenharmony_ci * 5609bf215546Sopenharmony_ci * which basically says to unwrap the per-vertex aspect and apply 5610bf215546Sopenharmony_ci * the old rules. 5611bf215546Sopenharmony_ci */ 5612bf215546Sopenharmony_ci if (state->es_shader) { 5613bf215546Sopenharmony_ci if (var->type->is_array() && 5614bf215546Sopenharmony_ci var->type->fields.array->is_array()) { 5615bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5616bf215546Sopenharmony_ci "%s shader output " 5617bf215546Sopenharmony_ci "cannot have an array of arrays", 5618bf215546Sopenharmony_ci _mesa_shader_stage_to_string(state->stage)); 5619bf215546Sopenharmony_ci } 5620bf215546Sopenharmony_ci if (state->stage <= MESA_SHADER_GEOMETRY) { 5621bf215546Sopenharmony_ci const glsl_type *type = var->type; 5622bf215546Sopenharmony_ci 5623bf215546Sopenharmony_ci if (state->stage == MESA_SHADER_TESS_CTRL && 5624bf215546Sopenharmony_ci !var->data.patch && var->type->is_array()) { 5625bf215546Sopenharmony_ci type = var->type->fields.array; 5626bf215546Sopenharmony_ci } 5627bf215546Sopenharmony_ci 5628bf215546Sopenharmony_ci if (type->is_array() && type->fields.array->is_struct()) { 5629bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5630bf215546Sopenharmony_ci "%s shader output cannot have " 5631bf215546Sopenharmony_ci "an array of structs", 5632bf215546Sopenharmony_ci _mesa_shader_stage_to_string(state->stage)); 5633bf215546Sopenharmony_ci } 5634bf215546Sopenharmony_ci if (type->is_struct()) { 5635bf215546Sopenharmony_ci for (unsigned i = 0; i < type->length; i++) { 5636bf215546Sopenharmony_ci if (type->fields.structure[i].type->is_array() || 5637bf215546Sopenharmony_ci type->fields.structure[i].type->is_struct()) 5638bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5639bf215546Sopenharmony_ci "%s shader output cannot have a " 5640bf215546Sopenharmony_ci "struct that contains an " 5641bf215546Sopenharmony_ci "array or struct", 5642bf215546Sopenharmony_ci _mesa_shader_stage_to_string(state->stage)); 5643bf215546Sopenharmony_ci } 5644bf215546Sopenharmony_ci } 5645bf215546Sopenharmony_ci } 5646bf215546Sopenharmony_ci } 5647bf215546Sopenharmony_ci 5648bf215546Sopenharmony_ci if (state->stage == MESA_SHADER_TESS_CTRL) { 5649bf215546Sopenharmony_ci handle_tess_ctrl_shader_output_decl(state, loc, var); 5650bf215546Sopenharmony_ci } 5651bf215546Sopenharmony_ci } else if (var->type->contains_subroutine()) { 5652bf215546Sopenharmony_ci /* declare subroutine uniforms as hidden */ 5653bf215546Sopenharmony_ci var->data.how_declared = ir_var_hidden; 5654bf215546Sopenharmony_ci } 5655bf215546Sopenharmony_ci 5656bf215546Sopenharmony_ci /* From section 4.3.4 of the GLSL 4.00 spec: 5657bf215546Sopenharmony_ci * "Input variables may not be declared using the patch in qualifier 5658bf215546Sopenharmony_ci * in tessellation control or geometry shaders." 5659bf215546Sopenharmony_ci * 5660bf215546Sopenharmony_ci * From section 4.3.6 of the GLSL 4.00 spec: 5661bf215546Sopenharmony_ci * "It is an error to use patch out in a vertex, tessellation 5662bf215546Sopenharmony_ci * evaluation, or geometry shader." 5663bf215546Sopenharmony_ci * 5664bf215546Sopenharmony_ci * This doesn't explicitly forbid using them in a fragment shader, but 5665bf215546Sopenharmony_ci * that's probably just an oversight. 5666bf215546Sopenharmony_ci */ 5667bf215546Sopenharmony_ci if (state->stage != MESA_SHADER_TESS_EVAL 5668bf215546Sopenharmony_ci && this->type->qualifier.flags.q.patch 5669bf215546Sopenharmony_ci && this->type->qualifier.flags.q.in) { 5670bf215546Sopenharmony_ci 5671bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "'patch in' can only be used in a " 5672bf215546Sopenharmony_ci "tessellation evaluation shader"); 5673bf215546Sopenharmony_ci } 5674bf215546Sopenharmony_ci 5675bf215546Sopenharmony_ci if (state->stage != MESA_SHADER_TESS_CTRL 5676bf215546Sopenharmony_ci && this->type->qualifier.flags.q.patch 5677bf215546Sopenharmony_ci && this->type->qualifier.flags.q.out) { 5678bf215546Sopenharmony_ci 5679bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "'patch out' can only be used in a " 5680bf215546Sopenharmony_ci "tessellation control shader"); 5681bf215546Sopenharmony_ci } 5682bf215546Sopenharmony_ci 5683bf215546Sopenharmony_ci /* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30. 5684bf215546Sopenharmony_ci */ 5685bf215546Sopenharmony_ci if (this->type->qualifier.precision != ast_precision_none) { 5686bf215546Sopenharmony_ci state->check_precision_qualifiers_allowed(&loc); 5687bf215546Sopenharmony_ci } 5688bf215546Sopenharmony_ci 5689bf215546Sopenharmony_ci if (this->type->qualifier.precision != ast_precision_none && 5690bf215546Sopenharmony_ci !precision_qualifier_allowed(var->type)) { 5691bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5692bf215546Sopenharmony_ci "precision qualifiers apply only to floating point" 5693bf215546Sopenharmony_ci ", integer and opaque types"); 5694bf215546Sopenharmony_ci } 5695bf215546Sopenharmony_ci 5696bf215546Sopenharmony_ci /* From section 4.1.7 of the GLSL 4.40 spec: 5697bf215546Sopenharmony_ci * 5698bf215546Sopenharmony_ci * "[Opaque types] can only be declared as function 5699bf215546Sopenharmony_ci * parameters or uniform-qualified variables." 5700bf215546Sopenharmony_ci * 5701bf215546Sopenharmony_ci * From section 4.1.7 of the ARB_bindless_texture spec: 5702bf215546Sopenharmony_ci * 5703bf215546Sopenharmony_ci * "Samplers may be declared as shader inputs and outputs, as uniform 5704bf215546Sopenharmony_ci * variables, as temporary variables, and as function parameters." 5705bf215546Sopenharmony_ci * 5706bf215546Sopenharmony_ci * From section 4.1.X of the ARB_bindless_texture spec: 5707bf215546Sopenharmony_ci * 5708bf215546Sopenharmony_ci * "Images may be declared as shader inputs and outputs, as uniform 5709bf215546Sopenharmony_ci * variables, as temporary variables, and as function parameters." 5710bf215546Sopenharmony_ci */ 5711bf215546Sopenharmony_ci if (!this->type->qualifier.flags.q.uniform && 5712bf215546Sopenharmony_ci (var_type->contains_atomic() || 5713bf215546Sopenharmony_ci (!state->has_bindless() && var_type->contains_opaque()))) { 5714bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5715bf215546Sopenharmony_ci "%s variables must be declared uniform", 5716bf215546Sopenharmony_ci state->has_bindless() ? "atomic" : "opaque"); 5717bf215546Sopenharmony_ci } 5718bf215546Sopenharmony_ci 5719bf215546Sopenharmony_ci /* Process the initializer and add its instructions to a temporary 5720bf215546Sopenharmony_ci * list. This list will be added to the instruction stream (below) after 5721bf215546Sopenharmony_ci * the declaration is added. This is done because in some cases (such as 5722bf215546Sopenharmony_ci * redeclarations) the declaration may not actually be added to the 5723bf215546Sopenharmony_ci * instruction stream. 5724bf215546Sopenharmony_ci */ 5725bf215546Sopenharmony_ci exec_list initializer_instructions; 5726bf215546Sopenharmony_ci 5727bf215546Sopenharmony_ci /* Examine var name here since var may get deleted in the next call */ 5728bf215546Sopenharmony_ci bool var_is_gl_id = is_gl_identifier(var->name); 5729bf215546Sopenharmony_ci 5730bf215546Sopenharmony_ci bool is_redeclaration; 5731bf215546Sopenharmony_ci var = get_variable_being_redeclared(&var, decl->get_location(), state, 5732bf215546Sopenharmony_ci false /* allow_all_redeclarations */, 5733bf215546Sopenharmony_ci &is_redeclaration); 5734bf215546Sopenharmony_ci if (is_redeclaration) { 5735bf215546Sopenharmony_ci if (var_is_gl_id && 5736bf215546Sopenharmony_ci var->data.how_declared == ir_var_declared_in_block) { 5737bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 5738bf215546Sopenharmony_ci "`%s' has already been redeclared using " 5739bf215546Sopenharmony_ci "gl_PerVertex", var->name); 5740bf215546Sopenharmony_ci } 5741bf215546Sopenharmony_ci var->data.how_declared = ir_var_declared_normally; 5742bf215546Sopenharmony_ci } 5743bf215546Sopenharmony_ci 5744bf215546Sopenharmony_ci if (decl->initializer != NULL) { 5745bf215546Sopenharmony_ci result = process_initializer(var, 5746bf215546Sopenharmony_ci decl, this->type, 5747bf215546Sopenharmony_ci &initializer_instructions, state); 5748bf215546Sopenharmony_ci } else { 5749bf215546Sopenharmony_ci validate_array_dimensions(var_type, state, &loc); 5750bf215546Sopenharmony_ci } 5751bf215546Sopenharmony_ci 5752bf215546Sopenharmony_ci /* From page 23 (page 29 of the PDF) of the GLSL 1.10 spec: 5753bf215546Sopenharmony_ci * 5754bf215546Sopenharmony_ci * "It is an error to write to a const variable outside of 5755bf215546Sopenharmony_ci * its declaration, so they must be initialized when 5756bf215546Sopenharmony_ci * declared." 5757bf215546Sopenharmony_ci */ 5758bf215546Sopenharmony_ci if (this->type->qualifier.flags.q.constant && decl->initializer == NULL) { 5759bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5760bf215546Sopenharmony_ci "const declaration of `%s' must be initialized", 5761bf215546Sopenharmony_ci decl->identifier); 5762bf215546Sopenharmony_ci } 5763bf215546Sopenharmony_ci 5764bf215546Sopenharmony_ci if (state->es_shader) { 5765bf215546Sopenharmony_ci const glsl_type *const t = var->type; 5766bf215546Sopenharmony_ci 5767bf215546Sopenharmony_ci /* Skip the unsized array check for TCS/TES/GS inputs & TCS outputs. 5768bf215546Sopenharmony_ci * 5769bf215546Sopenharmony_ci * The GL_OES_tessellation_shader spec says about inputs: 5770bf215546Sopenharmony_ci * 5771bf215546Sopenharmony_ci * "Declaring an array size is optional. If no size is specified, 5772bf215546Sopenharmony_ci * it will be taken from the implementation-dependent maximum 5773bf215546Sopenharmony_ci * patch size (gl_MaxPatchVertices)." 5774bf215546Sopenharmony_ci * 5775bf215546Sopenharmony_ci * and about TCS outputs: 5776bf215546Sopenharmony_ci * 5777bf215546Sopenharmony_ci * "If no size is specified, it will be taken from output patch 5778bf215546Sopenharmony_ci * size declared in the shader." 5779bf215546Sopenharmony_ci * 5780bf215546Sopenharmony_ci * The GL_OES_geometry_shader spec says: 5781bf215546Sopenharmony_ci * 5782bf215546Sopenharmony_ci * "All geometry shader input unsized array declarations will be 5783bf215546Sopenharmony_ci * sized by an earlier input primitive layout qualifier, when 5784bf215546Sopenharmony_ci * present, as per the following table." 5785bf215546Sopenharmony_ci */ 5786bf215546Sopenharmony_ci const bool implicitly_sized = 5787bf215546Sopenharmony_ci (var->data.mode == ir_var_shader_in && 5788bf215546Sopenharmony_ci state->stage >= MESA_SHADER_TESS_CTRL && 5789bf215546Sopenharmony_ci state->stage <= MESA_SHADER_GEOMETRY) || 5790bf215546Sopenharmony_ci (var->data.mode == ir_var_shader_out && 5791bf215546Sopenharmony_ci state->stage == MESA_SHADER_TESS_CTRL); 5792bf215546Sopenharmony_ci 5793bf215546Sopenharmony_ci if (t->is_unsized_array() && !implicitly_sized) 5794bf215546Sopenharmony_ci /* Section 10.17 of the GLSL ES 1.00 specification states that 5795bf215546Sopenharmony_ci * unsized array declarations have been removed from the language. 5796bf215546Sopenharmony_ci * Arrays that are sized using an initializer are still explicitly 5797bf215546Sopenharmony_ci * sized. However, GLSL ES 1.00 does not allow array 5798bf215546Sopenharmony_ci * initializers. That is only allowed in GLSL ES 3.00. 5799bf215546Sopenharmony_ci * 5800bf215546Sopenharmony_ci * Section 4.1.9 (Arrays) of the GLSL ES 3.00 spec says: 5801bf215546Sopenharmony_ci * 5802bf215546Sopenharmony_ci * "An array type can also be formed without specifying a size 5803bf215546Sopenharmony_ci * if the definition includes an initializer: 5804bf215546Sopenharmony_ci * 5805bf215546Sopenharmony_ci * float x[] = float[2] (1.0, 2.0); // declares an array of size 2 5806bf215546Sopenharmony_ci * float y[] = float[] (1.0, 2.0, 3.0); // declares an array of size 3 5807bf215546Sopenharmony_ci * 5808bf215546Sopenharmony_ci * float a[5]; 5809bf215546Sopenharmony_ci * float b[] = a;" 5810bf215546Sopenharmony_ci */ 5811bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5812bf215546Sopenharmony_ci "unsized array declarations are not allowed in " 5813bf215546Sopenharmony_ci "GLSL ES"); 5814bf215546Sopenharmony_ci } 5815bf215546Sopenharmony_ci 5816bf215546Sopenharmony_ci /* Section 4.4.6.1 Atomic Counter Layout Qualifiers of the GLSL 4.60 spec: 5817bf215546Sopenharmony_ci * 5818bf215546Sopenharmony_ci * "It is a compile-time error to declare an unsized array of 5819bf215546Sopenharmony_ci * atomic_uint" 5820bf215546Sopenharmony_ci */ 5821bf215546Sopenharmony_ci if (var->type->is_unsized_array() && 5822bf215546Sopenharmony_ci var->type->without_array()->base_type == GLSL_TYPE_ATOMIC_UINT) { 5823bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5824bf215546Sopenharmony_ci "Unsized array of atomic_uint is not allowed"); 5825bf215546Sopenharmony_ci } 5826bf215546Sopenharmony_ci 5827bf215546Sopenharmony_ci /* If the declaration is not a redeclaration, there are a few additional 5828bf215546Sopenharmony_ci * semantic checks that must be applied. In addition, variable that was 5829bf215546Sopenharmony_ci * created for the declaration should be added to the IR stream. 5830bf215546Sopenharmony_ci */ 5831bf215546Sopenharmony_ci if (!is_redeclaration) { 5832bf215546Sopenharmony_ci validate_identifier(decl->identifier, loc, state); 5833bf215546Sopenharmony_ci 5834bf215546Sopenharmony_ci /* Add the variable to the symbol table. Note that the initializer's 5835bf215546Sopenharmony_ci * IR was already processed earlier (though it hasn't been emitted 5836bf215546Sopenharmony_ci * yet), without the variable in scope. 5837bf215546Sopenharmony_ci * 5838bf215546Sopenharmony_ci * This differs from most C-like languages, but it follows the GLSL 5839bf215546Sopenharmony_ci * specification. From page 28 (page 34 of the PDF) of the GLSL 1.50 5840bf215546Sopenharmony_ci * spec: 5841bf215546Sopenharmony_ci * 5842bf215546Sopenharmony_ci * "Within a declaration, the scope of a name starts immediately 5843bf215546Sopenharmony_ci * after the initializer if present or immediately after the name 5844bf215546Sopenharmony_ci * being declared if not." 5845bf215546Sopenharmony_ci */ 5846bf215546Sopenharmony_ci if (!state->symbols->add_variable(var)) { 5847bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 5848bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "name `%s' already taken in the " 5849bf215546Sopenharmony_ci "current scope", decl->identifier); 5850bf215546Sopenharmony_ci continue; 5851bf215546Sopenharmony_ci } 5852bf215546Sopenharmony_ci 5853bf215546Sopenharmony_ci /* Push the variable declaration to the top. It means that all the 5854bf215546Sopenharmony_ci * variable declarations will appear in a funny last-to-first order, 5855bf215546Sopenharmony_ci * but otherwise we run into trouble if a function is prototyped, a 5856bf215546Sopenharmony_ci * global var is decled, then the function is defined with usage of 5857bf215546Sopenharmony_ci * the global var. See glslparsertest's CorrectModule.frag. 5858bf215546Sopenharmony_ci */ 5859bf215546Sopenharmony_ci instructions->push_head(var); 5860bf215546Sopenharmony_ci } 5861bf215546Sopenharmony_ci 5862bf215546Sopenharmony_ci instructions->append_list(&initializer_instructions); 5863bf215546Sopenharmony_ci } 5864bf215546Sopenharmony_ci 5865bf215546Sopenharmony_ci 5866bf215546Sopenharmony_ci /* Generally, variable declarations do not have r-values. However, 5867bf215546Sopenharmony_ci * one is used for the declaration in 5868bf215546Sopenharmony_ci * 5869bf215546Sopenharmony_ci * while (bool b = some_condition()) { 5870bf215546Sopenharmony_ci * ... 5871bf215546Sopenharmony_ci * } 5872bf215546Sopenharmony_ci * 5873bf215546Sopenharmony_ci * so we return the rvalue from the last seen declaration here. 5874bf215546Sopenharmony_ci */ 5875bf215546Sopenharmony_ci return result; 5876bf215546Sopenharmony_ci} 5877bf215546Sopenharmony_ci 5878bf215546Sopenharmony_ci 5879bf215546Sopenharmony_ciir_rvalue * 5880bf215546Sopenharmony_ciast_parameter_declarator::hir(exec_list *instructions, 5881bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 5882bf215546Sopenharmony_ci{ 5883bf215546Sopenharmony_ci void *ctx = state; 5884bf215546Sopenharmony_ci const struct glsl_type *type; 5885bf215546Sopenharmony_ci const char *name = NULL; 5886bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 5887bf215546Sopenharmony_ci 5888bf215546Sopenharmony_ci type = this->type->glsl_type(& name, state); 5889bf215546Sopenharmony_ci 5890bf215546Sopenharmony_ci if (type == NULL) { 5891bf215546Sopenharmony_ci if (name != NULL) { 5892bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5893bf215546Sopenharmony_ci "invalid type `%s' in declaration of `%s'", 5894bf215546Sopenharmony_ci name, this->identifier); 5895bf215546Sopenharmony_ci } else { 5896bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5897bf215546Sopenharmony_ci "invalid type in declaration of `%s'", 5898bf215546Sopenharmony_ci this->identifier); 5899bf215546Sopenharmony_ci } 5900bf215546Sopenharmony_ci 5901bf215546Sopenharmony_ci type = glsl_type::error_type; 5902bf215546Sopenharmony_ci } 5903bf215546Sopenharmony_ci 5904bf215546Sopenharmony_ci /* From page 62 (page 68 of the PDF) of the GLSL 1.50 spec: 5905bf215546Sopenharmony_ci * 5906bf215546Sopenharmony_ci * "Functions that accept no input arguments need not use void in the 5907bf215546Sopenharmony_ci * argument list because prototypes (or definitions) are required and 5908bf215546Sopenharmony_ci * therefore there is no ambiguity when an empty argument list "( )" is 5909bf215546Sopenharmony_ci * declared. The idiom "(void)" as a parameter list is provided for 5910bf215546Sopenharmony_ci * convenience." 5911bf215546Sopenharmony_ci * 5912bf215546Sopenharmony_ci * Placing this check here prevents a void parameter being set up 5913bf215546Sopenharmony_ci * for a function, which avoids tripping up checks for main taking 5914bf215546Sopenharmony_ci * parameters and lookups of an unnamed symbol. 5915bf215546Sopenharmony_ci */ 5916bf215546Sopenharmony_ci if (type->is_void()) { 5917bf215546Sopenharmony_ci if (this->identifier != NULL) 5918bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 5919bf215546Sopenharmony_ci "named parameter cannot have type `void'"); 5920bf215546Sopenharmony_ci 5921bf215546Sopenharmony_ci is_void = true; 5922bf215546Sopenharmony_ci return NULL; 5923bf215546Sopenharmony_ci } 5924bf215546Sopenharmony_ci 5925bf215546Sopenharmony_ci if (formal_parameter && (this->identifier == NULL)) { 5926bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "formal parameter lacks a name"); 5927bf215546Sopenharmony_ci return NULL; 5928bf215546Sopenharmony_ci } 5929bf215546Sopenharmony_ci 5930bf215546Sopenharmony_ci /* This only handles "vec4 foo[..]". The earlier specifier->glsl_type(...) 5931bf215546Sopenharmony_ci * call already handled the "vec4[..] foo" case. 5932bf215546Sopenharmony_ci */ 5933bf215546Sopenharmony_ci type = process_array_type(&loc, type, this->array_specifier, state); 5934bf215546Sopenharmony_ci 5935bf215546Sopenharmony_ci if (!type->is_error() && type->is_unsized_array()) { 5936bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "arrays passed as parameters must have " 5937bf215546Sopenharmony_ci "a declared size"); 5938bf215546Sopenharmony_ci type = glsl_type::error_type; 5939bf215546Sopenharmony_ci } 5940bf215546Sopenharmony_ci 5941bf215546Sopenharmony_ci is_void = false; 5942bf215546Sopenharmony_ci ir_variable *var = new(ctx) 5943bf215546Sopenharmony_ci ir_variable(type, this->identifier, ir_var_function_in); 5944bf215546Sopenharmony_ci 5945bf215546Sopenharmony_ci /* Apply any specified qualifiers to the parameter declaration. Note that 5946bf215546Sopenharmony_ci * for function parameters the default mode is 'in'. 5947bf215546Sopenharmony_ci */ 5948bf215546Sopenharmony_ci apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc, 5949bf215546Sopenharmony_ci true); 5950bf215546Sopenharmony_ci 5951bf215546Sopenharmony_ci if (((1u << var->data.mode) & state->zero_init) && 5952bf215546Sopenharmony_ci (var->type->is_numeric() || var->type->is_boolean())) { 5953bf215546Sopenharmony_ci const ir_constant_data data = { { 0 } }; 5954bf215546Sopenharmony_ci var->data.has_initializer = true; 5955bf215546Sopenharmony_ci var->data.is_implicit_initializer = true; 5956bf215546Sopenharmony_ci var->constant_initializer = new(var) ir_constant(var->type, &data); 5957bf215546Sopenharmony_ci } 5958bf215546Sopenharmony_ci 5959bf215546Sopenharmony_ci /* From section 4.1.7 of the GLSL 4.40 spec: 5960bf215546Sopenharmony_ci * 5961bf215546Sopenharmony_ci * "Opaque variables cannot be treated as l-values; hence cannot 5962bf215546Sopenharmony_ci * be used as out or inout function parameters, nor can they be 5963bf215546Sopenharmony_ci * assigned into." 5964bf215546Sopenharmony_ci * 5965bf215546Sopenharmony_ci * From section 4.1.7 of the ARB_bindless_texture spec: 5966bf215546Sopenharmony_ci * 5967bf215546Sopenharmony_ci * "Samplers can be used as l-values, so can be assigned into and used 5968bf215546Sopenharmony_ci * as "out" and "inout" function parameters." 5969bf215546Sopenharmony_ci * 5970bf215546Sopenharmony_ci * From section 4.1.X of the ARB_bindless_texture spec: 5971bf215546Sopenharmony_ci * 5972bf215546Sopenharmony_ci * "Images can be used as l-values, so can be assigned into and used as 5973bf215546Sopenharmony_ci * "out" and "inout" function parameters." 5974bf215546Sopenharmony_ci */ 5975bf215546Sopenharmony_ci if ((var->data.mode == ir_var_function_inout || var->data.mode == ir_var_function_out) 5976bf215546Sopenharmony_ci && (type->contains_atomic() || 5977bf215546Sopenharmony_ci (!state->has_bindless() && type->contains_opaque()))) { 5978bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "out and inout parameters cannot " 5979bf215546Sopenharmony_ci "contain %s variables", 5980bf215546Sopenharmony_ci state->has_bindless() ? "atomic" : "opaque"); 5981bf215546Sopenharmony_ci type = glsl_type::error_type; 5982bf215546Sopenharmony_ci } 5983bf215546Sopenharmony_ci 5984bf215546Sopenharmony_ci /* From page 39 (page 45 of the PDF) of the GLSL 1.10 spec: 5985bf215546Sopenharmony_ci * 5986bf215546Sopenharmony_ci * "When calling a function, expressions that do not evaluate to 5987bf215546Sopenharmony_ci * l-values cannot be passed to parameters declared as out or inout." 5988bf215546Sopenharmony_ci * 5989bf215546Sopenharmony_ci * From page 32 (page 38 of the PDF) of the GLSL 1.10 spec: 5990bf215546Sopenharmony_ci * 5991bf215546Sopenharmony_ci * "Other binary or unary expressions, non-dereferenced arrays, 5992bf215546Sopenharmony_ci * function names, swizzles with repeated fields, and constants 5993bf215546Sopenharmony_ci * cannot be l-values." 5994bf215546Sopenharmony_ci * 5995bf215546Sopenharmony_ci * So for GLSL 1.10, passing an array as an out or inout parameter is not 5996bf215546Sopenharmony_ci * allowed. This restriction is removed in GLSL 1.20, and in GLSL ES. 5997bf215546Sopenharmony_ci */ 5998bf215546Sopenharmony_ci if ((var->data.mode == ir_var_function_inout || var->data.mode == ir_var_function_out) 5999bf215546Sopenharmony_ci && type->is_array() 6000bf215546Sopenharmony_ci && !state->check_version(120, 100, &loc, 6001bf215546Sopenharmony_ci "arrays cannot be out or inout parameters")) { 6002bf215546Sopenharmony_ci type = glsl_type::error_type; 6003bf215546Sopenharmony_ci } 6004bf215546Sopenharmony_ci 6005bf215546Sopenharmony_ci instructions->push_tail(var); 6006bf215546Sopenharmony_ci 6007bf215546Sopenharmony_ci /* Parameter declarations do not have r-values. 6008bf215546Sopenharmony_ci */ 6009bf215546Sopenharmony_ci return NULL; 6010bf215546Sopenharmony_ci} 6011bf215546Sopenharmony_ci 6012bf215546Sopenharmony_ci 6013bf215546Sopenharmony_civoid 6014bf215546Sopenharmony_ciast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters, 6015bf215546Sopenharmony_ci bool formal, 6016bf215546Sopenharmony_ci exec_list *ir_parameters, 6017bf215546Sopenharmony_ci _mesa_glsl_parse_state *state) 6018bf215546Sopenharmony_ci{ 6019bf215546Sopenharmony_ci ast_parameter_declarator *void_param = NULL; 6020bf215546Sopenharmony_ci unsigned count = 0; 6021bf215546Sopenharmony_ci 6022bf215546Sopenharmony_ci foreach_list_typed (ast_parameter_declarator, param, link, ast_parameters) { 6023bf215546Sopenharmony_ci param->formal_parameter = formal; 6024bf215546Sopenharmony_ci param->hir(ir_parameters, state); 6025bf215546Sopenharmony_ci 6026bf215546Sopenharmony_ci if (param->is_void) 6027bf215546Sopenharmony_ci void_param = param; 6028bf215546Sopenharmony_ci 6029bf215546Sopenharmony_ci count++; 6030bf215546Sopenharmony_ci } 6031bf215546Sopenharmony_ci 6032bf215546Sopenharmony_ci if ((void_param != NULL) && (count > 1)) { 6033bf215546Sopenharmony_ci YYLTYPE loc = void_param->get_location(); 6034bf215546Sopenharmony_ci 6035bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 6036bf215546Sopenharmony_ci "`void' parameter must be only parameter"); 6037bf215546Sopenharmony_ci } 6038bf215546Sopenharmony_ci} 6039bf215546Sopenharmony_ci 6040bf215546Sopenharmony_ci 6041bf215546Sopenharmony_civoid 6042bf215546Sopenharmony_ciemit_function(_mesa_glsl_parse_state *state, ir_function *f) 6043bf215546Sopenharmony_ci{ 6044bf215546Sopenharmony_ci /* IR invariants disallow function declarations or definitions 6045bf215546Sopenharmony_ci * nested within other function definitions. But there is no 6046bf215546Sopenharmony_ci * requirement about the relative order of function declarations 6047bf215546Sopenharmony_ci * and definitions with respect to one another. So simply insert 6048bf215546Sopenharmony_ci * the new ir_function block at the end of the toplevel instruction 6049bf215546Sopenharmony_ci * list. 6050bf215546Sopenharmony_ci */ 6051bf215546Sopenharmony_ci state->toplevel_ir->push_tail(f); 6052bf215546Sopenharmony_ci} 6053bf215546Sopenharmony_ci 6054bf215546Sopenharmony_ci 6055bf215546Sopenharmony_ciir_rvalue * 6056bf215546Sopenharmony_ciast_function::hir(exec_list *instructions, 6057bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 6058bf215546Sopenharmony_ci{ 6059bf215546Sopenharmony_ci void *ctx = state; 6060bf215546Sopenharmony_ci ir_function *f = NULL; 6061bf215546Sopenharmony_ci ir_function_signature *sig = NULL; 6062bf215546Sopenharmony_ci exec_list hir_parameters; 6063bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6064bf215546Sopenharmony_ci 6065bf215546Sopenharmony_ci const char *const name = identifier; 6066bf215546Sopenharmony_ci 6067bf215546Sopenharmony_ci /* New functions are always added to the top-level IR instruction stream, 6068bf215546Sopenharmony_ci * so this instruction list pointer is ignored. See also emit_function 6069bf215546Sopenharmony_ci * (called below). 6070bf215546Sopenharmony_ci */ 6071bf215546Sopenharmony_ci (void) instructions; 6072bf215546Sopenharmony_ci 6073bf215546Sopenharmony_ci /* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec, 6074bf215546Sopenharmony_ci * 6075bf215546Sopenharmony_ci * "Function declarations (prototypes) cannot occur inside of functions; 6076bf215546Sopenharmony_ci * they must be at global scope, or for the built-in functions, outside 6077bf215546Sopenharmony_ci * the global scope." 6078bf215546Sopenharmony_ci * 6079bf215546Sopenharmony_ci * From page 27 (page 33 of the PDF) of the GLSL ES 1.00.16 spec, 6080bf215546Sopenharmony_ci * 6081bf215546Sopenharmony_ci * "User defined functions may only be defined within the global scope." 6082bf215546Sopenharmony_ci * 6083bf215546Sopenharmony_ci * Note that this language does not appear in GLSL 1.10. 6084bf215546Sopenharmony_ci */ 6085bf215546Sopenharmony_ci if ((state->current_function != NULL) && 6086bf215546Sopenharmony_ci state->is_version(120, 100)) { 6087bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6088bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 6089bf215546Sopenharmony_ci "declaration of function `%s' not allowed within " 6090bf215546Sopenharmony_ci "function body", name); 6091bf215546Sopenharmony_ci } 6092bf215546Sopenharmony_ci 6093bf215546Sopenharmony_ci validate_identifier(name, this->get_location(), state); 6094bf215546Sopenharmony_ci 6095bf215546Sopenharmony_ci /* Convert the list of function parameters to HIR now so that they can be 6096bf215546Sopenharmony_ci * used below to compare this function's signature with previously seen 6097bf215546Sopenharmony_ci * signatures for functions with the same name. 6098bf215546Sopenharmony_ci */ 6099bf215546Sopenharmony_ci ast_parameter_declarator::parameters_to_hir(& this->parameters, 6100bf215546Sopenharmony_ci is_definition, 6101bf215546Sopenharmony_ci & hir_parameters, state); 6102bf215546Sopenharmony_ci 6103bf215546Sopenharmony_ci const char *return_type_name; 6104bf215546Sopenharmony_ci const glsl_type *return_type = 6105bf215546Sopenharmony_ci this->return_type->glsl_type(& return_type_name, state); 6106bf215546Sopenharmony_ci 6107bf215546Sopenharmony_ci if (!return_type) { 6108bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6109bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 6110bf215546Sopenharmony_ci "function `%s' has undeclared return type `%s'", 6111bf215546Sopenharmony_ci name, return_type_name); 6112bf215546Sopenharmony_ci return_type = glsl_type::error_type; 6113bf215546Sopenharmony_ci } 6114bf215546Sopenharmony_ci 6115bf215546Sopenharmony_ci /* ARB_shader_subroutine states: 6116bf215546Sopenharmony_ci * "Subroutine declarations cannot be prototyped. It is an error to prepend 6117bf215546Sopenharmony_ci * subroutine(...) to a function declaration." 6118bf215546Sopenharmony_ci */ 6119bf215546Sopenharmony_ci if (this->return_type->qualifier.subroutine_list && !is_definition) { 6120bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6121bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 6122bf215546Sopenharmony_ci "function declaration `%s' cannot have subroutine prepended", 6123bf215546Sopenharmony_ci name); 6124bf215546Sopenharmony_ci } 6125bf215546Sopenharmony_ci 6126bf215546Sopenharmony_ci /* From page 56 (page 62 of the PDF) of the GLSL 1.30 spec: 6127bf215546Sopenharmony_ci * "No qualifier is allowed on the return type of a function." 6128bf215546Sopenharmony_ci */ 6129bf215546Sopenharmony_ci if (this->return_type->has_qualifiers(state)) { 6130bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6131bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 6132bf215546Sopenharmony_ci "function `%s' return type has qualifiers", name); 6133bf215546Sopenharmony_ci } 6134bf215546Sopenharmony_ci 6135bf215546Sopenharmony_ci /* Section 6.1 (Function Definitions) of the GLSL 1.20 spec says: 6136bf215546Sopenharmony_ci * 6137bf215546Sopenharmony_ci * "Arrays are allowed as arguments and as the return type. In both 6138bf215546Sopenharmony_ci * cases, the array must be explicitly sized." 6139bf215546Sopenharmony_ci */ 6140bf215546Sopenharmony_ci if (return_type->is_unsized_array()) { 6141bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6142bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 6143bf215546Sopenharmony_ci "function `%s' return type array must be explicitly " 6144bf215546Sopenharmony_ci "sized", name); 6145bf215546Sopenharmony_ci } 6146bf215546Sopenharmony_ci 6147bf215546Sopenharmony_ci /* From Section 6.1 (Function Definitions) of the GLSL 1.00 spec: 6148bf215546Sopenharmony_ci * 6149bf215546Sopenharmony_ci * "Arrays are allowed as arguments, but not as the return type. [...] 6150bf215546Sopenharmony_ci * The return type can also be a structure if the structure does not 6151bf215546Sopenharmony_ci * contain an array." 6152bf215546Sopenharmony_ci */ 6153bf215546Sopenharmony_ci if (state->language_version == 100 && return_type->contains_array()) { 6154bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6155bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 6156bf215546Sopenharmony_ci "function `%s' return type contains an array", name); 6157bf215546Sopenharmony_ci } 6158bf215546Sopenharmony_ci 6159bf215546Sopenharmony_ci /* From section 4.1.7 of the GLSL 4.40 spec: 6160bf215546Sopenharmony_ci * 6161bf215546Sopenharmony_ci * "[Opaque types] can only be declared as function parameters 6162bf215546Sopenharmony_ci * or uniform-qualified variables." 6163bf215546Sopenharmony_ci * 6164bf215546Sopenharmony_ci * The ARB_bindless_texture spec doesn't clearly state this, but as it says 6165bf215546Sopenharmony_ci * "Replace Section 4.1.7 (Samplers), p. 25" and, "Replace Section 4.1.X, 6166bf215546Sopenharmony_ci * (Images)", this should be allowed. 6167bf215546Sopenharmony_ci */ 6168bf215546Sopenharmony_ci if (return_type->contains_atomic() || 6169bf215546Sopenharmony_ci (!state->has_bindless() && return_type->contains_opaque())) { 6170bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6171bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 6172bf215546Sopenharmony_ci "function `%s' return type can't contain an %s type", 6173bf215546Sopenharmony_ci name, state->has_bindless() ? "atomic" : "opaque"); 6174bf215546Sopenharmony_ci } 6175bf215546Sopenharmony_ci 6176bf215546Sopenharmony_ci /**/ 6177bf215546Sopenharmony_ci if (return_type->is_subroutine()) { 6178bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6179bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 6180bf215546Sopenharmony_ci "function `%s' return type can't be a subroutine type", 6181bf215546Sopenharmony_ci name); 6182bf215546Sopenharmony_ci } 6183bf215546Sopenharmony_ci 6184bf215546Sopenharmony_ci /* Get the precision for the return type */ 6185bf215546Sopenharmony_ci unsigned return_precision; 6186bf215546Sopenharmony_ci 6187bf215546Sopenharmony_ci if (state->es_shader) { 6188bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6189bf215546Sopenharmony_ci return_precision = 6190bf215546Sopenharmony_ci select_gles_precision(this->return_type->qualifier.precision, 6191bf215546Sopenharmony_ci return_type, 6192bf215546Sopenharmony_ci state, 6193bf215546Sopenharmony_ci &loc); 6194bf215546Sopenharmony_ci } else { 6195bf215546Sopenharmony_ci return_precision = GLSL_PRECISION_NONE; 6196bf215546Sopenharmony_ci } 6197bf215546Sopenharmony_ci 6198bf215546Sopenharmony_ci /* Create an ir_function if one doesn't already exist. */ 6199bf215546Sopenharmony_ci f = state->symbols->get_function(name); 6200bf215546Sopenharmony_ci if (f == NULL) { 6201bf215546Sopenharmony_ci f = new(ctx) ir_function(name); 6202bf215546Sopenharmony_ci if (!this->return_type->qualifier.is_subroutine_decl()) { 6203bf215546Sopenharmony_ci if (!state->symbols->add_function(f)) { 6204bf215546Sopenharmony_ci /* This function name shadows a non-function use of the same name. */ 6205bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6206bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "function name `%s' conflicts with " 6207bf215546Sopenharmony_ci "non-function", name); 6208bf215546Sopenharmony_ci return NULL; 6209bf215546Sopenharmony_ci } 6210bf215546Sopenharmony_ci } 6211bf215546Sopenharmony_ci emit_function(state, f); 6212bf215546Sopenharmony_ci } 6213bf215546Sopenharmony_ci 6214bf215546Sopenharmony_ci /* From GLSL ES 3.0 spec, chapter 6.1 "Function Definitions", page 71: 6215bf215546Sopenharmony_ci * 6216bf215546Sopenharmony_ci * "A shader cannot redefine or overload built-in functions." 6217bf215546Sopenharmony_ci * 6218bf215546Sopenharmony_ci * While in GLSL ES 1.0 specification, chapter 8 "Built-in Functions": 6219bf215546Sopenharmony_ci * 6220bf215546Sopenharmony_ci * "User code can overload the built-in functions but cannot redefine 6221bf215546Sopenharmony_ci * them." 6222bf215546Sopenharmony_ci */ 6223bf215546Sopenharmony_ci if (state->es_shader) { 6224bf215546Sopenharmony_ci /* Local shader has no exact candidates; check the built-ins. */ 6225bf215546Sopenharmony_ci if (state->language_version >= 300 && 6226bf215546Sopenharmony_ci _mesa_glsl_has_builtin_function(state, name)) { 6227bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6228bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 6229bf215546Sopenharmony_ci "A shader cannot redefine or overload built-in " 6230bf215546Sopenharmony_ci "function `%s' in GLSL ES 3.00", name); 6231bf215546Sopenharmony_ci return NULL; 6232bf215546Sopenharmony_ci } 6233bf215546Sopenharmony_ci 6234bf215546Sopenharmony_ci if (state->language_version == 100) { 6235bf215546Sopenharmony_ci ir_function_signature *sig = 6236bf215546Sopenharmony_ci _mesa_glsl_find_builtin_function(state, name, &hir_parameters); 6237bf215546Sopenharmony_ci if (sig && sig->is_builtin()) { 6238bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 6239bf215546Sopenharmony_ci "A shader cannot redefine built-in " 6240bf215546Sopenharmony_ci "function `%s' in GLSL ES 1.00", name); 6241bf215546Sopenharmony_ci } 6242bf215546Sopenharmony_ci } 6243bf215546Sopenharmony_ci } 6244bf215546Sopenharmony_ci 6245bf215546Sopenharmony_ci /* Verify that this function's signature either doesn't match a previously 6246bf215546Sopenharmony_ci * seen signature for a function with the same name, or, if a match is found, 6247bf215546Sopenharmony_ci * that the previously seen signature does not have an associated definition. 6248bf215546Sopenharmony_ci */ 6249bf215546Sopenharmony_ci if (state->es_shader || f->has_user_signature()) { 6250bf215546Sopenharmony_ci sig = f->exact_matching_signature(state, &hir_parameters); 6251bf215546Sopenharmony_ci if (sig != NULL) { 6252bf215546Sopenharmony_ci const char *badvar = sig->qualifiers_match(&hir_parameters); 6253bf215546Sopenharmony_ci if (badvar != NULL) { 6254bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6255bf215546Sopenharmony_ci 6256bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "function `%s' parameter `%s' " 6257bf215546Sopenharmony_ci "qualifiers don't match prototype", name, badvar); 6258bf215546Sopenharmony_ci } 6259bf215546Sopenharmony_ci 6260bf215546Sopenharmony_ci if (sig->return_type != return_type) { 6261bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6262bf215546Sopenharmony_ci 6263bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "function `%s' return type doesn't " 6264bf215546Sopenharmony_ci "match prototype", name); 6265bf215546Sopenharmony_ci } 6266bf215546Sopenharmony_ci 6267bf215546Sopenharmony_ci if (sig->return_precision != return_precision) { 6268bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6269bf215546Sopenharmony_ci 6270bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "function `%s' return type precision " 6271bf215546Sopenharmony_ci "doesn't match prototype", name); 6272bf215546Sopenharmony_ci } 6273bf215546Sopenharmony_ci 6274bf215546Sopenharmony_ci if (sig->is_defined) { 6275bf215546Sopenharmony_ci if (is_definition) { 6276bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6277bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "function `%s' redefined", name); 6278bf215546Sopenharmony_ci } else { 6279bf215546Sopenharmony_ci /* We just encountered a prototype that exactly matches a 6280bf215546Sopenharmony_ci * function that's already been defined. This is redundant, 6281bf215546Sopenharmony_ci * and we should ignore it. 6282bf215546Sopenharmony_ci */ 6283bf215546Sopenharmony_ci return NULL; 6284bf215546Sopenharmony_ci } 6285bf215546Sopenharmony_ci } else if (state->language_version == 100 && !is_definition) { 6286bf215546Sopenharmony_ci /* From the GLSL 1.00 spec, section 4.2.7: 6287bf215546Sopenharmony_ci * 6288bf215546Sopenharmony_ci * "A particular variable, structure or function declaration 6289bf215546Sopenharmony_ci * may occur at most once within a scope with the exception 6290bf215546Sopenharmony_ci * that a single function prototype plus the corresponding 6291bf215546Sopenharmony_ci * function definition are allowed." 6292bf215546Sopenharmony_ci */ 6293bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6294bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "function `%s' redeclared", name); 6295bf215546Sopenharmony_ci } 6296bf215546Sopenharmony_ci } 6297bf215546Sopenharmony_ci } 6298bf215546Sopenharmony_ci 6299bf215546Sopenharmony_ci /* Verify the return type of main() */ 6300bf215546Sopenharmony_ci if (strcmp(name, "main") == 0) { 6301bf215546Sopenharmony_ci if (! return_type->is_void()) { 6302bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6303bf215546Sopenharmony_ci 6304bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "main() must return void"); 6305bf215546Sopenharmony_ci } 6306bf215546Sopenharmony_ci 6307bf215546Sopenharmony_ci if (!hir_parameters.is_empty()) { 6308bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6309bf215546Sopenharmony_ci 6310bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "main() must not take any parameters"); 6311bf215546Sopenharmony_ci } 6312bf215546Sopenharmony_ci } 6313bf215546Sopenharmony_ci 6314bf215546Sopenharmony_ci /* Finish storing the information about this new function in its signature. 6315bf215546Sopenharmony_ci */ 6316bf215546Sopenharmony_ci if (sig == NULL) { 6317bf215546Sopenharmony_ci sig = new(ctx) ir_function_signature(return_type); 6318bf215546Sopenharmony_ci sig->return_precision = return_precision; 6319bf215546Sopenharmony_ci f->add_signature(sig); 6320bf215546Sopenharmony_ci } 6321bf215546Sopenharmony_ci 6322bf215546Sopenharmony_ci sig->replace_parameters(&hir_parameters); 6323bf215546Sopenharmony_ci signature = sig; 6324bf215546Sopenharmony_ci 6325bf215546Sopenharmony_ci if (this->return_type->qualifier.subroutine_list) { 6326bf215546Sopenharmony_ci int idx; 6327bf215546Sopenharmony_ci 6328bf215546Sopenharmony_ci if (this->return_type->qualifier.flags.q.explicit_index) { 6329bf215546Sopenharmony_ci unsigned qual_index; 6330bf215546Sopenharmony_ci if (process_qualifier_constant(state, &loc, "index", 6331bf215546Sopenharmony_ci this->return_type->qualifier.index, 6332bf215546Sopenharmony_ci &qual_index)) { 6333bf215546Sopenharmony_ci if (!state->has_explicit_uniform_location()) { 6334bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "subroutine index requires " 6335bf215546Sopenharmony_ci "GL_ARB_explicit_uniform_location or " 6336bf215546Sopenharmony_ci "GLSL 4.30"); 6337bf215546Sopenharmony_ci } else if (qual_index >= MAX_SUBROUTINES) { 6338bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 6339bf215546Sopenharmony_ci "invalid subroutine index (%d) index must " 6340bf215546Sopenharmony_ci "be a number between 0 and " 6341bf215546Sopenharmony_ci "GL_MAX_SUBROUTINES - 1 (%d)", qual_index, 6342bf215546Sopenharmony_ci MAX_SUBROUTINES - 1); 6343bf215546Sopenharmony_ci } else { 6344bf215546Sopenharmony_ci f->subroutine_index = qual_index; 6345bf215546Sopenharmony_ci } 6346bf215546Sopenharmony_ci } 6347bf215546Sopenharmony_ci } 6348bf215546Sopenharmony_ci 6349bf215546Sopenharmony_ci f->num_subroutine_types = this->return_type->qualifier.subroutine_list->declarations.length(); 6350bf215546Sopenharmony_ci f->subroutine_types = ralloc_array(state, const struct glsl_type *, 6351bf215546Sopenharmony_ci f->num_subroutine_types); 6352bf215546Sopenharmony_ci idx = 0; 6353bf215546Sopenharmony_ci foreach_list_typed(ast_declaration, decl, link, &this->return_type->qualifier.subroutine_list->declarations) { 6354bf215546Sopenharmony_ci const struct glsl_type *type; 6355bf215546Sopenharmony_ci /* the subroutine type must be already declared */ 6356bf215546Sopenharmony_ci type = state->symbols->get_type(decl->identifier); 6357bf215546Sopenharmony_ci if (!type) { 6358bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "unknown type '%s' in subroutine function definition", decl->identifier); 6359bf215546Sopenharmony_ci } 6360bf215546Sopenharmony_ci 6361bf215546Sopenharmony_ci for (int i = 0; i < state->num_subroutine_types; i++) { 6362bf215546Sopenharmony_ci ir_function *fn = state->subroutine_types[i]; 6363bf215546Sopenharmony_ci ir_function_signature *tsig = NULL; 6364bf215546Sopenharmony_ci 6365bf215546Sopenharmony_ci if (strcmp(fn->name, decl->identifier)) 6366bf215546Sopenharmony_ci continue; 6367bf215546Sopenharmony_ci 6368bf215546Sopenharmony_ci tsig = fn->matching_signature(state, &sig->parameters, 6369bf215546Sopenharmony_ci false); 6370bf215546Sopenharmony_ci if (!tsig) { 6371bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "subroutine type mismatch '%s' - signatures do not match\n", decl->identifier); 6372bf215546Sopenharmony_ci } else { 6373bf215546Sopenharmony_ci if (tsig->return_type != sig->return_type) { 6374bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "subroutine type mismatch '%s' - return types do not match\n", decl->identifier); 6375bf215546Sopenharmony_ci } 6376bf215546Sopenharmony_ci } 6377bf215546Sopenharmony_ci } 6378bf215546Sopenharmony_ci f->subroutine_types[idx++] = type; 6379bf215546Sopenharmony_ci } 6380bf215546Sopenharmony_ci state->subroutines = (ir_function **)reralloc(state, state->subroutines, 6381bf215546Sopenharmony_ci ir_function *, 6382bf215546Sopenharmony_ci state->num_subroutines + 1); 6383bf215546Sopenharmony_ci state->subroutines[state->num_subroutines] = f; 6384bf215546Sopenharmony_ci state->num_subroutines++; 6385bf215546Sopenharmony_ci 6386bf215546Sopenharmony_ci } 6387bf215546Sopenharmony_ci 6388bf215546Sopenharmony_ci if (this->return_type->qualifier.is_subroutine_decl()) { 6389bf215546Sopenharmony_ci if (!state->symbols->add_type(this->identifier, glsl_type::get_subroutine_instance(this->identifier))) { 6390bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "type '%s' previously defined", this->identifier); 6391bf215546Sopenharmony_ci return NULL; 6392bf215546Sopenharmony_ci } 6393bf215546Sopenharmony_ci state->subroutine_types = (ir_function **)reralloc(state, state->subroutine_types, 6394bf215546Sopenharmony_ci ir_function *, 6395bf215546Sopenharmony_ci state->num_subroutine_types + 1); 6396bf215546Sopenharmony_ci state->subroutine_types[state->num_subroutine_types] = f; 6397bf215546Sopenharmony_ci state->num_subroutine_types++; 6398bf215546Sopenharmony_ci 6399bf215546Sopenharmony_ci f->is_subroutine = true; 6400bf215546Sopenharmony_ci } 6401bf215546Sopenharmony_ci 6402bf215546Sopenharmony_ci /* Function declarations (prototypes) do not have r-values. 6403bf215546Sopenharmony_ci */ 6404bf215546Sopenharmony_ci return NULL; 6405bf215546Sopenharmony_ci} 6406bf215546Sopenharmony_ci 6407bf215546Sopenharmony_ci 6408bf215546Sopenharmony_ciir_rvalue * 6409bf215546Sopenharmony_ciast_function_definition::hir(exec_list *instructions, 6410bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 6411bf215546Sopenharmony_ci{ 6412bf215546Sopenharmony_ci prototype->is_definition = true; 6413bf215546Sopenharmony_ci prototype->hir(instructions, state); 6414bf215546Sopenharmony_ci 6415bf215546Sopenharmony_ci ir_function_signature *signature = prototype->signature; 6416bf215546Sopenharmony_ci if (signature == NULL) 6417bf215546Sopenharmony_ci return NULL; 6418bf215546Sopenharmony_ci 6419bf215546Sopenharmony_ci assert(state->current_function == NULL); 6420bf215546Sopenharmony_ci state->current_function = signature; 6421bf215546Sopenharmony_ci state->found_return = false; 6422bf215546Sopenharmony_ci state->found_begin_interlock = false; 6423bf215546Sopenharmony_ci state->found_end_interlock = false; 6424bf215546Sopenharmony_ci 6425bf215546Sopenharmony_ci /* Duplicate parameters declared in the prototype as concrete variables. 6426bf215546Sopenharmony_ci * Add these to the symbol table. 6427bf215546Sopenharmony_ci */ 6428bf215546Sopenharmony_ci state->symbols->push_scope(); 6429bf215546Sopenharmony_ci foreach_in_list(ir_variable, var, &signature->parameters) { 6430bf215546Sopenharmony_ci assert(var->as_variable() != NULL); 6431bf215546Sopenharmony_ci 6432bf215546Sopenharmony_ci /* The only way a parameter would "exist" is if two parameters have 6433bf215546Sopenharmony_ci * the same name. 6434bf215546Sopenharmony_ci */ 6435bf215546Sopenharmony_ci if (state->symbols->name_declared_this_scope(var->name)) { 6436bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6437bf215546Sopenharmony_ci 6438bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name); 6439bf215546Sopenharmony_ci } else { 6440bf215546Sopenharmony_ci state->symbols->add_variable(var); 6441bf215546Sopenharmony_ci } 6442bf215546Sopenharmony_ci } 6443bf215546Sopenharmony_ci 6444bf215546Sopenharmony_ci /* Convert the body of the function to HIR. */ 6445bf215546Sopenharmony_ci this->body->hir(&signature->body, state); 6446bf215546Sopenharmony_ci signature->is_defined = true; 6447bf215546Sopenharmony_ci 6448bf215546Sopenharmony_ci state->symbols->pop_scope(); 6449bf215546Sopenharmony_ci 6450bf215546Sopenharmony_ci assert(state->current_function == signature); 6451bf215546Sopenharmony_ci state->current_function = NULL; 6452bf215546Sopenharmony_ci 6453bf215546Sopenharmony_ci if (!signature->return_type->is_void() && !state->found_return) { 6454bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6455bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "function `%s' has non-void return type " 6456bf215546Sopenharmony_ci "%s, but no return statement", 6457bf215546Sopenharmony_ci signature->function_name(), 6458bf215546Sopenharmony_ci signature->return_type->name); 6459bf215546Sopenharmony_ci } 6460bf215546Sopenharmony_ci 6461bf215546Sopenharmony_ci /* Function definitions do not have r-values. 6462bf215546Sopenharmony_ci */ 6463bf215546Sopenharmony_ci return NULL; 6464bf215546Sopenharmony_ci} 6465bf215546Sopenharmony_ci 6466bf215546Sopenharmony_ci 6467bf215546Sopenharmony_ciir_rvalue * 6468bf215546Sopenharmony_ciast_jump_statement::hir(exec_list *instructions, 6469bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 6470bf215546Sopenharmony_ci{ 6471bf215546Sopenharmony_ci void *ctx = state; 6472bf215546Sopenharmony_ci 6473bf215546Sopenharmony_ci switch (mode) { 6474bf215546Sopenharmony_ci case ast_return: { 6475bf215546Sopenharmony_ci ir_return *inst; 6476bf215546Sopenharmony_ci assert(state->current_function); 6477bf215546Sopenharmony_ci 6478bf215546Sopenharmony_ci if (opt_return_value) { 6479bf215546Sopenharmony_ci ir_rvalue *ret = opt_return_value->hir(instructions, state); 6480bf215546Sopenharmony_ci 6481bf215546Sopenharmony_ci /* The value of the return type can be NULL if the shader says 6482bf215546Sopenharmony_ci * 'return foo();' and foo() is a function that returns void. 6483bf215546Sopenharmony_ci * 6484bf215546Sopenharmony_ci * NOTE: The GLSL spec doesn't say that this is an error. The type 6485bf215546Sopenharmony_ci * of the return value is void. If the return type of the function is 6486bf215546Sopenharmony_ci * also void, then this should compile without error. Seriously. 6487bf215546Sopenharmony_ci */ 6488bf215546Sopenharmony_ci const glsl_type *const ret_type = 6489bf215546Sopenharmony_ci (ret == NULL) ? glsl_type::void_type : ret->type; 6490bf215546Sopenharmony_ci 6491bf215546Sopenharmony_ci /* Implicit conversions are not allowed for return values prior to 6492bf215546Sopenharmony_ci * ARB_shading_language_420pack. 6493bf215546Sopenharmony_ci */ 6494bf215546Sopenharmony_ci if (state->current_function->return_type != ret_type) { 6495bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6496bf215546Sopenharmony_ci 6497bf215546Sopenharmony_ci if (state->has_420pack()) { 6498bf215546Sopenharmony_ci if (!apply_implicit_conversion(state->current_function->return_type, 6499bf215546Sopenharmony_ci ret, state) 6500bf215546Sopenharmony_ci || (ret->type != state->current_function->return_type)) { 6501bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 6502bf215546Sopenharmony_ci "could not implicitly convert return value " 6503bf215546Sopenharmony_ci "to %s, in function `%s'", 6504bf215546Sopenharmony_ci state->current_function->return_type->name, 6505bf215546Sopenharmony_ci state->current_function->function_name()); 6506bf215546Sopenharmony_ci } 6507bf215546Sopenharmony_ci } else { 6508bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 6509bf215546Sopenharmony_ci "`return' with wrong type %s, in function `%s' " 6510bf215546Sopenharmony_ci "returning %s", 6511bf215546Sopenharmony_ci ret_type->name, 6512bf215546Sopenharmony_ci state->current_function->function_name(), 6513bf215546Sopenharmony_ci state->current_function->return_type->name); 6514bf215546Sopenharmony_ci } 6515bf215546Sopenharmony_ci } else if (state->current_function->return_type->base_type == 6516bf215546Sopenharmony_ci GLSL_TYPE_VOID) { 6517bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6518bf215546Sopenharmony_ci 6519bf215546Sopenharmony_ci /* The ARB_shading_language_420pack, GLSL ES 3.0, and GLSL 4.20 6520bf215546Sopenharmony_ci * specs add a clarification: 6521bf215546Sopenharmony_ci * 6522bf215546Sopenharmony_ci * "A void function can only use return without a return argument, even if 6523bf215546Sopenharmony_ci * the return argument has void type. Return statements only accept values: 6524bf215546Sopenharmony_ci * 6525bf215546Sopenharmony_ci * void func1() { } 6526bf215546Sopenharmony_ci * void func2() { return func1(); } // illegal return statement" 6527bf215546Sopenharmony_ci */ 6528bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 6529bf215546Sopenharmony_ci "void functions can only use `return' without a " 6530bf215546Sopenharmony_ci "return argument"); 6531bf215546Sopenharmony_ci } 6532bf215546Sopenharmony_ci 6533bf215546Sopenharmony_ci inst = new(ctx) ir_return(ret); 6534bf215546Sopenharmony_ci } else { 6535bf215546Sopenharmony_ci if (state->current_function->return_type->base_type != 6536bf215546Sopenharmony_ci GLSL_TYPE_VOID) { 6537bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6538bf215546Sopenharmony_ci 6539bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 6540bf215546Sopenharmony_ci "`return' with no value, in function %s returning " 6541bf215546Sopenharmony_ci "non-void", 6542bf215546Sopenharmony_ci state->current_function->function_name()); 6543bf215546Sopenharmony_ci } 6544bf215546Sopenharmony_ci inst = new(ctx) ir_return; 6545bf215546Sopenharmony_ci } 6546bf215546Sopenharmony_ci 6547bf215546Sopenharmony_ci state->found_return = true; 6548bf215546Sopenharmony_ci instructions->push_tail(inst); 6549bf215546Sopenharmony_ci break; 6550bf215546Sopenharmony_ci } 6551bf215546Sopenharmony_ci 6552bf215546Sopenharmony_ci case ast_discard: 6553bf215546Sopenharmony_ci if (state->stage != MESA_SHADER_FRAGMENT) { 6554bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6555bf215546Sopenharmony_ci 6556bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 6557bf215546Sopenharmony_ci "`discard' may only appear in a fragment shader"); 6558bf215546Sopenharmony_ci } 6559bf215546Sopenharmony_ci instructions->push_tail(new(ctx) ir_discard); 6560bf215546Sopenharmony_ci break; 6561bf215546Sopenharmony_ci 6562bf215546Sopenharmony_ci case ast_break: 6563bf215546Sopenharmony_ci case ast_continue: 6564bf215546Sopenharmony_ci if (mode == ast_continue && 6565bf215546Sopenharmony_ci state->loop_nesting_ast == NULL) { 6566bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6567bf215546Sopenharmony_ci 6568bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "continue may only appear in a loop"); 6569bf215546Sopenharmony_ci } else if (mode == ast_break && 6570bf215546Sopenharmony_ci state->loop_nesting_ast == NULL && 6571bf215546Sopenharmony_ci state->switch_state.switch_nesting_ast == NULL) { 6572bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6573bf215546Sopenharmony_ci 6574bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 6575bf215546Sopenharmony_ci "break may only appear in a loop or a switch"); 6576bf215546Sopenharmony_ci } else { 6577bf215546Sopenharmony_ci /* For a loop, inline the for loop expression again, since we don't 6578bf215546Sopenharmony_ci * know where near the end of the loop body the normal copy of it is 6579bf215546Sopenharmony_ci * going to be placed. Same goes for the condition for a do-while 6580bf215546Sopenharmony_ci * loop. 6581bf215546Sopenharmony_ci */ 6582bf215546Sopenharmony_ci if (state->loop_nesting_ast != NULL && 6583bf215546Sopenharmony_ci mode == ast_continue && !state->switch_state.is_switch_innermost) { 6584bf215546Sopenharmony_ci if (state->loop_nesting_ast->rest_expression) { 6585bf215546Sopenharmony_ci clone_ir_list(ctx, instructions, 6586bf215546Sopenharmony_ci &state->loop_nesting_ast->rest_instructions); 6587bf215546Sopenharmony_ci } 6588bf215546Sopenharmony_ci if (state->loop_nesting_ast->mode == 6589bf215546Sopenharmony_ci ast_iteration_statement::ast_do_while) { 6590bf215546Sopenharmony_ci state->loop_nesting_ast->condition_to_hir(instructions, state); 6591bf215546Sopenharmony_ci } 6592bf215546Sopenharmony_ci } 6593bf215546Sopenharmony_ci 6594bf215546Sopenharmony_ci if (state->switch_state.is_switch_innermost && 6595bf215546Sopenharmony_ci mode == ast_continue) { 6596bf215546Sopenharmony_ci /* Set 'continue_inside' to true. */ 6597bf215546Sopenharmony_ci ir_rvalue *const true_val = new (ctx) ir_constant(true); 6598bf215546Sopenharmony_ci ir_dereference_variable *deref_continue_inside_var = 6599bf215546Sopenharmony_ci new(ctx) ir_dereference_variable(state->switch_state.continue_inside); 6600bf215546Sopenharmony_ci instructions->push_tail(new(ctx) ir_assignment(deref_continue_inside_var, 6601bf215546Sopenharmony_ci true_val)); 6602bf215546Sopenharmony_ci 6603bf215546Sopenharmony_ci /* Break out from the switch, continue for the loop will 6604bf215546Sopenharmony_ci * be called right after switch. */ 6605bf215546Sopenharmony_ci ir_loop_jump *const jump = 6606bf215546Sopenharmony_ci new(ctx) ir_loop_jump(ir_loop_jump::jump_break); 6607bf215546Sopenharmony_ci instructions->push_tail(jump); 6608bf215546Sopenharmony_ci 6609bf215546Sopenharmony_ci } else if (state->switch_state.is_switch_innermost && 6610bf215546Sopenharmony_ci mode == ast_break) { 6611bf215546Sopenharmony_ci /* Force break out of switch by inserting a break. */ 6612bf215546Sopenharmony_ci ir_loop_jump *const jump = 6613bf215546Sopenharmony_ci new(ctx) ir_loop_jump(ir_loop_jump::jump_break); 6614bf215546Sopenharmony_ci instructions->push_tail(jump); 6615bf215546Sopenharmony_ci } else { 6616bf215546Sopenharmony_ci ir_loop_jump *const jump = 6617bf215546Sopenharmony_ci new(ctx) ir_loop_jump((mode == ast_break) 6618bf215546Sopenharmony_ci ? ir_loop_jump::jump_break 6619bf215546Sopenharmony_ci : ir_loop_jump::jump_continue); 6620bf215546Sopenharmony_ci instructions->push_tail(jump); 6621bf215546Sopenharmony_ci } 6622bf215546Sopenharmony_ci } 6623bf215546Sopenharmony_ci 6624bf215546Sopenharmony_ci break; 6625bf215546Sopenharmony_ci } 6626bf215546Sopenharmony_ci 6627bf215546Sopenharmony_ci /* Jump instructions do not have r-values. 6628bf215546Sopenharmony_ci */ 6629bf215546Sopenharmony_ci return NULL; 6630bf215546Sopenharmony_ci} 6631bf215546Sopenharmony_ci 6632bf215546Sopenharmony_ci 6633bf215546Sopenharmony_ciir_rvalue * 6634bf215546Sopenharmony_ciast_demote_statement::hir(exec_list *instructions, 6635bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 6636bf215546Sopenharmony_ci{ 6637bf215546Sopenharmony_ci void *ctx = state; 6638bf215546Sopenharmony_ci 6639bf215546Sopenharmony_ci if (state->stage != MESA_SHADER_FRAGMENT) { 6640bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 6641bf215546Sopenharmony_ci 6642bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 6643bf215546Sopenharmony_ci "`demote' may only appear in a fragment shader"); 6644bf215546Sopenharmony_ci } 6645bf215546Sopenharmony_ci 6646bf215546Sopenharmony_ci instructions->push_tail(new(ctx) ir_demote); 6647bf215546Sopenharmony_ci 6648bf215546Sopenharmony_ci return NULL; 6649bf215546Sopenharmony_ci} 6650bf215546Sopenharmony_ci 6651bf215546Sopenharmony_ci 6652bf215546Sopenharmony_ciir_rvalue * 6653bf215546Sopenharmony_ciast_selection_statement::hir(exec_list *instructions, 6654bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 6655bf215546Sopenharmony_ci{ 6656bf215546Sopenharmony_ci void *ctx = state; 6657bf215546Sopenharmony_ci 6658bf215546Sopenharmony_ci ir_rvalue *const condition = this->condition->hir(instructions, state); 6659bf215546Sopenharmony_ci 6660bf215546Sopenharmony_ci /* From page 66 (page 72 of the PDF) of the GLSL 1.50 spec: 6661bf215546Sopenharmony_ci * 6662bf215546Sopenharmony_ci * "Any expression whose type evaluates to a Boolean can be used as the 6663bf215546Sopenharmony_ci * conditional expression bool-expression. Vector types are not accepted 6664bf215546Sopenharmony_ci * as the expression to if." 6665bf215546Sopenharmony_ci * 6666bf215546Sopenharmony_ci * The checks are separated so that higher quality diagnostics can be 6667bf215546Sopenharmony_ci * generated for cases where both rules are violated. 6668bf215546Sopenharmony_ci */ 6669bf215546Sopenharmony_ci if (!condition->type->is_boolean() || !condition->type->is_scalar()) { 6670bf215546Sopenharmony_ci YYLTYPE loc = this->condition->get_location(); 6671bf215546Sopenharmony_ci 6672bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "if-statement condition must be scalar " 6673bf215546Sopenharmony_ci "boolean"); 6674bf215546Sopenharmony_ci } 6675bf215546Sopenharmony_ci 6676bf215546Sopenharmony_ci ir_if *const stmt = new(ctx) ir_if(condition); 6677bf215546Sopenharmony_ci 6678bf215546Sopenharmony_ci if (then_statement != NULL) { 6679bf215546Sopenharmony_ci state->symbols->push_scope(); 6680bf215546Sopenharmony_ci then_statement->hir(& stmt->then_instructions, state); 6681bf215546Sopenharmony_ci state->symbols->pop_scope(); 6682bf215546Sopenharmony_ci } 6683bf215546Sopenharmony_ci 6684bf215546Sopenharmony_ci if (else_statement != NULL) { 6685bf215546Sopenharmony_ci state->symbols->push_scope(); 6686bf215546Sopenharmony_ci else_statement->hir(& stmt->else_instructions, state); 6687bf215546Sopenharmony_ci state->symbols->pop_scope(); 6688bf215546Sopenharmony_ci } 6689bf215546Sopenharmony_ci 6690bf215546Sopenharmony_ci instructions->push_tail(stmt); 6691bf215546Sopenharmony_ci 6692bf215546Sopenharmony_ci /* if-statements do not have r-values. 6693bf215546Sopenharmony_ci */ 6694bf215546Sopenharmony_ci return NULL; 6695bf215546Sopenharmony_ci} 6696bf215546Sopenharmony_ci 6697bf215546Sopenharmony_ci 6698bf215546Sopenharmony_cistruct case_label { 6699bf215546Sopenharmony_ci /** Value of the case label. */ 6700bf215546Sopenharmony_ci unsigned value; 6701bf215546Sopenharmony_ci 6702bf215546Sopenharmony_ci /** Does this label occur after the default? */ 6703bf215546Sopenharmony_ci bool after_default; 6704bf215546Sopenharmony_ci 6705bf215546Sopenharmony_ci /** 6706bf215546Sopenharmony_ci * AST for the case label. 6707bf215546Sopenharmony_ci * 6708bf215546Sopenharmony_ci * This is only used to generate error messages for duplicate labels. 6709bf215546Sopenharmony_ci */ 6710bf215546Sopenharmony_ci ast_expression *ast; 6711bf215546Sopenharmony_ci}; 6712bf215546Sopenharmony_ci 6713bf215546Sopenharmony_ci/* Used for detection of duplicate case values, compare 6714bf215546Sopenharmony_ci * given contents directly. 6715bf215546Sopenharmony_ci */ 6716bf215546Sopenharmony_cistatic bool 6717bf215546Sopenharmony_cicompare_case_value(const void *a, const void *b) 6718bf215546Sopenharmony_ci{ 6719bf215546Sopenharmony_ci return ((struct case_label *) a)->value == ((struct case_label *) b)->value; 6720bf215546Sopenharmony_ci} 6721bf215546Sopenharmony_ci 6722bf215546Sopenharmony_ci 6723bf215546Sopenharmony_ci/* Used for detection of duplicate case values, just 6724bf215546Sopenharmony_ci * returns key contents as is. 6725bf215546Sopenharmony_ci */ 6726bf215546Sopenharmony_cistatic unsigned 6727bf215546Sopenharmony_cikey_contents(const void *key) 6728bf215546Sopenharmony_ci{ 6729bf215546Sopenharmony_ci return ((struct case_label *) key)->value; 6730bf215546Sopenharmony_ci} 6731bf215546Sopenharmony_ci 6732bf215546Sopenharmony_civoid 6733bf215546Sopenharmony_ciast_switch_statement::eval_test_expression(exec_list *instructions, 6734bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 6735bf215546Sopenharmony_ci{ 6736bf215546Sopenharmony_ci if (test_val == NULL) 6737bf215546Sopenharmony_ci test_val = this->test_expression->hir(instructions, state); 6738bf215546Sopenharmony_ci} 6739bf215546Sopenharmony_ci 6740bf215546Sopenharmony_ciir_rvalue * 6741bf215546Sopenharmony_ciast_switch_statement::hir(exec_list *instructions, 6742bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 6743bf215546Sopenharmony_ci{ 6744bf215546Sopenharmony_ci void *ctx = state; 6745bf215546Sopenharmony_ci 6746bf215546Sopenharmony_ci this->eval_test_expression(instructions, state); 6747bf215546Sopenharmony_ci 6748bf215546Sopenharmony_ci /* From page 66 (page 55 of the PDF) of the GLSL 1.50 spec: 6749bf215546Sopenharmony_ci * 6750bf215546Sopenharmony_ci * "The type of init-expression in a switch statement must be a 6751bf215546Sopenharmony_ci * scalar integer." 6752bf215546Sopenharmony_ci */ 6753bf215546Sopenharmony_ci if (!test_val->type->is_scalar() || 6754bf215546Sopenharmony_ci !test_val->type->is_integer_32()) { 6755bf215546Sopenharmony_ci YYLTYPE loc = this->test_expression->get_location(); 6756bf215546Sopenharmony_ci 6757bf215546Sopenharmony_ci _mesa_glsl_error(& loc, 6758bf215546Sopenharmony_ci state, 6759bf215546Sopenharmony_ci "switch-statement expression must be scalar " 6760bf215546Sopenharmony_ci "integer"); 6761bf215546Sopenharmony_ci return NULL; 6762bf215546Sopenharmony_ci } 6763bf215546Sopenharmony_ci 6764bf215546Sopenharmony_ci /* Track the switch-statement nesting in a stack-like manner. 6765bf215546Sopenharmony_ci */ 6766bf215546Sopenharmony_ci struct glsl_switch_state saved = state->switch_state; 6767bf215546Sopenharmony_ci 6768bf215546Sopenharmony_ci state->switch_state.is_switch_innermost = true; 6769bf215546Sopenharmony_ci state->switch_state.switch_nesting_ast = this; 6770bf215546Sopenharmony_ci state->switch_state.labels_ht = 6771bf215546Sopenharmony_ci _mesa_hash_table_create(NULL, key_contents, 6772bf215546Sopenharmony_ci compare_case_value); 6773bf215546Sopenharmony_ci state->switch_state.previous_default = NULL; 6774bf215546Sopenharmony_ci 6775bf215546Sopenharmony_ci /* Initalize is_fallthru state to false. 6776bf215546Sopenharmony_ci */ 6777bf215546Sopenharmony_ci ir_rvalue *const is_fallthru_val = new (ctx) ir_constant(false); 6778bf215546Sopenharmony_ci state->switch_state.is_fallthru_var = 6779bf215546Sopenharmony_ci new(ctx) ir_variable(glsl_type::bool_type, 6780bf215546Sopenharmony_ci "switch_is_fallthru_tmp", 6781bf215546Sopenharmony_ci ir_var_temporary); 6782bf215546Sopenharmony_ci instructions->push_tail(state->switch_state.is_fallthru_var); 6783bf215546Sopenharmony_ci 6784bf215546Sopenharmony_ci ir_dereference_variable *deref_is_fallthru_var = 6785bf215546Sopenharmony_ci new(ctx) ir_dereference_variable(state->switch_state.is_fallthru_var); 6786bf215546Sopenharmony_ci instructions->push_tail(new(ctx) ir_assignment(deref_is_fallthru_var, 6787bf215546Sopenharmony_ci is_fallthru_val)); 6788bf215546Sopenharmony_ci 6789bf215546Sopenharmony_ci /* Initialize continue_inside state to false. 6790bf215546Sopenharmony_ci */ 6791bf215546Sopenharmony_ci state->switch_state.continue_inside = 6792bf215546Sopenharmony_ci new(ctx) ir_variable(glsl_type::bool_type, 6793bf215546Sopenharmony_ci "continue_inside_tmp", 6794bf215546Sopenharmony_ci ir_var_temporary); 6795bf215546Sopenharmony_ci instructions->push_tail(state->switch_state.continue_inside); 6796bf215546Sopenharmony_ci 6797bf215546Sopenharmony_ci ir_rvalue *const false_val = new (ctx) ir_constant(false); 6798bf215546Sopenharmony_ci ir_dereference_variable *deref_continue_inside_var = 6799bf215546Sopenharmony_ci new(ctx) ir_dereference_variable(state->switch_state.continue_inside); 6800bf215546Sopenharmony_ci instructions->push_tail(new(ctx) ir_assignment(deref_continue_inside_var, 6801bf215546Sopenharmony_ci false_val)); 6802bf215546Sopenharmony_ci 6803bf215546Sopenharmony_ci state->switch_state.run_default = 6804bf215546Sopenharmony_ci new(ctx) ir_variable(glsl_type::bool_type, 6805bf215546Sopenharmony_ci "run_default_tmp", 6806bf215546Sopenharmony_ci ir_var_temporary); 6807bf215546Sopenharmony_ci instructions->push_tail(state->switch_state.run_default); 6808bf215546Sopenharmony_ci 6809bf215546Sopenharmony_ci /* Loop around the switch is used for flow control. */ 6810bf215546Sopenharmony_ci ir_loop * loop = new(ctx) ir_loop(); 6811bf215546Sopenharmony_ci instructions->push_tail(loop); 6812bf215546Sopenharmony_ci 6813bf215546Sopenharmony_ci /* Cache test expression. 6814bf215546Sopenharmony_ci */ 6815bf215546Sopenharmony_ci test_to_hir(&loop->body_instructions, state); 6816bf215546Sopenharmony_ci 6817bf215546Sopenharmony_ci /* Emit code for body of switch stmt. 6818bf215546Sopenharmony_ci */ 6819bf215546Sopenharmony_ci body->hir(&loop->body_instructions, state); 6820bf215546Sopenharmony_ci 6821bf215546Sopenharmony_ci /* Insert a break at the end to exit loop. */ 6822bf215546Sopenharmony_ci ir_loop_jump *jump = new(ctx) ir_loop_jump(ir_loop_jump::jump_break); 6823bf215546Sopenharmony_ci loop->body_instructions.push_tail(jump); 6824bf215546Sopenharmony_ci 6825bf215546Sopenharmony_ci /* If we are inside loop, check if continue got called inside switch. */ 6826bf215546Sopenharmony_ci if (state->loop_nesting_ast != NULL) { 6827bf215546Sopenharmony_ci ir_dereference_variable *deref_continue_inside = 6828bf215546Sopenharmony_ci new(ctx) ir_dereference_variable(state->switch_state.continue_inside); 6829bf215546Sopenharmony_ci ir_if *irif = new(ctx) ir_if(deref_continue_inside); 6830bf215546Sopenharmony_ci ir_loop_jump *jump = new(ctx) ir_loop_jump(ir_loop_jump::jump_continue); 6831bf215546Sopenharmony_ci 6832bf215546Sopenharmony_ci if (state->loop_nesting_ast != NULL) { 6833bf215546Sopenharmony_ci if (state->loop_nesting_ast->rest_expression) { 6834bf215546Sopenharmony_ci clone_ir_list(ctx, &irif->then_instructions, 6835bf215546Sopenharmony_ci &state->loop_nesting_ast->rest_instructions); 6836bf215546Sopenharmony_ci } 6837bf215546Sopenharmony_ci if (state->loop_nesting_ast->mode == 6838bf215546Sopenharmony_ci ast_iteration_statement::ast_do_while) { 6839bf215546Sopenharmony_ci state->loop_nesting_ast->condition_to_hir(&irif->then_instructions, state); 6840bf215546Sopenharmony_ci } 6841bf215546Sopenharmony_ci } 6842bf215546Sopenharmony_ci irif->then_instructions.push_tail(jump); 6843bf215546Sopenharmony_ci instructions->push_tail(irif); 6844bf215546Sopenharmony_ci } 6845bf215546Sopenharmony_ci 6846bf215546Sopenharmony_ci _mesa_hash_table_destroy(state->switch_state.labels_ht, NULL); 6847bf215546Sopenharmony_ci 6848bf215546Sopenharmony_ci state->switch_state = saved; 6849bf215546Sopenharmony_ci 6850bf215546Sopenharmony_ci /* Switch statements do not have r-values. */ 6851bf215546Sopenharmony_ci return NULL; 6852bf215546Sopenharmony_ci} 6853bf215546Sopenharmony_ci 6854bf215546Sopenharmony_ci 6855bf215546Sopenharmony_civoid 6856bf215546Sopenharmony_ciast_switch_statement::test_to_hir(exec_list *instructions, 6857bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 6858bf215546Sopenharmony_ci{ 6859bf215546Sopenharmony_ci void *ctx = state; 6860bf215546Sopenharmony_ci 6861bf215546Sopenharmony_ci /* set to true to avoid a duplicate "use of uninitialized variable" warning 6862bf215546Sopenharmony_ci * on the switch test case. The first one would be already raised when 6863bf215546Sopenharmony_ci * getting the test_expression at ast_switch_statement::hir 6864bf215546Sopenharmony_ci */ 6865bf215546Sopenharmony_ci test_expression->set_is_lhs(true); 6866bf215546Sopenharmony_ci /* Cache value of test expression. */ 6867bf215546Sopenharmony_ci this->eval_test_expression(instructions, state); 6868bf215546Sopenharmony_ci 6869bf215546Sopenharmony_ci state->switch_state.test_var = new(ctx) ir_variable(test_val->type, 6870bf215546Sopenharmony_ci "switch_test_tmp", 6871bf215546Sopenharmony_ci ir_var_temporary); 6872bf215546Sopenharmony_ci ir_dereference_variable *deref_test_var = 6873bf215546Sopenharmony_ci new(ctx) ir_dereference_variable(state->switch_state.test_var); 6874bf215546Sopenharmony_ci 6875bf215546Sopenharmony_ci instructions->push_tail(state->switch_state.test_var); 6876bf215546Sopenharmony_ci instructions->push_tail(new(ctx) ir_assignment(deref_test_var, test_val)); 6877bf215546Sopenharmony_ci} 6878bf215546Sopenharmony_ci 6879bf215546Sopenharmony_ci 6880bf215546Sopenharmony_ciir_rvalue * 6881bf215546Sopenharmony_ciast_switch_body::hir(exec_list *instructions, 6882bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 6883bf215546Sopenharmony_ci{ 6884bf215546Sopenharmony_ci if (stmts != NULL) { 6885bf215546Sopenharmony_ci state->symbols->push_scope(); 6886bf215546Sopenharmony_ci stmts->hir(instructions, state); 6887bf215546Sopenharmony_ci state->symbols->pop_scope(); 6888bf215546Sopenharmony_ci } 6889bf215546Sopenharmony_ci 6890bf215546Sopenharmony_ci /* Switch bodies do not have r-values. */ 6891bf215546Sopenharmony_ci return NULL; 6892bf215546Sopenharmony_ci} 6893bf215546Sopenharmony_ci 6894bf215546Sopenharmony_ciir_rvalue * 6895bf215546Sopenharmony_ciast_case_statement_list::hir(exec_list *instructions, 6896bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 6897bf215546Sopenharmony_ci{ 6898bf215546Sopenharmony_ci exec_list default_case, after_default, tmp; 6899bf215546Sopenharmony_ci 6900bf215546Sopenharmony_ci foreach_list_typed (ast_case_statement, case_stmt, link, & this->cases) { 6901bf215546Sopenharmony_ci case_stmt->hir(&tmp, state); 6902bf215546Sopenharmony_ci 6903bf215546Sopenharmony_ci /* Default case. */ 6904bf215546Sopenharmony_ci if (state->switch_state.previous_default && default_case.is_empty()) { 6905bf215546Sopenharmony_ci default_case.append_list(&tmp); 6906bf215546Sopenharmony_ci continue; 6907bf215546Sopenharmony_ci } 6908bf215546Sopenharmony_ci 6909bf215546Sopenharmony_ci /* If default case found, append 'after_default' list. */ 6910bf215546Sopenharmony_ci if (!default_case.is_empty()) 6911bf215546Sopenharmony_ci after_default.append_list(&tmp); 6912bf215546Sopenharmony_ci else 6913bf215546Sopenharmony_ci instructions->append_list(&tmp); 6914bf215546Sopenharmony_ci } 6915bf215546Sopenharmony_ci 6916bf215546Sopenharmony_ci /* Handle the default case. This is done here because default might not be 6917bf215546Sopenharmony_ci * the last case. We need to add checks against following cases first to see 6918bf215546Sopenharmony_ci * if default should be chosen or not. 6919bf215546Sopenharmony_ci */ 6920bf215546Sopenharmony_ci if (!default_case.is_empty()) { 6921bf215546Sopenharmony_ci ir_factory body(instructions, state); 6922bf215546Sopenharmony_ci 6923bf215546Sopenharmony_ci ir_expression *cmp = NULL; 6924bf215546Sopenharmony_ci 6925bf215546Sopenharmony_ci hash_table_foreach(state->switch_state.labels_ht, entry) { 6926bf215546Sopenharmony_ci const struct case_label *const l = (struct case_label *) entry->data; 6927bf215546Sopenharmony_ci 6928bf215546Sopenharmony_ci /* If the switch init-value is the value of one of the labels that 6929bf215546Sopenharmony_ci * occurs after the default case, disable execution of the default 6930bf215546Sopenharmony_ci * case. 6931bf215546Sopenharmony_ci */ 6932bf215546Sopenharmony_ci if (l->after_default) { 6933bf215546Sopenharmony_ci ir_constant *const cnst = 6934bf215546Sopenharmony_ci state->switch_state.test_var->type->base_type == GLSL_TYPE_UINT 6935bf215546Sopenharmony_ci ? body.constant(unsigned(l->value)) 6936bf215546Sopenharmony_ci : body.constant(int(l->value)); 6937bf215546Sopenharmony_ci 6938bf215546Sopenharmony_ci cmp = cmp == NULL 6939bf215546Sopenharmony_ci ? equal(cnst, state->switch_state.test_var) 6940bf215546Sopenharmony_ci : logic_or(cmp, equal(cnst, state->switch_state.test_var)); 6941bf215546Sopenharmony_ci } 6942bf215546Sopenharmony_ci } 6943bf215546Sopenharmony_ci 6944bf215546Sopenharmony_ci if (cmp != NULL) 6945bf215546Sopenharmony_ci body.emit(assign(state->switch_state.run_default, logic_not(cmp))); 6946bf215546Sopenharmony_ci else 6947bf215546Sopenharmony_ci body.emit(assign(state->switch_state.run_default, body.constant(true))); 6948bf215546Sopenharmony_ci 6949bf215546Sopenharmony_ci /* Append default case and all cases after it. */ 6950bf215546Sopenharmony_ci instructions->append_list(&default_case); 6951bf215546Sopenharmony_ci instructions->append_list(&after_default); 6952bf215546Sopenharmony_ci } 6953bf215546Sopenharmony_ci 6954bf215546Sopenharmony_ci /* Case statements do not have r-values. */ 6955bf215546Sopenharmony_ci return NULL; 6956bf215546Sopenharmony_ci} 6957bf215546Sopenharmony_ci 6958bf215546Sopenharmony_ciir_rvalue * 6959bf215546Sopenharmony_ciast_case_statement::hir(exec_list *instructions, 6960bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 6961bf215546Sopenharmony_ci{ 6962bf215546Sopenharmony_ci labels->hir(instructions, state); 6963bf215546Sopenharmony_ci 6964bf215546Sopenharmony_ci /* Guard case statements depending on fallthru state. */ 6965bf215546Sopenharmony_ci ir_dereference_variable *const deref_fallthru_guard = 6966bf215546Sopenharmony_ci new(state) ir_dereference_variable(state->switch_state.is_fallthru_var); 6967bf215546Sopenharmony_ci ir_if *const test_fallthru = new(state) ir_if(deref_fallthru_guard); 6968bf215546Sopenharmony_ci 6969bf215546Sopenharmony_ci foreach_list_typed (ast_node, stmt, link, & this->stmts) 6970bf215546Sopenharmony_ci stmt->hir(& test_fallthru->then_instructions, state); 6971bf215546Sopenharmony_ci 6972bf215546Sopenharmony_ci instructions->push_tail(test_fallthru); 6973bf215546Sopenharmony_ci 6974bf215546Sopenharmony_ci /* Case statements do not have r-values. */ 6975bf215546Sopenharmony_ci return NULL; 6976bf215546Sopenharmony_ci} 6977bf215546Sopenharmony_ci 6978bf215546Sopenharmony_ci 6979bf215546Sopenharmony_ciir_rvalue * 6980bf215546Sopenharmony_ciast_case_label_list::hir(exec_list *instructions, 6981bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 6982bf215546Sopenharmony_ci{ 6983bf215546Sopenharmony_ci foreach_list_typed (ast_case_label, label, link, & this->labels) 6984bf215546Sopenharmony_ci label->hir(instructions, state); 6985bf215546Sopenharmony_ci 6986bf215546Sopenharmony_ci /* Case labels do not have r-values. */ 6987bf215546Sopenharmony_ci return NULL; 6988bf215546Sopenharmony_ci} 6989bf215546Sopenharmony_ci 6990bf215546Sopenharmony_ciir_rvalue * 6991bf215546Sopenharmony_ciast_case_label::hir(exec_list *instructions, 6992bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 6993bf215546Sopenharmony_ci{ 6994bf215546Sopenharmony_ci ir_factory body(instructions, state); 6995bf215546Sopenharmony_ci 6996bf215546Sopenharmony_ci ir_variable *const fallthru_var = state->switch_state.is_fallthru_var; 6997bf215546Sopenharmony_ci 6998bf215546Sopenharmony_ci /* If not default case, ... */ 6999bf215546Sopenharmony_ci if (this->test_value != NULL) { 7000bf215546Sopenharmony_ci /* Conditionally set fallthru state based on 7001bf215546Sopenharmony_ci * comparison of cached test expression value to case label. 7002bf215546Sopenharmony_ci */ 7003bf215546Sopenharmony_ci ir_rvalue *const label_rval = this->test_value->hir(instructions, state); 7004bf215546Sopenharmony_ci ir_constant *label_const = 7005bf215546Sopenharmony_ci label_rval->constant_expression_value(body.mem_ctx); 7006bf215546Sopenharmony_ci 7007bf215546Sopenharmony_ci if (!label_const) { 7008bf215546Sopenharmony_ci YYLTYPE loc = this->test_value->get_location(); 7009bf215546Sopenharmony_ci 7010bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 7011bf215546Sopenharmony_ci "switch statement case label must be a " 7012bf215546Sopenharmony_ci "constant expression"); 7013bf215546Sopenharmony_ci 7014bf215546Sopenharmony_ci /* Stuff a dummy value in to allow processing to continue. */ 7015bf215546Sopenharmony_ci label_const = body.constant(0); 7016bf215546Sopenharmony_ci } else { 7017bf215546Sopenharmony_ci hash_entry *entry = 7018bf215546Sopenharmony_ci _mesa_hash_table_search(state->switch_state.labels_ht, 7019bf215546Sopenharmony_ci &label_const->value.u[0]); 7020bf215546Sopenharmony_ci 7021bf215546Sopenharmony_ci if (entry) { 7022bf215546Sopenharmony_ci const struct case_label *const l = 7023bf215546Sopenharmony_ci (struct case_label *) entry->data; 7024bf215546Sopenharmony_ci const ast_expression *const previous_label = l->ast; 7025bf215546Sopenharmony_ci YYLTYPE loc = this->test_value->get_location(); 7026bf215546Sopenharmony_ci 7027bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "duplicate case value"); 7028bf215546Sopenharmony_ci 7029bf215546Sopenharmony_ci loc = previous_label->get_location(); 7030bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "this is the previous case label"); 7031bf215546Sopenharmony_ci } else { 7032bf215546Sopenharmony_ci struct case_label *l = ralloc(state->switch_state.labels_ht, 7033bf215546Sopenharmony_ci struct case_label); 7034bf215546Sopenharmony_ci 7035bf215546Sopenharmony_ci l->value = label_const->value.u[0]; 7036bf215546Sopenharmony_ci l->after_default = state->switch_state.previous_default != NULL; 7037bf215546Sopenharmony_ci l->ast = this->test_value; 7038bf215546Sopenharmony_ci 7039bf215546Sopenharmony_ci _mesa_hash_table_insert(state->switch_state.labels_ht, 7040bf215546Sopenharmony_ci &label_const->value.u[0], 7041bf215546Sopenharmony_ci l); 7042bf215546Sopenharmony_ci } 7043bf215546Sopenharmony_ci } 7044bf215546Sopenharmony_ci 7045bf215546Sopenharmony_ci /* Create an r-value version of the ir_constant label here (after we may 7046bf215546Sopenharmony_ci * have created a fake one in error cases) that can be passed to 7047bf215546Sopenharmony_ci * apply_implicit_conversion below. 7048bf215546Sopenharmony_ci */ 7049bf215546Sopenharmony_ci ir_rvalue *label = label_const; 7050bf215546Sopenharmony_ci 7051bf215546Sopenharmony_ci ir_rvalue *deref_test_var = 7052bf215546Sopenharmony_ci new(body.mem_ctx) ir_dereference_variable(state->switch_state.test_var); 7053bf215546Sopenharmony_ci 7054bf215546Sopenharmony_ci /* 7055bf215546Sopenharmony_ci * From GLSL 4.40 specification section 6.2 ("Selection"): 7056bf215546Sopenharmony_ci * 7057bf215546Sopenharmony_ci * "The type of the init-expression value in a switch statement must 7058bf215546Sopenharmony_ci * be a scalar int or uint. The type of the constant-expression value 7059bf215546Sopenharmony_ci * in a case label also must be a scalar int or uint. When any pair 7060bf215546Sopenharmony_ci * of these values is tested for "equal value" and the types do not 7061bf215546Sopenharmony_ci * match, an implicit conversion will be done to convert the int to a 7062bf215546Sopenharmony_ci * uint (see section 4.1.10 “Implicit Conversions”) before the compare 7063bf215546Sopenharmony_ci * is done." 7064bf215546Sopenharmony_ci */ 7065bf215546Sopenharmony_ci if (label->type != state->switch_state.test_var->type) { 7066bf215546Sopenharmony_ci YYLTYPE loc = this->test_value->get_location(); 7067bf215546Sopenharmony_ci 7068bf215546Sopenharmony_ci const glsl_type *type_a = label->type; 7069bf215546Sopenharmony_ci const glsl_type *type_b = state->switch_state.test_var->type; 7070bf215546Sopenharmony_ci 7071bf215546Sopenharmony_ci /* Check if int->uint implicit conversion is supported. */ 7072bf215546Sopenharmony_ci bool integer_conversion_supported = 7073bf215546Sopenharmony_ci glsl_type::int_type->can_implicitly_convert_to(glsl_type::uint_type, 7074bf215546Sopenharmony_ci state); 7075bf215546Sopenharmony_ci 7076bf215546Sopenharmony_ci if ((!type_a->is_integer_32() || !type_b->is_integer_32()) || 7077bf215546Sopenharmony_ci !integer_conversion_supported) { 7078bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "type mismatch with switch " 7079bf215546Sopenharmony_ci "init-expression and case label (%s != %s)", 7080bf215546Sopenharmony_ci type_a->name, type_b->name); 7081bf215546Sopenharmony_ci } else { 7082bf215546Sopenharmony_ci /* Conversion of the case label. */ 7083bf215546Sopenharmony_ci if (type_a->base_type == GLSL_TYPE_INT) { 7084bf215546Sopenharmony_ci if (!apply_implicit_conversion(glsl_type::uint_type, 7085bf215546Sopenharmony_ci label, state)) 7086bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "implicit type conversion error"); 7087bf215546Sopenharmony_ci } else { 7088bf215546Sopenharmony_ci /* Conversion of the init-expression value. */ 7089bf215546Sopenharmony_ci if (!apply_implicit_conversion(glsl_type::uint_type, 7090bf215546Sopenharmony_ci deref_test_var, state)) 7091bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "implicit type conversion error"); 7092bf215546Sopenharmony_ci } 7093bf215546Sopenharmony_ci } 7094bf215546Sopenharmony_ci 7095bf215546Sopenharmony_ci /* If the implicit conversion was allowed, the types will already be 7096bf215546Sopenharmony_ci * the same. If the implicit conversion wasn't allowed, smash the 7097bf215546Sopenharmony_ci * type of the label anyway. This will prevent the expression 7098bf215546Sopenharmony_ci * constructor (below) from failing an assertion. 7099bf215546Sopenharmony_ci */ 7100bf215546Sopenharmony_ci label->type = deref_test_var->type; 7101bf215546Sopenharmony_ci } 7102bf215546Sopenharmony_ci 7103bf215546Sopenharmony_ci body.emit(assign(fallthru_var, 7104bf215546Sopenharmony_ci logic_or(fallthru_var, equal(label, deref_test_var)))); 7105bf215546Sopenharmony_ci } else { /* default case */ 7106bf215546Sopenharmony_ci if (state->switch_state.previous_default) { 7107bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 7108bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 7109bf215546Sopenharmony_ci "multiple default labels in one switch"); 7110bf215546Sopenharmony_ci 7111bf215546Sopenharmony_ci loc = state->switch_state.previous_default->get_location(); 7112bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "this is the first default label"); 7113bf215546Sopenharmony_ci } 7114bf215546Sopenharmony_ci state->switch_state.previous_default = this; 7115bf215546Sopenharmony_ci 7116bf215546Sopenharmony_ci /* Set fallthru condition on 'run_default' bool. */ 7117bf215546Sopenharmony_ci body.emit(assign(fallthru_var, 7118bf215546Sopenharmony_ci logic_or(fallthru_var, 7119bf215546Sopenharmony_ci state->switch_state.run_default))); 7120bf215546Sopenharmony_ci } 7121bf215546Sopenharmony_ci 7122bf215546Sopenharmony_ci /* Case statements do not have r-values. */ 7123bf215546Sopenharmony_ci return NULL; 7124bf215546Sopenharmony_ci} 7125bf215546Sopenharmony_ci 7126bf215546Sopenharmony_civoid 7127bf215546Sopenharmony_ciast_iteration_statement::condition_to_hir(exec_list *instructions, 7128bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 7129bf215546Sopenharmony_ci{ 7130bf215546Sopenharmony_ci void *ctx = state; 7131bf215546Sopenharmony_ci 7132bf215546Sopenharmony_ci if (condition != NULL) { 7133bf215546Sopenharmony_ci ir_rvalue *const cond = 7134bf215546Sopenharmony_ci condition->hir(instructions, state); 7135bf215546Sopenharmony_ci 7136bf215546Sopenharmony_ci if ((cond == NULL) 7137bf215546Sopenharmony_ci || !cond->type->is_boolean() || !cond->type->is_scalar()) { 7138bf215546Sopenharmony_ci YYLTYPE loc = condition->get_location(); 7139bf215546Sopenharmony_ci 7140bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, 7141bf215546Sopenharmony_ci "loop condition must be scalar boolean"); 7142bf215546Sopenharmony_ci } else { 7143bf215546Sopenharmony_ci /* As the first code in the loop body, generate a block that looks 7144bf215546Sopenharmony_ci * like 'if (!condition) break;' as the loop termination condition. 7145bf215546Sopenharmony_ci */ 7146bf215546Sopenharmony_ci ir_rvalue *const not_cond = 7147bf215546Sopenharmony_ci new(ctx) ir_expression(ir_unop_logic_not, cond); 7148bf215546Sopenharmony_ci 7149bf215546Sopenharmony_ci ir_if *const if_stmt = new(ctx) ir_if(not_cond); 7150bf215546Sopenharmony_ci 7151bf215546Sopenharmony_ci ir_jump *const break_stmt = 7152bf215546Sopenharmony_ci new(ctx) ir_loop_jump(ir_loop_jump::jump_break); 7153bf215546Sopenharmony_ci 7154bf215546Sopenharmony_ci if_stmt->then_instructions.push_tail(break_stmt); 7155bf215546Sopenharmony_ci instructions->push_tail(if_stmt); 7156bf215546Sopenharmony_ci } 7157bf215546Sopenharmony_ci } 7158bf215546Sopenharmony_ci} 7159bf215546Sopenharmony_ci 7160bf215546Sopenharmony_ci 7161bf215546Sopenharmony_ciir_rvalue * 7162bf215546Sopenharmony_ciast_iteration_statement::hir(exec_list *instructions, 7163bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 7164bf215546Sopenharmony_ci{ 7165bf215546Sopenharmony_ci void *ctx = state; 7166bf215546Sopenharmony_ci 7167bf215546Sopenharmony_ci /* For-loops and while-loops start a new scope, but do-while loops do not. 7168bf215546Sopenharmony_ci */ 7169bf215546Sopenharmony_ci if (mode != ast_do_while) 7170bf215546Sopenharmony_ci state->symbols->push_scope(); 7171bf215546Sopenharmony_ci 7172bf215546Sopenharmony_ci if (init_statement != NULL) 7173bf215546Sopenharmony_ci init_statement->hir(instructions, state); 7174bf215546Sopenharmony_ci 7175bf215546Sopenharmony_ci ir_loop *const stmt = new(ctx) ir_loop(); 7176bf215546Sopenharmony_ci instructions->push_tail(stmt); 7177bf215546Sopenharmony_ci 7178bf215546Sopenharmony_ci /* Track the current loop nesting. */ 7179bf215546Sopenharmony_ci ast_iteration_statement *nesting_ast = state->loop_nesting_ast; 7180bf215546Sopenharmony_ci 7181bf215546Sopenharmony_ci state->loop_nesting_ast = this; 7182bf215546Sopenharmony_ci 7183bf215546Sopenharmony_ci /* Likewise, indicate that following code is closest to a loop, 7184bf215546Sopenharmony_ci * NOT closest to a switch. 7185bf215546Sopenharmony_ci */ 7186bf215546Sopenharmony_ci bool saved_is_switch_innermost = state->switch_state.is_switch_innermost; 7187bf215546Sopenharmony_ci state->switch_state.is_switch_innermost = false; 7188bf215546Sopenharmony_ci 7189bf215546Sopenharmony_ci if (mode != ast_do_while) 7190bf215546Sopenharmony_ci condition_to_hir(&stmt->body_instructions, state); 7191bf215546Sopenharmony_ci 7192bf215546Sopenharmony_ci if (rest_expression != NULL) 7193bf215546Sopenharmony_ci rest_expression->hir(&rest_instructions, state); 7194bf215546Sopenharmony_ci 7195bf215546Sopenharmony_ci if (body != NULL) { 7196bf215546Sopenharmony_ci if (mode == ast_do_while) 7197bf215546Sopenharmony_ci state->symbols->push_scope(); 7198bf215546Sopenharmony_ci 7199bf215546Sopenharmony_ci body->hir(& stmt->body_instructions, state); 7200bf215546Sopenharmony_ci 7201bf215546Sopenharmony_ci if (mode == ast_do_while) 7202bf215546Sopenharmony_ci state->symbols->pop_scope(); 7203bf215546Sopenharmony_ci } 7204bf215546Sopenharmony_ci 7205bf215546Sopenharmony_ci if (rest_expression != NULL) 7206bf215546Sopenharmony_ci stmt->body_instructions.append_list(&rest_instructions); 7207bf215546Sopenharmony_ci 7208bf215546Sopenharmony_ci if (mode == ast_do_while) 7209bf215546Sopenharmony_ci condition_to_hir(&stmt->body_instructions, state); 7210bf215546Sopenharmony_ci 7211bf215546Sopenharmony_ci if (mode != ast_do_while) 7212bf215546Sopenharmony_ci state->symbols->pop_scope(); 7213bf215546Sopenharmony_ci 7214bf215546Sopenharmony_ci /* Restore previous nesting before returning. */ 7215bf215546Sopenharmony_ci state->loop_nesting_ast = nesting_ast; 7216bf215546Sopenharmony_ci state->switch_state.is_switch_innermost = saved_is_switch_innermost; 7217bf215546Sopenharmony_ci 7218bf215546Sopenharmony_ci /* Loops do not have r-values. 7219bf215546Sopenharmony_ci */ 7220bf215546Sopenharmony_ci return NULL; 7221bf215546Sopenharmony_ci} 7222bf215546Sopenharmony_ci 7223bf215546Sopenharmony_ci 7224bf215546Sopenharmony_ci/** 7225bf215546Sopenharmony_ci * Determine if the given type is valid for establishing a default precision 7226bf215546Sopenharmony_ci * qualifier. 7227bf215546Sopenharmony_ci * 7228bf215546Sopenharmony_ci * From GLSL ES 3.00 section 4.5.4 ("Default Precision Qualifiers"): 7229bf215546Sopenharmony_ci * 7230bf215546Sopenharmony_ci * "The precision statement 7231bf215546Sopenharmony_ci * 7232bf215546Sopenharmony_ci * precision precision-qualifier type; 7233bf215546Sopenharmony_ci * 7234bf215546Sopenharmony_ci * can be used to establish a default precision qualifier. The type field 7235bf215546Sopenharmony_ci * can be either int or float or any of the sampler types, and the 7236bf215546Sopenharmony_ci * precision-qualifier can be lowp, mediump, or highp." 7237bf215546Sopenharmony_ci * 7238bf215546Sopenharmony_ci * GLSL ES 1.00 has similar language. GLSL 1.30 doesn't allow precision 7239bf215546Sopenharmony_ci * qualifiers on sampler types, but this seems like an oversight (since the 7240bf215546Sopenharmony_ci * intention of including these in GLSL 1.30 is to allow compatibility with ES 7241bf215546Sopenharmony_ci * shaders). So we allow int, float, and all sampler types regardless of GLSL 7242bf215546Sopenharmony_ci * version. 7243bf215546Sopenharmony_ci */ 7244bf215546Sopenharmony_cistatic bool 7245bf215546Sopenharmony_ciis_valid_default_precision_type(const struct glsl_type *const type) 7246bf215546Sopenharmony_ci{ 7247bf215546Sopenharmony_ci if (type == NULL) 7248bf215546Sopenharmony_ci return false; 7249bf215546Sopenharmony_ci 7250bf215546Sopenharmony_ci switch (type->base_type) { 7251bf215546Sopenharmony_ci case GLSL_TYPE_INT: 7252bf215546Sopenharmony_ci case GLSL_TYPE_FLOAT: 7253bf215546Sopenharmony_ci /* "int" and "float" are valid, but vectors and matrices are not. */ 7254bf215546Sopenharmony_ci return type->vector_elements == 1 && type->matrix_columns == 1; 7255bf215546Sopenharmony_ci case GLSL_TYPE_SAMPLER: 7256bf215546Sopenharmony_ci case GLSL_TYPE_TEXTURE: 7257bf215546Sopenharmony_ci case GLSL_TYPE_IMAGE: 7258bf215546Sopenharmony_ci case GLSL_TYPE_ATOMIC_UINT: 7259bf215546Sopenharmony_ci return true; 7260bf215546Sopenharmony_ci default: 7261bf215546Sopenharmony_ci return false; 7262bf215546Sopenharmony_ci } 7263bf215546Sopenharmony_ci} 7264bf215546Sopenharmony_ci 7265bf215546Sopenharmony_ci 7266bf215546Sopenharmony_ciir_rvalue * 7267bf215546Sopenharmony_ciast_type_specifier::hir(exec_list *instructions, 7268bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 7269bf215546Sopenharmony_ci{ 7270bf215546Sopenharmony_ci if (this->default_precision == ast_precision_none && this->structure == NULL) 7271bf215546Sopenharmony_ci return NULL; 7272bf215546Sopenharmony_ci 7273bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 7274bf215546Sopenharmony_ci 7275bf215546Sopenharmony_ci /* If this is a precision statement, check that the type to which it is 7276bf215546Sopenharmony_ci * applied is either float or int. 7277bf215546Sopenharmony_ci * 7278bf215546Sopenharmony_ci * From section 4.5.3 of the GLSL 1.30 spec: 7279bf215546Sopenharmony_ci * "The precision statement 7280bf215546Sopenharmony_ci * precision precision-qualifier type; 7281bf215546Sopenharmony_ci * can be used to establish a default precision qualifier. The type 7282bf215546Sopenharmony_ci * field can be either int or float [...]. Any other types or 7283bf215546Sopenharmony_ci * qualifiers will result in an error. 7284bf215546Sopenharmony_ci */ 7285bf215546Sopenharmony_ci if (this->default_precision != ast_precision_none) { 7286bf215546Sopenharmony_ci if (!state->check_precision_qualifiers_allowed(&loc)) 7287bf215546Sopenharmony_ci return NULL; 7288bf215546Sopenharmony_ci 7289bf215546Sopenharmony_ci if (this->structure != NULL) { 7290bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 7291bf215546Sopenharmony_ci "precision qualifiers do not apply to structures"); 7292bf215546Sopenharmony_ci return NULL; 7293bf215546Sopenharmony_ci } 7294bf215546Sopenharmony_ci 7295bf215546Sopenharmony_ci if (this->array_specifier != NULL) { 7296bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 7297bf215546Sopenharmony_ci "default precision statements do not apply to " 7298bf215546Sopenharmony_ci "arrays"); 7299bf215546Sopenharmony_ci return NULL; 7300bf215546Sopenharmony_ci } 7301bf215546Sopenharmony_ci 7302bf215546Sopenharmony_ci const struct glsl_type *const type = 7303bf215546Sopenharmony_ci state->symbols->get_type(this->type_name); 7304bf215546Sopenharmony_ci if (!is_valid_default_precision_type(type)) { 7305bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 7306bf215546Sopenharmony_ci "default precision statements apply only to " 7307bf215546Sopenharmony_ci "float, int, and opaque types"); 7308bf215546Sopenharmony_ci return NULL; 7309bf215546Sopenharmony_ci } 7310bf215546Sopenharmony_ci 7311bf215546Sopenharmony_ci if (state->es_shader) { 7312bf215546Sopenharmony_ci /* Section 4.5.3 (Default Precision Qualifiers) of the GLSL ES 1.00 7313bf215546Sopenharmony_ci * spec says: 7314bf215546Sopenharmony_ci * 7315bf215546Sopenharmony_ci * "Non-precision qualified declarations will use the precision 7316bf215546Sopenharmony_ci * qualifier specified in the most recent precision statement 7317bf215546Sopenharmony_ci * that is still in scope. The precision statement has the same 7318bf215546Sopenharmony_ci * scoping rules as variable declarations. If it is declared 7319bf215546Sopenharmony_ci * inside a compound statement, its effect stops at the end of 7320bf215546Sopenharmony_ci * the innermost statement it was declared in. Precision 7321bf215546Sopenharmony_ci * statements in nested scopes override precision statements in 7322bf215546Sopenharmony_ci * outer scopes. Multiple precision statements for the same basic 7323bf215546Sopenharmony_ci * type can appear inside the same scope, with later statements 7324bf215546Sopenharmony_ci * overriding earlier statements within that scope." 7325bf215546Sopenharmony_ci * 7326bf215546Sopenharmony_ci * Default precision specifications follow the same scope rules as 7327bf215546Sopenharmony_ci * variables. So, we can track the state of the default precision 7328bf215546Sopenharmony_ci * qualifiers in the symbol table, and the rules will just work. This 7329bf215546Sopenharmony_ci * is a slight abuse of the symbol table, but it has the semantics 7330bf215546Sopenharmony_ci * that we want. 7331bf215546Sopenharmony_ci */ 7332bf215546Sopenharmony_ci state->symbols->add_default_precision_qualifier(this->type_name, 7333bf215546Sopenharmony_ci this->default_precision); 7334bf215546Sopenharmony_ci } 7335bf215546Sopenharmony_ci 7336bf215546Sopenharmony_ci /* FINISHME: Translate precision statements into IR. */ 7337bf215546Sopenharmony_ci return NULL; 7338bf215546Sopenharmony_ci } 7339bf215546Sopenharmony_ci 7340bf215546Sopenharmony_ci /* _mesa_ast_set_aggregate_type() sets the <structure> field so that 7341bf215546Sopenharmony_ci * process_record_constructor() can do type-checking on C-style initializer 7342bf215546Sopenharmony_ci * expressions of structs, but ast_struct_specifier should only be translated 7343bf215546Sopenharmony_ci * to HIR if it is declaring the type of a structure. 7344bf215546Sopenharmony_ci * 7345bf215546Sopenharmony_ci * The ->is_declaration field is false for initializers of variables 7346bf215546Sopenharmony_ci * declared separately from the struct's type definition. 7347bf215546Sopenharmony_ci * 7348bf215546Sopenharmony_ci * struct S { ... }; (is_declaration = true) 7349bf215546Sopenharmony_ci * struct T { ... } t = { ... }; (is_declaration = true) 7350bf215546Sopenharmony_ci * S s = { ... }; (is_declaration = false) 7351bf215546Sopenharmony_ci */ 7352bf215546Sopenharmony_ci if (this->structure != NULL && this->structure->is_declaration) 7353bf215546Sopenharmony_ci return this->structure->hir(instructions, state); 7354bf215546Sopenharmony_ci 7355bf215546Sopenharmony_ci return NULL; 7356bf215546Sopenharmony_ci} 7357bf215546Sopenharmony_ci 7358bf215546Sopenharmony_ci 7359bf215546Sopenharmony_ci/** 7360bf215546Sopenharmony_ci * Process a structure or interface block tree into an array of structure fields 7361bf215546Sopenharmony_ci * 7362bf215546Sopenharmony_ci * After parsing, where there are some syntax differnces, structures and 7363bf215546Sopenharmony_ci * interface blocks are almost identical. They are similar enough that the 7364bf215546Sopenharmony_ci * AST for each can be processed the same way into a set of 7365bf215546Sopenharmony_ci * \c glsl_struct_field to describe the members. 7366bf215546Sopenharmony_ci * 7367bf215546Sopenharmony_ci * If we're processing an interface block, var_mode should be the type of the 7368bf215546Sopenharmony_ci * interface block (ir_var_shader_in, ir_var_shader_out, ir_var_uniform or 7369bf215546Sopenharmony_ci * ir_var_shader_storage). If we're processing a structure, var_mode should be 7370bf215546Sopenharmony_ci * ir_var_auto. 7371bf215546Sopenharmony_ci * 7372bf215546Sopenharmony_ci * \return 7373bf215546Sopenharmony_ci * The number of fields processed. A pointer to the array structure fields is 7374bf215546Sopenharmony_ci * stored in \c *fields_ret. 7375bf215546Sopenharmony_ci */ 7376bf215546Sopenharmony_cistatic unsigned 7377bf215546Sopenharmony_ciast_process_struct_or_iface_block_members(exec_list *instructions, 7378bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state, 7379bf215546Sopenharmony_ci exec_list *declarations, 7380bf215546Sopenharmony_ci glsl_struct_field **fields_ret, 7381bf215546Sopenharmony_ci bool is_interface, 7382bf215546Sopenharmony_ci enum glsl_matrix_layout matrix_layout, 7383bf215546Sopenharmony_ci bool allow_reserved_names, 7384bf215546Sopenharmony_ci ir_variable_mode var_mode, 7385bf215546Sopenharmony_ci ast_type_qualifier *layout, 7386bf215546Sopenharmony_ci unsigned block_stream, 7387bf215546Sopenharmony_ci unsigned block_xfb_buffer, 7388bf215546Sopenharmony_ci unsigned block_xfb_offset, 7389bf215546Sopenharmony_ci unsigned expl_location, 7390bf215546Sopenharmony_ci unsigned expl_align) 7391bf215546Sopenharmony_ci{ 7392bf215546Sopenharmony_ci unsigned decl_count = 0; 7393bf215546Sopenharmony_ci unsigned next_offset = 0; 7394bf215546Sopenharmony_ci 7395bf215546Sopenharmony_ci /* Make an initial pass over the list of fields to determine how 7396bf215546Sopenharmony_ci * many there are. Each element in this list is an ast_declarator_list. 7397bf215546Sopenharmony_ci * This means that we actually need to count the number of elements in the 7398bf215546Sopenharmony_ci * 'declarations' list in each of the elements. 7399bf215546Sopenharmony_ci */ 7400bf215546Sopenharmony_ci foreach_list_typed (ast_declarator_list, decl_list, link, declarations) { 7401bf215546Sopenharmony_ci decl_count += decl_list->declarations.length(); 7402bf215546Sopenharmony_ci } 7403bf215546Sopenharmony_ci 7404bf215546Sopenharmony_ci /* Allocate storage for the fields and process the field 7405bf215546Sopenharmony_ci * declarations. As the declarations are processed, try to also convert 7406bf215546Sopenharmony_ci * the types to HIR. This ensures that structure definitions embedded in 7407bf215546Sopenharmony_ci * other structure definitions or in interface blocks are processed. 7408bf215546Sopenharmony_ci */ 7409bf215546Sopenharmony_ci glsl_struct_field *const fields = rzalloc_array(state, glsl_struct_field, 7410bf215546Sopenharmony_ci decl_count); 7411bf215546Sopenharmony_ci 7412bf215546Sopenharmony_ci bool first_member = true; 7413bf215546Sopenharmony_ci bool first_member_has_explicit_location = false; 7414bf215546Sopenharmony_ci 7415bf215546Sopenharmony_ci unsigned i = 0; 7416bf215546Sopenharmony_ci foreach_list_typed (ast_declarator_list, decl_list, link, declarations) { 7417bf215546Sopenharmony_ci const char *type_name; 7418bf215546Sopenharmony_ci YYLTYPE loc = decl_list->get_location(); 7419bf215546Sopenharmony_ci 7420bf215546Sopenharmony_ci decl_list->type->specifier->hir(instructions, state); 7421bf215546Sopenharmony_ci 7422bf215546Sopenharmony_ci /* Section 4.1.8 (Structures) of the GLSL 1.10 spec says: 7423bf215546Sopenharmony_ci * 7424bf215546Sopenharmony_ci * "Anonymous structures are not supported; so embedded structures 7425bf215546Sopenharmony_ci * must have a declarator. A name given to an embedded struct is 7426bf215546Sopenharmony_ci * scoped at the same level as the struct it is embedded in." 7427bf215546Sopenharmony_ci * 7428bf215546Sopenharmony_ci * The same section of the GLSL 1.20 spec says: 7429bf215546Sopenharmony_ci * 7430bf215546Sopenharmony_ci * "Anonymous structures are not supported. Embedded structures are 7431bf215546Sopenharmony_ci * not supported." 7432bf215546Sopenharmony_ci * 7433bf215546Sopenharmony_ci * The GLSL ES 1.00 and 3.00 specs have similar langauge. So, we allow 7434bf215546Sopenharmony_ci * embedded structures in 1.10 only. 7435bf215546Sopenharmony_ci */ 7436bf215546Sopenharmony_ci if (state->language_version != 110 && 7437bf215546Sopenharmony_ci decl_list->type->specifier->structure != NULL) 7438bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 7439bf215546Sopenharmony_ci "embedded structure declarations are not allowed"); 7440bf215546Sopenharmony_ci 7441bf215546Sopenharmony_ci const glsl_type *decl_type = 7442bf215546Sopenharmony_ci decl_list->type->glsl_type(& type_name, state); 7443bf215546Sopenharmony_ci 7444bf215546Sopenharmony_ci const struct ast_type_qualifier *const qual = 7445bf215546Sopenharmony_ci &decl_list->type->qualifier; 7446bf215546Sopenharmony_ci 7447bf215546Sopenharmony_ci /* From section 4.3.9 of the GLSL 4.40 spec: 7448bf215546Sopenharmony_ci * 7449bf215546Sopenharmony_ci * "[In interface blocks] opaque types are not allowed." 7450bf215546Sopenharmony_ci * 7451bf215546Sopenharmony_ci * It should be impossible for decl_type to be NULL here. Cases that 7452bf215546Sopenharmony_ci * might naturally lead to decl_type being NULL, especially for the 7453bf215546Sopenharmony_ci * is_interface case, will have resulted in compilation having 7454bf215546Sopenharmony_ci * already halted due to a syntax error. 7455bf215546Sopenharmony_ci */ 7456bf215546Sopenharmony_ci assert(decl_type); 7457bf215546Sopenharmony_ci 7458bf215546Sopenharmony_ci if (is_interface) { 7459bf215546Sopenharmony_ci /* From section 4.3.7 of the ARB_bindless_texture spec: 7460bf215546Sopenharmony_ci * 7461bf215546Sopenharmony_ci * "(remove the following bullet from the last list on p. 39, 7462bf215546Sopenharmony_ci * thereby permitting sampler types in interface blocks; image 7463bf215546Sopenharmony_ci * types are also permitted in blocks by this extension)" 7464bf215546Sopenharmony_ci * 7465bf215546Sopenharmony_ci * * sampler types are not allowed 7466bf215546Sopenharmony_ci */ 7467bf215546Sopenharmony_ci if (decl_type->contains_atomic() || 7468bf215546Sopenharmony_ci (!state->has_bindless() && decl_type->contains_opaque())) { 7469bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "uniform/buffer in non-default " 7470bf215546Sopenharmony_ci "interface block contains %s variable", 7471bf215546Sopenharmony_ci state->has_bindless() ? "atomic" : "opaque"); 7472bf215546Sopenharmony_ci } 7473bf215546Sopenharmony_ci } else { 7474bf215546Sopenharmony_ci if (decl_type->contains_atomic()) { 7475bf215546Sopenharmony_ci /* From section 4.1.7.3 of the GLSL 4.40 spec: 7476bf215546Sopenharmony_ci * 7477bf215546Sopenharmony_ci * "Members of structures cannot be declared as atomic counter 7478bf215546Sopenharmony_ci * types." 7479bf215546Sopenharmony_ci */ 7480bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "atomic counter in structure"); 7481bf215546Sopenharmony_ci } 7482bf215546Sopenharmony_ci 7483bf215546Sopenharmony_ci if (!state->has_bindless() && decl_type->contains_image()) { 7484bf215546Sopenharmony_ci /* FINISHME: Same problem as with atomic counters. 7485bf215546Sopenharmony_ci * FINISHME: Request clarification from Khronos and add 7486bf215546Sopenharmony_ci * FINISHME: spec quotation here. 7487bf215546Sopenharmony_ci */ 7488bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "image in structure"); 7489bf215546Sopenharmony_ci } 7490bf215546Sopenharmony_ci } 7491bf215546Sopenharmony_ci 7492bf215546Sopenharmony_ci if (qual->flags.q.explicit_binding) { 7493bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 7494bf215546Sopenharmony_ci "binding layout qualifier cannot be applied " 7495bf215546Sopenharmony_ci "to struct or interface block members"); 7496bf215546Sopenharmony_ci } 7497bf215546Sopenharmony_ci 7498bf215546Sopenharmony_ci if (is_interface) { 7499bf215546Sopenharmony_ci if (!first_member) { 7500bf215546Sopenharmony_ci if (!layout->flags.q.explicit_location && 7501bf215546Sopenharmony_ci ((first_member_has_explicit_location && 7502bf215546Sopenharmony_ci !qual->flags.q.explicit_location) || 7503bf215546Sopenharmony_ci (!first_member_has_explicit_location && 7504bf215546Sopenharmony_ci qual->flags.q.explicit_location))) { 7505bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 7506bf215546Sopenharmony_ci "when block-level location layout qualifier " 7507bf215546Sopenharmony_ci "is not supplied either all members must " 7508bf215546Sopenharmony_ci "have a location layout qualifier or all " 7509bf215546Sopenharmony_ci "members must not have a location layout " 7510bf215546Sopenharmony_ci "qualifier"); 7511bf215546Sopenharmony_ci } 7512bf215546Sopenharmony_ci } else { 7513bf215546Sopenharmony_ci first_member = false; 7514bf215546Sopenharmony_ci first_member_has_explicit_location = 7515bf215546Sopenharmony_ci qual->flags.q.explicit_location; 7516bf215546Sopenharmony_ci } 7517bf215546Sopenharmony_ci } 7518bf215546Sopenharmony_ci 7519bf215546Sopenharmony_ci if (qual->flags.q.std140 || 7520bf215546Sopenharmony_ci qual->flags.q.std430 || 7521bf215546Sopenharmony_ci qual->flags.q.packed || 7522bf215546Sopenharmony_ci qual->flags.q.shared) { 7523bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 7524bf215546Sopenharmony_ci "uniform/shader storage block layout qualifiers " 7525bf215546Sopenharmony_ci "std140, std430, packed, and shared can only be " 7526bf215546Sopenharmony_ci "applied to uniform/shader storage blocks, not " 7527bf215546Sopenharmony_ci "members"); 7528bf215546Sopenharmony_ci } 7529bf215546Sopenharmony_ci 7530bf215546Sopenharmony_ci if (qual->flags.q.constant) { 7531bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 7532bf215546Sopenharmony_ci "const storage qualifier cannot be applied " 7533bf215546Sopenharmony_ci "to struct or interface block members"); 7534bf215546Sopenharmony_ci } 7535bf215546Sopenharmony_ci 7536bf215546Sopenharmony_ci validate_memory_qualifier_for_type(state, &loc, qual, decl_type); 7537bf215546Sopenharmony_ci validate_image_format_qualifier_for_type(state, &loc, qual, decl_type); 7538bf215546Sopenharmony_ci 7539bf215546Sopenharmony_ci /* From Section 4.4.2.3 (Geometry Outputs) of the GLSL 4.50 spec: 7540bf215546Sopenharmony_ci * 7541bf215546Sopenharmony_ci * "A block member may be declared with a stream identifier, but 7542bf215546Sopenharmony_ci * the specified stream must match the stream associated with the 7543bf215546Sopenharmony_ci * containing block." 7544bf215546Sopenharmony_ci */ 7545bf215546Sopenharmony_ci if (qual->flags.q.explicit_stream) { 7546bf215546Sopenharmony_ci unsigned qual_stream; 7547bf215546Sopenharmony_ci if (process_qualifier_constant(state, &loc, "stream", 7548bf215546Sopenharmony_ci qual->stream, &qual_stream) && 7549bf215546Sopenharmony_ci qual_stream != block_stream) { 7550bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "stream layout qualifier on " 7551bf215546Sopenharmony_ci "interface block member does not match " 7552bf215546Sopenharmony_ci "the interface block (%u vs %u)", qual_stream, 7553bf215546Sopenharmony_ci block_stream); 7554bf215546Sopenharmony_ci } 7555bf215546Sopenharmony_ci } 7556bf215546Sopenharmony_ci 7557bf215546Sopenharmony_ci int xfb_buffer; 7558bf215546Sopenharmony_ci unsigned explicit_xfb_buffer = 0; 7559bf215546Sopenharmony_ci if (qual->flags.q.explicit_xfb_buffer) { 7560bf215546Sopenharmony_ci unsigned qual_xfb_buffer; 7561bf215546Sopenharmony_ci if (process_qualifier_constant(state, &loc, "xfb_buffer", 7562bf215546Sopenharmony_ci qual->xfb_buffer, &qual_xfb_buffer)) { 7563bf215546Sopenharmony_ci explicit_xfb_buffer = 1; 7564bf215546Sopenharmony_ci if (qual_xfb_buffer != block_xfb_buffer) 7565bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "xfb_buffer layout qualifier on " 7566bf215546Sopenharmony_ci "interface block member does not match " 7567bf215546Sopenharmony_ci "the interface block (%u vs %u)", 7568bf215546Sopenharmony_ci qual_xfb_buffer, block_xfb_buffer); 7569bf215546Sopenharmony_ci } 7570bf215546Sopenharmony_ci xfb_buffer = (int) qual_xfb_buffer; 7571bf215546Sopenharmony_ci } else { 7572bf215546Sopenharmony_ci if (layout) 7573bf215546Sopenharmony_ci explicit_xfb_buffer = layout->flags.q.explicit_xfb_buffer; 7574bf215546Sopenharmony_ci xfb_buffer = (int) block_xfb_buffer; 7575bf215546Sopenharmony_ci } 7576bf215546Sopenharmony_ci 7577bf215546Sopenharmony_ci int xfb_stride = -1; 7578bf215546Sopenharmony_ci if (qual->flags.q.explicit_xfb_stride) { 7579bf215546Sopenharmony_ci unsigned qual_xfb_stride; 7580bf215546Sopenharmony_ci if (process_qualifier_constant(state, &loc, "xfb_stride", 7581bf215546Sopenharmony_ci qual->xfb_stride, &qual_xfb_stride)) { 7582bf215546Sopenharmony_ci xfb_stride = (int) qual_xfb_stride; 7583bf215546Sopenharmony_ci } 7584bf215546Sopenharmony_ci } 7585bf215546Sopenharmony_ci 7586bf215546Sopenharmony_ci if (qual->flags.q.uniform && qual->has_interpolation()) { 7587bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 7588bf215546Sopenharmony_ci "interpolation qualifiers cannot be used " 7589bf215546Sopenharmony_ci "with uniform interface blocks"); 7590bf215546Sopenharmony_ci } 7591bf215546Sopenharmony_ci 7592bf215546Sopenharmony_ci if ((qual->flags.q.uniform || !is_interface) && 7593bf215546Sopenharmony_ci qual->has_auxiliary_storage()) { 7594bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 7595bf215546Sopenharmony_ci "auxiliary storage qualifiers cannot be used " 7596bf215546Sopenharmony_ci "in uniform blocks or structures."); 7597bf215546Sopenharmony_ci } 7598bf215546Sopenharmony_ci 7599bf215546Sopenharmony_ci if (qual->flags.q.row_major || qual->flags.q.column_major) { 7600bf215546Sopenharmony_ci if (!qual->flags.q.uniform && !qual->flags.q.buffer) { 7601bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 7602bf215546Sopenharmony_ci "row_major and column_major can only be " 7603bf215546Sopenharmony_ci "applied to interface blocks"); 7604bf215546Sopenharmony_ci } else 7605bf215546Sopenharmony_ci validate_matrix_layout_for_type(state, &loc, decl_type, NULL); 7606bf215546Sopenharmony_ci } 7607bf215546Sopenharmony_ci 7608bf215546Sopenharmony_ci foreach_list_typed (ast_declaration, decl, link, 7609bf215546Sopenharmony_ci &decl_list->declarations) { 7610bf215546Sopenharmony_ci YYLTYPE loc = decl->get_location(); 7611bf215546Sopenharmony_ci 7612bf215546Sopenharmony_ci if (!allow_reserved_names) 7613bf215546Sopenharmony_ci validate_identifier(decl->identifier, loc, state); 7614bf215546Sopenharmony_ci 7615bf215546Sopenharmony_ci const struct glsl_type *field_type = 7616bf215546Sopenharmony_ci process_array_type(&loc, decl_type, decl->array_specifier, state); 7617bf215546Sopenharmony_ci validate_array_dimensions(field_type, state, &loc); 7618bf215546Sopenharmony_ci fields[i].type = field_type; 7619bf215546Sopenharmony_ci fields[i].name = decl->identifier; 7620bf215546Sopenharmony_ci fields[i].interpolation = 7621bf215546Sopenharmony_ci interpret_interpolation_qualifier(qual, field_type, 7622bf215546Sopenharmony_ci var_mode, state, &loc); 7623bf215546Sopenharmony_ci fields[i].centroid = qual->flags.q.centroid ? 1 : 0; 7624bf215546Sopenharmony_ci fields[i].sample = qual->flags.q.sample ? 1 : 0; 7625bf215546Sopenharmony_ci fields[i].patch = qual->flags.q.patch ? 1 : 0; 7626bf215546Sopenharmony_ci fields[i].offset = -1; 7627bf215546Sopenharmony_ci fields[i].explicit_xfb_buffer = explicit_xfb_buffer; 7628bf215546Sopenharmony_ci fields[i].xfb_buffer = xfb_buffer; 7629bf215546Sopenharmony_ci fields[i].xfb_stride = xfb_stride; 7630bf215546Sopenharmony_ci 7631bf215546Sopenharmony_ci if (qual->flags.q.explicit_location) { 7632bf215546Sopenharmony_ci unsigned qual_location; 7633bf215546Sopenharmony_ci if (process_qualifier_constant(state, &loc, "location", 7634bf215546Sopenharmony_ci qual->location, &qual_location)) { 7635bf215546Sopenharmony_ci fields[i].location = qual_location + 7636bf215546Sopenharmony_ci (fields[i].patch ? VARYING_SLOT_PATCH0 : VARYING_SLOT_VAR0); 7637bf215546Sopenharmony_ci expl_location = fields[i].location + 7638bf215546Sopenharmony_ci fields[i].type->count_attribute_slots(false); 7639bf215546Sopenharmony_ci } 7640bf215546Sopenharmony_ci } else { 7641bf215546Sopenharmony_ci if (layout && layout->flags.q.explicit_location) { 7642bf215546Sopenharmony_ci fields[i].location = expl_location; 7643bf215546Sopenharmony_ci expl_location += fields[i].type->count_attribute_slots(false); 7644bf215546Sopenharmony_ci } else { 7645bf215546Sopenharmony_ci fields[i].location = -1; 7646bf215546Sopenharmony_ci } 7647bf215546Sopenharmony_ci } 7648bf215546Sopenharmony_ci 7649bf215546Sopenharmony_ci if (qual->flags.q.explicit_component) { 7650bf215546Sopenharmony_ci unsigned qual_component; 7651bf215546Sopenharmony_ci if (process_qualifier_constant(state, &loc, "component", 7652bf215546Sopenharmony_ci qual->component, &qual_component)) { 7653bf215546Sopenharmony_ci validate_component_layout_for_type(state, &loc, fields[i].type, 7654bf215546Sopenharmony_ci qual_component); 7655bf215546Sopenharmony_ci fields[i].component = qual_component; 7656bf215546Sopenharmony_ci } 7657bf215546Sopenharmony_ci } else { 7658bf215546Sopenharmony_ci fields[i].component = -1; 7659bf215546Sopenharmony_ci } 7660bf215546Sopenharmony_ci 7661bf215546Sopenharmony_ci /* Offset can only be used with std430 and std140 layouts an initial 7662bf215546Sopenharmony_ci * value of 0 is used for error detection. 7663bf215546Sopenharmony_ci */ 7664bf215546Sopenharmony_ci unsigned align = 0; 7665bf215546Sopenharmony_ci unsigned size = 0; 7666bf215546Sopenharmony_ci if (layout) { 7667bf215546Sopenharmony_ci bool row_major; 7668bf215546Sopenharmony_ci if (qual->flags.q.row_major || 7669bf215546Sopenharmony_ci matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR) { 7670bf215546Sopenharmony_ci row_major = true; 7671bf215546Sopenharmony_ci } else { 7672bf215546Sopenharmony_ci row_major = false; 7673bf215546Sopenharmony_ci } 7674bf215546Sopenharmony_ci 7675bf215546Sopenharmony_ci if(layout->flags.q.std140) { 7676bf215546Sopenharmony_ci align = field_type->std140_base_alignment(row_major); 7677bf215546Sopenharmony_ci size = field_type->std140_size(row_major); 7678bf215546Sopenharmony_ci } else if (layout->flags.q.std430) { 7679bf215546Sopenharmony_ci align = field_type->std430_base_alignment(row_major); 7680bf215546Sopenharmony_ci size = field_type->std430_size(row_major); 7681bf215546Sopenharmony_ci } 7682bf215546Sopenharmony_ci } 7683bf215546Sopenharmony_ci 7684bf215546Sopenharmony_ci if (qual->flags.q.explicit_offset) { 7685bf215546Sopenharmony_ci unsigned qual_offset; 7686bf215546Sopenharmony_ci if (process_qualifier_constant(state, &loc, "offset", 7687bf215546Sopenharmony_ci qual->offset, &qual_offset)) { 7688bf215546Sopenharmony_ci if (align != 0 && size != 0) { 7689bf215546Sopenharmony_ci if (next_offset > qual_offset) 7690bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "layout qualifier " 7691bf215546Sopenharmony_ci "offset overlaps previous member"); 7692bf215546Sopenharmony_ci 7693bf215546Sopenharmony_ci if (qual_offset % align) { 7694bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "layout qualifier offset " 7695bf215546Sopenharmony_ci "must be a multiple of the base " 7696bf215546Sopenharmony_ci "alignment of %s", field_type->name); 7697bf215546Sopenharmony_ci } 7698bf215546Sopenharmony_ci fields[i].offset = qual_offset; 7699bf215546Sopenharmony_ci next_offset = qual_offset + size; 7700bf215546Sopenharmony_ci } else { 7701bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "offset can only be used " 7702bf215546Sopenharmony_ci "with std430 and std140 layouts"); 7703bf215546Sopenharmony_ci } 7704bf215546Sopenharmony_ci } 7705bf215546Sopenharmony_ci } 7706bf215546Sopenharmony_ci 7707bf215546Sopenharmony_ci if (qual->flags.q.explicit_align || expl_align != 0) { 7708bf215546Sopenharmony_ci unsigned offset = fields[i].offset != -1 ? fields[i].offset : 7709bf215546Sopenharmony_ci next_offset; 7710bf215546Sopenharmony_ci if (align == 0 || size == 0) { 7711bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "align can only be used with " 7712bf215546Sopenharmony_ci "std430 and std140 layouts"); 7713bf215546Sopenharmony_ci } else if (qual->flags.q.explicit_align) { 7714bf215546Sopenharmony_ci unsigned member_align; 7715bf215546Sopenharmony_ci if (process_qualifier_constant(state, &loc, "align", 7716bf215546Sopenharmony_ci qual->align, &member_align)) { 7717bf215546Sopenharmony_ci if (member_align == 0 || 7718bf215546Sopenharmony_ci member_align & (member_align - 1)) { 7719bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "align layout qualifier " 7720bf215546Sopenharmony_ci "is not a power of 2"); 7721bf215546Sopenharmony_ci } else { 7722bf215546Sopenharmony_ci fields[i].offset = glsl_align(offset, member_align); 7723bf215546Sopenharmony_ci next_offset = fields[i].offset + size; 7724bf215546Sopenharmony_ci } 7725bf215546Sopenharmony_ci } 7726bf215546Sopenharmony_ci } else { 7727bf215546Sopenharmony_ci fields[i].offset = glsl_align(offset, expl_align); 7728bf215546Sopenharmony_ci next_offset = fields[i].offset + size; 7729bf215546Sopenharmony_ci } 7730bf215546Sopenharmony_ci } else if (!qual->flags.q.explicit_offset) { 7731bf215546Sopenharmony_ci if (align != 0 && size != 0) 7732bf215546Sopenharmony_ci next_offset = glsl_align(next_offset, align) + size; 7733bf215546Sopenharmony_ci } 7734bf215546Sopenharmony_ci 7735bf215546Sopenharmony_ci /* From the ARB_enhanced_layouts spec: 7736bf215546Sopenharmony_ci * 7737bf215546Sopenharmony_ci * "The given offset applies to the first component of the first 7738bf215546Sopenharmony_ci * member of the qualified entity. Then, within the qualified 7739bf215546Sopenharmony_ci * entity, subsequent components are each assigned, in order, to 7740bf215546Sopenharmony_ci * the next available offset aligned to a multiple of that 7741bf215546Sopenharmony_ci * component's size. Aggregate types are flattened down to the 7742bf215546Sopenharmony_ci * component level to get this sequence of components." 7743bf215546Sopenharmony_ci */ 7744bf215546Sopenharmony_ci if (qual->flags.q.explicit_xfb_offset) { 7745bf215546Sopenharmony_ci unsigned xfb_offset; 7746bf215546Sopenharmony_ci if (process_qualifier_constant(state, &loc, "xfb_offset", 7747bf215546Sopenharmony_ci qual->offset, &xfb_offset)) { 7748bf215546Sopenharmony_ci fields[i].offset = xfb_offset; 7749bf215546Sopenharmony_ci block_xfb_offset = fields[i].offset + 7750bf215546Sopenharmony_ci 4 * field_type->component_slots(); 7751bf215546Sopenharmony_ci } 7752bf215546Sopenharmony_ci } else { 7753bf215546Sopenharmony_ci if (layout && layout->flags.q.explicit_xfb_offset) { 7754bf215546Sopenharmony_ci unsigned align = field_type->is_64bit() ? 8 : 4; 7755bf215546Sopenharmony_ci fields[i].offset = glsl_align(block_xfb_offset, align); 7756bf215546Sopenharmony_ci block_xfb_offset += 4 * field_type->component_slots(); 7757bf215546Sopenharmony_ci } 7758bf215546Sopenharmony_ci } 7759bf215546Sopenharmony_ci 7760bf215546Sopenharmony_ci /* Propogate row- / column-major information down the fields of the 7761bf215546Sopenharmony_ci * structure or interface block. Structures need this data because 7762bf215546Sopenharmony_ci * the structure may contain a structure that contains ... a matrix 7763bf215546Sopenharmony_ci * that need the proper layout. 7764bf215546Sopenharmony_ci */ 7765bf215546Sopenharmony_ci if (is_interface && layout && 7766bf215546Sopenharmony_ci (layout->flags.q.uniform || layout->flags.q.buffer) && 7767bf215546Sopenharmony_ci (field_type->without_array()->is_matrix() 7768bf215546Sopenharmony_ci || field_type->without_array()->is_struct())) { 7769bf215546Sopenharmony_ci /* If no layout is specified for the field, inherit the layout 7770bf215546Sopenharmony_ci * from the block. 7771bf215546Sopenharmony_ci */ 7772bf215546Sopenharmony_ci fields[i].matrix_layout = matrix_layout; 7773bf215546Sopenharmony_ci 7774bf215546Sopenharmony_ci if (qual->flags.q.row_major) 7775bf215546Sopenharmony_ci fields[i].matrix_layout = GLSL_MATRIX_LAYOUT_ROW_MAJOR; 7776bf215546Sopenharmony_ci else if (qual->flags.q.column_major) 7777bf215546Sopenharmony_ci fields[i].matrix_layout = GLSL_MATRIX_LAYOUT_COLUMN_MAJOR; 7778bf215546Sopenharmony_ci 7779bf215546Sopenharmony_ci /* If we're processing an uniform or buffer block, the matrix 7780bf215546Sopenharmony_ci * layout must be decided by this point. 7781bf215546Sopenharmony_ci */ 7782bf215546Sopenharmony_ci assert(fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR 7783bf215546Sopenharmony_ci || fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_COLUMN_MAJOR); 7784bf215546Sopenharmony_ci } 7785bf215546Sopenharmony_ci 7786bf215546Sopenharmony_ci /* Memory qualifiers are allowed on buffer and image variables, while 7787bf215546Sopenharmony_ci * the format qualifier is only accepted for images. 7788bf215546Sopenharmony_ci */ 7789bf215546Sopenharmony_ci if (var_mode == ir_var_shader_storage || 7790bf215546Sopenharmony_ci field_type->without_array()->is_image()) { 7791bf215546Sopenharmony_ci /* For readonly and writeonly qualifiers the field definition, 7792bf215546Sopenharmony_ci * if set, overwrites the layout qualifier. 7793bf215546Sopenharmony_ci */ 7794bf215546Sopenharmony_ci if (qual->flags.q.read_only || qual->flags.q.write_only) { 7795bf215546Sopenharmony_ci fields[i].memory_read_only = qual->flags.q.read_only; 7796bf215546Sopenharmony_ci fields[i].memory_write_only = qual->flags.q.write_only; 7797bf215546Sopenharmony_ci } else { 7798bf215546Sopenharmony_ci fields[i].memory_read_only = 7799bf215546Sopenharmony_ci layout ? layout->flags.q.read_only : 0; 7800bf215546Sopenharmony_ci fields[i].memory_write_only = 7801bf215546Sopenharmony_ci layout ? layout->flags.q.write_only : 0; 7802bf215546Sopenharmony_ci } 7803bf215546Sopenharmony_ci 7804bf215546Sopenharmony_ci /* For other qualifiers, we set the flag if either the layout 7805bf215546Sopenharmony_ci * qualifier or the field qualifier are set 7806bf215546Sopenharmony_ci */ 7807bf215546Sopenharmony_ci fields[i].memory_coherent = qual->flags.q.coherent || 7808bf215546Sopenharmony_ci (layout && layout->flags.q.coherent); 7809bf215546Sopenharmony_ci fields[i].memory_volatile = qual->flags.q._volatile || 7810bf215546Sopenharmony_ci (layout && layout->flags.q._volatile); 7811bf215546Sopenharmony_ci fields[i].memory_restrict = qual->flags.q.restrict_flag || 7812bf215546Sopenharmony_ci (layout && layout->flags.q.restrict_flag); 7813bf215546Sopenharmony_ci 7814bf215546Sopenharmony_ci if (field_type->without_array()->is_image()) { 7815bf215546Sopenharmony_ci if (qual->flags.q.explicit_image_format) { 7816bf215546Sopenharmony_ci if (qual->image_base_type != 7817bf215546Sopenharmony_ci field_type->without_array()->sampled_type) { 7818bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "format qualifier doesn't " 7819bf215546Sopenharmony_ci "match the base data type of the image"); 7820bf215546Sopenharmony_ci } 7821bf215546Sopenharmony_ci 7822bf215546Sopenharmony_ci fields[i].image_format = qual->image_format; 7823bf215546Sopenharmony_ci } else { 7824bf215546Sopenharmony_ci if (!qual->flags.q.write_only) { 7825bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "image not qualified with " 7826bf215546Sopenharmony_ci "`writeonly' must have a format layout " 7827bf215546Sopenharmony_ci "qualifier"); 7828bf215546Sopenharmony_ci } 7829bf215546Sopenharmony_ci 7830bf215546Sopenharmony_ci fields[i].image_format = PIPE_FORMAT_NONE; 7831bf215546Sopenharmony_ci } 7832bf215546Sopenharmony_ci } 7833bf215546Sopenharmony_ci } 7834bf215546Sopenharmony_ci 7835bf215546Sopenharmony_ci /* Precision qualifiers do not hold any meaning in Desktop GLSL */ 7836bf215546Sopenharmony_ci if (state->es_shader) { 7837bf215546Sopenharmony_ci fields[i].precision = select_gles_precision(qual->precision, 7838bf215546Sopenharmony_ci field_type, 7839bf215546Sopenharmony_ci state, 7840bf215546Sopenharmony_ci &loc); 7841bf215546Sopenharmony_ci } else { 7842bf215546Sopenharmony_ci fields[i].precision = qual->precision; 7843bf215546Sopenharmony_ci } 7844bf215546Sopenharmony_ci 7845bf215546Sopenharmony_ci i++; 7846bf215546Sopenharmony_ci } 7847bf215546Sopenharmony_ci } 7848bf215546Sopenharmony_ci 7849bf215546Sopenharmony_ci assert(i == decl_count); 7850bf215546Sopenharmony_ci 7851bf215546Sopenharmony_ci *fields_ret = fields; 7852bf215546Sopenharmony_ci return decl_count; 7853bf215546Sopenharmony_ci} 7854bf215546Sopenharmony_ci 7855bf215546Sopenharmony_ci 7856bf215546Sopenharmony_ciir_rvalue * 7857bf215546Sopenharmony_ciast_struct_specifier::hir(exec_list *instructions, 7858bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 7859bf215546Sopenharmony_ci{ 7860bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 7861bf215546Sopenharmony_ci 7862bf215546Sopenharmony_ci unsigned expl_location = 0; 7863bf215546Sopenharmony_ci if (layout && layout->flags.q.explicit_location) { 7864bf215546Sopenharmony_ci if (!process_qualifier_constant(state, &loc, "location", 7865bf215546Sopenharmony_ci layout->location, &expl_location)) { 7866bf215546Sopenharmony_ci return NULL; 7867bf215546Sopenharmony_ci } else { 7868bf215546Sopenharmony_ci expl_location = VARYING_SLOT_VAR0 + expl_location; 7869bf215546Sopenharmony_ci } 7870bf215546Sopenharmony_ci } 7871bf215546Sopenharmony_ci 7872bf215546Sopenharmony_ci glsl_struct_field *fields; 7873bf215546Sopenharmony_ci unsigned decl_count = 7874bf215546Sopenharmony_ci ast_process_struct_or_iface_block_members(instructions, 7875bf215546Sopenharmony_ci state, 7876bf215546Sopenharmony_ci &this->declarations, 7877bf215546Sopenharmony_ci &fields, 7878bf215546Sopenharmony_ci false, 7879bf215546Sopenharmony_ci GLSL_MATRIX_LAYOUT_INHERITED, 7880bf215546Sopenharmony_ci false /* allow_reserved_names */, 7881bf215546Sopenharmony_ci ir_var_auto, 7882bf215546Sopenharmony_ci layout, 7883bf215546Sopenharmony_ci 0, /* for interface only */ 7884bf215546Sopenharmony_ci 0, /* for interface only */ 7885bf215546Sopenharmony_ci 0, /* for interface only */ 7886bf215546Sopenharmony_ci expl_location, 7887bf215546Sopenharmony_ci 0 /* for interface only */); 7888bf215546Sopenharmony_ci 7889bf215546Sopenharmony_ci validate_identifier(this->name, loc, state); 7890bf215546Sopenharmony_ci 7891bf215546Sopenharmony_ci type = glsl_type::get_struct_instance(fields, decl_count, this->name); 7892bf215546Sopenharmony_ci 7893bf215546Sopenharmony_ci if (!type->is_anonymous() && !state->symbols->add_type(name, type)) { 7894bf215546Sopenharmony_ci const glsl_type *match = state->symbols->get_type(name); 7895bf215546Sopenharmony_ci /* allow struct matching for desktop GL - older UE4 does this */ 7896bf215546Sopenharmony_ci if (match != NULL && state->is_version(130, 0) && match->record_compare(type, true, false)) 7897bf215546Sopenharmony_ci _mesa_glsl_warning(& loc, state, "struct `%s' previously defined", name); 7898bf215546Sopenharmony_ci else 7899bf215546Sopenharmony_ci _mesa_glsl_error(& loc, state, "struct `%s' previously defined", name); 7900bf215546Sopenharmony_ci } else { 7901bf215546Sopenharmony_ci const glsl_type **s = reralloc(state, state->user_structures, 7902bf215546Sopenharmony_ci const glsl_type *, 7903bf215546Sopenharmony_ci state->num_user_structures + 1); 7904bf215546Sopenharmony_ci if (s != NULL) { 7905bf215546Sopenharmony_ci s[state->num_user_structures] = type; 7906bf215546Sopenharmony_ci state->user_structures = s; 7907bf215546Sopenharmony_ci state->num_user_structures++; 7908bf215546Sopenharmony_ci } 7909bf215546Sopenharmony_ci } 7910bf215546Sopenharmony_ci 7911bf215546Sopenharmony_ci /* Structure type definitions do not have r-values. 7912bf215546Sopenharmony_ci */ 7913bf215546Sopenharmony_ci return NULL; 7914bf215546Sopenharmony_ci} 7915bf215546Sopenharmony_ci 7916bf215546Sopenharmony_ci 7917bf215546Sopenharmony_ci/** 7918bf215546Sopenharmony_ci * Visitor class which detects whether a given interface block has been used. 7919bf215546Sopenharmony_ci */ 7920bf215546Sopenharmony_ciclass interface_block_usage_visitor : public ir_hierarchical_visitor 7921bf215546Sopenharmony_ci{ 7922bf215546Sopenharmony_cipublic: 7923bf215546Sopenharmony_ci interface_block_usage_visitor(ir_variable_mode mode, const glsl_type *block) 7924bf215546Sopenharmony_ci : mode(mode), block(block), found(false) 7925bf215546Sopenharmony_ci { 7926bf215546Sopenharmony_ci } 7927bf215546Sopenharmony_ci 7928bf215546Sopenharmony_ci virtual ir_visitor_status visit(ir_dereference_variable *ir) 7929bf215546Sopenharmony_ci { 7930bf215546Sopenharmony_ci if (ir->var->data.mode == mode && ir->var->get_interface_type() == block) { 7931bf215546Sopenharmony_ci found = true; 7932bf215546Sopenharmony_ci return visit_stop; 7933bf215546Sopenharmony_ci } 7934bf215546Sopenharmony_ci return visit_continue; 7935bf215546Sopenharmony_ci } 7936bf215546Sopenharmony_ci 7937bf215546Sopenharmony_ci bool usage_found() const 7938bf215546Sopenharmony_ci { 7939bf215546Sopenharmony_ci return this->found; 7940bf215546Sopenharmony_ci } 7941bf215546Sopenharmony_ci 7942bf215546Sopenharmony_ciprivate: 7943bf215546Sopenharmony_ci ir_variable_mode mode; 7944bf215546Sopenharmony_ci const glsl_type *block; 7945bf215546Sopenharmony_ci bool found; 7946bf215546Sopenharmony_ci}; 7947bf215546Sopenharmony_ci 7948bf215546Sopenharmony_cistatic bool 7949bf215546Sopenharmony_ciis_unsized_array_last_element(ir_variable *v) 7950bf215546Sopenharmony_ci{ 7951bf215546Sopenharmony_ci const glsl_type *interface_type = v->get_interface_type(); 7952bf215546Sopenharmony_ci int length = interface_type->length; 7953bf215546Sopenharmony_ci 7954bf215546Sopenharmony_ci assert(v->type->is_unsized_array()); 7955bf215546Sopenharmony_ci 7956bf215546Sopenharmony_ci /* Check if it is the last element of the interface */ 7957bf215546Sopenharmony_ci if (strcmp(interface_type->fields.structure[length-1].name, v->name) == 0) 7958bf215546Sopenharmony_ci return true; 7959bf215546Sopenharmony_ci return false; 7960bf215546Sopenharmony_ci} 7961bf215546Sopenharmony_ci 7962bf215546Sopenharmony_cistatic void 7963bf215546Sopenharmony_ciapply_memory_qualifiers(ir_variable *var, glsl_struct_field field) 7964bf215546Sopenharmony_ci{ 7965bf215546Sopenharmony_ci var->data.memory_read_only = field.memory_read_only; 7966bf215546Sopenharmony_ci var->data.memory_write_only = field.memory_write_only; 7967bf215546Sopenharmony_ci var->data.memory_coherent = field.memory_coherent; 7968bf215546Sopenharmony_ci var->data.memory_volatile = field.memory_volatile; 7969bf215546Sopenharmony_ci var->data.memory_restrict = field.memory_restrict; 7970bf215546Sopenharmony_ci} 7971bf215546Sopenharmony_ci 7972bf215546Sopenharmony_ciir_rvalue * 7973bf215546Sopenharmony_ciast_interface_block::hir(exec_list *instructions, 7974bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 7975bf215546Sopenharmony_ci{ 7976bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 7977bf215546Sopenharmony_ci 7978bf215546Sopenharmony_ci /* Interface blocks must be declared at global scope */ 7979bf215546Sopenharmony_ci if (state->current_function != NULL) { 7980bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 7981bf215546Sopenharmony_ci "Interface block `%s' must be declared " 7982bf215546Sopenharmony_ci "at global scope", 7983bf215546Sopenharmony_ci this->block_name); 7984bf215546Sopenharmony_ci } 7985bf215546Sopenharmony_ci 7986bf215546Sopenharmony_ci /* Validate qualifiers: 7987bf215546Sopenharmony_ci * 7988bf215546Sopenharmony_ci * - Layout Qualifiers as per the table in Section 4.4 7989bf215546Sopenharmony_ci * ("Layout Qualifiers") of the GLSL 4.50 spec. 7990bf215546Sopenharmony_ci * 7991bf215546Sopenharmony_ci * - Memory Qualifiers as per Section 4.10 ("Memory Qualifiers") of the 7992bf215546Sopenharmony_ci * GLSL 4.50 spec: 7993bf215546Sopenharmony_ci * 7994bf215546Sopenharmony_ci * "Additionally, memory qualifiers may also be used in the declaration 7995bf215546Sopenharmony_ci * of shader storage blocks" 7996bf215546Sopenharmony_ci * 7997bf215546Sopenharmony_ci * Note the table in Section 4.4 says std430 is allowed on both uniform and 7998bf215546Sopenharmony_ci * buffer blocks however Section 4.4.5 (Uniform and Shader Storage Block 7999bf215546Sopenharmony_ci * Layout Qualifiers) of the GLSL 4.50 spec says: 8000bf215546Sopenharmony_ci * 8001bf215546Sopenharmony_ci * "The std430 qualifier is supported only for shader storage blocks; 8002bf215546Sopenharmony_ci * using std430 on a uniform block will result in a compile-time error." 8003bf215546Sopenharmony_ci */ 8004bf215546Sopenharmony_ci ast_type_qualifier allowed_blk_qualifiers; 8005bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.i = 0; 8006bf215546Sopenharmony_ci if (this->layout.flags.q.buffer || this->layout.flags.q.uniform) { 8007bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.shared = 1; 8008bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.packed = 1; 8009bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.std140 = 1; 8010bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.row_major = 1; 8011bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.column_major = 1; 8012bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.explicit_align = 1; 8013bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.explicit_binding = 1; 8014bf215546Sopenharmony_ci if (this->layout.flags.q.buffer) { 8015bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.buffer = 1; 8016bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.std430 = 1; 8017bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.coherent = 1; 8018bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q._volatile = 1; 8019bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.restrict_flag = 1; 8020bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.read_only = 1; 8021bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.write_only = 1; 8022bf215546Sopenharmony_ci } else { 8023bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.uniform = 1; 8024bf215546Sopenharmony_ci } 8025bf215546Sopenharmony_ci } else { 8026bf215546Sopenharmony_ci /* Interface block */ 8027bf215546Sopenharmony_ci assert(this->layout.flags.q.in || this->layout.flags.q.out); 8028bf215546Sopenharmony_ci 8029bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.explicit_location = 1; 8030bf215546Sopenharmony_ci if (this->layout.flags.q.out) { 8031bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.out = 1; 8032bf215546Sopenharmony_ci if (state->stage == MESA_SHADER_GEOMETRY || 8033bf215546Sopenharmony_ci state->stage == MESA_SHADER_TESS_CTRL || 8034bf215546Sopenharmony_ci state->stage == MESA_SHADER_TESS_EVAL || 8035bf215546Sopenharmony_ci state->stage == MESA_SHADER_VERTEX ) { 8036bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.explicit_xfb_offset = 1; 8037bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.explicit_xfb_buffer = 1; 8038bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.xfb_buffer = 1; 8039bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.explicit_xfb_stride = 1; 8040bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.xfb_stride = 1; 8041bf215546Sopenharmony_ci } 8042bf215546Sopenharmony_ci if (state->stage == MESA_SHADER_GEOMETRY) { 8043bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.stream = 1; 8044bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.explicit_stream = 1; 8045bf215546Sopenharmony_ci } 8046bf215546Sopenharmony_ci if (state->stage == MESA_SHADER_TESS_CTRL) { 8047bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.patch = 1; 8048bf215546Sopenharmony_ci } 8049bf215546Sopenharmony_ci } else { 8050bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.in = 1; 8051bf215546Sopenharmony_ci if (state->stage == MESA_SHADER_TESS_EVAL) { 8052bf215546Sopenharmony_ci allowed_blk_qualifiers.flags.q.patch = 1; 8053bf215546Sopenharmony_ci } 8054bf215546Sopenharmony_ci } 8055bf215546Sopenharmony_ci } 8056bf215546Sopenharmony_ci 8057bf215546Sopenharmony_ci this->layout.validate_flags(&loc, state, allowed_blk_qualifiers, 8058bf215546Sopenharmony_ci "invalid qualifier for block", 8059bf215546Sopenharmony_ci this->block_name); 8060bf215546Sopenharmony_ci 8061bf215546Sopenharmony_ci enum glsl_interface_packing packing; 8062bf215546Sopenharmony_ci if (this->layout.flags.q.std140) { 8063bf215546Sopenharmony_ci packing = GLSL_INTERFACE_PACKING_STD140; 8064bf215546Sopenharmony_ci } else if (this->layout.flags.q.packed) { 8065bf215546Sopenharmony_ci packing = GLSL_INTERFACE_PACKING_PACKED; 8066bf215546Sopenharmony_ci } else if (this->layout.flags.q.std430) { 8067bf215546Sopenharmony_ci packing = GLSL_INTERFACE_PACKING_STD430; 8068bf215546Sopenharmony_ci } else { 8069bf215546Sopenharmony_ci /* The default layout is shared. 8070bf215546Sopenharmony_ci */ 8071bf215546Sopenharmony_ci packing = GLSL_INTERFACE_PACKING_SHARED; 8072bf215546Sopenharmony_ci } 8073bf215546Sopenharmony_ci 8074bf215546Sopenharmony_ci ir_variable_mode var_mode; 8075bf215546Sopenharmony_ci const char *iface_type_name; 8076bf215546Sopenharmony_ci if (this->layout.flags.q.in) { 8077bf215546Sopenharmony_ci var_mode = ir_var_shader_in; 8078bf215546Sopenharmony_ci iface_type_name = "in"; 8079bf215546Sopenharmony_ci } else if (this->layout.flags.q.out) { 8080bf215546Sopenharmony_ci var_mode = ir_var_shader_out; 8081bf215546Sopenharmony_ci iface_type_name = "out"; 8082bf215546Sopenharmony_ci } else if (this->layout.flags.q.uniform) { 8083bf215546Sopenharmony_ci var_mode = ir_var_uniform; 8084bf215546Sopenharmony_ci iface_type_name = "uniform"; 8085bf215546Sopenharmony_ci } else if (this->layout.flags.q.buffer) { 8086bf215546Sopenharmony_ci var_mode = ir_var_shader_storage; 8087bf215546Sopenharmony_ci iface_type_name = "buffer"; 8088bf215546Sopenharmony_ci } else { 8089bf215546Sopenharmony_ci var_mode = ir_var_auto; 8090bf215546Sopenharmony_ci iface_type_name = "UNKNOWN"; 8091bf215546Sopenharmony_ci assert(!"interface block layout qualifier not found!"); 8092bf215546Sopenharmony_ci } 8093bf215546Sopenharmony_ci 8094bf215546Sopenharmony_ci enum glsl_matrix_layout matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED; 8095bf215546Sopenharmony_ci if (this->layout.flags.q.row_major) 8096bf215546Sopenharmony_ci matrix_layout = GLSL_MATRIX_LAYOUT_ROW_MAJOR; 8097bf215546Sopenharmony_ci else if (this->layout.flags.q.column_major) 8098bf215546Sopenharmony_ci matrix_layout = GLSL_MATRIX_LAYOUT_COLUMN_MAJOR; 8099bf215546Sopenharmony_ci 8100bf215546Sopenharmony_ci bool redeclaring_per_vertex = strcmp(this->block_name, "gl_PerVertex") == 0; 8101bf215546Sopenharmony_ci exec_list declared_variables; 8102bf215546Sopenharmony_ci glsl_struct_field *fields; 8103bf215546Sopenharmony_ci 8104bf215546Sopenharmony_ci /* For blocks that accept memory qualifiers (i.e. shader storage), verify 8105bf215546Sopenharmony_ci * that we don't have incompatible qualifiers 8106bf215546Sopenharmony_ci */ 8107bf215546Sopenharmony_ci if (this->layout.flags.q.read_only && this->layout.flags.q.write_only) { 8108bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8109bf215546Sopenharmony_ci "Interface block sets both readonly and writeonly"); 8110bf215546Sopenharmony_ci } 8111bf215546Sopenharmony_ci 8112bf215546Sopenharmony_ci unsigned qual_stream; 8113bf215546Sopenharmony_ci if (!process_qualifier_constant(state, &loc, "stream", this->layout.stream, 8114bf215546Sopenharmony_ci &qual_stream) || 8115bf215546Sopenharmony_ci !validate_stream_qualifier(&loc, state, qual_stream)) { 8116bf215546Sopenharmony_ci /* If the stream qualifier is invalid it doesn't make sense to continue 8117bf215546Sopenharmony_ci * on and try to compare stream layouts on member variables against it 8118bf215546Sopenharmony_ci * so just return early. 8119bf215546Sopenharmony_ci */ 8120bf215546Sopenharmony_ci return NULL; 8121bf215546Sopenharmony_ci } 8122bf215546Sopenharmony_ci 8123bf215546Sopenharmony_ci unsigned qual_xfb_buffer = 0; 8124bf215546Sopenharmony_ci if (layout.flags.q.xfb_buffer) { 8125bf215546Sopenharmony_ci if (!process_qualifier_constant(state, &loc, "xfb_buffer", 8126bf215546Sopenharmony_ci layout.xfb_buffer, &qual_xfb_buffer) || 8127bf215546Sopenharmony_ci !validate_xfb_buffer_qualifier(&loc, state, qual_xfb_buffer)) { 8128bf215546Sopenharmony_ci return NULL; 8129bf215546Sopenharmony_ci } 8130bf215546Sopenharmony_ci } 8131bf215546Sopenharmony_ci 8132bf215546Sopenharmony_ci unsigned qual_xfb_offset = 0; 8133bf215546Sopenharmony_ci if (layout.flags.q.explicit_xfb_offset) { 8134bf215546Sopenharmony_ci if (!process_qualifier_constant(state, &loc, "xfb_offset", 8135bf215546Sopenharmony_ci layout.offset, &qual_xfb_offset)) { 8136bf215546Sopenharmony_ci return NULL; 8137bf215546Sopenharmony_ci } 8138bf215546Sopenharmony_ci } 8139bf215546Sopenharmony_ci 8140bf215546Sopenharmony_ci unsigned qual_xfb_stride = 0; 8141bf215546Sopenharmony_ci if (layout.flags.q.explicit_xfb_stride) { 8142bf215546Sopenharmony_ci if (!process_qualifier_constant(state, &loc, "xfb_stride", 8143bf215546Sopenharmony_ci layout.xfb_stride, &qual_xfb_stride)) { 8144bf215546Sopenharmony_ci return NULL; 8145bf215546Sopenharmony_ci } 8146bf215546Sopenharmony_ci } 8147bf215546Sopenharmony_ci 8148bf215546Sopenharmony_ci unsigned expl_location = 0; 8149bf215546Sopenharmony_ci if (layout.flags.q.explicit_location) { 8150bf215546Sopenharmony_ci if (!process_qualifier_constant(state, &loc, "location", 8151bf215546Sopenharmony_ci layout.location, &expl_location)) { 8152bf215546Sopenharmony_ci return NULL; 8153bf215546Sopenharmony_ci } else { 8154bf215546Sopenharmony_ci expl_location += this->layout.flags.q.patch ? VARYING_SLOT_PATCH0 8155bf215546Sopenharmony_ci : VARYING_SLOT_VAR0; 8156bf215546Sopenharmony_ci } 8157bf215546Sopenharmony_ci } 8158bf215546Sopenharmony_ci 8159bf215546Sopenharmony_ci unsigned expl_align = 0; 8160bf215546Sopenharmony_ci if (layout.flags.q.explicit_align) { 8161bf215546Sopenharmony_ci if (!process_qualifier_constant(state, &loc, "align", 8162bf215546Sopenharmony_ci layout.align, &expl_align)) { 8163bf215546Sopenharmony_ci return NULL; 8164bf215546Sopenharmony_ci } else { 8165bf215546Sopenharmony_ci if (expl_align == 0 || expl_align & (expl_align - 1)) { 8166bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "align layout qualifier is not a " 8167bf215546Sopenharmony_ci "power of 2."); 8168bf215546Sopenharmony_ci return NULL; 8169bf215546Sopenharmony_ci } 8170bf215546Sopenharmony_ci } 8171bf215546Sopenharmony_ci } 8172bf215546Sopenharmony_ci 8173bf215546Sopenharmony_ci unsigned int num_variables = 8174bf215546Sopenharmony_ci ast_process_struct_or_iface_block_members(&declared_variables, 8175bf215546Sopenharmony_ci state, 8176bf215546Sopenharmony_ci &this->declarations, 8177bf215546Sopenharmony_ci &fields, 8178bf215546Sopenharmony_ci true, 8179bf215546Sopenharmony_ci matrix_layout, 8180bf215546Sopenharmony_ci redeclaring_per_vertex, 8181bf215546Sopenharmony_ci var_mode, 8182bf215546Sopenharmony_ci &this->layout, 8183bf215546Sopenharmony_ci qual_stream, 8184bf215546Sopenharmony_ci qual_xfb_buffer, 8185bf215546Sopenharmony_ci qual_xfb_offset, 8186bf215546Sopenharmony_ci expl_location, 8187bf215546Sopenharmony_ci expl_align); 8188bf215546Sopenharmony_ci 8189bf215546Sopenharmony_ci if (!redeclaring_per_vertex) { 8190bf215546Sopenharmony_ci validate_identifier(this->block_name, loc, state); 8191bf215546Sopenharmony_ci 8192bf215546Sopenharmony_ci /* From section 4.3.9 ("Interface Blocks") of the GLSL 4.50 spec: 8193bf215546Sopenharmony_ci * 8194bf215546Sopenharmony_ci * "Block names have no other use within a shader beyond interface 8195bf215546Sopenharmony_ci * matching; it is a compile-time error to use a block name at global 8196bf215546Sopenharmony_ci * scope for anything other than as a block name." 8197bf215546Sopenharmony_ci */ 8198bf215546Sopenharmony_ci ir_variable *var = state->symbols->get_variable(this->block_name); 8199bf215546Sopenharmony_ci if (var && !var->type->is_interface()) { 8200bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "Block name `%s' is " 8201bf215546Sopenharmony_ci "already used in the scope.", 8202bf215546Sopenharmony_ci this->block_name); 8203bf215546Sopenharmony_ci } 8204bf215546Sopenharmony_ci } 8205bf215546Sopenharmony_ci 8206bf215546Sopenharmony_ci const glsl_type *earlier_per_vertex = NULL; 8207bf215546Sopenharmony_ci if (redeclaring_per_vertex) { 8208bf215546Sopenharmony_ci /* Find the previous declaration of gl_PerVertex. If we're redeclaring 8209bf215546Sopenharmony_ci * the named interface block gl_in, we can find it by looking at the 8210bf215546Sopenharmony_ci * previous declaration of gl_in. Otherwise we can find it by looking 8211bf215546Sopenharmony_ci * at the previous decalartion of any of the built-in outputs, 8212bf215546Sopenharmony_ci * e.g. gl_Position. 8213bf215546Sopenharmony_ci * 8214bf215546Sopenharmony_ci * Also check that the instance name and array-ness of the redeclaration 8215bf215546Sopenharmony_ci * are correct. 8216bf215546Sopenharmony_ci */ 8217bf215546Sopenharmony_ci switch (var_mode) { 8218bf215546Sopenharmony_ci case ir_var_shader_in: 8219bf215546Sopenharmony_ci if (ir_variable *earlier_gl_in = 8220bf215546Sopenharmony_ci state->symbols->get_variable("gl_in")) { 8221bf215546Sopenharmony_ci earlier_per_vertex = earlier_gl_in->get_interface_type(); 8222bf215546Sopenharmony_ci } else { 8223bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8224bf215546Sopenharmony_ci "redeclaration of gl_PerVertex input not allowed " 8225bf215546Sopenharmony_ci "in the %s shader", 8226bf215546Sopenharmony_ci _mesa_shader_stage_to_string(state->stage)); 8227bf215546Sopenharmony_ci } 8228bf215546Sopenharmony_ci if (this->instance_name == NULL || 8229bf215546Sopenharmony_ci strcmp(this->instance_name, "gl_in") != 0 || this->array_specifier == NULL || 8230bf215546Sopenharmony_ci !this->array_specifier->is_single_dimension()) { 8231bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8232bf215546Sopenharmony_ci "gl_PerVertex input must be redeclared as " 8233bf215546Sopenharmony_ci "gl_in[]"); 8234bf215546Sopenharmony_ci } 8235bf215546Sopenharmony_ci break; 8236bf215546Sopenharmony_ci case ir_var_shader_out: 8237bf215546Sopenharmony_ci if (ir_variable *earlier_gl_Position = 8238bf215546Sopenharmony_ci state->symbols->get_variable("gl_Position")) { 8239bf215546Sopenharmony_ci earlier_per_vertex = earlier_gl_Position->get_interface_type(); 8240bf215546Sopenharmony_ci } else if (ir_variable *earlier_gl_out = 8241bf215546Sopenharmony_ci state->symbols->get_variable("gl_out")) { 8242bf215546Sopenharmony_ci earlier_per_vertex = earlier_gl_out->get_interface_type(); 8243bf215546Sopenharmony_ci } else { 8244bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8245bf215546Sopenharmony_ci "redeclaration of gl_PerVertex output not " 8246bf215546Sopenharmony_ci "allowed in the %s shader", 8247bf215546Sopenharmony_ci _mesa_shader_stage_to_string(state->stage)); 8248bf215546Sopenharmony_ci } 8249bf215546Sopenharmony_ci if (state->stage == MESA_SHADER_TESS_CTRL) { 8250bf215546Sopenharmony_ci if (this->instance_name == NULL || 8251bf215546Sopenharmony_ci strcmp(this->instance_name, "gl_out") != 0 || this->array_specifier == NULL) { 8252bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8253bf215546Sopenharmony_ci "gl_PerVertex output must be redeclared as " 8254bf215546Sopenharmony_ci "gl_out[]"); 8255bf215546Sopenharmony_ci } 8256bf215546Sopenharmony_ci } else { 8257bf215546Sopenharmony_ci if (this->instance_name != NULL) { 8258bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8259bf215546Sopenharmony_ci "gl_PerVertex output may not be redeclared with " 8260bf215546Sopenharmony_ci "an instance name"); 8261bf215546Sopenharmony_ci } 8262bf215546Sopenharmony_ci } 8263bf215546Sopenharmony_ci break; 8264bf215546Sopenharmony_ci default: 8265bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8266bf215546Sopenharmony_ci "gl_PerVertex must be declared as an input or an " 8267bf215546Sopenharmony_ci "output"); 8268bf215546Sopenharmony_ci break; 8269bf215546Sopenharmony_ci } 8270bf215546Sopenharmony_ci 8271bf215546Sopenharmony_ci if (earlier_per_vertex == NULL) { 8272bf215546Sopenharmony_ci /* An error has already been reported. Bail out to avoid null 8273bf215546Sopenharmony_ci * dereferences later in this function. 8274bf215546Sopenharmony_ci */ 8275bf215546Sopenharmony_ci return NULL; 8276bf215546Sopenharmony_ci } 8277bf215546Sopenharmony_ci 8278bf215546Sopenharmony_ci /* Copy locations from the old gl_PerVertex interface block. */ 8279bf215546Sopenharmony_ci for (unsigned i = 0; i < num_variables; i++) { 8280bf215546Sopenharmony_ci int j = earlier_per_vertex->field_index(fields[i].name); 8281bf215546Sopenharmony_ci if (j == -1) { 8282bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8283bf215546Sopenharmony_ci "redeclaration of gl_PerVertex must be a subset " 8284bf215546Sopenharmony_ci "of the built-in members of gl_PerVertex"); 8285bf215546Sopenharmony_ci } else { 8286bf215546Sopenharmony_ci fields[i].location = 8287bf215546Sopenharmony_ci earlier_per_vertex->fields.structure[j].location; 8288bf215546Sopenharmony_ci fields[i].offset = 8289bf215546Sopenharmony_ci earlier_per_vertex->fields.structure[j].offset; 8290bf215546Sopenharmony_ci fields[i].interpolation = 8291bf215546Sopenharmony_ci earlier_per_vertex->fields.structure[j].interpolation; 8292bf215546Sopenharmony_ci fields[i].centroid = 8293bf215546Sopenharmony_ci earlier_per_vertex->fields.structure[j].centroid; 8294bf215546Sopenharmony_ci fields[i].sample = 8295bf215546Sopenharmony_ci earlier_per_vertex->fields.structure[j].sample; 8296bf215546Sopenharmony_ci fields[i].patch = 8297bf215546Sopenharmony_ci earlier_per_vertex->fields.structure[j].patch; 8298bf215546Sopenharmony_ci fields[i].precision = 8299bf215546Sopenharmony_ci earlier_per_vertex->fields.structure[j].precision; 8300bf215546Sopenharmony_ci fields[i].explicit_xfb_buffer = 8301bf215546Sopenharmony_ci earlier_per_vertex->fields.structure[j].explicit_xfb_buffer; 8302bf215546Sopenharmony_ci fields[i].xfb_buffer = 8303bf215546Sopenharmony_ci earlier_per_vertex->fields.structure[j].xfb_buffer; 8304bf215546Sopenharmony_ci fields[i].xfb_stride = 8305bf215546Sopenharmony_ci earlier_per_vertex->fields.structure[j].xfb_stride; 8306bf215546Sopenharmony_ci } 8307bf215546Sopenharmony_ci } 8308bf215546Sopenharmony_ci 8309bf215546Sopenharmony_ci /* From section 7.1 ("Built-in Language Variables") of the GLSL 4.10 8310bf215546Sopenharmony_ci * spec: 8311bf215546Sopenharmony_ci * 8312bf215546Sopenharmony_ci * If a built-in interface block is redeclared, it must appear in 8313bf215546Sopenharmony_ci * the shader before any use of any member included in the built-in 8314bf215546Sopenharmony_ci * declaration, or a compilation error will result. 8315bf215546Sopenharmony_ci * 8316bf215546Sopenharmony_ci * This appears to be a clarification to the behaviour established for 8317bf215546Sopenharmony_ci * gl_PerVertex by GLSL 1.50, therefore we implement this behaviour 8318bf215546Sopenharmony_ci * regardless of GLSL version. 8319bf215546Sopenharmony_ci */ 8320bf215546Sopenharmony_ci interface_block_usage_visitor v(var_mode, earlier_per_vertex); 8321bf215546Sopenharmony_ci v.run(instructions); 8322bf215546Sopenharmony_ci if (v.usage_found()) { 8323bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8324bf215546Sopenharmony_ci "redeclaration of a built-in interface block must " 8325bf215546Sopenharmony_ci "appear before any use of any member of the " 8326bf215546Sopenharmony_ci "interface block"); 8327bf215546Sopenharmony_ci } 8328bf215546Sopenharmony_ci } 8329bf215546Sopenharmony_ci 8330bf215546Sopenharmony_ci const glsl_type *block_type = 8331bf215546Sopenharmony_ci glsl_type::get_interface_instance(fields, 8332bf215546Sopenharmony_ci num_variables, 8333bf215546Sopenharmony_ci packing, 8334bf215546Sopenharmony_ci matrix_layout == 8335bf215546Sopenharmony_ci GLSL_MATRIX_LAYOUT_ROW_MAJOR, 8336bf215546Sopenharmony_ci this->block_name); 8337bf215546Sopenharmony_ci 8338bf215546Sopenharmony_ci unsigned component_size = block_type->contains_double() ? 8 : 4; 8339bf215546Sopenharmony_ci int xfb_offset = 8340bf215546Sopenharmony_ci layout.flags.q.explicit_xfb_offset ? (int) qual_xfb_offset : -1; 8341bf215546Sopenharmony_ci validate_xfb_offset_qualifier(&loc, state, xfb_offset, block_type, 8342bf215546Sopenharmony_ci component_size); 8343bf215546Sopenharmony_ci 8344bf215546Sopenharmony_ci if (!state->symbols->add_interface(block_type->name, block_type, var_mode)) { 8345bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 8346bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "interface block `%s' with type `%s' " 8347bf215546Sopenharmony_ci "already taken in the current scope", 8348bf215546Sopenharmony_ci this->block_name, iface_type_name); 8349bf215546Sopenharmony_ci } 8350bf215546Sopenharmony_ci 8351bf215546Sopenharmony_ci /* Since interface blocks cannot contain statements, it should be 8352bf215546Sopenharmony_ci * impossible for the block to generate any instructions. 8353bf215546Sopenharmony_ci */ 8354bf215546Sopenharmony_ci assert(declared_variables.is_empty()); 8355bf215546Sopenharmony_ci 8356bf215546Sopenharmony_ci /* From section 4.3.4 (Inputs) of the GLSL 1.50 spec: 8357bf215546Sopenharmony_ci * 8358bf215546Sopenharmony_ci * Geometry shader input variables get the per-vertex values written 8359bf215546Sopenharmony_ci * out by vertex shader output variables of the same names. Since a 8360bf215546Sopenharmony_ci * geometry shader operates on a set of vertices, each input varying 8361bf215546Sopenharmony_ci * variable (or input block, see interface blocks below) needs to be 8362bf215546Sopenharmony_ci * declared as an array. 8363bf215546Sopenharmony_ci */ 8364bf215546Sopenharmony_ci if (state->stage == MESA_SHADER_GEOMETRY && this->array_specifier == NULL && 8365bf215546Sopenharmony_ci var_mode == ir_var_shader_in) { 8366bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "geometry shader inputs must be arrays"); 8367bf215546Sopenharmony_ci } else if ((state->stage == MESA_SHADER_TESS_CTRL || 8368bf215546Sopenharmony_ci state->stage == MESA_SHADER_TESS_EVAL) && 8369bf215546Sopenharmony_ci !this->layout.flags.q.patch && 8370bf215546Sopenharmony_ci this->array_specifier == NULL && 8371bf215546Sopenharmony_ci var_mode == ir_var_shader_in) { 8372bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "per-vertex tessellation shader inputs must be arrays"); 8373bf215546Sopenharmony_ci } else if (state->stage == MESA_SHADER_TESS_CTRL && 8374bf215546Sopenharmony_ci !this->layout.flags.q.patch && 8375bf215546Sopenharmony_ci this->array_specifier == NULL && 8376bf215546Sopenharmony_ci var_mode == ir_var_shader_out) { 8377bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "tessellation control shader outputs must be arrays"); 8378bf215546Sopenharmony_ci } 8379bf215546Sopenharmony_ci 8380bf215546Sopenharmony_ci 8381bf215546Sopenharmony_ci /* Page 39 (page 45 of the PDF) of section 4.3.7 in the GLSL ES 3.00 spec 8382bf215546Sopenharmony_ci * says: 8383bf215546Sopenharmony_ci * 8384bf215546Sopenharmony_ci * "If an instance name (instance-name) is used, then it puts all the 8385bf215546Sopenharmony_ci * members inside a scope within its own name space, accessed with the 8386bf215546Sopenharmony_ci * field selector ( . ) operator (analogously to structures)." 8387bf215546Sopenharmony_ci */ 8388bf215546Sopenharmony_ci if (this->instance_name) { 8389bf215546Sopenharmony_ci if (redeclaring_per_vertex) { 8390bf215546Sopenharmony_ci /* When a built-in in an unnamed interface block is redeclared, 8391bf215546Sopenharmony_ci * get_variable_being_redeclared() calls 8392bf215546Sopenharmony_ci * check_builtin_array_max_size() to make sure that built-in array 8393bf215546Sopenharmony_ci * variables aren't redeclared to illegal sizes. But we're looking 8394bf215546Sopenharmony_ci * at a redeclaration of a named built-in interface block. So we 8395bf215546Sopenharmony_ci * have to manually call check_builtin_array_max_size() for all parts 8396bf215546Sopenharmony_ci * of the interface that are arrays. 8397bf215546Sopenharmony_ci */ 8398bf215546Sopenharmony_ci for (unsigned i = 0; i < num_variables; i++) { 8399bf215546Sopenharmony_ci if (fields[i].type->is_array()) { 8400bf215546Sopenharmony_ci const unsigned size = fields[i].type->array_size(); 8401bf215546Sopenharmony_ci check_builtin_array_max_size(fields[i].name, size, loc, state); 8402bf215546Sopenharmony_ci } 8403bf215546Sopenharmony_ci } 8404bf215546Sopenharmony_ci } else { 8405bf215546Sopenharmony_ci validate_identifier(this->instance_name, loc, state); 8406bf215546Sopenharmony_ci } 8407bf215546Sopenharmony_ci 8408bf215546Sopenharmony_ci ir_variable *var; 8409bf215546Sopenharmony_ci 8410bf215546Sopenharmony_ci if (this->array_specifier != NULL) { 8411bf215546Sopenharmony_ci const glsl_type *block_array_type = 8412bf215546Sopenharmony_ci process_array_type(&loc, block_type, this->array_specifier, state); 8413bf215546Sopenharmony_ci 8414bf215546Sopenharmony_ci /* From Section 4.4.1 (Input Layout Qualifiers) of the GLSL 4.50 spec: 8415bf215546Sopenharmony_ci * 8416bf215546Sopenharmony_ci * "For some blocks declared as arrays, the location can only be applied 8417bf215546Sopenharmony_ci * at the block level: When a block is declared as an array where 8418bf215546Sopenharmony_ci * additional locations are needed for each member for each block array 8419bf215546Sopenharmony_ci * element, it is a compile-time error to specify locations on the block 8420bf215546Sopenharmony_ci * members. That is, when locations would be under specified by applying 8421bf215546Sopenharmony_ci * them on block members, they are not allowed on block members. For 8422bf215546Sopenharmony_ci * arrayed interfaces (those generally having an extra level of 8423bf215546Sopenharmony_ci * arrayness due to interface expansion), the outer array is stripped 8424bf215546Sopenharmony_ci * before applying this rule" 8425bf215546Sopenharmony_ci * 8426bf215546Sopenharmony_ci * From 4.4.1 (Input Layout Qualifiers) and 8427bf215546Sopenharmony_ci * 4.4.2 (Output Layout Qualifiers) of GLSL ES 3.20 8428bf215546Sopenharmony_ci * 8429bf215546Sopenharmony_ci * "If an input is declared as an array of blocks, excluding 8430bf215546Sopenharmony_ci * per-vertex-arrays as required for tessellation, it is an error 8431bf215546Sopenharmony_ci * to declare a member of the block with a location qualifier." 8432bf215546Sopenharmony_ci * 8433bf215546Sopenharmony_ci * "If an output is declared as an array of blocks, excluding 8434bf215546Sopenharmony_ci * per-vertex-arrays as required for tessellation, it is an error 8435bf215546Sopenharmony_ci * to declare a member of the block with a location qualifier." 8436bf215546Sopenharmony_ci */ 8437bf215546Sopenharmony_ci if (!redeclaring_per_vertex && 8438bf215546Sopenharmony_ci (state->has_enhanced_layouts() || state->has_shader_io_blocks())) { 8439bf215546Sopenharmony_ci bool allow_location; 8440bf215546Sopenharmony_ci switch (state->stage) 8441bf215546Sopenharmony_ci { 8442bf215546Sopenharmony_ci case MESA_SHADER_TESS_CTRL: 8443bf215546Sopenharmony_ci allow_location = this->array_specifier->is_single_dimension(); 8444bf215546Sopenharmony_ci break; 8445bf215546Sopenharmony_ci case MESA_SHADER_TESS_EVAL: 8446bf215546Sopenharmony_ci case MESA_SHADER_GEOMETRY: 8447bf215546Sopenharmony_ci allow_location = (this->array_specifier->is_single_dimension() 8448bf215546Sopenharmony_ci && var_mode == ir_var_shader_in); 8449bf215546Sopenharmony_ci break; 8450bf215546Sopenharmony_ci default: 8451bf215546Sopenharmony_ci allow_location = false; 8452bf215546Sopenharmony_ci break; 8453bf215546Sopenharmony_ci } 8454bf215546Sopenharmony_ci 8455bf215546Sopenharmony_ci if (!allow_location) { 8456bf215546Sopenharmony_ci for (unsigned i = 0; i < num_variables; i++) { 8457bf215546Sopenharmony_ci if (fields[i].location != -1) { 8458bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8459bf215546Sopenharmony_ci "explicit member locations are not allowed in " 8460bf215546Sopenharmony_ci "blocks declared as arrays %s shader", 8461bf215546Sopenharmony_ci _mesa_shader_stage_to_string(state->stage)); 8462bf215546Sopenharmony_ci } 8463bf215546Sopenharmony_ci } 8464bf215546Sopenharmony_ci } 8465bf215546Sopenharmony_ci } 8466bf215546Sopenharmony_ci 8467bf215546Sopenharmony_ci /* Section 4.3.7 (Interface Blocks) of the GLSL 1.50 spec says: 8468bf215546Sopenharmony_ci * 8469bf215546Sopenharmony_ci * For uniform blocks declared an array, each individual array 8470bf215546Sopenharmony_ci * element corresponds to a separate buffer object backing one 8471bf215546Sopenharmony_ci * instance of the block. As the array size indicates the number 8472bf215546Sopenharmony_ci * of buffer objects needed, uniform block array declarations 8473bf215546Sopenharmony_ci * must specify an array size. 8474bf215546Sopenharmony_ci * 8475bf215546Sopenharmony_ci * And a few paragraphs later: 8476bf215546Sopenharmony_ci * 8477bf215546Sopenharmony_ci * Geometry shader input blocks must be declared as arrays and 8478bf215546Sopenharmony_ci * follow the array declaration and linking rules for all 8479bf215546Sopenharmony_ci * geometry shader inputs. All other input and output block 8480bf215546Sopenharmony_ci * arrays must specify an array size. 8481bf215546Sopenharmony_ci * 8482bf215546Sopenharmony_ci * The same applies to tessellation shaders. 8483bf215546Sopenharmony_ci * 8484bf215546Sopenharmony_ci * The upshot of this is that the only circumstance where an 8485bf215546Sopenharmony_ci * interface array size *doesn't* need to be specified is on a 8486bf215546Sopenharmony_ci * geometry shader input, tessellation control shader input, 8487bf215546Sopenharmony_ci * tessellation control shader output, and tessellation evaluation 8488bf215546Sopenharmony_ci * shader input. 8489bf215546Sopenharmony_ci */ 8490bf215546Sopenharmony_ci if (block_array_type->is_unsized_array()) { 8491bf215546Sopenharmony_ci bool allow_inputs = state->stage == MESA_SHADER_GEOMETRY || 8492bf215546Sopenharmony_ci state->stage == MESA_SHADER_TESS_CTRL || 8493bf215546Sopenharmony_ci state->stage == MESA_SHADER_TESS_EVAL; 8494bf215546Sopenharmony_ci bool allow_outputs = state->stage == MESA_SHADER_TESS_CTRL; 8495bf215546Sopenharmony_ci 8496bf215546Sopenharmony_ci if (this->layout.flags.q.in) { 8497bf215546Sopenharmony_ci if (!allow_inputs) 8498bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8499bf215546Sopenharmony_ci "unsized input block arrays not allowed in " 8500bf215546Sopenharmony_ci "%s shader", 8501bf215546Sopenharmony_ci _mesa_shader_stage_to_string(state->stage)); 8502bf215546Sopenharmony_ci } else if (this->layout.flags.q.out) { 8503bf215546Sopenharmony_ci if (!allow_outputs) 8504bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8505bf215546Sopenharmony_ci "unsized output block arrays not allowed in " 8506bf215546Sopenharmony_ci "%s shader", 8507bf215546Sopenharmony_ci _mesa_shader_stage_to_string(state->stage)); 8508bf215546Sopenharmony_ci } else { 8509bf215546Sopenharmony_ci /* by elimination, this is a uniform block array */ 8510bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8511bf215546Sopenharmony_ci "unsized uniform block arrays not allowed in " 8512bf215546Sopenharmony_ci "%s shader", 8513bf215546Sopenharmony_ci _mesa_shader_stage_to_string(state->stage)); 8514bf215546Sopenharmony_ci } 8515bf215546Sopenharmony_ci } 8516bf215546Sopenharmony_ci 8517bf215546Sopenharmony_ci /* From section 4.3.9 (Interface Blocks) of the GLSL ES 3.10 spec: 8518bf215546Sopenharmony_ci * 8519bf215546Sopenharmony_ci * * Arrays of arrays of blocks are not allowed 8520bf215546Sopenharmony_ci */ 8521bf215546Sopenharmony_ci if (state->es_shader && block_array_type->is_array() && 8522bf215546Sopenharmony_ci block_array_type->fields.array->is_array()) { 8523bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8524bf215546Sopenharmony_ci "arrays of arrays interface blocks are " 8525bf215546Sopenharmony_ci "not allowed"); 8526bf215546Sopenharmony_ci } 8527bf215546Sopenharmony_ci 8528bf215546Sopenharmony_ci var = new(state) ir_variable(block_array_type, 8529bf215546Sopenharmony_ci this->instance_name, 8530bf215546Sopenharmony_ci var_mode); 8531bf215546Sopenharmony_ci } else { 8532bf215546Sopenharmony_ci var = new(state) ir_variable(block_type, 8533bf215546Sopenharmony_ci this->instance_name, 8534bf215546Sopenharmony_ci var_mode); 8535bf215546Sopenharmony_ci } 8536bf215546Sopenharmony_ci 8537bf215546Sopenharmony_ci var->data.matrix_layout = matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED 8538bf215546Sopenharmony_ci ? GLSL_MATRIX_LAYOUT_COLUMN_MAJOR : matrix_layout; 8539bf215546Sopenharmony_ci 8540bf215546Sopenharmony_ci if (var_mode == ir_var_shader_in || var_mode == ir_var_uniform) 8541bf215546Sopenharmony_ci var->data.read_only = true; 8542bf215546Sopenharmony_ci 8543bf215546Sopenharmony_ci var->data.patch = this->layout.flags.q.patch; 8544bf215546Sopenharmony_ci 8545bf215546Sopenharmony_ci if (state->stage == MESA_SHADER_GEOMETRY && var_mode == ir_var_shader_in) 8546bf215546Sopenharmony_ci handle_geometry_shader_input_decl(state, loc, var); 8547bf215546Sopenharmony_ci else if ((state->stage == MESA_SHADER_TESS_CTRL || 8548bf215546Sopenharmony_ci state->stage == MESA_SHADER_TESS_EVAL) && var_mode == ir_var_shader_in) 8549bf215546Sopenharmony_ci handle_tess_shader_input_decl(state, loc, var); 8550bf215546Sopenharmony_ci else if (state->stage == MESA_SHADER_TESS_CTRL && var_mode == ir_var_shader_out) 8551bf215546Sopenharmony_ci handle_tess_ctrl_shader_output_decl(state, loc, var); 8552bf215546Sopenharmony_ci 8553bf215546Sopenharmony_ci for (unsigned i = 0; i < num_variables; i++) { 8554bf215546Sopenharmony_ci if (var->data.mode == ir_var_shader_storage) 8555bf215546Sopenharmony_ci apply_memory_qualifiers(var, fields[i]); 8556bf215546Sopenharmony_ci } 8557bf215546Sopenharmony_ci 8558bf215546Sopenharmony_ci if (ir_variable *earlier = 8559bf215546Sopenharmony_ci state->symbols->get_variable(this->instance_name)) { 8560bf215546Sopenharmony_ci if (!redeclaring_per_vertex) { 8561bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "`%s' redeclared", 8562bf215546Sopenharmony_ci this->instance_name); 8563bf215546Sopenharmony_ci } 8564bf215546Sopenharmony_ci earlier->data.how_declared = ir_var_declared_normally; 8565bf215546Sopenharmony_ci earlier->type = var->type; 8566bf215546Sopenharmony_ci earlier->reinit_interface_type(block_type); 8567bf215546Sopenharmony_ci delete var; 8568bf215546Sopenharmony_ci } else { 8569bf215546Sopenharmony_ci if (this->layout.flags.q.explicit_binding) { 8570bf215546Sopenharmony_ci apply_explicit_binding(state, &loc, var, var->type, 8571bf215546Sopenharmony_ci &this->layout); 8572bf215546Sopenharmony_ci } 8573bf215546Sopenharmony_ci 8574bf215546Sopenharmony_ci var->data.stream = qual_stream; 8575bf215546Sopenharmony_ci if (layout.flags.q.explicit_location) { 8576bf215546Sopenharmony_ci var->data.location = expl_location; 8577bf215546Sopenharmony_ci var->data.explicit_location = true; 8578bf215546Sopenharmony_ci } 8579bf215546Sopenharmony_ci 8580bf215546Sopenharmony_ci state->symbols->add_variable(var); 8581bf215546Sopenharmony_ci instructions->push_tail(var); 8582bf215546Sopenharmony_ci } 8583bf215546Sopenharmony_ci } else { 8584bf215546Sopenharmony_ci /* In order to have an array size, the block must also be declared with 8585bf215546Sopenharmony_ci * an instance name. 8586bf215546Sopenharmony_ci */ 8587bf215546Sopenharmony_ci assert(this->array_specifier == NULL); 8588bf215546Sopenharmony_ci 8589bf215546Sopenharmony_ci for (unsigned i = 0; i < num_variables; i++) { 8590bf215546Sopenharmony_ci ir_variable *var = 8591bf215546Sopenharmony_ci new(state) ir_variable(fields[i].type, 8592bf215546Sopenharmony_ci ralloc_strdup(state, fields[i].name), 8593bf215546Sopenharmony_ci var_mode); 8594bf215546Sopenharmony_ci var->data.interpolation = fields[i].interpolation; 8595bf215546Sopenharmony_ci var->data.centroid = fields[i].centroid; 8596bf215546Sopenharmony_ci var->data.sample = fields[i].sample; 8597bf215546Sopenharmony_ci var->data.patch = fields[i].patch; 8598bf215546Sopenharmony_ci var->data.stream = qual_stream; 8599bf215546Sopenharmony_ci var->data.location = fields[i].location; 8600bf215546Sopenharmony_ci 8601bf215546Sopenharmony_ci if (fields[i].location != -1) 8602bf215546Sopenharmony_ci var->data.explicit_location = true; 8603bf215546Sopenharmony_ci 8604bf215546Sopenharmony_ci var->data.explicit_xfb_buffer = fields[i].explicit_xfb_buffer; 8605bf215546Sopenharmony_ci var->data.xfb_buffer = fields[i].xfb_buffer; 8606bf215546Sopenharmony_ci 8607bf215546Sopenharmony_ci if (fields[i].offset != -1) 8608bf215546Sopenharmony_ci var->data.explicit_xfb_offset = true; 8609bf215546Sopenharmony_ci var->data.offset = fields[i].offset; 8610bf215546Sopenharmony_ci 8611bf215546Sopenharmony_ci var->init_interface_type(block_type); 8612bf215546Sopenharmony_ci 8613bf215546Sopenharmony_ci if (var_mode == ir_var_shader_in || var_mode == ir_var_uniform) 8614bf215546Sopenharmony_ci var->data.read_only = true; 8615bf215546Sopenharmony_ci 8616bf215546Sopenharmony_ci /* Precision qualifiers do not have any meaning in Desktop GLSL */ 8617bf215546Sopenharmony_ci if (state->es_shader) { 8618bf215546Sopenharmony_ci var->data.precision = 8619bf215546Sopenharmony_ci select_gles_precision(fields[i].precision, fields[i].type, 8620bf215546Sopenharmony_ci state, &loc); 8621bf215546Sopenharmony_ci } 8622bf215546Sopenharmony_ci 8623bf215546Sopenharmony_ci if (fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED) { 8624bf215546Sopenharmony_ci var->data.matrix_layout = matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED 8625bf215546Sopenharmony_ci ? GLSL_MATRIX_LAYOUT_COLUMN_MAJOR : matrix_layout; 8626bf215546Sopenharmony_ci } else { 8627bf215546Sopenharmony_ci var->data.matrix_layout = fields[i].matrix_layout; 8628bf215546Sopenharmony_ci } 8629bf215546Sopenharmony_ci 8630bf215546Sopenharmony_ci if (var->data.mode == ir_var_shader_storage) 8631bf215546Sopenharmony_ci apply_memory_qualifiers(var, fields[i]); 8632bf215546Sopenharmony_ci 8633bf215546Sopenharmony_ci /* Examine var name here since var may get deleted in the next call */ 8634bf215546Sopenharmony_ci bool var_is_gl_id = is_gl_identifier(var->name); 8635bf215546Sopenharmony_ci 8636bf215546Sopenharmony_ci if (redeclaring_per_vertex) { 8637bf215546Sopenharmony_ci bool is_redeclaration; 8638bf215546Sopenharmony_ci var = 8639bf215546Sopenharmony_ci get_variable_being_redeclared(&var, loc, state, 8640bf215546Sopenharmony_ci true /* allow_all_redeclarations */, 8641bf215546Sopenharmony_ci &is_redeclaration); 8642bf215546Sopenharmony_ci if (!var_is_gl_id || !is_redeclaration) { 8643bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8644bf215546Sopenharmony_ci "redeclaration of gl_PerVertex can only " 8645bf215546Sopenharmony_ci "include built-in variables"); 8646bf215546Sopenharmony_ci } else if (var->data.how_declared == ir_var_declared_normally) { 8647bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8648bf215546Sopenharmony_ci "`%s' has already been redeclared", 8649bf215546Sopenharmony_ci var->name); 8650bf215546Sopenharmony_ci } else { 8651bf215546Sopenharmony_ci var->data.how_declared = ir_var_declared_in_block; 8652bf215546Sopenharmony_ci var->reinit_interface_type(block_type); 8653bf215546Sopenharmony_ci } 8654bf215546Sopenharmony_ci continue; 8655bf215546Sopenharmony_ci } 8656bf215546Sopenharmony_ci 8657bf215546Sopenharmony_ci if (state->symbols->get_variable(var->name) != NULL) 8658bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "`%s' redeclared", var->name); 8659bf215546Sopenharmony_ci 8660bf215546Sopenharmony_ci /* Propagate the "binding" keyword into this UBO/SSBO's fields. 8661bf215546Sopenharmony_ci * The UBO declaration itself doesn't get an ir_variable unless it 8662bf215546Sopenharmony_ci * has an instance name. This is ugly. 8663bf215546Sopenharmony_ci */ 8664bf215546Sopenharmony_ci if (this->layout.flags.q.explicit_binding) { 8665bf215546Sopenharmony_ci apply_explicit_binding(state, &loc, var, 8666bf215546Sopenharmony_ci var->get_interface_type(), &this->layout); 8667bf215546Sopenharmony_ci } 8668bf215546Sopenharmony_ci 8669bf215546Sopenharmony_ci if (var->type->is_unsized_array()) { 8670bf215546Sopenharmony_ci if (var->is_in_shader_storage_block() && 8671bf215546Sopenharmony_ci is_unsized_array_last_element(var)) { 8672bf215546Sopenharmony_ci var->data.from_ssbo_unsized_array = true; 8673bf215546Sopenharmony_ci } else { 8674bf215546Sopenharmony_ci /* From GLSL ES 3.10 spec, section 4.1.9 "Arrays": 8675bf215546Sopenharmony_ci * 8676bf215546Sopenharmony_ci * "If an array is declared as the last member of a shader storage 8677bf215546Sopenharmony_ci * block and the size is not specified at compile-time, it is 8678bf215546Sopenharmony_ci * sized at run-time. In all other cases, arrays are sized only 8679bf215546Sopenharmony_ci * at compile-time." 8680bf215546Sopenharmony_ci * 8681bf215546Sopenharmony_ci * In desktop GLSL it is allowed to have unsized-arrays that are 8682bf215546Sopenharmony_ci * not last, as long as we can determine that they are implicitly 8683bf215546Sopenharmony_ci * sized. 8684bf215546Sopenharmony_ci */ 8685bf215546Sopenharmony_ci if (state->es_shader) { 8686bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "unsized array `%s' " 8687bf215546Sopenharmony_ci "definition: only last member of a shader " 8688bf215546Sopenharmony_ci "storage block can be defined as unsized " 8689bf215546Sopenharmony_ci "array", fields[i].name); 8690bf215546Sopenharmony_ci } 8691bf215546Sopenharmony_ci } 8692bf215546Sopenharmony_ci } 8693bf215546Sopenharmony_ci 8694bf215546Sopenharmony_ci state->symbols->add_variable(var); 8695bf215546Sopenharmony_ci instructions->push_tail(var); 8696bf215546Sopenharmony_ci } 8697bf215546Sopenharmony_ci 8698bf215546Sopenharmony_ci if (redeclaring_per_vertex && block_type != earlier_per_vertex) { 8699bf215546Sopenharmony_ci /* From section 7.1 ("Built-in Language Variables") of the GLSL 4.10 spec: 8700bf215546Sopenharmony_ci * 8701bf215546Sopenharmony_ci * It is also a compilation error ... to redeclare a built-in 8702bf215546Sopenharmony_ci * block and then use a member from that built-in block that was 8703bf215546Sopenharmony_ci * not included in the redeclaration. 8704bf215546Sopenharmony_ci * 8705bf215546Sopenharmony_ci * This appears to be a clarification to the behaviour established 8706bf215546Sopenharmony_ci * for gl_PerVertex by GLSL 1.50, therefore we implement this 8707bf215546Sopenharmony_ci * behaviour regardless of GLSL version. 8708bf215546Sopenharmony_ci * 8709bf215546Sopenharmony_ci * To prevent the shader from using a member that was not included in 8710bf215546Sopenharmony_ci * the redeclaration, we disable any ir_variables that are still 8711bf215546Sopenharmony_ci * associated with the old declaration of gl_PerVertex (since we've 8712bf215546Sopenharmony_ci * already updated all of the variables contained in the new 8713bf215546Sopenharmony_ci * gl_PerVertex to point to it). 8714bf215546Sopenharmony_ci * 8715bf215546Sopenharmony_ci * As a side effect this will prevent 8716bf215546Sopenharmony_ci * validate_intrastage_interface_blocks() from getting confused and 8717bf215546Sopenharmony_ci * thinking there are conflicting definitions of gl_PerVertex in the 8718bf215546Sopenharmony_ci * shader. 8719bf215546Sopenharmony_ci */ 8720bf215546Sopenharmony_ci foreach_in_list_safe(ir_instruction, node, instructions) { 8721bf215546Sopenharmony_ci ir_variable *const var = node->as_variable(); 8722bf215546Sopenharmony_ci if (var != NULL && 8723bf215546Sopenharmony_ci var->get_interface_type() == earlier_per_vertex && 8724bf215546Sopenharmony_ci var->data.mode == var_mode) { 8725bf215546Sopenharmony_ci if (var->data.how_declared == ir_var_declared_normally) { 8726bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8727bf215546Sopenharmony_ci "redeclaration of gl_PerVertex cannot " 8728bf215546Sopenharmony_ci "follow a redeclaration of `%s'", 8729bf215546Sopenharmony_ci var->name); 8730bf215546Sopenharmony_ci } 8731bf215546Sopenharmony_ci state->symbols->disable_variable(var->name); 8732bf215546Sopenharmony_ci var->remove(); 8733bf215546Sopenharmony_ci } 8734bf215546Sopenharmony_ci } 8735bf215546Sopenharmony_ci } 8736bf215546Sopenharmony_ci } 8737bf215546Sopenharmony_ci 8738bf215546Sopenharmony_ci return NULL; 8739bf215546Sopenharmony_ci} 8740bf215546Sopenharmony_ci 8741bf215546Sopenharmony_ci 8742bf215546Sopenharmony_ciir_rvalue * 8743bf215546Sopenharmony_ciast_tcs_output_layout::hir(exec_list *instructions, 8744bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 8745bf215546Sopenharmony_ci{ 8746bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 8747bf215546Sopenharmony_ci 8748bf215546Sopenharmony_ci unsigned num_vertices; 8749bf215546Sopenharmony_ci if (!state->out_qualifier->vertices-> 8750bf215546Sopenharmony_ci process_qualifier_constant(state, "vertices", &num_vertices, 8751bf215546Sopenharmony_ci false)) { 8752bf215546Sopenharmony_ci /* return here to stop cascading incorrect error messages */ 8753bf215546Sopenharmony_ci return NULL; 8754bf215546Sopenharmony_ci } 8755bf215546Sopenharmony_ci 8756bf215546Sopenharmony_ci /* If any shader outputs occurred before this declaration and specified an 8757bf215546Sopenharmony_ci * array size, make sure the size they specified is consistent with the 8758bf215546Sopenharmony_ci * primitive type. 8759bf215546Sopenharmony_ci */ 8760bf215546Sopenharmony_ci if (state->tcs_output_size != 0 && state->tcs_output_size != num_vertices) { 8761bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8762bf215546Sopenharmony_ci "this tessellation control shader output layout " 8763bf215546Sopenharmony_ci "specifies %u vertices, but a previous output " 8764bf215546Sopenharmony_ci "is declared with size %u", 8765bf215546Sopenharmony_ci num_vertices, state->tcs_output_size); 8766bf215546Sopenharmony_ci return NULL; 8767bf215546Sopenharmony_ci } 8768bf215546Sopenharmony_ci 8769bf215546Sopenharmony_ci state->tcs_output_vertices_specified = true; 8770bf215546Sopenharmony_ci 8771bf215546Sopenharmony_ci /* If any shader outputs occurred before this declaration and did not 8772bf215546Sopenharmony_ci * specify an array size, their size is determined now. 8773bf215546Sopenharmony_ci */ 8774bf215546Sopenharmony_ci foreach_in_list (ir_instruction, node, instructions) { 8775bf215546Sopenharmony_ci ir_variable *var = node->as_variable(); 8776bf215546Sopenharmony_ci if (var == NULL || var->data.mode != ir_var_shader_out) 8777bf215546Sopenharmony_ci continue; 8778bf215546Sopenharmony_ci 8779bf215546Sopenharmony_ci /* Note: Not all tessellation control shader output are arrays. */ 8780bf215546Sopenharmony_ci if (!var->type->is_unsized_array() || var->data.patch) 8781bf215546Sopenharmony_ci continue; 8782bf215546Sopenharmony_ci 8783bf215546Sopenharmony_ci if (var->data.max_array_access >= (int)num_vertices) { 8784bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8785bf215546Sopenharmony_ci "this tessellation control shader output layout " 8786bf215546Sopenharmony_ci "specifies %u vertices, but an access to element " 8787bf215546Sopenharmony_ci "%u of output `%s' already exists", num_vertices, 8788bf215546Sopenharmony_ci var->data.max_array_access, var->name); 8789bf215546Sopenharmony_ci } else { 8790bf215546Sopenharmony_ci var->type = glsl_type::get_array_instance(var->type->fields.array, 8791bf215546Sopenharmony_ci num_vertices); 8792bf215546Sopenharmony_ci } 8793bf215546Sopenharmony_ci } 8794bf215546Sopenharmony_ci 8795bf215546Sopenharmony_ci return NULL; 8796bf215546Sopenharmony_ci} 8797bf215546Sopenharmony_ci 8798bf215546Sopenharmony_ci 8799bf215546Sopenharmony_ciir_rvalue * 8800bf215546Sopenharmony_ciast_gs_input_layout::hir(exec_list *instructions, 8801bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 8802bf215546Sopenharmony_ci{ 8803bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 8804bf215546Sopenharmony_ci 8805bf215546Sopenharmony_ci /* Should have been prevented by the parser. */ 8806bf215546Sopenharmony_ci assert(!state->gs_input_prim_type_specified 8807bf215546Sopenharmony_ci || state->in_qualifier->prim_type == this->prim_type); 8808bf215546Sopenharmony_ci 8809bf215546Sopenharmony_ci /* If any shader inputs occurred before this declaration and specified an 8810bf215546Sopenharmony_ci * array size, make sure the size they specified is consistent with the 8811bf215546Sopenharmony_ci * primitive type. 8812bf215546Sopenharmony_ci */ 8813bf215546Sopenharmony_ci unsigned num_vertices = vertices_per_prim(this->prim_type); 8814bf215546Sopenharmony_ci if (state->gs_input_size != 0 && state->gs_input_size != num_vertices) { 8815bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8816bf215546Sopenharmony_ci "this geometry shader input layout implies %u vertices" 8817bf215546Sopenharmony_ci " per primitive, but a previous input is declared" 8818bf215546Sopenharmony_ci " with size %u", num_vertices, state->gs_input_size); 8819bf215546Sopenharmony_ci return NULL; 8820bf215546Sopenharmony_ci } 8821bf215546Sopenharmony_ci 8822bf215546Sopenharmony_ci state->gs_input_prim_type_specified = true; 8823bf215546Sopenharmony_ci 8824bf215546Sopenharmony_ci /* If any shader inputs occurred before this declaration and did not 8825bf215546Sopenharmony_ci * specify an array size, their size is determined now. 8826bf215546Sopenharmony_ci */ 8827bf215546Sopenharmony_ci foreach_in_list(ir_instruction, node, instructions) { 8828bf215546Sopenharmony_ci ir_variable *var = node->as_variable(); 8829bf215546Sopenharmony_ci if (var == NULL || var->data.mode != ir_var_shader_in) 8830bf215546Sopenharmony_ci continue; 8831bf215546Sopenharmony_ci 8832bf215546Sopenharmony_ci /* Note: gl_PrimitiveIDIn has mode ir_var_shader_in, but it's not an 8833bf215546Sopenharmony_ci * array; skip it. 8834bf215546Sopenharmony_ci */ 8835bf215546Sopenharmony_ci 8836bf215546Sopenharmony_ci if (var->type->is_unsized_array()) { 8837bf215546Sopenharmony_ci if (var->data.max_array_access >= (int)num_vertices) { 8838bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8839bf215546Sopenharmony_ci "this geometry shader input layout implies %u" 8840bf215546Sopenharmony_ci " vertices, but an access to element %u of input" 8841bf215546Sopenharmony_ci " `%s' already exists", num_vertices, 8842bf215546Sopenharmony_ci var->data.max_array_access, var->name); 8843bf215546Sopenharmony_ci } else { 8844bf215546Sopenharmony_ci var->type = glsl_type::get_array_instance(var->type->fields.array, 8845bf215546Sopenharmony_ci num_vertices); 8846bf215546Sopenharmony_ci } 8847bf215546Sopenharmony_ci } 8848bf215546Sopenharmony_ci } 8849bf215546Sopenharmony_ci 8850bf215546Sopenharmony_ci return NULL; 8851bf215546Sopenharmony_ci} 8852bf215546Sopenharmony_ci 8853bf215546Sopenharmony_ci 8854bf215546Sopenharmony_ciir_rvalue * 8855bf215546Sopenharmony_ciast_cs_input_layout::hir(exec_list *instructions, 8856bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 8857bf215546Sopenharmony_ci{ 8858bf215546Sopenharmony_ci YYLTYPE loc = this->get_location(); 8859bf215546Sopenharmony_ci 8860bf215546Sopenharmony_ci /* From the ARB_compute_shader specification: 8861bf215546Sopenharmony_ci * 8862bf215546Sopenharmony_ci * If the local size of the shader in any dimension is greater 8863bf215546Sopenharmony_ci * than the maximum size supported by the implementation for that 8864bf215546Sopenharmony_ci * dimension, a compile-time error results. 8865bf215546Sopenharmony_ci * 8866bf215546Sopenharmony_ci * It is not clear from the spec how the error should be reported if 8867bf215546Sopenharmony_ci * the total size of the work group exceeds 8868bf215546Sopenharmony_ci * MAX_COMPUTE_WORK_GROUP_INVOCATIONS, but it seems reasonable to 8869bf215546Sopenharmony_ci * report it at compile time as well. 8870bf215546Sopenharmony_ci */ 8871bf215546Sopenharmony_ci GLuint64 total_invocations = 1; 8872bf215546Sopenharmony_ci unsigned qual_local_size[3]; 8873bf215546Sopenharmony_ci for (int i = 0; i < 3; i++) { 8874bf215546Sopenharmony_ci 8875bf215546Sopenharmony_ci char *local_size_str = ralloc_asprintf(NULL, "invalid local_size_%c", 8876bf215546Sopenharmony_ci 'x' + i); 8877bf215546Sopenharmony_ci /* Infer a local_size of 1 for unspecified dimensions */ 8878bf215546Sopenharmony_ci if (this->local_size[i] == NULL) { 8879bf215546Sopenharmony_ci qual_local_size[i] = 1; 8880bf215546Sopenharmony_ci } else if (!this->local_size[i]-> 8881bf215546Sopenharmony_ci process_qualifier_constant(state, local_size_str, 8882bf215546Sopenharmony_ci &qual_local_size[i], false)) { 8883bf215546Sopenharmony_ci ralloc_free(local_size_str); 8884bf215546Sopenharmony_ci return NULL; 8885bf215546Sopenharmony_ci } 8886bf215546Sopenharmony_ci ralloc_free(local_size_str); 8887bf215546Sopenharmony_ci 8888bf215546Sopenharmony_ci if (qual_local_size[i] > state->consts->MaxComputeWorkGroupSize[i]) { 8889bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8890bf215546Sopenharmony_ci "local_size_%c exceeds MAX_COMPUTE_WORK_GROUP_SIZE" 8891bf215546Sopenharmony_ci " (%d)", 'x' + i, 8892bf215546Sopenharmony_ci state->consts->MaxComputeWorkGroupSize[i]); 8893bf215546Sopenharmony_ci break; 8894bf215546Sopenharmony_ci } 8895bf215546Sopenharmony_ci total_invocations *= qual_local_size[i]; 8896bf215546Sopenharmony_ci if (total_invocations > 8897bf215546Sopenharmony_ci state->consts->MaxComputeWorkGroupInvocations) { 8898bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8899bf215546Sopenharmony_ci "product of local_sizes exceeds " 8900bf215546Sopenharmony_ci "MAX_COMPUTE_WORK_GROUP_INVOCATIONS (%d)", 8901bf215546Sopenharmony_ci state->consts->MaxComputeWorkGroupInvocations); 8902bf215546Sopenharmony_ci break; 8903bf215546Sopenharmony_ci } 8904bf215546Sopenharmony_ci } 8905bf215546Sopenharmony_ci 8906bf215546Sopenharmony_ci /* If any compute input layout declaration preceded this one, make sure it 8907bf215546Sopenharmony_ci * was consistent with this one. 8908bf215546Sopenharmony_ci */ 8909bf215546Sopenharmony_ci if (state->cs_input_local_size_specified) { 8910bf215546Sopenharmony_ci for (int i = 0; i < 3; i++) { 8911bf215546Sopenharmony_ci if (state->cs_input_local_size[i] != qual_local_size[i]) { 8912bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8913bf215546Sopenharmony_ci "compute shader input layout does not match" 8914bf215546Sopenharmony_ci " previous declaration"); 8915bf215546Sopenharmony_ci return NULL; 8916bf215546Sopenharmony_ci } 8917bf215546Sopenharmony_ci } 8918bf215546Sopenharmony_ci } 8919bf215546Sopenharmony_ci 8920bf215546Sopenharmony_ci /* The ARB_compute_variable_group_size spec says: 8921bf215546Sopenharmony_ci * 8922bf215546Sopenharmony_ci * If a compute shader including a *local_size_variable* qualifier also 8923bf215546Sopenharmony_ci * declares a fixed local group size using the *local_size_x*, 8924bf215546Sopenharmony_ci * *local_size_y*, or *local_size_z* qualifiers, a compile-time error 8925bf215546Sopenharmony_ci * results 8926bf215546Sopenharmony_ci */ 8927bf215546Sopenharmony_ci if (state->cs_input_local_size_variable_specified) { 8928bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 8929bf215546Sopenharmony_ci "compute shader can't include both a variable and a " 8930bf215546Sopenharmony_ci "fixed local group size"); 8931bf215546Sopenharmony_ci return NULL; 8932bf215546Sopenharmony_ci } 8933bf215546Sopenharmony_ci 8934bf215546Sopenharmony_ci state->cs_input_local_size_specified = true; 8935bf215546Sopenharmony_ci for (int i = 0; i < 3; i++) 8936bf215546Sopenharmony_ci state->cs_input_local_size[i] = qual_local_size[i]; 8937bf215546Sopenharmony_ci 8938bf215546Sopenharmony_ci /* We may now declare the built-in constant gl_WorkGroupSize (see 8939bf215546Sopenharmony_ci * builtin_variable_generator::generate_constants() for why we didn't 8940bf215546Sopenharmony_ci * declare it earlier). 8941bf215546Sopenharmony_ci */ 8942bf215546Sopenharmony_ci ir_variable *var = new(state->symbols) 8943bf215546Sopenharmony_ci ir_variable(glsl_type::uvec3_type, "gl_WorkGroupSize", ir_var_auto); 8944bf215546Sopenharmony_ci var->data.how_declared = ir_var_declared_implicitly; 8945bf215546Sopenharmony_ci var->data.read_only = true; 8946bf215546Sopenharmony_ci instructions->push_tail(var); 8947bf215546Sopenharmony_ci state->symbols->add_variable(var); 8948bf215546Sopenharmony_ci ir_constant_data data; 8949bf215546Sopenharmony_ci memset(&data, 0, sizeof(data)); 8950bf215546Sopenharmony_ci for (int i = 0; i < 3; i++) 8951bf215546Sopenharmony_ci data.u[i] = qual_local_size[i]; 8952bf215546Sopenharmony_ci var->constant_value = new(var) ir_constant(glsl_type::uvec3_type, &data); 8953bf215546Sopenharmony_ci var->constant_initializer = 8954bf215546Sopenharmony_ci new(var) ir_constant(glsl_type::uvec3_type, &data); 8955bf215546Sopenharmony_ci var->data.has_initializer = true; 8956bf215546Sopenharmony_ci var->data.is_implicit_initializer = false; 8957bf215546Sopenharmony_ci 8958bf215546Sopenharmony_ci return NULL; 8959bf215546Sopenharmony_ci} 8960bf215546Sopenharmony_ci 8961bf215546Sopenharmony_ci 8962bf215546Sopenharmony_cistatic void 8963bf215546Sopenharmony_cidetect_conflicting_assignments(struct _mesa_glsl_parse_state *state, 8964bf215546Sopenharmony_ci exec_list *instructions) 8965bf215546Sopenharmony_ci{ 8966bf215546Sopenharmony_ci bool gl_FragColor_assigned = false; 8967bf215546Sopenharmony_ci bool gl_FragData_assigned = false; 8968bf215546Sopenharmony_ci bool gl_FragSecondaryColor_assigned = false; 8969bf215546Sopenharmony_ci bool gl_FragSecondaryData_assigned = false; 8970bf215546Sopenharmony_ci bool user_defined_fs_output_assigned = false; 8971bf215546Sopenharmony_ci ir_variable *user_defined_fs_output = NULL; 8972bf215546Sopenharmony_ci 8973bf215546Sopenharmony_ci /* It would be nice to have proper location information. */ 8974bf215546Sopenharmony_ci YYLTYPE loc; 8975bf215546Sopenharmony_ci memset(&loc, 0, sizeof(loc)); 8976bf215546Sopenharmony_ci 8977bf215546Sopenharmony_ci foreach_in_list(ir_instruction, node, instructions) { 8978bf215546Sopenharmony_ci ir_variable *var = node->as_variable(); 8979bf215546Sopenharmony_ci 8980bf215546Sopenharmony_ci if (!var || !var->data.assigned) 8981bf215546Sopenharmony_ci continue; 8982bf215546Sopenharmony_ci 8983bf215546Sopenharmony_ci if (strcmp(var->name, "gl_FragColor") == 0) { 8984bf215546Sopenharmony_ci gl_FragColor_assigned = true; 8985bf215546Sopenharmony_ci if (!var->constant_initializer && state->zero_init) { 8986bf215546Sopenharmony_ci const ir_constant_data data = { { 0 } }; 8987bf215546Sopenharmony_ci var->data.has_initializer = true; 8988bf215546Sopenharmony_ci var->data.is_implicit_initializer = true; 8989bf215546Sopenharmony_ci var->constant_initializer = new(var) ir_constant(var->type, &data); 8990bf215546Sopenharmony_ci } 8991bf215546Sopenharmony_ci } 8992bf215546Sopenharmony_ci else if (strcmp(var->name, "gl_FragData") == 0) 8993bf215546Sopenharmony_ci gl_FragData_assigned = true; 8994bf215546Sopenharmony_ci else if (strcmp(var->name, "gl_SecondaryFragColorEXT") == 0) 8995bf215546Sopenharmony_ci gl_FragSecondaryColor_assigned = true; 8996bf215546Sopenharmony_ci else if (strcmp(var->name, "gl_SecondaryFragDataEXT") == 0) 8997bf215546Sopenharmony_ci gl_FragSecondaryData_assigned = true; 8998bf215546Sopenharmony_ci else if (!is_gl_identifier(var->name)) { 8999bf215546Sopenharmony_ci if (state->stage == MESA_SHADER_FRAGMENT && 9000bf215546Sopenharmony_ci var->data.mode == ir_var_shader_out) { 9001bf215546Sopenharmony_ci user_defined_fs_output_assigned = true; 9002bf215546Sopenharmony_ci user_defined_fs_output = var; 9003bf215546Sopenharmony_ci } 9004bf215546Sopenharmony_ci } 9005bf215546Sopenharmony_ci } 9006bf215546Sopenharmony_ci 9007bf215546Sopenharmony_ci /* From the GLSL 1.30 spec: 9008bf215546Sopenharmony_ci * 9009bf215546Sopenharmony_ci * "If a shader statically assigns a value to gl_FragColor, it 9010bf215546Sopenharmony_ci * may not assign a value to any element of gl_FragData. If a 9011bf215546Sopenharmony_ci * shader statically writes a value to any element of 9012bf215546Sopenharmony_ci * gl_FragData, it may not assign a value to 9013bf215546Sopenharmony_ci * gl_FragColor. That is, a shader may assign values to either 9014bf215546Sopenharmony_ci * gl_FragColor or gl_FragData, but not both. Multiple shaders 9015bf215546Sopenharmony_ci * linked together must also consistently write just one of 9016bf215546Sopenharmony_ci * these variables. Similarly, if user declared output 9017bf215546Sopenharmony_ci * variables are in use (statically assigned to), then the 9018bf215546Sopenharmony_ci * built-in variables gl_FragColor and gl_FragData may not be 9019bf215546Sopenharmony_ci * assigned to. These incorrect usages all generate compile 9020bf215546Sopenharmony_ci * time errors." 9021bf215546Sopenharmony_ci */ 9022bf215546Sopenharmony_ci if (gl_FragColor_assigned && gl_FragData_assigned) { 9023bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "fragment shader writes to both " 9024bf215546Sopenharmony_ci "`gl_FragColor' and `gl_FragData'"); 9025bf215546Sopenharmony_ci } else if (gl_FragColor_assigned && user_defined_fs_output_assigned) { 9026bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "fragment shader writes to both " 9027bf215546Sopenharmony_ci "`gl_FragColor' and `%s'", 9028bf215546Sopenharmony_ci user_defined_fs_output->name); 9029bf215546Sopenharmony_ci } else if (gl_FragSecondaryColor_assigned && gl_FragSecondaryData_assigned) { 9030bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "fragment shader writes to both " 9031bf215546Sopenharmony_ci "`gl_FragSecondaryColorEXT' and" 9032bf215546Sopenharmony_ci " `gl_FragSecondaryDataEXT'"); 9033bf215546Sopenharmony_ci } else if (gl_FragColor_assigned && gl_FragSecondaryData_assigned) { 9034bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "fragment shader writes to both " 9035bf215546Sopenharmony_ci "`gl_FragColor' and" 9036bf215546Sopenharmony_ci " `gl_FragSecondaryDataEXT'"); 9037bf215546Sopenharmony_ci } else if (gl_FragData_assigned && gl_FragSecondaryColor_assigned) { 9038bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "fragment shader writes to both " 9039bf215546Sopenharmony_ci "`gl_FragData' and" 9040bf215546Sopenharmony_ci " `gl_FragSecondaryColorEXT'"); 9041bf215546Sopenharmony_ci } else if (gl_FragData_assigned && user_defined_fs_output_assigned) { 9042bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, "fragment shader writes to both " 9043bf215546Sopenharmony_ci "`gl_FragData' and `%s'", 9044bf215546Sopenharmony_ci user_defined_fs_output->name); 9045bf215546Sopenharmony_ci } 9046bf215546Sopenharmony_ci 9047bf215546Sopenharmony_ci if ((gl_FragSecondaryColor_assigned || gl_FragSecondaryData_assigned) && 9048bf215546Sopenharmony_ci !state->EXT_blend_func_extended_enable) { 9049bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 9050bf215546Sopenharmony_ci "Dual source blending requires EXT_blend_func_extended"); 9051bf215546Sopenharmony_ci } 9052bf215546Sopenharmony_ci} 9053bf215546Sopenharmony_ci 9054bf215546Sopenharmony_cistatic void 9055bf215546Sopenharmony_civerify_subroutine_associated_funcs(struct _mesa_glsl_parse_state *state) 9056bf215546Sopenharmony_ci{ 9057bf215546Sopenharmony_ci YYLTYPE loc; 9058bf215546Sopenharmony_ci memset(&loc, 0, sizeof(loc)); 9059bf215546Sopenharmony_ci 9060bf215546Sopenharmony_ci /* Section 6.1.2 (Subroutines) of the GLSL 4.00 spec says: 9061bf215546Sopenharmony_ci * 9062bf215546Sopenharmony_ci * "A program will fail to compile or link if any shader 9063bf215546Sopenharmony_ci * or stage contains two or more functions with the same 9064bf215546Sopenharmony_ci * name if the name is associated with a subroutine type." 9065bf215546Sopenharmony_ci */ 9066bf215546Sopenharmony_ci 9067bf215546Sopenharmony_ci for (int i = 0; i < state->num_subroutines; i++) { 9068bf215546Sopenharmony_ci unsigned definitions = 0; 9069bf215546Sopenharmony_ci ir_function *fn = state->subroutines[i]; 9070bf215546Sopenharmony_ci /* Calculate number of function definitions with the same name */ 9071bf215546Sopenharmony_ci foreach_in_list(ir_function_signature, sig, &fn->signatures) { 9072bf215546Sopenharmony_ci if (sig->is_defined) { 9073bf215546Sopenharmony_ci if (++definitions > 1) { 9074bf215546Sopenharmony_ci _mesa_glsl_error(&loc, state, 9075bf215546Sopenharmony_ci "%s shader contains two or more function " 9076bf215546Sopenharmony_ci "definitions with name `%s', which is " 9077bf215546Sopenharmony_ci "associated with a subroutine type.\n", 9078bf215546Sopenharmony_ci _mesa_shader_stage_to_string(state->stage), 9079bf215546Sopenharmony_ci fn->name); 9080bf215546Sopenharmony_ci return; 9081bf215546Sopenharmony_ci } 9082bf215546Sopenharmony_ci } 9083bf215546Sopenharmony_ci } 9084bf215546Sopenharmony_ci } 9085bf215546Sopenharmony_ci} 9086bf215546Sopenharmony_ci 9087bf215546Sopenharmony_cistatic void 9088bf215546Sopenharmony_ciremove_per_vertex_blocks(exec_list *instructions, 9089bf215546Sopenharmony_ci _mesa_glsl_parse_state *state, ir_variable_mode mode) 9090bf215546Sopenharmony_ci{ 9091bf215546Sopenharmony_ci /* Find the gl_PerVertex interface block of the appropriate (in/out) mode, 9092bf215546Sopenharmony_ci * if it exists in this shader type. 9093bf215546Sopenharmony_ci */ 9094bf215546Sopenharmony_ci const glsl_type *per_vertex = NULL; 9095bf215546Sopenharmony_ci switch (mode) { 9096bf215546Sopenharmony_ci case ir_var_shader_in: 9097bf215546Sopenharmony_ci if (ir_variable *gl_in = state->symbols->get_variable("gl_in")) 9098bf215546Sopenharmony_ci per_vertex = gl_in->get_interface_type(); 9099bf215546Sopenharmony_ci break; 9100bf215546Sopenharmony_ci case ir_var_shader_out: 9101bf215546Sopenharmony_ci if (ir_variable *gl_Position = 9102bf215546Sopenharmony_ci state->symbols->get_variable("gl_Position")) { 9103bf215546Sopenharmony_ci per_vertex = gl_Position->get_interface_type(); 9104bf215546Sopenharmony_ci } 9105bf215546Sopenharmony_ci break; 9106bf215546Sopenharmony_ci default: 9107bf215546Sopenharmony_ci assert(!"Unexpected mode"); 9108bf215546Sopenharmony_ci break; 9109bf215546Sopenharmony_ci } 9110bf215546Sopenharmony_ci 9111bf215546Sopenharmony_ci /* If we didn't find a built-in gl_PerVertex interface block, then we don't 9112bf215546Sopenharmony_ci * need to do anything. 9113bf215546Sopenharmony_ci */ 9114bf215546Sopenharmony_ci if (per_vertex == NULL) 9115bf215546Sopenharmony_ci return; 9116bf215546Sopenharmony_ci 9117bf215546Sopenharmony_ci /* If the interface block is used by the shader, then we don't need to do 9118bf215546Sopenharmony_ci * anything. 9119bf215546Sopenharmony_ci */ 9120bf215546Sopenharmony_ci interface_block_usage_visitor v(mode, per_vertex); 9121bf215546Sopenharmony_ci v.run(instructions); 9122bf215546Sopenharmony_ci if (v.usage_found()) 9123bf215546Sopenharmony_ci return; 9124bf215546Sopenharmony_ci 9125bf215546Sopenharmony_ci /* Remove any ir_variable declarations that refer to the interface block 9126bf215546Sopenharmony_ci * we're removing. 9127bf215546Sopenharmony_ci */ 9128bf215546Sopenharmony_ci foreach_in_list_safe(ir_instruction, node, instructions) { 9129bf215546Sopenharmony_ci ir_variable *const var = node->as_variable(); 9130bf215546Sopenharmony_ci if (var != NULL && var->get_interface_type() == per_vertex && 9131bf215546Sopenharmony_ci var->data.mode == mode) { 9132bf215546Sopenharmony_ci state->symbols->disable_variable(var->name); 9133bf215546Sopenharmony_ci var->remove(); 9134bf215546Sopenharmony_ci } 9135bf215546Sopenharmony_ci } 9136bf215546Sopenharmony_ci} 9137bf215546Sopenharmony_ci 9138bf215546Sopenharmony_ciir_rvalue * 9139bf215546Sopenharmony_ciast_warnings_toggle::hir(exec_list *, 9140bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state) 9141bf215546Sopenharmony_ci{ 9142bf215546Sopenharmony_ci state->warnings_enabled = enable; 9143bf215546Sopenharmony_ci return NULL; 9144bf215546Sopenharmony_ci} 9145