1bf215546Sopenharmony_ci/* -*- c++ -*- */ 2bf215546Sopenharmony_ci/* 3bf215546Sopenharmony_ci * Copyright © 2010 Intel Corporation 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci * Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci#ifndef IR_H 26bf215546Sopenharmony_ci#define IR_H 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include <stdio.h> 29bf215546Sopenharmony_ci#include <stdlib.h> 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "util/ralloc.h" 32bf215546Sopenharmony_ci#include "util/format/u_format.h" 33bf215546Sopenharmony_ci#include "util/half_float.h" 34bf215546Sopenharmony_ci#include "compiler/glsl_types.h" 35bf215546Sopenharmony_ci#include "list.h" 36bf215546Sopenharmony_ci#include "ir_visitor.h" 37bf215546Sopenharmony_ci#include "ir_hierarchical_visitor.h" 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci#ifdef __cplusplus 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci/** 42bf215546Sopenharmony_ci * \defgroup IR Intermediate representation nodes 43bf215546Sopenharmony_ci * 44bf215546Sopenharmony_ci * @{ 45bf215546Sopenharmony_ci */ 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci/** 48bf215546Sopenharmony_ci * Class tags 49bf215546Sopenharmony_ci * 50bf215546Sopenharmony_ci * Each concrete class derived from \c ir_instruction has a value in this 51bf215546Sopenharmony_ci * enumerant. The value for the type is stored in \c ir_instruction::ir_type 52bf215546Sopenharmony_ci * by the constructor. While using type tags is not very C++, it is extremely 53bf215546Sopenharmony_ci * convenient. For example, during debugging you can simply inspect 54bf215546Sopenharmony_ci * \c ir_instruction::ir_type to find out the actual type of the object. 55bf215546Sopenharmony_ci * 56bf215546Sopenharmony_ci * In addition, it is possible to use a switch-statement based on \c 57bf215546Sopenharmony_ci * \c ir_instruction::ir_type to select different behavior for different object 58bf215546Sopenharmony_ci * types. For functions that have only slight differences for several object 59bf215546Sopenharmony_ci * types, this allows writing very straightforward, readable code. 60bf215546Sopenharmony_ci */ 61bf215546Sopenharmony_cienum ir_node_type { 62bf215546Sopenharmony_ci ir_type_dereference_array, 63bf215546Sopenharmony_ci ir_type_dereference_record, 64bf215546Sopenharmony_ci ir_type_dereference_variable, 65bf215546Sopenharmony_ci ir_type_constant, 66bf215546Sopenharmony_ci ir_type_expression, 67bf215546Sopenharmony_ci ir_type_swizzle, 68bf215546Sopenharmony_ci ir_type_texture, 69bf215546Sopenharmony_ci ir_type_variable, 70bf215546Sopenharmony_ci ir_type_assignment, 71bf215546Sopenharmony_ci ir_type_call, 72bf215546Sopenharmony_ci ir_type_function, 73bf215546Sopenharmony_ci ir_type_function_signature, 74bf215546Sopenharmony_ci ir_type_if, 75bf215546Sopenharmony_ci ir_type_loop, 76bf215546Sopenharmony_ci ir_type_loop_jump, 77bf215546Sopenharmony_ci ir_type_return, 78bf215546Sopenharmony_ci ir_type_discard, 79bf215546Sopenharmony_ci ir_type_demote, 80bf215546Sopenharmony_ci ir_type_emit_vertex, 81bf215546Sopenharmony_ci ir_type_end_primitive, 82bf215546Sopenharmony_ci ir_type_barrier, 83bf215546Sopenharmony_ci ir_type_max, /**< maximum ir_type enum number, for validation */ 84bf215546Sopenharmony_ci ir_type_unset = ir_type_max 85bf215546Sopenharmony_ci}; 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci/** 89bf215546Sopenharmony_ci * Base class of all IR instructions 90bf215546Sopenharmony_ci */ 91bf215546Sopenharmony_ciclass ir_instruction : public exec_node { 92bf215546Sopenharmony_cipublic: 93bf215546Sopenharmony_ci enum ir_node_type ir_type; 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci /** 96bf215546Sopenharmony_ci * GCC 4.7+ and clang warn when deleting an ir_instruction unless 97bf215546Sopenharmony_ci * there's a virtual destructor present. Because we almost 98bf215546Sopenharmony_ci * universally use ralloc for our memory management of 99bf215546Sopenharmony_ci * ir_instructions, the destructor doesn't need to do any work. 100bf215546Sopenharmony_ci */ 101bf215546Sopenharmony_ci virtual ~ir_instruction() 102bf215546Sopenharmony_ci { 103bf215546Sopenharmony_ci } 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci /** ir_print_visitor helper for debugging. */ 106bf215546Sopenharmony_ci void print(void) const; 107bf215546Sopenharmony_ci void fprint(FILE *f) const; 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci virtual void accept(ir_visitor *) = 0; 110bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *) = 0; 111bf215546Sopenharmony_ci virtual ir_instruction *clone(void *mem_ctx, 112bf215546Sopenharmony_ci struct hash_table *ht) const = 0; 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci bool is_rvalue() const 115bf215546Sopenharmony_ci { 116bf215546Sopenharmony_ci return ir_type == ir_type_dereference_array || 117bf215546Sopenharmony_ci ir_type == ir_type_dereference_record || 118bf215546Sopenharmony_ci ir_type == ir_type_dereference_variable || 119bf215546Sopenharmony_ci ir_type == ir_type_constant || 120bf215546Sopenharmony_ci ir_type == ir_type_expression || 121bf215546Sopenharmony_ci ir_type == ir_type_swizzle || 122bf215546Sopenharmony_ci ir_type == ir_type_texture; 123bf215546Sopenharmony_ci } 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci bool is_dereference() const 126bf215546Sopenharmony_ci { 127bf215546Sopenharmony_ci return ir_type == ir_type_dereference_array || 128bf215546Sopenharmony_ci ir_type == ir_type_dereference_record || 129bf215546Sopenharmony_ci ir_type == ir_type_dereference_variable; 130bf215546Sopenharmony_ci } 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci bool is_jump() const 133bf215546Sopenharmony_ci { 134bf215546Sopenharmony_ci return ir_type == ir_type_loop_jump || 135bf215546Sopenharmony_ci ir_type == ir_type_return || 136bf215546Sopenharmony_ci ir_type == ir_type_discard; 137bf215546Sopenharmony_ci } 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci /** 140bf215546Sopenharmony_ci * \name IR instruction downcast functions 141bf215546Sopenharmony_ci * 142bf215546Sopenharmony_ci * These functions either cast the object to a derived class or return 143bf215546Sopenharmony_ci * \c NULL if the object's type does not match the specified derived class. 144bf215546Sopenharmony_ci * Additional downcast functions will be added as needed. 145bf215546Sopenharmony_ci */ 146bf215546Sopenharmony_ci /*@{*/ 147bf215546Sopenharmony_ci #define AS_BASE(TYPE) \ 148bf215546Sopenharmony_ci class ir_##TYPE *as_##TYPE() \ 149bf215546Sopenharmony_ci { \ 150bf215546Sopenharmony_ci return is_##TYPE() ? (ir_##TYPE *) this : NULL; \ 151bf215546Sopenharmony_ci } \ 152bf215546Sopenharmony_ci const class ir_##TYPE *as_##TYPE() const \ 153bf215546Sopenharmony_ci { \ 154bf215546Sopenharmony_ci return is_##TYPE() ? (ir_##TYPE *) this : NULL; \ 155bf215546Sopenharmony_ci } 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci AS_BASE(rvalue) 158bf215546Sopenharmony_ci AS_BASE(dereference) 159bf215546Sopenharmony_ci AS_BASE(jump) 160bf215546Sopenharmony_ci #undef AS_BASE 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci #define AS_CHILD(TYPE) \ 163bf215546Sopenharmony_ci class ir_##TYPE * as_##TYPE() \ 164bf215546Sopenharmony_ci { \ 165bf215546Sopenharmony_ci return ir_type == ir_type_##TYPE ? (ir_##TYPE *) this : NULL; \ 166bf215546Sopenharmony_ci } \ 167bf215546Sopenharmony_ci const class ir_##TYPE * as_##TYPE() const \ 168bf215546Sopenharmony_ci { \ 169bf215546Sopenharmony_ci return ir_type == ir_type_##TYPE ? (const ir_##TYPE *) this : NULL; \ 170bf215546Sopenharmony_ci } 171bf215546Sopenharmony_ci AS_CHILD(variable) 172bf215546Sopenharmony_ci AS_CHILD(function) 173bf215546Sopenharmony_ci AS_CHILD(dereference_array) 174bf215546Sopenharmony_ci AS_CHILD(dereference_variable) 175bf215546Sopenharmony_ci AS_CHILD(dereference_record) 176bf215546Sopenharmony_ci AS_CHILD(expression) 177bf215546Sopenharmony_ci AS_CHILD(loop) 178bf215546Sopenharmony_ci AS_CHILD(assignment) 179bf215546Sopenharmony_ci AS_CHILD(call) 180bf215546Sopenharmony_ci AS_CHILD(return) 181bf215546Sopenharmony_ci AS_CHILD(if) 182bf215546Sopenharmony_ci AS_CHILD(swizzle) 183bf215546Sopenharmony_ci AS_CHILD(texture) 184bf215546Sopenharmony_ci AS_CHILD(constant) 185bf215546Sopenharmony_ci AS_CHILD(discard) 186bf215546Sopenharmony_ci #undef AS_CHILD 187bf215546Sopenharmony_ci /*@}*/ 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci /** 190bf215546Sopenharmony_ci * IR equality method: Return true if the referenced instruction would 191bf215546Sopenharmony_ci * return the same value as this one. 192bf215546Sopenharmony_ci * 193bf215546Sopenharmony_ci * This intended to be used for CSE and algebraic optimizations, on rvalues 194bf215546Sopenharmony_ci * in particular. No support for other instruction types (assignments, 195bf215546Sopenharmony_ci * jumps, calls, etc.) is planned. 196bf215546Sopenharmony_ci */ 197bf215546Sopenharmony_ci virtual bool equals(const ir_instruction *ir, 198bf215546Sopenharmony_ci enum ir_node_type ignore = ir_type_unset) const; 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ciprotected: 201bf215546Sopenharmony_ci ir_instruction(enum ir_node_type t) 202bf215546Sopenharmony_ci : ir_type(t) 203bf215546Sopenharmony_ci { 204bf215546Sopenharmony_ci } 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ciprivate: 207bf215546Sopenharmony_ci ir_instruction() 208bf215546Sopenharmony_ci { 209bf215546Sopenharmony_ci assert(!"Should not get here."); 210bf215546Sopenharmony_ci } 211bf215546Sopenharmony_ci}; 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci/** 215bf215546Sopenharmony_ci * The base class for all "values"/expression trees. 216bf215546Sopenharmony_ci */ 217bf215546Sopenharmony_ciclass ir_rvalue : public ir_instruction { 218bf215546Sopenharmony_cipublic: 219bf215546Sopenharmony_ci const struct glsl_type *type; 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci virtual ir_rvalue *clone(void *mem_ctx, struct hash_table *) const; 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 224bf215546Sopenharmony_ci { 225bf215546Sopenharmony_ci v->visit(this); 226bf215546Sopenharmony_ci } 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci virtual ir_constant *constant_expression_value(void *mem_ctx, 231bf215546Sopenharmony_ci struct hash_table *variable_context = NULL); 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci ir_rvalue *as_rvalue_to_saturate(); 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci virtual bool is_lvalue(const struct _mesa_glsl_parse_state * = NULL) const 236bf215546Sopenharmony_ci { 237bf215546Sopenharmony_ci return false; 238bf215546Sopenharmony_ci } 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_ci /** 241bf215546Sopenharmony_ci * Get the variable that is ultimately referenced by an r-value 242bf215546Sopenharmony_ci */ 243bf215546Sopenharmony_ci virtual ir_variable *variable_referenced() const 244bf215546Sopenharmony_ci { 245bf215546Sopenharmony_ci return NULL; 246bf215546Sopenharmony_ci } 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci /** 250bf215546Sopenharmony_ci * If an r-value is a reference to a whole variable, get that variable 251bf215546Sopenharmony_ci * 252bf215546Sopenharmony_ci * \return 253bf215546Sopenharmony_ci * Pointer to a variable that is completely dereferenced by the r-value. If 254bf215546Sopenharmony_ci * the r-value is not a dereference or the dereference does not access the 255bf215546Sopenharmony_ci * entire variable (i.e., it's just one array element, struct field), \c NULL 256bf215546Sopenharmony_ci * is returned. 257bf215546Sopenharmony_ci */ 258bf215546Sopenharmony_ci virtual ir_variable *whole_variable_referenced() 259bf215546Sopenharmony_ci { 260bf215546Sopenharmony_ci return NULL; 261bf215546Sopenharmony_ci } 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci /** 264bf215546Sopenharmony_ci * Determine if an r-value has the value zero 265bf215546Sopenharmony_ci * 266bf215546Sopenharmony_ci * The base implementation of this function always returns \c false. The 267bf215546Sopenharmony_ci * \c ir_constant class over-rides this function to return \c true \b only 268bf215546Sopenharmony_ci * for vector and scalar types that have all elements set to the value 269bf215546Sopenharmony_ci * zero (or \c false for booleans). 270bf215546Sopenharmony_ci * 271bf215546Sopenharmony_ci * \sa ir_constant::has_value, ir_rvalue::is_one, ir_rvalue::is_negative_one 272bf215546Sopenharmony_ci */ 273bf215546Sopenharmony_ci virtual bool is_zero() const; 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ci /** 276bf215546Sopenharmony_ci * Determine if an r-value has the value one 277bf215546Sopenharmony_ci * 278bf215546Sopenharmony_ci * The base implementation of this function always returns \c false. The 279bf215546Sopenharmony_ci * \c ir_constant class over-rides this function to return \c true \b only 280bf215546Sopenharmony_ci * for vector and scalar types that have all elements set to the value 281bf215546Sopenharmony_ci * one (or \c true for booleans). 282bf215546Sopenharmony_ci * 283bf215546Sopenharmony_ci * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_negative_one 284bf215546Sopenharmony_ci */ 285bf215546Sopenharmony_ci virtual bool is_one() const; 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci /** 288bf215546Sopenharmony_ci * Determine if an r-value has the value negative one 289bf215546Sopenharmony_ci * 290bf215546Sopenharmony_ci * The base implementation of this function always returns \c false. The 291bf215546Sopenharmony_ci * \c ir_constant class over-rides this function to return \c true \b only 292bf215546Sopenharmony_ci * for vector and scalar types that have all elements set to the value 293bf215546Sopenharmony_ci * negative one. For boolean types, the result is always \c false. 294bf215546Sopenharmony_ci * 295bf215546Sopenharmony_ci * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_one 296bf215546Sopenharmony_ci */ 297bf215546Sopenharmony_ci virtual bool is_negative_one() const; 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci /** 300bf215546Sopenharmony_ci * Determine if an r-value is an unsigned integer constant which can be 301bf215546Sopenharmony_ci * stored in 16 bits. 302bf215546Sopenharmony_ci * 303bf215546Sopenharmony_ci * \sa ir_constant::is_uint16_constant. 304bf215546Sopenharmony_ci */ 305bf215546Sopenharmony_ci virtual bool is_uint16_constant() const { return false; } 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ci /** 308bf215546Sopenharmony_ci * Return a generic value of error_type. 309bf215546Sopenharmony_ci * 310bf215546Sopenharmony_ci * Allocation will be performed with 'mem_ctx' as ralloc owner. 311bf215546Sopenharmony_ci */ 312bf215546Sopenharmony_ci static ir_rvalue *error_value(void *mem_ctx); 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_ciprotected: 315bf215546Sopenharmony_ci ir_rvalue(enum ir_node_type t); 316bf215546Sopenharmony_ci}; 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci/** 320bf215546Sopenharmony_ci * Variable storage classes 321bf215546Sopenharmony_ci */ 322bf215546Sopenharmony_cienum ir_variable_mode { 323bf215546Sopenharmony_ci ir_var_auto = 0, /**< Function local variables and globals. */ 324bf215546Sopenharmony_ci ir_var_uniform, /**< Variable declared as a uniform. */ 325bf215546Sopenharmony_ci ir_var_shader_storage, /**< Variable declared as an ssbo. */ 326bf215546Sopenharmony_ci ir_var_shader_shared, /**< Variable declared as shared. */ 327bf215546Sopenharmony_ci ir_var_shader_in, 328bf215546Sopenharmony_ci ir_var_shader_out, 329bf215546Sopenharmony_ci ir_var_function_in, 330bf215546Sopenharmony_ci ir_var_function_out, 331bf215546Sopenharmony_ci ir_var_function_inout, 332bf215546Sopenharmony_ci ir_var_const_in, /**< "in" param that must be a constant expression */ 333bf215546Sopenharmony_ci ir_var_system_value, /**< Ex: front-face, instance-id, etc. */ 334bf215546Sopenharmony_ci ir_var_temporary, /**< Temporary variable generated during compilation. */ 335bf215546Sopenharmony_ci ir_var_mode_count /**< Number of variable modes */ 336bf215546Sopenharmony_ci}; 337bf215546Sopenharmony_ci 338bf215546Sopenharmony_ci/** 339bf215546Sopenharmony_ci * Enum keeping track of how a variable was declared. For error checking of 340bf215546Sopenharmony_ci * the gl_PerVertex redeclaration rules. 341bf215546Sopenharmony_ci */ 342bf215546Sopenharmony_cienum ir_var_declaration_type { 343bf215546Sopenharmony_ci /** 344bf215546Sopenharmony_ci * Normal declaration (for most variables, this means an explicit 345bf215546Sopenharmony_ci * declaration. Exception: temporaries are always implicitly declared, but 346bf215546Sopenharmony_ci * they still use ir_var_declared_normally). 347bf215546Sopenharmony_ci * 348bf215546Sopenharmony_ci * Note: an ir_variable that represents a named interface block uses 349bf215546Sopenharmony_ci * ir_var_declared_normally. 350bf215546Sopenharmony_ci */ 351bf215546Sopenharmony_ci ir_var_declared_normally = 0, 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci /** 354bf215546Sopenharmony_ci * Variable was explicitly declared (or re-declared) in an unnamed 355bf215546Sopenharmony_ci * interface block. 356bf215546Sopenharmony_ci */ 357bf215546Sopenharmony_ci ir_var_declared_in_block, 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci /** 360bf215546Sopenharmony_ci * Variable is an implicitly declared built-in that has not been explicitly 361bf215546Sopenharmony_ci * re-declared by the shader. 362bf215546Sopenharmony_ci */ 363bf215546Sopenharmony_ci ir_var_declared_implicitly, 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci /** 366bf215546Sopenharmony_ci * Variable is implicitly generated by the compiler and should not be 367bf215546Sopenharmony_ci * visible via the API. 368bf215546Sopenharmony_ci */ 369bf215546Sopenharmony_ci ir_var_hidden, 370bf215546Sopenharmony_ci}; 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ci/** 373bf215546Sopenharmony_ci * \brief Layout qualifiers for gl_FragDepth. 374bf215546Sopenharmony_ci * 375bf215546Sopenharmony_ci * The AMD/ARB_conservative_depth extensions allow gl_FragDepth to be redeclared 376bf215546Sopenharmony_ci * with a layout qualifier. 377bf215546Sopenharmony_ci */ 378bf215546Sopenharmony_cienum ir_depth_layout { 379bf215546Sopenharmony_ci ir_depth_layout_none, /**< No depth layout is specified. */ 380bf215546Sopenharmony_ci ir_depth_layout_any, 381bf215546Sopenharmony_ci ir_depth_layout_greater, 382bf215546Sopenharmony_ci ir_depth_layout_less, 383bf215546Sopenharmony_ci ir_depth_layout_unchanged 384bf215546Sopenharmony_ci}; 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci/** 387bf215546Sopenharmony_ci * \brief Convert depth layout qualifier to string. 388bf215546Sopenharmony_ci */ 389bf215546Sopenharmony_ciconst char* 390bf215546Sopenharmony_cidepth_layout_string(ir_depth_layout layout); 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci/** 393bf215546Sopenharmony_ci * Description of built-in state associated with a uniform 394bf215546Sopenharmony_ci * 395bf215546Sopenharmony_ci * \sa ir_variable::state_slots 396bf215546Sopenharmony_ci */ 397bf215546Sopenharmony_cistruct ir_state_slot { 398bf215546Sopenharmony_ci gl_state_index16 tokens[STATE_LENGTH]; 399bf215546Sopenharmony_ci int swizzle; 400bf215546Sopenharmony_ci}; 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci 403bf215546Sopenharmony_ci/** 404bf215546Sopenharmony_ci * Get the string value for an interpolation qualifier 405bf215546Sopenharmony_ci * 406bf215546Sopenharmony_ci * \return The string that would be used in a shader to specify \c 407bf215546Sopenharmony_ci * mode will be returned. 408bf215546Sopenharmony_ci * 409bf215546Sopenharmony_ci * This function is used to generate error messages of the form "shader 410bf215546Sopenharmony_ci * uses %s interpolation qualifier", so in the case where there is no 411bf215546Sopenharmony_ci * interpolation qualifier, it returns "no". 412bf215546Sopenharmony_ci * 413bf215546Sopenharmony_ci * This function should only be used on a shader input or output variable. 414bf215546Sopenharmony_ci */ 415bf215546Sopenharmony_ciconst char *interpolation_string(unsigned interpolation); 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ciclass ir_variable : public ir_instruction { 419bf215546Sopenharmony_cipublic: 420bf215546Sopenharmony_ci ir_variable(const struct glsl_type *, const char *, ir_variable_mode); 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ci virtual ir_variable *clone(void *mem_ctx, struct hash_table *ht) const; 423bf215546Sopenharmony_ci 424bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 425bf215546Sopenharmony_ci { 426bf215546Sopenharmony_ci v->visit(this); 427bf215546Sopenharmony_ci } 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 430bf215546Sopenharmony_ci 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_ci /** 433bf215546Sopenharmony_ci * Determine whether or not a variable is part of a uniform or 434bf215546Sopenharmony_ci * shader storage block. 435bf215546Sopenharmony_ci */ 436bf215546Sopenharmony_ci inline bool is_in_buffer_block() const 437bf215546Sopenharmony_ci { 438bf215546Sopenharmony_ci return (this->data.mode == ir_var_uniform || 439bf215546Sopenharmony_ci this->data.mode == ir_var_shader_storage) && 440bf215546Sopenharmony_ci this->interface_type != NULL; 441bf215546Sopenharmony_ci } 442bf215546Sopenharmony_ci 443bf215546Sopenharmony_ci /** 444bf215546Sopenharmony_ci * Determine whether or not a variable is part of a shader storage block. 445bf215546Sopenharmony_ci */ 446bf215546Sopenharmony_ci inline bool is_in_shader_storage_block() const 447bf215546Sopenharmony_ci { 448bf215546Sopenharmony_ci return this->data.mode == ir_var_shader_storage && 449bf215546Sopenharmony_ci this->interface_type != NULL; 450bf215546Sopenharmony_ci } 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci /** 453bf215546Sopenharmony_ci * Determine whether or not a variable is the declaration of an interface 454bf215546Sopenharmony_ci * block 455bf215546Sopenharmony_ci * 456bf215546Sopenharmony_ci * For the first declaration below, there will be an \c ir_variable named 457bf215546Sopenharmony_ci * "instance" whose type and whose instance_type will be the same 458bf215546Sopenharmony_ci * \c glsl_type. For the second declaration, there will be an \c ir_variable 459bf215546Sopenharmony_ci * named "f" whose type is float and whose instance_type is B2. 460bf215546Sopenharmony_ci * 461bf215546Sopenharmony_ci * "instance" is an interface instance variable, but "f" is not. 462bf215546Sopenharmony_ci * 463bf215546Sopenharmony_ci * uniform B1 { 464bf215546Sopenharmony_ci * float f; 465bf215546Sopenharmony_ci * } instance; 466bf215546Sopenharmony_ci * 467bf215546Sopenharmony_ci * uniform B2 { 468bf215546Sopenharmony_ci * float f; 469bf215546Sopenharmony_ci * }; 470bf215546Sopenharmony_ci */ 471bf215546Sopenharmony_ci inline bool is_interface_instance() const 472bf215546Sopenharmony_ci { 473bf215546Sopenharmony_ci return this->type->without_array() == this->interface_type; 474bf215546Sopenharmony_ci } 475bf215546Sopenharmony_ci 476bf215546Sopenharmony_ci /** 477bf215546Sopenharmony_ci * Return whether this variable contains a bindless sampler/image. 478bf215546Sopenharmony_ci */ 479bf215546Sopenharmony_ci inline bool contains_bindless() const 480bf215546Sopenharmony_ci { 481bf215546Sopenharmony_ci if (!this->type->contains_sampler() && !this->type->contains_image()) 482bf215546Sopenharmony_ci return false; 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_ci return this->data.bindless || this->data.mode != ir_var_uniform; 485bf215546Sopenharmony_ci } 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_ci /** 488bf215546Sopenharmony_ci * Set this->interface_type on a newly created variable. 489bf215546Sopenharmony_ci */ 490bf215546Sopenharmony_ci void init_interface_type(const struct glsl_type *type) 491bf215546Sopenharmony_ci { 492bf215546Sopenharmony_ci assert(this->interface_type == NULL); 493bf215546Sopenharmony_ci this->interface_type = type; 494bf215546Sopenharmony_ci if (this->is_interface_instance()) { 495bf215546Sopenharmony_ci this->u.max_ifc_array_access = 496bf215546Sopenharmony_ci ralloc_array(this, int, type->length); 497bf215546Sopenharmony_ci for (unsigned i = 0; i < type->length; i++) { 498bf215546Sopenharmony_ci this->u.max_ifc_array_access[i] = -1; 499bf215546Sopenharmony_ci } 500bf215546Sopenharmony_ci } 501bf215546Sopenharmony_ci } 502bf215546Sopenharmony_ci 503bf215546Sopenharmony_ci /** 504bf215546Sopenharmony_ci * Change this->interface_type on a variable that previously had a 505bf215546Sopenharmony_ci * different, but compatible, interface_type. This is used during linking 506bf215546Sopenharmony_ci * to set the size of arrays in interface blocks. 507bf215546Sopenharmony_ci */ 508bf215546Sopenharmony_ci void change_interface_type(const struct glsl_type *type) 509bf215546Sopenharmony_ci { 510bf215546Sopenharmony_ci if (this->u.max_ifc_array_access != NULL) { 511bf215546Sopenharmony_ci /* max_ifc_array_access has already been allocated, so make sure the 512bf215546Sopenharmony_ci * new interface has the same number of fields as the old one. 513bf215546Sopenharmony_ci */ 514bf215546Sopenharmony_ci assert(this->interface_type->length == type->length); 515bf215546Sopenharmony_ci } 516bf215546Sopenharmony_ci this->interface_type = type; 517bf215546Sopenharmony_ci } 518bf215546Sopenharmony_ci 519bf215546Sopenharmony_ci /** 520bf215546Sopenharmony_ci * Change this->interface_type on a variable that previously had a 521bf215546Sopenharmony_ci * different, and incompatible, interface_type. This is used during 522bf215546Sopenharmony_ci * compilation to handle redeclaration of the built-in gl_PerVertex 523bf215546Sopenharmony_ci * interface block. 524bf215546Sopenharmony_ci */ 525bf215546Sopenharmony_ci void reinit_interface_type(const struct glsl_type *type) 526bf215546Sopenharmony_ci { 527bf215546Sopenharmony_ci if (this->u.max_ifc_array_access != NULL) { 528bf215546Sopenharmony_ci#ifndef NDEBUG 529bf215546Sopenharmony_ci /* Redeclaring gl_PerVertex is only allowed if none of the built-ins 530bf215546Sopenharmony_ci * it defines have been accessed yet; so it's safe to throw away the 531bf215546Sopenharmony_ci * old max_ifc_array_access pointer, since all of its values are 532bf215546Sopenharmony_ci * zero. 533bf215546Sopenharmony_ci */ 534bf215546Sopenharmony_ci for (unsigned i = 0; i < this->interface_type->length; i++) 535bf215546Sopenharmony_ci assert(this->u.max_ifc_array_access[i] == -1); 536bf215546Sopenharmony_ci#endif 537bf215546Sopenharmony_ci ralloc_free(this->u.max_ifc_array_access); 538bf215546Sopenharmony_ci this->u.max_ifc_array_access = NULL; 539bf215546Sopenharmony_ci } 540bf215546Sopenharmony_ci this->interface_type = NULL; 541bf215546Sopenharmony_ci init_interface_type(type); 542bf215546Sopenharmony_ci } 543bf215546Sopenharmony_ci 544bf215546Sopenharmony_ci const glsl_type *get_interface_type() const 545bf215546Sopenharmony_ci { 546bf215546Sopenharmony_ci return this->interface_type; 547bf215546Sopenharmony_ci } 548bf215546Sopenharmony_ci 549bf215546Sopenharmony_ci enum glsl_interface_packing get_interface_type_packing() const 550bf215546Sopenharmony_ci { 551bf215546Sopenharmony_ci return this->interface_type->get_interface_packing(); 552bf215546Sopenharmony_ci } 553bf215546Sopenharmony_ci /** 554bf215546Sopenharmony_ci * Get the max_ifc_array_access pointer 555bf215546Sopenharmony_ci * 556bf215546Sopenharmony_ci * A "set" function is not needed because the array is dynamically allocated 557bf215546Sopenharmony_ci * as necessary. 558bf215546Sopenharmony_ci */ 559bf215546Sopenharmony_ci inline int *get_max_ifc_array_access() 560bf215546Sopenharmony_ci { 561bf215546Sopenharmony_ci assert(this->data._num_state_slots == 0); 562bf215546Sopenharmony_ci return this->u.max_ifc_array_access; 563bf215546Sopenharmony_ci } 564bf215546Sopenharmony_ci 565bf215546Sopenharmony_ci inline unsigned get_num_state_slots() const 566bf215546Sopenharmony_ci { 567bf215546Sopenharmony_ci assert(!this->is_interface_instance() 568bf215546Sopenharmony_ci || this->data._num_state_slots == 0); 569bf215546Sopenharmony_ci return this->data._num_state_slots; 570bf215546Sopenharmony_ci } 571bf215546Sopenharmony_ci 572bf215546Sopenharmony_ci inline void set_num_state_slots(unsigned n) 573bf215546Sopenharmony_ci { 574bf215546Sopenharmony_ci assert(!this->is_interface_instance() 575bf215546Sopenharmony_ci || n == 0); 576bf215546Sopenharmony_ci this->data._num_state_slots = n; 577bf215546Sopenharmony_ci } 578bf215546Sopenharmony_ci 579bf215546Sopenharmony_ci inline ir_state_slot *get_state_slots() 580bf215546Sopenharmony_ci { 581bf215546Sopenharmony_ci return this->is_interface_instance() ? NULL : this->u.state_slots; 582bf215546Sopenharmony_ci } 583bf215546Sopenharmony_ci 584bf215546Sopenharmony_ci inline const ir_state_slot *get_state_slots() const 585bf215546Sopenharmony_ci { 586bf215546Sopenharmony_ci return this->is_interface_instance() ? NULL : this->u.state_slots; 587bf215546Sopenharmony_ci } 588bf215546Sopenharmony_ci 589bf215546Sopenharmony_ci inline ir_state_slot *allocate_state_slots(unsigned n) 590bf215546Sopenharmony_ci { 591bf215546Sopenharmony_ci assert(!this->is_interface_instance()); 592bf215546Sopenharmony_ci 593bf215546Sopenharmony_ci this->u.state_slots = ralloc_array(this, ir_state_slot, n); 594bf215546Sopenharmony_ci this->data._num_state_slots = 0; 595bf215546Sopenharmony_ci 596bf215546Sopenharmony_ci if (this->u.state_slots != NULL) 597bf215546Sopenharmony_ci this->data._num_state_slots = n; 598bf215546Sopenharmony_ci 599bf215546Sopenharmony_ci return this->u.state_slots; 600bf215546Sopenharmony_ci } 601bf215546Sopenharmony_ci 602bf215546Sopenharmony_ci inline bool is_interpolation_flat() const 603bf215546Sopenharmony_ci { 604bf215546Sopenharmony_ci return this->data.interpolation == INTERP_MODE_FLAT || 605bf215546Sopenharmony_ci this->type->contains_integer() || 606bf215546Sopenharmony_ci this->type->contains_double(); 607bf215546Sopenharmony_ci } 608bf215546Sopenharmony_ci 609bf215546Sopenharmony_ci inline bool is_name_ralloced() const 610bf215546Sopenharmony_ci { 611bf215546Sopenharmony_ci return this->name != ir_variable::tmp_name && 612bf215546Sopenharmony_ci this->name != this->name_storage; 613bf215546Sopenharmony_ci } 614bf215546Sopenharmony_ci 615bf215546Sopenharmony_ci inline bool is_fb_fetch_color_output() const 616bf215546Sopenharmony_ci { 617bf215546Sopenharmony_ci return this->data.fb_fetch_output && 618bf215546Sopenharmony_ci this->data.location != FRAG_RESULT_DEPTH && 619bf215546Sopenharmony_ci this->data.location != FRAG_RESULT_STENCIL; 620bf215546Sopenharmony_ci } 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_ci /** 623bf215546Sopenharmony_ci * Enable emitting extension warnings for this variable 624bf215546Sopenharmony_ci */ 625bf215546Sopenharmony_ci void enable_extension_warning(const char *extension); 626bf215546Sopenharmony_ci 627bf215546Sopenharmony_ci /** 628bf215546Sopenharmony_ci * Get the extension warning string for this variable 629bf215546Sopenharmony_ci * 630bf215546Sopenharmony_ci * If warnings are not enabled, \c NULL is returned. 631bf215546Sopenharmony_ci */ 632bf215546Sopenharmony_ci const char *get_extension_warning() const; 633bf215546Sopenharmony_ci 634bf215546Sopenharmony_ci /** 635bf215546Sopenharmony_ci * Declared type of the variable 636bf215546Sopenharmony_ci */ 637bf215546Sopenharmony_ci const struct glsl_type *type; 638bf215546Sopenharmony_ci 639bf215546Sopenharmony_ci /** 640bf215546Sopenharmony_ci * Declared name of the variable 641bf215546Sopenharmony_ci */ 642bf215546Sopenharmony_ci const char *name; 643bf215546Sopenharmony_ci 644bf215546Sopenharmony_ciprivate: 645bf215546Sopenharmony_ci /** 646bf215546Sopenharmony_ci * If the name length fits into name_storage, it's used, otherwise 647bf215546Sopenharmony_ci * the name is ralloc'd. shader-db mining showed that 70% of variables 648bf215546Sopenharmony_ci * fit here. This is a win over ralloc where only ralloc_header has 649bf215546Sopenharmony_ci * 20 bytes on 64-bit (28 bytes with DEBUG), and we can also skip malloc. 650bf215546Sopenharmony_ci */ 651bf215546Sopenharmony_ci char name_storage[16]; 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_cipublic: 654bf215546Sopenharmony_ci struct ir_variable_data { 655bf215546Sopenharmony_ci 656bf215546Sopenharmony_ci /** 657bf215546Sopenharmony_ci * Is the variable read-only? 658bf215546Sopenharmony_ci * 659bf215546Sopenharmony_ci * This is set for variables declared as \c const, shader inputs, 660bf215546Sopenharmony_ci * and uniforms. 661bf215546Sopenharmony_ci */ 662bf215546Sopenharmony_ci unsigned read_only:1; 663bf215546Sopenharmony_ci unsigned centroid:1; 664bf215546Sopenharmony_ci unsigned sample:1; 665bf215546Sopenharmony_ci unsigned patch:1; 666bf215546Sopenharmony_ci /** 667bf215546Sopenharmony_ci * Was an 'invariant' qualifier explicitly set in the shader? 668bf215546Sopenharmony_ci * 669bf215546Sopenharmony_ci * This is used to cross validate qualifiers. 670bf215546Sopenharmony_ci */ 671bf215546Sopenharmony_ci unsigned explicit_invariant:1; 672bf215546Sopenharmony_ci /** 673bf215546Sopenharmony_ci * Is the variable invariant? 674bf215546Sopenharmony_ci * 675bf215546Sopenharmony_ci * It can happen either by having the 'invariant' qualifier 676bf215546Sopenharmony_ci * explicitly set in the shader or by being used in calculations 677bf215546Sopenharmony_ci * of other invariant variables. 678bf215546Sopenharmony_ci */ 679bf215546Sopenharmony_ci unsigned invariant:1; 680bf215546Sopenharmony_ci unsigned precise:1; 681bf215546Sopenharmony_ci 682bf215546Sopenharmony_ci /** 683bf215546Sopenharmony_ci * Has this variable been used for reading or writing? 684bf215546Sopenharmony_ci * 685bf215546Sopenharmony_ci * Several GLSL semantic checks require knowledge of whether or not a 686bf215546Sopenharmony_ci * variable has been used. For example, it is an error to redeclare a 687bf215546Sopenharmony_ci * variable as invariant after it has been used. 688bf215546Sopenharmony_ci * 689bf215546Sopenharmony_ci * This is maintained in the ast_to_hir.cpp path and during linking, 690bf215546Sopenharmony_ci * but not in Mesa's fixed function or ARB program paths. 691bf215546Sopenharmony_ci */ 692bf215546Sopenharmony_ci unsigned used:1; 693bf215546Sopenharmony_ci 694bf215546Sopenharmony_ci /** 695bf215546Sopenharmony_ci * Has this variable been statically assigned? 696bf215546Sopenharmony_ci * 697bf215546Sopenharmony_ci * This answers whether the variable was assigned in any path of 698bf215546Sopenharmony_ci * the shader during ast_to_hir. This doesn't answer whether it is 699bf215546Sopenharmony_ci * still written after dead code removal, nor is it maintained in 700bf215546Sopenharmony_ci * non-ast_to_hir.cpp (GLSL parsing) paths. 701bf215546Sopenharmony_ci */ 702bf215546Sopenharmony_ci unsigned assigned:1; 703bf215546Sopenharmony_ci 704bf215546Sopenharmony_ci /** 705bf215546Sopenharmony_ci * When separate shader programs are enabled, only input/outputs between 706bf215546Sopenharmony_ci * the stages of a multi-stage separate program can be safely removed 707bf215546Sopenharmony_ci * from the shader interface. Other input/outputs must remains active. 708bf215546Sopenharmony_ci */ 709bf215546Sopenharmony_ci unsigned always_active_io:1; 710bf215546Sopenharmony_ci 711bf215546Sopenharmony_ci /** 712bf215546Sopenharmony_ci * Enum indicating how the variable was declared. See 713bf215546Sopenharmony_ci * ir_var_declaration_type. 714bf215546Sopenharmony_ci * 715bf215546Sopenharmony_ci * This is used to detect certain kinds of illegal variable redeclarations. 716bf215546Sopenharmony_ci */ 717bf215546Sopenharmony_ci unsigned how_declared:2; 718bf215546Sopenharmony_ci 719bf215546Sopenharmony_ci /** 720bf215546Sopenharmony_ci * Storage class of the variable. 721bf215546Sopenharmony_ci * 722bf215546Sopenharmony_ci * \sa ir_variable_mode 723bf215546Sopenharmony_ci */ 724bf215546Sopenharmony_ci unsigned mode:4; 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_ci /** 727bf215546Sopenharmony_ci * Interpolation mode for shader inputs / outputs 728bf215546Sopenharmony_ci * 729bf215546Sopenharmony_ci * \sa glsl_interp_mode 730bf215546Sopenharmony_ci */ 731bf215546Sopenharmony_ci unsigned interpolation:2; 732bf215546Sopenharmony_ci 733bf215546Sopenharmony_ci /** 734bf215546Sopenharmony_ci * Was the location explicitly set in the shader? 735bf215546Sopenharmony_ci * 736bf215546Sopenharmony_ci * If the location is explicitly set in the shader, it \b cannot be changed 737bf215546Sopenharmony_ci * by the linker or by the API (e.g., calls to \c glBindAttribLocation have 738bf215546Sopenharmony_ci * no effect). 739bf215546Sopenharmony_ci */ 740bf215546Sopenharmony_ci unsigned explicit_location:1; 741bf215546Sopenharmony_ci unsigned explicit_index:1; 742bf215546Sopenharmony_ci 743bf215546Sopenharmony_ci /** 744bf215546Sopenharmony_ci * Was an initial binding explicitly set in the shader? 745bf215546Sopenharmony_ci * 746bf215546Sopenharmony_ci * If so, constant_value contains an integer ir_constant representing the 747bf215546Sopenharmony_ci * initial binding point. 748bf215546Sopenharmony_ci */ 749bf215546Sopenharmony_ci unsigned explicit_binding:1; 750bf215546Sopenharmony_ci 751bf215546Sopenharmony_ci /** 752bf215546Sopenharmony_ci * Was an initial component explicitly set in the shader? 753bf215546Sopenharmony_ci */ 754bf215546Sopenharmony_ci unsigned explicit_component:1; 755bf215546Sopenharmony_ci 756bf215546Sopenharmony_ci /** 757bf215546Sopenharmony_ci * Does this variable have an initializer? 758bf215546Sopenharmony_ci * 759bf215546Sopenharmony_ci * This is used by the linker to cross-validiate initializers of global 760bf215546Sopenharmony_ci * variables. 761bf215546Sopenharmony_ci */ 762bf215546Sopenharmony_ci unsigned has_initializer:1; 763bf215546Sopenharmony_ci 764bf215546Sopenharmony_ci /** 765bf215546Sopenharmony_ci * Is the initializer created by the compiler (glsl_zero_init) 766bf215546Sopenharmony_ci */ 767bf215546Sopenharmony_ci unsigned is_implicit_initializer:1; 768bf215546Sopenharmony_ci 769bf215546Sopenharmony_ci /** 770bf215546Sopenharmony_ci * Is this varying used by transform feedback? 771bf215546Sopenharmony_ci * 772bf215546Sopenharmony_ci * This is used by the linker to decide if it's safe to pack the varying. 773bf215546Sopenharmony_ci */ 774bf215546Sopenharmony_ci unsigned is_xfb:1; 775bf215546Sopenharmony_ci 776bf215546Sopenharmony_ci /** 777bf215546Sopenharmony_ci * Is this varying used only by transform feedback? 778bf215546Sopenharmony_ci * 779bf215546Sopenharmony_ci * This is used by the linker to decide if its safe to pack the varying. 780bf215546Sopenharmony_ci */ 781bf215546Sopenharmony_ci unsigned is_xfb_only:1; 782bf215546Sopenharmony_ci 783bf215546Sopenharmony_ci /** 784bf215546Sopenharmony_ci * Was a transform feedback buffer set in the shader? 785bf215546Sopenharmony_ci */ 786bf215546Sopenharmony_ci unsigned explicit_xfb_buffer:1; 787bf215546Sopenharmony_ci 788bf215546Sopenharmony_ci /** 789bf215546Sopenharmony_ci * Was a transform feedback offset set in the shader? 790bf215546Sopenharmony_ci */ 791bf215546Sopenharmony_ci unsigned explicit_xfb_offset:1; 792bf215546Sopenharmony_ci 793bf215546Sopenharmony_ci /** 794bf215546Sopenharmony_ci * Was a transform feedback stride set in the shader? 795bf215546Sopenharmony_ci */ 796bf215546Sopenharmony_ci unsigned explicit_xfb_stride:1; 797bf215546Sopenharmony_ci 798bf215546Sopenharmony_ci /** 799bf215546Sopenharmony_ci * If non-zero, then this variable may be packed along with other variables 800bf215546Sopenharmony_ci * into a single varying slot, so this offset should be applied when 801bf215546Sopenharmony_ci * accessing components. For example, an offset of 1 means that the x 802bf215546Sopenharmony_ci * component of this variable is actually stored in component y of the 803bf215546Sopenharmony_ci * location specified by \c location. 804bf215546Sopenharmony_ci */ 805bf215546Sopenharmony_ci unsigned location_frac:2; 806bf215546Sopenharmony_ci 807bf215546Sopenharmony_ci /** 808bf215546Sopenharmony_ci * Layout of the matrix. Uses glsl_matrix_layout values. 809bf215546Sopenharmony_ci */ 810bf215546Sopenharmony_ci unsigned matrix_layout:2; 811bf215546Sopenharmony_ci 812bf215546Sopenharmony_ci /** 813bf215546Sopenharmony_ci * Non-zero if this variable was created by lowering a named interface 814bf215546Sopenharmony_ci * block. 815bf215546Sopenharmony_ci */ 816bf215546Sopenharmony_ci unsigned from_named_ifc_block:1; 817bf215546Sopenharmony_ci 818bf215546Sopenharmony_ci /** 819bf215546Sopenharmony_ci * Non-zero if the variable must be a shader input. This is useful for 820bf215546Sopenharmony_ci * constraints on function parameters. 821bf215546Sopenharmony_ci */ 822bf215546Sopenharmony_ci unsigned must_be_shader_input:1; 823bf215546Sopenharmony_ci 824bf215546Sopenharmony_ci /** 825bf215546Sopenharmony_ci * Output index for dual source blending. 826bf215546Sopenharmony_ci * 827bf215546Sopenharmony_ci * \note 828bf215546Sopenharmony_ci * The GLSL spec only allows the values 0 or 1 for the index in \b dual 829bf215546Sopenharmony_ci * source blending. 830bf215546Sopenharmony_ci */ 831bf215546Sopenharmony_ci unsigned index:1; 832bf215546Sopenharmony_ci 833bf215546Sopenharmony_ci /** 834bf215546Sopenharmony_ci * Precision qualifier. 835bf215546Sopenharmony_ci * 836bf215546Sopenharmony_ci * In desktop GLSL we do not care about precision qualifiers at all, in 837bf215546Sopenharmony_ci * fact, the spec says that precision qualifiers are ignored. 838bf215546Sopenharmony_ci * 839bf215546Sopenharmony_ci * To make things easy, we make it so that this field is always 840bf215546Sopenharmony_ci * GLSL_PRECISION_NONE on desktop shaders. This way all the variables 841bf215546Sopenharmony_ci * have the same precision value and the checks we add in the compiler 842bf215546Sopenharmony_ci * for this field will never break a desktop shader compile. 843bf215546Sopenharmony_ci */ 844bf215546Sopenharmony_ci unsigned precision:2; 845bf215546Sopenharmony_ci 846bf215546Sopenharmony_ci /** 847bf215546Sopenharmony_ci * \brief Layout qualifier for gl_FragDepth. 848bf215546Sopenharmony_ci * 849bf215546Sopenharmony_ci * This is not equal to \c ir_depth_layout_none if and only if this 850bf215546Sopenharmony_ci * variable is \c gl_FragDepth and a layout qualifier is specified. 851bf215546Sopenharmony_ci */ 852bf215546Sopenharmony_ci ir_depth_layout depth_layout:3; 853bf215546Sopenharmony_ci 854bf215546Sopenharmony_ci /** 855bf215546Sopenharmony_ci * Memory qualifiers. 856bf215546Sopenharmony_ci */ 857bf215546Sopenharmony_ci unsigned memory_read_only:1; /**< "readonly" qualifier. */ 858bf215546Sopenharmony_ci unsigned memory_write_only:1; /**< "writeonly" qualifier. */ 859bf215546Sopenharmony_ci unsigned memory_coherent:1; 860bf215546Sopenharmony_ci unsigned memory_volatile:1; 861bf215546Sopenharmony_ci unsigned memory_restrict:1; 862bf215546Sopenharmony_ci 863bf215546Sopenharmony_ci /** 864bf215546Sopenharmony_ci * ARB_shader_storage_buffer_object 865bf215546Sopenharmony_ci */ 866bf215546Sopenharmony_ci unsigned from_ssbo_unsized_array:1; /**< unsized array buffer variable. */ 867bf215546Sopenharmony_ci 868bf215546Sopenharmony_ci unsigned implicit_sized_array:1; 869bf215546Sopenharmony_ci 870bf215546Sopenharmony_ci /** 871bf215546Sopenharmony_ci * Whether this is a fragment shader output implicitly initialized with 872bf215546Sopenharmony_ci * the previous contents of the specified render target at the 873bf215546Sopenharmony_ci * framebuffer location corresponding to this shader invocation. 874bf215546Sopenharmony_ci */ 875bf215546Sopenharmony_ci unsigned fb_fetch_output:1; 876bf215546Sopenharmony_ci 877bf215546Sopenharmony_ci /** 878bf215546Sopenharmony_ci * Non-zero if this variable is considered bindless as defined by 879bf215546Sopenharmony_ci * ARB_bindless_texture. 880bf215546Sopenharmony_ci */ 881bf215546Sopenharmony_ci unsigned bindless:1; 882bf215546Sopenharmony_ci 883bf215546Sopenharmony_ci /** 884bf215546Sopenharmony_ci * Non-zero if this variable is considered bound as defined by 885bf215546Sopenharmony_ci * ARB_bindless_texture. 886bf215546Sopenharmony_ci */ 887bf215546Sopenharmony_ci unsigned bound:1; 888bf215546Sopenharmony_ci 889bf215546Sopenharmony_ci /** 890bf215546Sopenharmony_ci * Non-zero if the variable shall not be implicitly converted during 891bf215546Sopenharmony_ci * functions matching. 892bf215546Sopenharmony_ci */ 893bf215546Sopenharmony_ci unsigned implicit_conversion_prohibited:1; 894bf215546Sopenharmony_ci 895bf215546Sopenharmony_ci /** 896bf215546Sopenharmony_ci * Emit a warning if this variable is accessed. 897bf215546Sopenharmony_ci */ 898bf215546Sopenharmony_ci private: 899bf215546Sopenharmony_ci uint8_t warn_extension_index; 900bf215546Sopenharmony_ci 901bf215546Sopenharmony_ci public: 902bf215546Sopenharmony_ci /** 903bf215546Sopenharmony_ci * Image internal format if specified explicitly, otherwise 904bf215546Sopenharmony_ci * PIPE_FORMAT_NONE. 905bf215546Sopenharmony_ci */ 906bf215546Sopenharmony_ci enum pipe_format image_format; 907bf215546Sopenharmony_ci 908bf215546Sopenharmony_ci private: 909bf215546Sopenharmony_ci /** 910bf215546Sopenharmony_ci * Number of state slots used 911bf215546Sopenharmony_ci * 912bf215546Sopenharmony_ci * \note 913bf215546Sopenharmony_ci * This could be stored in as few as 7-bits, if necessary. If it is made 914bf215546Sopenharmony_ci * smaller, add an assertion to \c ir_variable::allocate_state_slots to 915bf215546Sopenharmony_ci * be safe. 916bf215546Sopenharmony_ci */ 917bf215546Sopenharmony_ci uint16_t _num_state_slots; 918bf215546Sopenharmony_ci 919bf215546Sopenharmony_ci public: 920bf215546Sopenharmony_ci /** 921bf215546Sopenharmony_ci * Initial binding point for a sampler, atomic, or UBO. 922bf215546Sopenharmony_ci * 923bf215546Sopenharmony_ci * For array types, this represents the binding point for the first element. 924bf215546Sopenharmony_ci */ 925bf215546Sopenharmony_ci uint16_t binding; 926bf215546Sopenharmony_ci 927bf215546Sopenharmony_ci /** 928bf215546Sopenharmony_ci * Storage location of the base of this variable 929bf215546Sopenharmony_ci * 930bf215546Sopenharmony_ci * The precise meaning of this field depends on the nature of the variable. 931bf215546Sopenharmony_ci * 932bf215546Sopenharmony_ci * - Vertex shader input: one of the values from \c gl_vert_attrib. 933bf215546Sopenharmony_ci * - Vertex shader output: one of the values from \c gl_varying_slot. 934bf215546Sopenharmony_ci * - Geometry shader input: one of the values from \c gl_varying_slot. 935bf215546Sopenharmony_ci * - Geometry shader output: one of the values from \c gl_varying_slot. 936bf215546Sopenharmony_ci * - Fragment shader input: one of the values from \c gl_varying_slot. 937bf215546Sopenharmony_ci * - Fragment shader output: one of the values from \c gl_frag_result. 938bf215546Sopenharmony_ci * - Uniforms: Per-stage uniform slot number for default uniform block. 939bf215546Sopenharmony_ci * - Uniforms: Index within the uniform block definition for UBO members. 940bf215546Sopenharmony_ci * - Non-UBO Uniforms: explicit location until linking then reused to 941bf215546Sopenharmony_ci * store uniform slot number. 942bf215546Sopenharmony_ci * - Other: This field is not currently used. 943bf215546Sopenharmony_ci * 944bf215546Sopenharmony_ci * If the variable is a uniform, shader input, or shader output, and the 945bf215546Sopenharmony_ci * slot has not been assigned, the value will be -1. 946bf215546Sopenharmony_ci */ 947bf215546Sopenharmony_ci int location; 948bf215546Sopenharmony_ci 949bf215546Sopenharmony_ci /** 950bf215546Sopenharmony_ci * for glsl->tgsi/mesa IR we need to store the index into the 951bf215546Sopenharmony_ci * parameters for uniforms, initially the code overloaded location 952bf215546Sopenharmony_ci * but this causes problems with indirect samplers and AoA. 953bf215546Sopenharmony_ci * This is assigned in _mesa_generate_parameters_list_for_uniforms. 954bf215546Sopenharmony_ci */ 955bf215546Sopenharmony_ci int param_index; 956bf215546Sopenharmony_ci 957bf215546Sopenharmony_ci /** 958bf215546Sopenharmony_ci * Vertex stream output identifier. 959bf215546Sopenharmony_ci * 960bf215546Sopenharmony_ci * For packed outputs, bit 31 is set and bits [2*i+1,2*i] indicate the 961bf215546Sopenharmony_ci * stream of the i-th component. 962bf215546Sopenharmony_ci */ 963bf215546Sopenharmony_ci unsigned stream; 964bf215546Sopenharmony_ci 965bf215546Sopenharmony_ci /** 966bf215546Sopenharmony_ci * Atomic, transform feedback or block member offset. 967bf215546Sopenharmony_ci */ 968bf215546Sopenharmony_ci unsigned offset; 969bf215546Sopenharmony_ci 970bf215546Sopenharmony_ci /** 971bf215546Sopenharmony_ci * Highest element accessed with a constant expression array index 972bf215546Sopenharmony_ci * 973bf215546Sopenharmony_ci * Not used for non-array variables. -1 is never accessed. 974bf215546Sopenharmony_ci */ 975bf215546Sopenharmony_ci int max_array_access; 976bf215546Sopenharmony_ci 977bf215546Sopenharmony_ci /** 978bf215546Sopenharmony_ci * Transform feedback buffer. 979bf215546Sopenharmony_ci */ 980bf215546Sopenharmony_ci unsigned xfb_buffer; 981bf215546Sopenharmony_ci 982bf215546Sopenharmony_ci /** 983bf215546Sopenharmony_ci * Transform feedback stride. 984bf215546Sopenharmony_ci */ 985bf215546Sopenharmony_ci unsigned xfb_stride; 986bf215546Sopenharmony_ci 987bf215546Sopenharmony_ci /** 988bf215546Sopenharmony_ci * Allow (only) ir_variable direct access private members. 989bf215546Sopenharmony_ci */ 990bf215546Sopenharmony_ci friend class ir_variable; 991bf215546Sopenharmony_ci } data; 992bf215546Sopenharmony_ci 993bf215546Sopenharmony_ci /** 994bf215546Sopenharmony_ci * Value assigned in the initializer of a variable declared "const" 995bf215546Sopenharmony_ci */ 996bf215546Sopenharmony_ci ir_constant *constant_value; 997bf215546Sopenharmony_ci 998bf215546Sopenharmony_ci /** 999bf215546Sopenharmony_ci * Constant expression assigned in the initializer of the variable 1000bf215546Sopenharmony_ci * 1001bf215546Sopenharmony_ci * \warning 1002bf215546Sopenharmony_ci * This field and \c ::constant_value are distinct. Even if the two fields 1003bf215546Sopenharmony_ci * refer to constants with the same value, they must point to separate 1004bf215546Sopenharmony_ci * objects. 1005bf215546Sopenharmony_ci */ 1006bf215546Sopenharmony_ci ir_constant *constant_initializer; 1007bf215546Sopenharmony_ci 1008bf215546Sopenharmony_ciprivate: 1009bf215546Sopenharmony_ci static const char *const warn_extension_table[]; 1010bf215546Sopenharmony_ci 1011bf215546Sopenharmony_ci union { 1012bf215546Sopenharmony_ci /** 1013bf215546Sopenharmony_ci * For variables which satisfy the is_interface_instance() predicate, 1014bf215546Sopenharmony_ci * this points to an array of integers such that if the ith member of 1015bf215546Sopenharmony_ci * the interface block is an array, max_ifc_array_access[i] is the 1016bf215546Sopenharmony_ci * maximum array element of that member that has been accessed. If the 1017bf215546Sopenharmony_ci * ith member of the interface block is not an array, 1018bf215546Sopenharmony_ci * max_ifc_array_access[i] is unused. 1019bf215546Sopenharmony_ci * 1020bf215546Sopenharmony_ci * For variables whose type is not an interface block, this pointer is 1021bf215546Sopenharmony_ci * NULL. 1022bf215546Sopenharmony_ci */ 1023bf215546Sopenharmony_ci int *max_ifc_array_access; 1024bf215546Sopenharmony_ci 1025bf215546Sopenharmony_ci /** 1026bf215546Sopenharmony_ci * Built-in state that backs this uniform 1027bf215546Sopenharmony_ci * 1028bf215546Sopenharmony_ci * Once set at variable creation, \c state_slots must remain invariant. 1029bf215546Sopenharmony_ci * 1030bf215546Sopenharmony_ci * If the variable is not a uniform, \c _num_state_slots will be zero 1031bf215546Sopenharmony_ci * and \c state_slots will be \c NULL. 1032bf215546Sopenharmony_ci */ 1033bf215546Sopenharmony_ci ir_state_slot *state_slots; 1034bf215546Sopenharmony_ci } u; 1035bf215546Sopenharmony_ci 1036bf215546Sopenharmony_ci /** 1037bf215546Sopenharmony_ci * For variables that are in an interface block or are an instance of an 1038bf215546Sopenharmony_ci * interface block, this is the \c GLSL_TYPE_INTERFACE type for that block. 1039bf215546Sopenharmony_ci * 1040bf215546Sopenharmony_ci * \sa ir_variable::location 1041bf215546Sopenharmony_ci */ 1042bf215546Sopenharmony_ci const glsl_type *interface_type; 1043bf215546Sopenharmony_ci 1044bf215546Sopenharmony_ci /** 1045bf215546Sopenharmony_ci * Name used for anonymous compiler temporaries 1046bf215546Sopenharmony_ci */ 1047bf215546Sopenharmony_ci static const char tmp_name[]; 1048bf215546Sopenharmony_ci 1049bf215546Sopenharmony_cipublic: 1050bf215546Sopenharmony_ci /** 1051bf215546Sopenharmony_ci * Should the construct keep names for ir_var_temporary variables? 1052bf215546Sopenharmony_ci * 1053bf215546Sopenharmony_ci * When this global is false, names passed to the constructor for 1054bf215546Sopenharmony_ci * \c ir_var_temporary variables will be dropped. Instead, the variable will 1055bf215546Sopenharmony_ci * be named "compiler_temp". This name will be in static storage. 1056bf215546Sopenharmony_ci * 1057bf215546Sopenharmony_ci * \warning 1058bf215546Sopenharmony_ci * \b NEVER change the mode of an \c ir_var_temporary. 1059bf215546Sopenharmony_ci * 1060bf215546Sopenharmony_ci * \warning 1061bf215546Sopenharmony_ci * This variable is \b not thread-safe. It is global, \b not 1062bf215546Sopenharmony_ci * per-context. It begins life false. A context can, at some point, make 1063bf215546Sopenharmony_ci * it true. From that point on, it will be true forever. This should be 1064bf215546Sopenharmony_ci * okay since it will only be set true while debugging. 1065bf215546Sopenharmony_ci */ 1066bf215546Sopenharmony_ci static bool temporaries_allocate_names; 1067bf215546Sopenharmony_ci}; 1068bf215546Sopenharmony_ci 1069bf215546Sopenharmony_ci/** 1070bf215546Sopenharmony_ci * A function that returns whether a built-in function is available in the 1071bf215546Sopenharmony_ci * current shading language (based on version, ES or desktop, and extensions). 1072bf215546Sopenharmony_ci */ 1073bf215546Sopenharmony_citypedef bool (*builtin_available_predicate)(const _mesa_glsl_parse_state *); 1074bf215546Sopenharmony_ci 1075bf215546Sopenharmony_ci#define MAKE_INTRINSIC_FOR_TYPE(op, t) \ 1076bf215546Sopenharmony_ci ir_intrinsic_generic_ ## op - ir_intrinsic_generic_load + ir_intrinsic_ ## t ## _ ## load 1077bf215546Sopenharmony_ci 1078bf215546Sopenharmony_ci#define MAP_INTRINSIC_TO_TYPE(i, t) \ 1079bf215546Sopenharmony_ci ir_intrinsic_id(int(i) - int(ir_intrinsic_generic_load) + int(ir_intrinsic_ ## t ## _ ## load)) 1080bf215546Sopenharmony_ci 1081bf215546Sopenharmony_cienum ir_intrinsic_id { 1082bf215546Sopenharmony_ci ir_intrinsic_invalid = 0, 1083bf215546Sopenharmony_ci 1084bf215546Sopenharmony_ci /** 1085bf215546Sopenharmony_ci * \name Generic intrinsics 1086bf215546Sopenharmony_ci * 1087bf215546Sopenharmony_ci * Each of these intrinsics has a specific version for shared variables and 1088bf215546Sopenharmony_ci * SSBOs. 1089bf215546Sopenharmony_ci */ 1090bf215546Sopenharmony_ci /*@{*/ 1091bf215546Sopenharmony_ci ir_intrinsic_generic_load, 1092bf215546Sopenharmony_ci ir_intrinsic_generic_store, 1093bf215546Sopenharmony_ci ir_intrinsic_generic_atomic_add, 1094bf215546Sopenharmony_ci ir_intrinsic_generic_atomic_and, 1095bf215546Sopenharmony_ci ir_intrinsic_generic_atomic_or, 1096bf215546Sopenharmony_ci ir_intrinsic_generic_atomic_xor, 1097bf215546Sopenharmony_ci ir_intrinsic_generic_atomic_min, 1098bf215546Sopenharmony_ci ir_intrinsic_generic_atomic_max, 1099bf215546Sopenharmony_ci ir_intrinsic_generic_atomic_exchange, 1100bf215546Sopenharmony_ci ir_intrinsic_generic_atomic_comp_swap, 1101bf215546Sopenharmony_ci /*@}*/ 1102bf215546Sopenharmony_ci 1103bf215546Sopenharmony_ci ir_intrinsic_atomic_counter_read, 1104bf215546Sopenharmony_ci ir_intrinsic_atomic_counter_increment, 1105bf215546Sopenharmony_ci ir_intrinsic_atomic_counter_predecrement, 1106bf215546Sopenharmony_ci ir_intrinsic_atomic_counter_add, 1107bf215546Sopenharmony_ci ir_intrinsic_atomic_counter_and, 1108bf215546Sopenharmony_ci ir_intrinsic_atomic_counter_or, 1109bf215546Sopenharmony_ci ir_intrinsic_atomic_counter_xor, 1110bf215546Sopenharmony_ci ir_intrinsic_atomic_counter_min, 1111bf215546Sopenharmony_ci ir_intrinsic_atomic_counter_max, 1112bf215546Sopenharmony_ci ir_intrinsic_atomic_counter_exchange, 1113bf215546Sopenharmony_ci ir_intrinsic_atomic_counter_comp_swap, 1114bf215546Sopenharmony_ci 1115bf215546Sopenharmony_ci ir_intrinsic_image_load, 1116bf215546Sopenharmony_ci ir_intrinsic_image_store, 1117bf215546Sopenharmony_ci ir_intrinsic_image_atomic_add, 1118bf215546Sopenharmony_ci ir_intrinsic_image_atomic_and, 1119bf215546Sopenharmony_ci ir_intrinsic_image_atomic_or, 1120bf215546Sopenharmony_ci ir_intrinsic_image_atomic_xor, 1121bf215546Sopenharmony_ci ir_intrinsic_image_atomic_min, 1122bf215546Sopenharmony_ci ir_intrinsic_image_atomic_max, 1123bf215546Sopenharmony_ci ir_intrinsic_image_atomic_exchange, 1124bf215546Sopenharmony_ci ir_intrinsic_image_atomic_comp_swap, 1125bf215546Sopenharmony_ci ir_intrinsic_image_size, 1126bf215546Sopenharmony_ci ir_intrinsic_image_samples, 1127bf215546Sopenharmony_ci ir_intrinsic_image_atomic_inc_wrap, 1128bf215546Sopenharmony_ci ir_intrinsic_image_atomic_dec_wrap, 1129bf215546Sopenharmony_ci ir_intrinsic_image_sparse_load, 1130bf215546Sopenharmony_ci 1131bf215546Sopenharmony_ci ir_intrinsic_ssbo_load, 1132bf215546Sopenharmony_ci ir_intrinsic_ssbo_store = MAKE_INTRINSIC_FOR_TYPE(store, ssbo), 1133bf215546Sopenharmony_ci ir_intrinsic_ssbo_atomic_add = MAKE_INTRINSIC_FOR_TYPE(atomic_add, ssbo), 1134bf215546Sopenharmony_ci ir_intrinsic_ssbo_atomic_and = MAKE_INTRINSIC_FOR_TYPE(atomic_and, ssbo), 1135bf215546Sopenharmony_ci ir_intrinsic_ssbo_atomic_or = MAKE_INTRINSIC_FOR_TYPE(atomic_or, ssbo), 1136bf215546Sopenharmony_ci ir_intrinsic_ssbo_atomic_xor = MAKE_INTRINSIC_FOR_TYPE(atomic_xor, ssbo), 1137bf215546Sopenharmony_ci ir_intrinsic_ssbo_atomic_min = MAKE_INTRINSIC_FOR_TYPE(atomic_min, ssbo), 1138bf215546Sopenharmony_ci ir_intrinsic_ssbo_atomic_max = MAKE_INTRINSIC_FOR_TYPE(atomic_max, ssbo), 1139bf215546Sopenharmony_ci ir_intrinsic_ssbo_atomic_exchange = MAKE_INTRINSIC_FOR_TYPE(atomic_exchange, ssbo), 1140bf215546Sopenharmony_ci ir_intrinsic_ssbo_atomic_comp_swap = MAKE_INTRINSIC_FOR_TYPE(atomic_comp_swap, ssbo), 1141bf215546Sopenharmony_ci 1142bf215546Sopenharmony_ci ir_intrinsic_memory_barrier, 1143bf215546Sopenharmony_ci ir_intrinsic_shader_clock, 1144bf215546Sopenharmony_ci ir_intrinsic_group_memory_barrier, 1145bf215546Sopenharmony_ci ir_intrinsic_memory_barrier_atomic_counter, 1146bf215546Sopenharmony_ci ir_intrinsic_memory_barrier_buffer, 1147bf215546Sopenharmony_ci ir_intrinsic_memory_barrier_image, 1148bf215546Sopenharmony_ci ir_intrinsic_memory_barrier_shared, 1149bf215546Sopenharmony_ci ir_intrinsic_begin_invocation_interlock, 1150bf215546Sopenharmony_ci ir_intrinsic_end_invocation_interlock, 1151bf215546Sopenharmony_ci 1152bf215546Sopenharmony_ci ir_intrinsic_vote_all, 1153bf215546Sopenharmony_ci ir_intrinsic_vote_any, 1154bf215546Sopenharmony_ci ir_intrinsic_vote_eq, 1155bf215546Sopenharmony_ci ir_intrinsic_ballot, 1156bf215546Sopenharmony_ci ir_intrinsic_read_invocation, 1157bf215546Sopenharmony_ci ir_intrinsic_read_first_invocation, 1158bf215546Sopenharmony_ci 1159bf215546Sopenharmony_ci ir_intrinsic_helper_invocation, 1160bf215546Sopenharmony_ci 1161bf215546Sopenharmony_ci ir_intrinsic_shared_load, 1162bf215546Sopenharmony_ci ir_intrinsic_shared_store = MAKE_INTRINSIC_FOR_TYPE(store, shared), 1163bf215546Sopenharmony_ci ir_intrinsic_shared_atomic_add = MAKE_INTRINSIC_FOR_TYPE(atomic_add, shared), 1164bf215546Sopenharmony_ci ir_intrinsic_shared_atomic_and = MAKE_INTRINSIC_FOR_TYPE(atomic_and, shared), 1165bf215546Sopenharmony_ci ir_intrinsic_shared_atomic_or = MAKE_INTRINSIC_FOR_TYPE(atomic_or, shared), 1166bf215546Sopenharmony_ci ir_intrinsic_shared_atomic_xor = MAKE_INTRINSIC_FOR_TYPE(atomic_xor, shared), 1167bf215546Sopenharmony_ci ir_intrinsic_shared_atomic_min = MAKE_INTRINSIC_FOR_TYPE(atomic_min, shared), 1168bf215546Sopenharmony_ci ir_intrinsic_shared_atomic_max = MAKE_INTRINSIC_FOR_TYPE(atomic_max, shared), 1169bf215546Sopenharmony_ci ir_intrinsic_shared_atomic_exchange = MAKE_INTRINSIC_FOR_TYPE(atomic_exchange, shared), 1170bf215546Sopenharmony_ci ir_intrinsic_shared_atomic_comp_swap = MAKE_INTRINSIC_FOR_TYPE(atomic_comp_swap, shared), 1171bf215546Sopenharmony_ci 1172bf215546Sopenharmony_ci ir_intrinsic_is_sparse_texels_resident, 1173bf215546Sopenharmony_ci}; 1174bf215546Sopenharmony_ci 1175bf215546Sopenharmony_ci/*@{*/ 1176bf215546Sopenharmony_ci/** 1177bf215546Sopenharmony_ci * The representation of a function instance; may be the full definition or 1178bf215546Sopenharmony_ci * simply a prototype. 1179bf215546Sopenharmony_ci */ 1180bf215546Sopenharmony_ciclass ir_function_signature : public ir_instruction { 1181bf215546Sopenharmony_ci /* An ir_function_signature will be part of the list of signatures in 1182bf215546Sopenharmony_ci * an ir_function. 1183bf215546Sopenharmony_ci */ 1184bf215546Sopenharmony_cipublic: 1185bf215546Sopenharmony_ci ir_function_signature(const glsl_type *return_type, 1186bf215546Sopenharmony_ci builtin_available_predicate builtin_avail = NULL); 1187bf215546Sopenharmony_ci 1188bf215546Sopenharmony_ci virtual ir_function_signature *clone(void *mem_ctx, 1189bf215546Sopenharmony_ci struct hash_table *ht) const; 1190bf215546Sopenharmony_ci ir_function_signature *clone_prototype(void *mem_ctx, 1191bf215546Sopenharmony_ci struct hash_table *ht) const; 1192bf215546Sopenharmony_ci 1193bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 1194bf215546Sopenharmony_ci { 1195bf215546Sopenharmony_ci v->visit(this); 1196bf215546Sopenharmony_ci } 1197bf215546Sopenharmony_ci 1198bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 1199bf215546Sopenharmony_ci 1200bf215546Sopenharmony_ci /** 1201bf215546Sopenharmony_ci * Attempt to evaluate this function as a constant expression, 1202bf215546Sopenharmony_ci * given a list of the actual parameters and the variable context. 1203bf215546Sopenharmony_ci * Returns NULL for non-built-ins. 1204bf215546Sopenharmony_ci */ 1205bf215546Sopenharmony_ci ir_constant *constant_expression_value(void *mem_ctx, 1206bf215546Sopenharmony_ci exec_list *actual_parameters, 1207bf215546Sopenharmony_ci struct hash_table *variable_context); 1208bf215546Sopenharmony_ci 1209bf215546Sopenharmony_ci /** 1210bf215546Sopenharmony_ci * Get the name of the function for which this is a signature 1211bf215546Sopenharmony_ci */ 1212bf215546Sopenharmony_ci const char *function_name() const; 1213bf215546Sopenharmony_ci 1214bf215546Sopenharmony_ci /** 1215bf215546Sopenharmony_ci * Get a handle to the function for which this is a signature 1216bf215546Sopenharmony_ci * 1217bf215546Sopenharmony_ci * There is no setter function, this function returns a \c const pointer, 1218bf215546Sopenharmony_ci * and \c ir_function_signature::_function is private for a reason. The 1219bf215546Sopenharmony_ci * only way to make a connection between a function and function signature 1220bf215546Sopenharmony_ci * is via \c ir_function::add_signature. This helps ensure that certain 1221bf215546Sopenharmony_ci * invariants (i.e., a function signature is in the list of signatures for 1222bf215546Sopenharmony_ci * its \c _function) are met. 1223bf215546Sopenharmony_ci * 1224bf215546Sopenharmony_ci * \sa ir_function::add_signature 1225bf215546Sopenharmony_ci */ 1226bf215546Sopenharmony_ci inline const class ir_function *function() const 1227bf215546Sopenharmony_ci { 1228bf215546Sopenharmony_ci return this->_function; 1229bf215546Sopenharmony_ci } 1230bf215546Sopenharmony_ci 1231bf215546Sopenharmony_ci /** 1232bf215546Sopenharmony_ci * Check whether the qualifiers match between this signature's parameters 1233bf215546Sopenharmony_ci * and the supplied parameter list. If not, returns the name of the first 1234bf215546Sopenharmony_ci * parameter with mismatched qualifiers (for use in error messages). 1235bf215546Sopenharmony_ci */ 1236bf215546Sopenharmony_ci const char *qualifiers_match(exec_list *params); 1237bf215546Sopenharmony_ci 1238bf215546Sopenharmony_ci /** 1239bf215546Sopenharmony_ci * Replace the current parameter list with the given one. This is useful 1240bf215546Sopenharmony_ci * if the current information came from a prototype, and either has invalid 1241bf215546Sopenharmony_ci * or missing parameter names. 1242bf215546Sopenharmony_ci */ 1243bf215546Sopenharmony_ci void replace_parameters(exec_list *new_params); 1244bf215546Sopenharmony_ci 1245bf215546Sopenharmony_ci /** 1246bf215546Sopenharmony_ci * Function return type. 1247bf215546Sopenharmony_ci * 1248bf215546Sopenharmony_ci * \note The precision qualifier is stored separately in return_precision. 1249bf215546Sopenharmony_ci */ 1250bf215546Sopenharmony_ci const struct glsl_type *return_type; 1251bf215546Sopenharmony_ci 1252bf215546Sopenharmony_ci /** 1253bf215546Sopenharmony_ci * List of ir_variable of function parameters. 1254bf215546Sopenharmony_ci * 1255bf215546Sopenharmony_ci * This represents the storage. The paramaters passed in a particular 1256bf215546Sopenharmony_ci * call will be in ir_call::actual_paramaters. 1257bf215546Sopenharmony_ci */ 1258bf215546Sopenharmony_ci struct exec_list parameters; 1259bf215546Sopenharmony_ci 1260bf215546Sopenharmony_ci /** Whether or not this function has a body (which may be empty). */ 1261bf215546Sopenharmony_ci unsigned is_defined:1; 1262bf215546Sopenharmony_ci 1263bf215546Sopenharmony_ci /* 1264bf215546Sopenharmony_ci * Precision qualifier for the return type. 1265bf215546Sopenharmony_ci * 1266bf215546Sopenharmony_ci * See the comment for ir_variable_data::precision for more details. 1267bf215546Sopenharmony_ci */ 1268bf215546Sopenharmony_ci unsigned return_precision:2; 1269bf215546Sopenharmony_ci 1270bf215546Sopenharmony_ci /** Whether or not this function signature is a built-in. */ 1271bf215546Sopenharmony_ci bool is_builtin() const; 1272bf215546Sopenharmony_ci 1273bf215546Sopenharmony_ci /** 1274bf215546Sopenharmony_ci * Whether or not this function is an intrinsic to be implemented 1275bf215546Sopenharmony_ci * by the driver. 1276bf215546Sopenharmony_ci */ 1277bf215546Sopenharmony_ci inline bool is_intrinsic() const 1278bf215546Sopenharmony_ci { 1279bf215546Sopenharmony_ci return intrinsic_id != ir_intrinsic_invalid; 1280bf215546Sopenharmony_ci } 1281bf215546Sopenharmony_ci 1282bf215546Sopenharmony_ci /** Identifier for this intrinsic. */ 1283bf215546Sopenharmony_ci enum ir_intrinsic_id intrinsic_id; 1284bf215546Sopenharmony_ci 1285bf215546Sopenharmony_ci /** Whether or not a built-in is available for this shader. */ 1286bf215546Sopenharmony_ci bool is_builtin_available(const _mesa_glsl_parse_state *state) const; 1287bf215546Sopenharmony_ci 1288bf215546Sopenharmony_ci /** Body of instructions in the function. */ 1289bf215546Sopenharmony_ci struct exec_list body; 1290bf215546Sopenharmony_ci 1291bf215546Sopenharmony_ciprivate: 1292bf215546Sopenharmony_ci /** 1293bf215546Sopenharmony_ci * A function pointer to a predicate that answers whether a built-in 1294bf215546Sopenharmony_ci * function is available in the current shader. NULL if not a built-in. 1295bf215546Sopenharmony_ci */ 1296bf215546Sopenharmony_ci builtin_available_predicate builtin_avail; 1297bf215546Sopenharmony_ci 1298bf215546Sopenharmony_ci /** Function of which this signature is one overload. */ 1299bf215546Sopenharmony_ci class ir_function *_function; 1300bf215546Sopenharmony_ci 1301bf215546Sopenharmony_ci /** Function signature of which this one is a prototype clone */ 1302bf215546Sopenharmony_ci const ir_function_signature *origin; 1303bf215546Sopenharmony_ci 1304bf215546Sopenharmony_ci friend class ir_function; 1305bf215546Sopenharmony_ci 1306bf215546Sopenharmony_ci /** 1307bf215546Sopenharmony_ci * Helper function to run a list of instructions for constant 1308bf215546Sopenharmony_ci * expression evaluation. 1309bf215546Sopenharmony_ci * 1310bf215546Sopenharmony_ci * The hash table represents the values of the visible variables. 1311bf215546Sopenharmony_ci * There are no scoping issues because the table is indexed on 1312bf215546Sopenharmony_ci * ir_variable pointers, not variable names. 1313bf215546Sopenharmony_ci * 1314bf215546Sopenharmony_ci * Returns false if the expression is not constant, true otherwise, 1315bf215546Sopenharmony_ci * and the value in *result if result is non-NULL. 1316bf215546Sopenharmony_ci */ 1317bf215546Sopenharmony_ci bool constant_expression_evaluate_expression_list(void *mem_ctx, 1318bf215546Sopenharmony_ci const struct exec_list &body, 1319bf215546Sopenharmony_ci struct hash_table *variable_context, 1320bf215546Sopenharmony_ci ir_constant **result); 1321bf215546Sopenharmony_ci}; 1322bf215546Sopenharmony_ci 1323bf215546Sopenharmony_ci 1324bf215546Sopenharmony_ci/** 1325bf215546Sopenharmony_ci * Header for tracking multiple overloaded functions with the same name. 1326bf215546Sopenharmony_ci * Contains a list of ir_function_signatures representing each of the 1327bf215546Sopenharmony_ci * actual functions. 1328bf215546Sopenharmony_ci */ 1329bf215546Sopenharmony_ciclass ir_function : public ir_instruction { 1330bf215546Sopenharmony_cipublic: 1331bf215546Sopenharmony_ci ir_function(const char *name); 1332bf215546Sopenharmony_ci 1333bf215546Sopenharmony_ci virtual ir_function *clone(void *mem_ctx, struct hash_table *ht) const; 1334bf215546Sopenharmony_ci 1335bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 1336bf215546Sopenharmony_ci { 1337bf215546Sopenharmony_ci v->visit(this); 1338bf215546Sopenharmony_ci } 1339bf215546Sopenharmony_ci 1340bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 1341bf215546Sopenharmony_ci 1342bf215546Sopenharmony_ci void add_signature(ir_function_signature *sig) 1343bf215546Sopenharmony_ci { 1344bf215546Sopenharmony_ci sig->_function = this; 1345bf215546Sopenharmony_ci this->signatures.push_tail(sig); 1346bf215546Sopenharmony_ci } 1347bf215546Sopenharmony_ci 1348bf215546Sopenharmony_ci /** 1349bf215546Sopenharmony_ci * Find a signature that matches a set of actual parameters, taking implicit 1350bf215546Sopenharmony_ci * conversions into account. Also flags whether the match was exact. 1351bf215546Sopenharmony_ci */ 1352bf215546Sopenharmony_ci ir_function_signature *matching_signature(_mesa_glsl_parse_state *state, 1353bf215546Sopenharmony_ci const exec_list *actual_param, 1354bf215546Sopenharmony_ci bool allow_builtins, 1355bf215546Sopenharmony_ci bool *match_is_exact); 1356bf215546Sopenharmony_ci 1357bf215546Sopenharmony_ci /** 1358bf215546Sopenharmony_ci * Find a signature that matches a set of actual parameters, taking implicit 1359bf215546Sopenharmony_ci * conversions into account. 1360bf215546Sopenharmony_ci */ 1361bf215546Sopenharmony_ci ir_function_signature *matching_signature(_mesa_glsl_parse_state *state, 1362bf215546Sopenharmony_ci const exec_list *actual_param, 1363bf215546Sopenharmony_ci bool allow_builtins); 1364bf215546Sopenharmony_ci 1365bf215546Sopenharmony_ci /** 1366bf215546Sopenharmony_ci * Find a signature that exactly matches a set of actual parameters without 1367bf215546Sopenharmony_ci * any implicit type conversions. 1368bf215546Sopenharmony_ci */ 1369bf215546Sopenharmony_ci ir_function_signature *exact_matching_signature(_mesa_glsl_parse_state *state, 1370bf215546Sopenharmony_ci const exec_list *actual_ps); 1371bf215546Sopenharmony_ci 1372bf215546Sopenharmony_ci /** 1373bf215546Sopenharmony_ci * Name of the function. 1374bf215546Sopenharmony_ci */ 1375bf215546Sopenharmony_ci const char *name; 1376bf215546Sopenharmony_ci 1377bf215546Sopenharmony_ci /** Whether or not this function has a signature that isn't a built-in. */ 1378bf215546Sopenharmony_ci bool has_user_signature(); 1379bf215546Sopenharmony_ci 1380bf215546Sopenharmony_ci /** 1381bf215546Sopenharmony_ci * List of ir_function_signature for each overloaded function with this name. 1382bf215546Sopenharmony_ci */ 1383bf215546Sopenharmony_ci struct exec_list signatures; 1384bf215546Sopenharmony_ci 1385bf215546Sopenharmony_ci /** 1386bf215546Sopenharmony_ci * is this function a subroutine type declaration 1387bf215546Sopenharmony_ci * e.g. subroutine void type1(float arg1); 1388bf215546Sopenharmony_ci */ 1389bf215546Sopenharmony_ci bool is_subroutine; 1390bf215546Sopenharmony_ci 1391bf215546Sopenharmony_ci /** 1392bf215546Sopenharmony_ci * is this function associated to a subroutine type 1393bf215546Sopenharmony_ci * e.g. subroutine (type1, type2) function_name { function_body }; 1394bf215546Sopenharmony_ci * would have num_subroutine_types 2, 1395bf215546Sopenharmony_ci * and pointers to the type1 and type2 types. 1396bf215546Sopenharmony_ci */ 1397bf215546Sopenharmony_ci int num_subroutine_types; 1398bf215546Sopenharmony_ci const struct glsl_type **subroutine_types; 1399bf215546Sopenharmony_ci 1400bf215546Sopenharmony_ci int subroutine_index; 1401bf215546Sopenharmony_ci}; 1402bf215546Sopenharmony_ci 1403bf215546Sopenharmony_ciinline const char *ir_function_signature::function_name() const 1404bf215546Sopenharmony_ci{ 1405bf215546Sopenharmony_ci return this->_function->name; 1406bf215546Sopenharmony_ci} 1407bf215546Sopenharmony_ci/*@}*/ 1408bf215546Sopenharmony_ci 1409bf215546Sopenharmony_ci 1410bf215546Sopenharmony_ci/** 1411bf215546Sopenharmony_ci * IR instruction representing high-level if-statements 1412bf215546Sopenharmony_ci */ 1413bf215546Sopenharmony_ciclass ir_if : public ir_instruction { 1414bf215546Sopenharmony_cipublic: 1415bf215546Sopenharmony_ci ir_if(ir_rvalue *condition) 1416bf215546Sopenharmony_ci : ir_instruction(ir_type_if), condition(condition) 1417bf215546Sopenharmony_ci { 1418bf215546Sopenharmony_ci } 1419bf215546Sopenharmony_ci 1420bf215546Sopenharmony_ci virtual ir_if *clone(void *mem_ctx, struct hash_table *ht) const; 1421bf215546Sopenharmony_ci 1422bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 1423bf215546Sopenharmony_ci { 1424bf215546Sopenharmony_ci v->visit(this); 1425bf215546Sopenharmony_ci } 1426bf215546Sopenharmony_ci 1427bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 1428bf215546Sopenharmony_ci 1429bf215546Sopenharmony_ci ir_rvalue *condition; 1430bf215546Sopenharmony_ci /** List of ir_instruction for the body of the then branch */ 1431bf215546Sopenharmony_ci exec_list then_instructions; 1432bf215546Sopenharmony_ci /** List of ir_instruction for the body of the else branch */ 1433bf215546Sopenharmony_ci exec_list else_instructions; 1434bf215546Sopenharmony_ci}; 1435bf215546Sopenharmony_ci 1436bf215546Sopenharmony_ci 1437bf215546Sopenharmony_ci/** 1438bf215546Sopenharmony_ci * IR instruction representing a high-level loop structure. 1439bf215546Sopenharmony_ci */ 1440bf215546Sopenharmony_ciclass ir_loop : public ir_instruction { 1441bf215546Sopenharmony_cipublic: 1442bf215546Sopenharmony_ci ir_loop(); 1443bf215546Sopenharmony_ci 1444bf215546Sopenharmony_ci virtual ir_loop *clone(void *mem_ctx, struct hash_table *ht) const; 1445bf215546Sopenharmony_ci 1446bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 1447bf215546Sopenharmony_ci { 1448bf215546Sopenharmony_ci v->visit(this); 1449bf215546Sopenharmony_ci } 1450bf215546Sopenharmony_ci 1451bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 1452bf215546Sopenharmony_ci 1453bf215546Sopenharmony_ci /** List of ir_instruction that make up the body of the loop. */ 1454bf215546Sopenharmony_ci exec_list body_instructions; 1455bf215546Sopenharmony_ci}; 1456bf215546Sopenharmony_ci 1457bf215546Sopenharmony_ci 1458bf215546Sopenharmony_ciclass ir_assignment : public ir_instruction { 1459bf215546Sopenharmony_cipublic: 1460bf215546Sopenharmony_ci ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs); 1461bf215546Sopenharmony_ci 1462bf215546Sopenharmony_ci /** 1463bf215546Sopenharmony_ci * Construct an assignment with an explicit write mask 1464bf215546Sopenharmony_ci * 1465bf215546Sopenharmony_ci * \note 1466bf215546Sopenharmony_ci * Since a write mask is supplied, the LHS must already be a bare 1467bf215546Sopenharmony_ci * \c ir_dereference. The cannot be any swizzles in the LHS. 1468bf215546Sopenharmony_ci */ 1469bf215546Sopenharmony_ci ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, unsigned write_mask); 1470bf215546Sopenharmony_ci 1471bf215546Sopenharmony_ci virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const; 1472bf215546Sopenharmony_ci 1473bf215546Sopenharmony_ci virtual ir_constant *constant_expression_value(void *mem_ctx, 1474bf215546Sopenharmony_ci struct hash_table *variable_context = NULL); 1475bf215546Sopenharmony_ci 1476bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 1477bf215546Sopenharmony_ci { 1478bf215546Sopenharmony_ci v->visit(this); 1479bf215546Sopenharmony_ci } 1480bf215546Sopenharmony_ci 1481bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 1482bf215546Sopenharmony_ci 1483bf215546Sopenharmony_ci /** 1484bf215546Sopenharmony_ci * Get a whole variable written by an assignment 1485bf215546Sopenharmony_ci * 1486bf215546Sopenharmony_ci * If the LHS of the assignment writes a whole variable, the variable is 1487bf215546Sopenharmony_ci * returned. Otherwise \c NULL is returned. Examples of whole-variable 1488bf215546Sopenharmony_ci * assignment are: 1489bf215546Sopenharmony_ci * 1490bf215546Sopenharmony_ci * - Assigning to a scalar 1491bf215546Sopenharmony_ci * - Assigning to all components of a vector 1492bf215546Sopenharmony_ci * - Whole array (or matrix) assignment 1493bf215546Sopenharmony_ci * - Whole structure assignment 1494bf215546Sopenharmony_ci */ 1495bf215546Sopenharmony_ci ir_variable *whole_variable_written(); 1496bf215546Sopenharmony_ci 1497bf215546Sopenharmony_ci /** 1498bf215546Sopenharmony_ci * Set the LHS of an assignment 1499bf215546Sopenharmony_ci */ 1500bf215546Sopenharmony_ci void set_lhs(ir_rvalue *lhs); 1501bf215546Sopenharmony_ci 1502bf215546Sopenharmony_ci /** 1503bf215546Sopenharmony_ci * Left-hand side of the assignment. 1504bf215546Sopenharmony_ci * 1505bf215546Sopenharmony_ci * This should be treated as read only. If you need to set the LHS of an 1506bf215546Sopenharmony_ci * assignment, use \c ir_assignment::set_lhs. 1507bf215546Sopenharmony_ci */ 1508bf215546Sopenharmony_ci ir_dereference *lhs; 1509bf215546Sopenharmony_ci 1510bf215546Sopenharmony_ci /** 1511bf215546Sopenharmony_ci * Value being assigned 1512bf215546Sopenharmony_ci */ 1513bf215546Sopenharmony_ci ir_rvalue *rhs; 1514bf215546Sopenharmony_ci 1515bf215546Sopenharmony_ci /** 1516bf215546Sopenharmony_ci * Component mask written 1517bf215546Sopenharmony_ci * 1518bf215546Sopenharmony_ci * For non-vector types in the LHS, this field will be zero. For vector 1519bf215546Sopenharmony_ci * types, a bit will be set for each component that is written. Note that 1520bf215546Sopenharmony_ci * for \c vec2 and \c vec3 types only the lower bits will ever be set. 1521bf215546Sopenharmony_ci * 1522bf215546Sopenharmony_ci * A partially-set write mask means that each enabled channel gets 1523bf215546Sopenharmony_ci * the value from a consecutive channel of the rhs. For example, 1524bf215546Sopenharmony_ci * to write just .xyw of gl_FrontColor with color: 1525bf215546Sopenharmony_ci * 1526bf215546Sopenharmony_ci * (assign (constant bool (1)) (xyw) 1527bf215546Sopenharmony_ci * (var_ref gl_FragColor) 1528bf215546Sopenharmony_ci * (swiz xyw (var_ref color))) 1529bf215546Sopenharmony_ci */ 1530bf215546Sopenharmony_ci unsigned write_mask:4; 1531bf215546Sopenharmony_ci}; 1532bf215546Sopenharmony_ci 1533bf215546Sopenharmony_ci#include "ir_expression_operation.h" 1534bf215546Sopenharmony_ci 1535bf215546Sopenharmony_ciextern const char *const ir_expression_operation_strings[ir_last_opcode + 1]; 1536bf215546Sopenharmony_ciextern const char *const ir_expression_operation_enum_strings[ir_last_opcode + 1]; 1537bf215546Sopenharmony_ci 1538bf215546Sopenharmony_ciclass ir_expression : public ir_rvalue { 1539bf215546Sopenharmony_cipublic: 1540bf215546Sopenharmony_ci ir_expression(int op, const struct glsl_type *type, 1541bf215546Sopenharmony_ci ir_rvalue *op0, ir_rvalue *op1 = NULL, 1542bf215546Sopenharmony_ci ir_rvalue *op2 = NULL, ir_rvalue *op3 = NULL); 1543bf215546Sopenharmony_ci 1544bf215546Sopenharmony_ci /** 1545bf215546Sopenharmony_ci * Constructor for unary operation expressions 1546bf215546Sopenharmony_ci */ 1547bf215546Sopenharmony_ci ir_expression(int op, ir_rvalue *); 1548bf215546Sopenharmony_ci 1549bf215546Sopenharmony_ci /** 1550bf215546Sopenharmony_ci * Constructor for binary operation expressions 1551bf215546Sopenharmony_ci */ 1552bf215546Sopenharmony_ci ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1); 1553bf215546Sopenharmony_ci 1554bf215546Sopenharmony_ci /** 1555bf215546Sopenharmony_ci * Constructor for ternary operation expressions 1556bf215546Sopenharmony_ci */ 1557bf215546Sopenharmony_ci ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2); 1558bf215546Sopenharmony_ci 1559bf215546Sopenharmony_ci virtual bool equals(const ir_instruction *ir, 1560bf215546Sopenharmony_ci enum ir_node_type ignore = ir_type_unset) const; 1561bf215546Sopenharmony_ci 1562bf215546Sopenharmony_ci virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const; 1563bf215546Sopenharmony_ci 1564bf215546Sopenharmony_ci /** 1565bf215546Sopenharmony_ci * Attempt to constant-fold the expression 1566bf215546Sopenharmony_ci * 1567bf215546Sopenharmony_ci * The "variable_context" hash table links ir_variable * to ir_constant * 1568bf215546Sopenharmony_ci * that represent the variables' values. \c NULL represents an empty 1569bf215546Sopenharmony_ci * context. 1570bf215546Sopenharmony_ci * 1571bf215546Sopenharmony_ci * If the expression cannot be constant folded, this method will return 1572bf215546Sopenharmony_ci * \c NULL. 1573bf215546Sopenharmony_ci */ 1574bf215546Sopenharmony_ci virtual ir_constant *constant_expression_value(void *mem_ctx, 1575bf215546Sopenharmony_ci struct hash_table *variable_context = NULL); 1576bf215546Sopenharmony_ci 1577bf215546Sopenharmony_ci /** 1578bf215546Sopenharmony_ci * This is only here for ir_reader to used for testing purposes please use 1579bf215546Sopenharmony_ci * the precomputed num_operands field if you need the number of operands. 1580bf215546Sopenharmony_ci */ 1581bf215546Sopenharmony_ci static unsigned get_num_operands(ir_expression_operation); 1582bf215546Sopenharmony_ci 1583bf215546Sopenharmony_ci /** 1584bf215546Sopenharmony_ci * Return whether the expression operates on vectors horizontally. 1585bf215546Sopenharmony_ci */ 1586bf215546Sopenharmony_ci bool is_horizontal() const 1587bf215546Sopenharmony_ci { 1588bf215546Sopenharmony_ci return operation == ir_binop_all_equal || 1589bf215546Sopenharmony_ci operation == ir_binop_any_nequal || 1590bf215546Sopenharmony_ci operation == ir_binop_dot || 1591bf215546Sopenharmony_ci operation == ir_binop_vector_extract || 1592bf215546Sopenharmony_ci operation == ir_triop_vector_insert || 1593bf215546Sopenharmony_ci operation == ir_binop_ubo_load || 1594bf215546Sopenharmony_ci operation == ir_quadop_vector; 1595bf215546Sopenharmony_ci } 1596bf215546Sopenharmony_ci 1597bf215546Sopenharmony_ci /** 1598bf215546Sopenharmony_ci * Do a reverse-lookup to translate the given string into an operator. 1599bf215546Sopenharmony_ci */ 1600bf215546Sopenharmony_ci static ir_expression_operation get_operator(const char *); 1601bf215546Sopenharmony_ci 1602bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 1603bf215546Sopenharmony_ci { 1604bf215546Sopenharmony_ci v->visit(this); 1605bf215546Sopenharmony_ci } 1606bf215546Sopenharmony_ci 1607bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 1608bf215546Sopenharmony_ci 1609bf215546Sopenharmony_ci virtual ir_variable *variable_referenced() const; 1610bf215546Sopenharmony_ci 1611bf215546Sopenharmony_ci /** 1612bf215546Sopenharmony_ci * Determine the number of operands used by an expression 1613bf215546Sopenharmony_ci */ 1614bf215546Sopenharmony_ci void init_num_operands() 1615bf215546Sopenharmony_ci { 1616bf215546Sopenharmony_ci if (operation == ir_quadop_vector) { 1617bf215546Sopenharmony_ci num_operands = this->type->vector_elements; 1618bf215546Sopenharmony_ci } else { 1619bf215546Sopenharmony_ci num_operands = get_num_operands(operation); 1620bf215546Sopenharmony_ci } 1621bf215546Sopenharmony_ci } 1622bf215546Sopenharmony_ci 1623bf215546Sopenharmony_ci ir_expression_operation operation; 1624bf215546Sopenharmony_ci ir_rvalue *operands[4]; 1625bf215546Sopenharmony_ci uint8_t num_operands; 1626bf215546Sopenharmony_ci}; 1627bf215546Sopenharmony_ci 1628bf215546Sopenharmony_ci 1629bf215546Sopenharmony_ci/** 1630bf215546Sopenharmony_ci * HIR instruction representing a high-level function call, containing a list 1631bf215546Sopenharmony_ci * of parameters and returning a value in the supplied temporary. 1632bf215546Sopenharmony_ci */ 1633bf215546Sopenharmony_ciclass ir_call : public ir_instruction { 1634bf215546Sopenharmony_cipublic: 1635bf215546Sopenharmony_ci ir_call(ir_function_signature *callee, 1636bf215546Sopenharmony_ci ir_dereference_variable *return_deref, 1637bf215546Sopenharmony_ci exec_list *actual_parameters) 1638bf215546Sopenharmony_ci : ir_instruction(ir_type_call), return_deref(return_deref), callee(callee), sub_var(NULL), array_idx(NULL) 1639bf215546Sopenharmony_ci { 1640bf215546Sopenharmony_ci assert(callee->return_type != NULL); 1641bf215546Sopenharmony_ci actual_parameters->move_nodes_to(& this->actual_parameters); 1642bf215546Sopenharmony_ci } 1643bf215546Sopenharmony_ci 1644bf215546Sopenharmony_ci ir_call(ir_function_signature *callee, 1645bf215546Sopenharmony_ci ir_dereference_variable *return_deref, 1646bf215546Sopenharmony_ci exec_list *actual_parameters, 1647bf215546Sopenharmony_ci ir_variable *var, ir_rvalue *array_idx) 1648bf215546Sopenharmony_ci : ir_instruction(ir_type_call), return_deref(return_deref), callee(callee), sub_var(var), array_idx(array_idx) 1649bf215546Sopenharmony_ci { 1650bf215546Sopenharmony_ci assert(callee->return_type != NULL); 1651bf215546Sopenharmony_ci actual_parameters->move_nodes_to(& this->actual_parameters); 1652bf215546Sopenharmony_ci } 1653bf215546Sopenharmony_ci 1654bf215546Sopenharmony_ci virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const; 1655bf215546Sopenharmony_ci 1656bf215546Sopenharmony_ci virtual ir_constant *constant_expression_value(void *mem_ctx, 1657bf215546Sopenharmony_ci struct hash_table *variable_context = NULL); 1658bf215546Sopenharmony_ci 1659bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 1660bf215546Sopenharmony_ci { 1661bf215546Sopenharmony_ci v->visit(this); 1662bf215546Sopenharmony_ci } 1663bf215546Sopenharmony_ci 1664bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 1665bf215546Sopenharmony_ci 1666bf215546Sopenharmony_ci /** 1667bf215546Sopenharmony_ci * Get the name of the function being called. 1668bf215546Sopenharmony_ci */ 1669bf215546Sopenharmony_ci const char *callee_name() const 1670bf215546Sopenharmony_ci { 1671bf215546Sopenharmony_ci return callee->function_name(); 1672bf215546Sopenharmony_ci } 1673bf215546Sopenharmony_ci 1674bf215546Sopenharmony_ci /** 1675bf215546Sopenharmony_ci * Generates an inline version of the function before @ir, 1676bf215546Sopenharmony_ci * storing the return value in return_deref. 1677bf215546Sopenharmony_ci */ 1678bf215546Sopenharmony_ci void generate_inline(ir_instruction *ir); 1679bf215546Sopenharmony_ci 1680bf215546Sopenharmony_ci /** 1681bf215546Sopenharmony_ci * Storage for the function's return value. 1682bf215546Sopenharmony_ci * This must be NULL if the return type is void. 1683bf215546Sopenharmony_ci */ 1684bf215546Sopenharmony_ci ir_dereference_variable *return_deref; 1685bf215546Sopenharmony_ci 1686bf215546Sopenharmony_ci /** 1687bf215546Sopenharmony_ci * The specific function signature being called. 1688bf215546Sopenharmony_ci */ 1689bf215546Sopenharmony_ci ir_function_signature *callee; 1690bf215546Sopenharmony_ci 1691bf215546Sopenharmony_ci /* List of ir_rvalue of paramaters passed in this call. */ 1692bf215546Sopenharmony_ci exec_list actual_parameters; 1693bf215546Sopenharmony_ci 1694bf215546Sopenharmony_ci /* 1695bf215546Sopenharmony_ci * ARB_shader_subroutine support - 1696bf215546Sopenharmony_ci * the subroutine uniform variable and array index 1697bf215546Sopenharmony_ci * rvalue to be used in the lowering pass later. 1698bf215546Sopenharmony_ci */ 1699bf215546Sopenharmony_ci ir_variable *sub_var; 1700bf215546Sopenharmony_ci ir_rvalue *array_idx; 1701bf215546Sopenharmony_ci}; 1702bf215546Sopenharmony_ci 1703bf215546Sopenharmony_ci 1704bf215546Sopenharmony_ci/** 1705bf215546Sopenharmony_ci * \name Jump-like IR instructions. 1706bf215546Sopenharmony_ci * 1707bf215546Sopenharmony_ci * These include \c break, \c continue, \c return, and \c discard. 1708bf215546Sopenharmony_ci */ 1709bf215546Sopenharmony_ci/*@{*/ 1710bf215546Sopenharmony_ciclass ir_jump : public ir_instruction { 1711bf215546Sopenharmony_ciprotected: 1712bf215546Sopenharmony_ci ir_jump(enum ir_node_type t) 1713bf215546Sopenharmony_ci : ir_instruction(t) 1714bf215546Sopenharmony_ci { 1715bf215546Sopenharmony_ci } 1716bf215546Sopenharmony_ci}; 1717bf215546Sopenharmony_ci 1718bf215546Sopenharmony_ciclass ir_return : public ir_jump { 1719bf215546Sopenharmony_cipublic: 1720bf215546Sopenharmony_ci ir_return() 1721bf215546Sopenharmony_ci : ir_jump(ir_type_return), value(NULL) 1722bf215546Sopenharmony_ci { 1723bf215546Sopenharmony_ci } 1724bf215546Sopenharmony_ci 1725bf215546Sopenharmony_ci ir_return(ir_rvalue *value) 1726bf215546Sopenharmony_ci : ir_jump(ir_type_return), value(value) 1727bf215546Sopenharmony_ci { 1728bf215546Sopenharmony_ci } 1729bf215546Sopenharmony_ci 1730bf215546Sopenharmony_ci virtual ir_return *clone(void *mem_ctx, struct hash_table *) const; 1731bf215546Sopenharmony_ci 1732bf215546Sopenharmony_ci ir_rvalue *get_value() const 1733bf215546Sopenharmony_ci { 1734bf215546Sopenharmony_ci return value; 1735bf215546Sopenharmony_ci } 1736bf215546Sopenharmony_ci 1737bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 1738bf215546Sopenharmony_ci { 1739bf215546Sopenharmony_ci v->visit(this); 1740bf215546Sopenharmony_ci } 1741bf215546Sopenharmony_ci 1742bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 1743bf215546Sopenharmony_ci 1744bf215546Sopenharmony_ci ir_rvalue *value; 1745bf215546Sopenharmony_ci}; 1746bf215546Sopenharmony_ci 1747bf215546Sopenharmony_ci 1748bf215546Sopenharmony_ci/** 1749bf215546Sopenharmony_ci * Jump instructions used inside loops 1750bf215546Sopenharmony_ci * 1751bf215546Sopenharmony_ci * These include \c break and \c continue. The \c break within a loop is 1752bf215546Sopenharmony_ci * different from the \c break within a switch-statement. 1753bf215546Sopenharmony_ci * 1754bf215546Sopenharmony_ci * \sa ir_switch_jump 1755bf215546Sopenharmony_ci */ 1756bf215546Sopenharmony_ciclass ir_loop_jump : public ir_jump { 1757bf215546Sopenharmony_cipublic: 1758bf215546Sopenharmony_ci enum jump_mode { 1759bf215546Sopenharmony_ci jump_break, 1760bf215546Sopenharmony_ci jump_continue 1761bf215546Sopenharmony_ci }; 1762bf215546Sopenharmony_ci 1763bf215546Sopenharmony_ci ir_loop_jump(jump_mode mode) 1764bf215546Sopenharmony_ci : ir_jump(ir_type_loop_jump) 1765bf215546Sopenharmony_ci { 1766bf215546Sopenharmony_ci this->mode = mode; 1767bf215546Sopenharmony_ci } 1768bf215546Sopenharmony_ci 1769bf215546Sopenharmony_ci virtual ir_loop_jump *clone(void *mem_ctx, struct hash_table *) const; 1770bf215546Sopenharmony_ci 1771bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 1772bf215546Sopenharmony_ci { 1773bf215546Sopenharmony_ci v->visit(this); 1774bf215546Sopenharmony_ci } 1775bf215546Sopenharmony_ci 1776bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 1777bf215546Sopenharmony_ci 1778bf215546Sopenharmony_ci bool is_break() const 1779bf215546Sopenharmony_ci { 1780bf215546Sopenharmony_ci return mode == jump_break; 1781bf215546Sopenharmony_ci } 1782bf215546Sopenharmony_ci 1783bf215546Sopenharmony_ci bool is_continue() const 1784bf215546Sopenharmony_ci { 1785bf215546Sopenharmony_ci return mode == jump_continue; 1786bf215546Sopenharmony_ci } 1787bf215546Sopenharmony_ci 1788bf215546Sopenharmony_ci /** Mode selector for the jump instruction. */ 1789bf215546Sopenharmony_ci enum jump_mode mode; 1790bf215546Sopenharmony_ci}; 1791bf215546Sopenharmony_ci 1792bf215546Sopenharmony_ci/** 1793bf215546Sopenharmony_ci * IR instruction representing discard statements. 1794bf215546Sopenharmony_ci */ 1795bf215546Sopenharmony_ciclass ir_discard : public ir_jump { 1796bf215546Sopenharmony_cipublic: 1797bf215546Sopenharmony_ci ir_discard() 1798bf215546Sopenharmony_ci : ir_jump(ir_type_discard) 1799bf215546Sopenharmony_ci { 1800bf215546Sopenharmony_ci this->condition = NULL; 1801bf215546Sopenharmony_ci } 1802bf215546Sopenharmony_ci 1803bf215546Sopenharmony_ci ir_discard(ir_rvalue *cond) 1804bf215546Sopenharmony_ci : ir_jump(ir_type_discard) 1805bf215546Sopenharmony_ci { 1806bf215546Sopenharmony_ci this->condition = cond; 1807bf215546Sopenharmony_ci } 1808bf215546Sopenharmony_ci 1809bf215546Sopenharmony_ci virtual ir_discard *clone(void *mem_ctx, struct hash_table *ht) const; 1810bf215546Sopenharmony_ci 1811bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 1812bf215546Sopenharmony_ci { 1813bf215546Sopenharmony_ci v->visit(this); 1814bf215546Sopenharmony_ci } 1815bf215546Sopenharmony_ci 1816bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 1817bf215546Sopenharmony_ci 1818bf215546Sopenharmony_ci ir_rvalue *condition; 1819bf215546Sopenharmony_ci}; 1820bf215546Sopenharmony_ci/*@}*/ 1821bf215546Sopenharmony_ci 1822bf215546Sopenharmony_ci 1823bf215546Sopenharmony_ci/** 1824bf215546Sopenharmony_ci * IR instruction representing demote statements from 1825bf215546Sopenharmony_ci * GL_EXT_demote_to_helper_invocation. 1826bf215546Sopenharmony_ci */ 1827bf215546Sopenharmony_ciclass ir_demote : public ir_instruction { 1828bf215546Sopenharmony_cipublic: 1829bf215546Sopenharmony_ci ir_demote() 1830bf215546Sopenharmony_ci : ir_instruction(ir_type_demote) 1831bf215546Sopenharmony_ci { 1832bf215546Sopenharmony_ci } 1833bf215546Sopenharmony_ci 1834bf215546Sopenharmony_ci virtual ir_demote *clone(void *mem_ctx, struct hash_table *ht) const; 1835bf215546Sopenharmony_ci 1836bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 1837bf215546Sopenharmony_ci { 1838bf215546Sopenharmony_ci v->visit(this); 1839bf215546Sopenharmony_ci } 1840bf215546Sopenharmony_ci 1841bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 1842bf215546Sopenharmony_ci}; 1843bf215546Sopenharmony_ci 1844bf215546Sopenharmony_ci 1845bf215546Sopenharmony_ci/** 1846bf215546Sopenharmony_ci * Texture sampling opcodes used in ir_texture 1847bf215546Sopenharmony_ci */ 1848bf215546Sopenharmony_cienum ir_texture_opcode { 1849bf215546Sopenharmony_ci ir_tex, /**< Regular texture look-up */ 1850bf215546Sopenharmony_ci ir_txb, /**< Texture look-up with LOD bias */ 1851bf215546Sopenharmony_ci ir_txl, /**< Texture look-up with explicit LOD */ 1852bf215546Sopenharmony_ci ir_txd, /**< Texture look-up with partial derivatives */ 1853bf215546Sopenharmony_ci ir_txf, /**< Texel fetch with explicit LOD */ 1854bf215546Sopenharmony_ci ir_txf_ms, /**< Multisample texture fetch */ 1855bf215546Sopenharmony_ci ir_txs, /**< Texture size */ 1856bf215546Sopenharmony_ci ir_lod, /**< Texture lod query */ 1857bf215546Sopenharmony_ci ir_tg4, /**< Texture gather */ 1858bf215546Sopenharmony_ci ir_query_levels, /**< Texture levels query */ 1859bf215546Sopenharmony_ci ir_texture_samples, /**< Texture samples query */ 1860bf215546Sopenharmony_ci ir_samples_identical, /**< Query whether all samples are definitely identical. */ 1861bf215546Sopenharmony_ci}; 1862bf215546Sopenharmony_ci 1863bf215546Sopenharmony_ci 1864bf215546Sopenharmony_ci/** 1865bf215546Sopenharmony_ci * IR instruction to sample a texture 1866bf215546Sopenharmony_ci * 1867bf215546Sopenharmony_ci * The specific form of the IR instruction depends on the \c mode value 1868bf215546Sopenharmony_ci * selected from \c ir_texture_opcodes. In the printed IR, these will 1869bf215546Sopenharmony_ci * appear as: 1870bf215546Sopenharmony_ci * 1871bf215546Sopenharmony_ci * Texel offset (0 or an expression) 1872bf215546Sopenharmony_ci * | Projection divisor 1873bf215546Sopenharmony_ci * | | Shadow comparator 1874bf215546Sopenharmony_ci * | | | Lod clamp 1875bf215546Sopenharmony_ci * | | | | 1876bf215546Sopenharmony_ci * v v v v 1877bf215546Sopenharmony_ci * (tex <type> <sampler> <coordinate> <sparse> 0 1 ( ) ( )) 1878bf215546Sopenharmony_ci * (txb <type> <sampler> <coordinate> <sparse> 0 1 ( ) ( ) <bias>) 1879bf215546Sopenharmony_ci * (txl <type> <sampler> <coordinate> <sparse> 0 1 ( ) <lod>) 1880bf215546Sopenharmony_ci * (txd <type> <sampler> <coordinate> <sparse> 0 1 ( ) ( ) (dPdx dPdy)) 1881bf215546Sopenharmony_ci * (txf <type> <sampler> <coordinate> <sparse> 0 <lod>) 1882bf215546Sopenharmony_ci * (txf_ms 1883bf215546Sopenharmony_ci * <type> <sampler> <coordinate> <sparse> <sample_index>) 1884bf215546Sopenharmony_ci * (txs <type> <sampler> <lod>) 1885bf215546Sopenharmony_ci * (lod <type> <sampler> <coordinate>) 1886bf215546Sopenharmony_ci * (tg4 <type> <sampler> <coordinate> <sparse> <offset> <component>) 1887bf215546Sopenharmony_ci * (query_levels <type> <sampler>) 1888bf215546Sopenharmony_ci * (samples_identical <sampler> <coordinate>) 1889bf215546Sopenharmony_ci */ 1890bf215546Sopenharmony_ciclass ir_texture : public ir_rvalue { 1891bf215546Sopenharmony_cipublic: 1892bf215546Sopenharmony_ci ir_texture(enum ir_texture_opcode op, bool sparse = false) 1893bf215546Sopenharmony_ci : ir_rvalue(ir_type_texture), 1894bf215546Sopenharmony_ci op(op), sampler(NULL), coordinate(NULL), projector(NULL), 1895bf215546Sopenharmony_ci shadow_comparator(NULL), offset(NULL), clamp(NULL), 1896bf215546Sopenharmony_ci is_sparse(sparse) 1897bf215546Sopenharmony_ci { 1898bf215546Sopenharmony_ci memset(&lod_info, 0, sizeof(lod_info)); 1899bf215546Sopenharmony_ci } 1900bf215546Sopenharmony_ci 1901bf215546Sopenharmony_ci virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const; 1902bf215546Sopenharmony_ci 1903bf215546Sopenharmony_ci virtual ir_constant *constant_expression_value(void *mem_ctx, 1904bf215546Sopenharmony_ci struct hash_table *variable_context = NULL); 1905bf215546Sopenharmony_ci 1906bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 1907bf215546Sopenharmony_ci { 1908bf215546Sopenharmony_ci v->visit(this); 1909bf215546Sopenharmony_ci } 1910bf215546Sopenharmony_ci 1911bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 1912bf215546Sopenharmony_ci 1913bf215546Sopenharmony_ci virtual bool equals(const ir_instruction *ir, 1914bf215546Sopenharmony_ci enum ir_node_type ignore = ir_type_unset) const; 1915bf215546Sopenharmony_ci 1916bf215546Sopenharmony_ci /** 1917bf215546Sopenharmony_ci * Return a string representing the ir_texture_opcode. 1918bf215546Sopenharmony_ci */ 1919bf215546Sopenharmony_ci const char *opcode_string(); 1920bf215546Sopenharmony_ci 1921bf215546Sopenharmony_ci /** Set the sampler and type. */ 1922bf215546Sopenharmony_ci void set_sampler(ir_dereference *sampler, const glsl_type *type); 1923bf215546Sopenharmony_ci 1924bf215546Sopenharmony_ci /** 1925bf215546Sopenharmony_ci * Do a reverse-lookup to translate a string into an ir_texture_opcode. 1926bf215546Sopenharmony_ci */ 1927bf215546Sopenharmony_ci static ir_texture_opcode get_opcode(const char *); 1928bf215546Sopenharmony_ci 1929bf215546Sopenharmony_ci enum ir_texture_opcode op; 1930bf215546Sopenharmony_ci 1931bf215546Sopenharmony_ci /** Sampler to use for the texture access. */ 1932bf215546Sopenharmony_ci ir_dereference *sampler; 1933bf215546Sopenharmony_ci 1934bf215546Sopenharmony_ci /** Texture coordinate to sample */ 1935bf215546Sopenharmony_ci ir_rvalue *coordinate; 1936bf215546Sopenharmony_ci 1937bf215546Sopenharmony_ci /** 1938bf215546Sopenharmony_ci * Value used for projective divide. 1939bf215546Sopenharmony_ci * 1940bf215546Sopenharmony_ci * If there is no projective divide (the common case), this will be 1941bf215546Sopenharmony_ci * \c NULL. Optimization passes should check for this to point to a constant 1942bf215546Sopenharmony_ci * of 1.0 and replace that with \c NULL. 1943bf215546Sopenharmony_ci */ 1944bf215546Sopenharmony_ci ir_rvalue *projector; 1945bf215546Sopenharmony_ci 1946bf215546Sopenharmony_ci /** 1947bf215546Sopenharmony_ci * Coordinate used for comparison on shadow look-ups. 1948bf215546Sopenharmony_ci * 1949bf215546Sopenharmony_ci * If there is no shadow comparison, this will be \c NULL. For the 1950bf215546Sopenharmony_ci * \c ir_txf opcode, this *must* be \c NULL. 1951bf215546Sopenharmony_ci */ 1952bf215546Sopenharmony_ci ir_rvalue *shadow_comparator; 1953bf215546Sopenharmony_ci 1954bf215546Sopenharmony_ci /** Texel offset. */ 1955bf215546Sopenharmony_ci ir_rvalue *offset; 1956bf215546Sopenharmony_ci 1957bf215546Sopenharmony_ci /** Lod clamp. */ 1958bf215546Sopenharmony_ci ir_rvalue *clamp; 1959bf215546Sopenharmony_ci 1960bf215546Sopenharmony_ci union { 1961bf215546Sopenharmony_ci ir_rvalue *lod; /**< Floating point LOD */ 1962bf215546Sopenharmony_ci ir_rvalue *bias; /**< Floating point LOD bias */ 1963bf215546Sopenharmony_ci ir_rvalue *sample_index; /**< MSAA sample index */ 1964bf215546Sopenharmony_ci ir_rvalue *component; /**< Gather component selector */ 1965bf215546Sopenharmony_ci struct { 1966bf215546Sopenharmony_ci ir_rvalue *dPdx; /**< Partial derivative of coordinate wrt X */ 1967bf215546Sopenharmony_ci ir_rvalue *dPdy; /**< Partial derivative of coordinate wrt Y */ 1968bf215546Sopenharmony_ci } grad; 1969bf215546Sopenharmony_ci } lod_info; 1970bf215546Sopenharmony_ci 1971bf215546Sopenharmony_ci /* Whether a sparse texture */ 1972bf215546Sopenharmony_ci bool is_sparse; 1973bf215546Sopenharmony_ci}; 1974bf215546Sopenharmony_ci 1975bf215546Sopenharmony_ci 1976bf215546Sopenharmony_cistruct ir_swizzle_mask { 1977bf215546Sopenharmony_ci unsigned x:2; 1978bf215546Sopenharmony_ci unsigned y:2; 1979bf215546Sopenharmony_ci unsigned z:2; 1980bf215546Sopenharmony_ci unsigned w:2; 1981bf215546Sopenharmony_ci 1982bf215546Sopenharmony_ci /** 1983bf215546Sopenharmony_ci * Number of components in the swizzle. 1984bf215546Sopenharmony_ci */ 1985bf215546Sopenharmony_ci unsigned num_components:3; 1986bf215546Sopenharmony_ci 1987bf215546Sopenharmony_ci /** 1988bf215546Sopenharmony_ci * Does the swizzle contain duplicate components? 1989bf215546Sopenharmony_ci * 1990bf215546Sopenharmony_ci * L-value swizzles cannot contain duplicate components. 1991bf215546Sopenharmony_ci */ 1992bf215546Sopenharmony_ci unsigned has_duplicates:1; 1993bf215546Sopenharmony_ci}; 1994bf215546Sopenharmony_ci 1995bf215546Sopenharmony_ci 1996bf215546Sopenharmony_ciclass ir_swizzle : public ir_rvalue { 1997bf215546Sopenharmony_cipublic: 1998bf215546Sopenharmony_ci ir_swizzle(ir_rvalue *, unsigned x, unsigned y, unsigned z, unsigned w, 1999bf215546Sopenharmony_ci unsigned count); 2000bf215546Sopenharmony_ci 2001bf215546Sopenharmony_ci ir_swizzle(ir_rvalue *val, const unsigned *components, unsigned count); 2002bf215546Sopenharmony_ci 2003bf215546Sopenharmony_ci ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask); 2004bf215546Sopenharmony_ci 2005bf215546Sopenharmony_ci virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const; 2006bf215546Sopenharmony_ci 2007bf215546Sopenharmony_ci virtual ir_constant *constant_expression_value(void *mem_ctx, 2008bf215546Sopenharmony_ci struct hash_table *variable_context = NULL); 2009bf215546Sopenharmony_ci 2010bf215546Sopenharmony_ci /** 2011bf215546Sopenharmony_ci * Construct an ir_swizzle from the textual representation. Can fail. 2012bf215546Sopenharmony_ci */ 2013bf215546Sopenharmony_ci static ir_swizzle *create(ir_rvalue *, const char *, unsigned vector_length); 2014bf215546Sopenharmony_ci 2015bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 2016bf215546Sopenharmony_ci { 2017bf215546Sopenharmony_ci v->visit(this); 2018bf215546Sopenharmony_ci } 2019bf215546Sopenharmony_ci 2020bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 2021bf215546Sopenharmony_ci 2022bf215546Sopenharmony_ci virtual bool equals(const ir_instruction *ir, 2023bf215546Sopenharmony_ci enum ir_node_type ignore = ir_type_unset) const; 2024bf215546Sopenharmony_ci 2025bf215546Sopenharmony_ci bool is_lvalue(const struct _mesa_glsl_parse_state *state) const 2026bf215546Sopenharmony_ci { 2027bf215546Sopenharmony_ci return val->is_lvalue(state) && !mask.has_duplicates; 2028bf215546Sopenharmony_ci } 2029bf215546Sopenharmony_ci 2030bf215546Sopenharmony_ci /** 2031bf215546Sopenharmony_ci * Get the variable that is ultimately referenced by an r-value 2032bf215546Sopenharmony_ci */ 2033bf215546Sopenharmony_ci virtual ir_variable *variable_referenced() const; 2034bf215546Sopenharmony_ci 2035bf215546Sopenharmony_ci ir_rvalue *val; 2036bf215546Sopenharmony_ci ir_swizzle_mask mask; 2037bf215546Sopenharmony_ci 2038bf215546Sopenharmony_ciprivate: 2039bf215546Sopenharmony_ci /** 2040bf215546Sopenharmony_ci * Initialize the mask component of a swizzle 2041bf215546Sopenharmony_ci * 2042bf215546Sopenharmony_ci * This is used by the \c ir_swizzle constructors. 2043bf215546Sopenharmony_ci */ 2044bf215546Sopenharmony_ci void init_mask(const unsigned *components, unsigned count); 2045bf215546Sopenharmony_ci}; 2046bf215546Sopenharmony_ci 2047bf215546Sopenharmony_ci 2048bf215546Sopenharmony_ciclass ir_dereference : public ir_rvalue { 2049bf215546Sopenharmony_cipublic: 2050bf215546Sopenharmony_ci virtual ir_dereference *clone(void *mem_ctx, struct hash_table *) const = 0; 2051bf215546Sopenharmony_ci 2052bf215546Sopenharmony_ci bool is_lvalue(const struct _mesa_glsl_parse_state *state) const; 2053bf215546Sopenharmony_ci 2054bf215546Sopenharmony_ci /** 2055bf215546Sopenharmony_ci * Get the variable that is ultimately referenced by an r-value 2056bf215546Sopenharmony_ci */ 2057bf215546Sopenharmony_ci virtual ir_variable *variable_referenced() const = 0; 2058bf215546Sopenharmony_ci 2059bf215546Sopenharmony_ci /** 2060bf215546Sopenharmony_ci * Get the precision. This can either come from the eventual variable that 2061bf215546Sopenharmony_ci * is dereferenced, or from a record member. 2062bf215546Sopenharmony_ci */ 2063bf215546Sopenharmony_ci virtual int precision() const = 0; 2064bf215546Sopenharmony_ci 2065bf215546Sopenharmony_ciprotected: 2066bf215546Sopenharmony_ci ir_dereference(enum ir_node_type t) 2067bf215546Sopenharmony_ci : ir_rvalue(t) 2068bf215546Sopenharmony_ci { 2069bf215546Sopenharmony_ci } 2070bf215546Sopenharmony_ci}; 2071bf215546Sopenharmony_ci 2072bf215546Sopenharmony_ci 2073bf215546Sopenharmony_ciclass ir_dereference_variable : public ir_dereference { 2074bf215546Sopenharmony_cipublic: 2075bf215546Sopenharmony_ci ir_dereference_variable(ir_variable *var); 2076bf215546Sopenharmony_ci 2077bf215546Sopenharmony_ci virtual ir_dereference_variable *clone(void *mem_ctx, 2078bf215546Sopenharmony_ci struct hash_table *) const; 2079bf215546Sopenharmony_ci 2080bf215546Sopenharmony_ci virtual ir_constant *constant_expression_value(void *mem_ctx, 2081bf215546Sopenharmony_ci struct hash_table *variable_context = NULL); 2082bf215546Sopenharmony_ci 2083bf215546Sopenharmony_ci virtual bool equals(const ir_instruction *ir, 2084bf215546Sopenharmony_ci enum ir_node_type ignore = ir_type_unset) const; 2085bf215546Sopenharmony_ci 2086bf215546Sopenharmony_ci /** 2087bf215546Sopenharmony_ci * Get the variable that is ultimately referenced by an r-value 2088bf215546Sopenharmony_ci */ 2089bf215546Sopenharmony_ci virtual ir_variable *variable_referenced() const 2090bf215546Sopenharmony_ci { 2091bf215546Sopenharmony_ci return this->var; 2092bf215546Sopenharmony_ci } 2093bf215546Sopenharmony_ci 2094bf215546Sopenharmony_ci virtual int precision() const 2095bf215546Sopenharmony_ci { 2096bf215546Sopenharmony_ci return this->var->data.precision; 2097bf215546Sopenharmony_ci } 2098bf215546Sopenharmony_ci 2099bf215546Sopenharmony_ci virtual ir_variable *whole_variable_referenced() 2100bf215546Sopenharmony_ci { 2101bf215546Sopenharmony_ci /* ir_dereference_variable objects always dereference the entire 2102bf215546Sopenharmony_ci * variable. However, if this dereference is dereferenced by anything 2103bf215546Sopenharmony_ci * else, the complete dereference chain is not a whole-variable 2104bf215546Sopenharmony_ci * dereference. This method should only be called on the top most 2105bf215546Sopenharmony_ci * ir_rvalue in a dereference chain. 2106bf215546Sopenharmony_ci */ 2107bf215546Sopenharmony_ci return this->var; 2108bf215546Sopenharmony_ci } 2109bf215546Sopenharmony_ci 2110bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 2111bf215546Sopenharmony_ci { 2112bf215546Sopenharmony_ci v->visit(this); 2113bf215546Sopenharmony_ci } 2114bf215546Sopenharmony_ci 2115bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 2116bf215546Sopenharmony_ci 2117bf215546Sopenharmony_ci /** 2118bf215546Sopenharmony_ci * Object being dereferenced. 2119bf215546Sopenharmony_ci */ 2120bf215546Sopenharmony_ci ir_variable *var; 2121bf215546Sopenharmony_ci}; 2122bf215546Sopenharmony_ci 2123bf215546Sopenharmony_ci 2124bf215546Sopenharmony_ciclass ir_dereference_array : public ir_dereference { 2125bf215546Sopenharmony_cipublic: 2126bf215546Sopenharmony_ci ir_dereference_array(ir_rvalue *value, ir_rvalue *array_index); 2127bf215546Sopenharmony_ci 2128bf215546Sopenharmony_ci ir_dereference_array(ir_variable *var, ir_rvalue *array_index); 2129bf215546Sopenharmony_ci 2130bf215546Sopenharmony_ci virtual ir_dereference_array *clone(void *mem_ctx, 2131bf215546Sopenharmony_ci struct hash_table *) const; 2132bf215546Sopenharmony_ci 2133bf215546Sopenharmony_ci virtual ir_constant *constant_expression_value(void *mem_ctx, 2134bf215546Sopenharmony_ci struct hash_table *variable_context = NULL); 2135bf215546Sopenharmony_ci 2136bf215546Sopenharmony_ci virtual bool equals(const ir_instruction *ir, 2137bf215546Sopenharmony_ci enum ir_node_type ignore = ir_type_unset) const; 2138bf215546Sopenharmony_ci 2139bf215546Sopenharmony_ci /** 2140bf215546Sopenharmony_ci * Get the variable that is ultimately referenced by an r-value 2141bf215546Sopenharmony_ci */ 2142bf215546Sopenharmony_ci virtual ir_variable *variable_referenced() const 2143bf215546Sopenharmony_ci { 2144bf215546Sopenharmony_ci return this->array->variable_referenced(); 2145bf215546Sopenharmony_ci } 2146bf215546Sopenharmony_ci 2147bf215546Sopenharmony_ci virtual int precision() const 2148bf215546Sopenharmony_ci { 2149bf215546Sopenharmony_ci ir_dereference *deref = this->array->as_dereference(); 2150bf215546Sopenharmony_ci 2151bf215546Sopenharmony_ci if (deref == NULL) 2152bf215546Sopenharmony_ci return GLSL_PRECISION_NONE; 2153bf215546Sopenharmony_ci else 2154bf215546Sopenharmony_ci return deref->precision(); 2155bf215546Sopenharmony_ci } 2156bf215546Sopenharmony_ci 2157bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 2158bf215546Sopenharmony_ci { 2159bf215546Sopenharmony_ci v->visit(this); 2160bf215546Sopenharmony_ci } 2161bf215546Sopenharmony_ci 2162bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 2163bf215546Sopenharmony_ci 2164bf215546Sopenharmony_ci ir_rvalue *array; 2165bf215546Sopenharmony_ci ir_rvalue *array_index; 2166bf215546Sopenharmony_ci 2167bf215546Sopenharmony_ciprivate: 2168bf215546Sopenharmony_ci void set_array(ir_rvalue *value); 2169bf215546Sopenharmony_ci}; 2170bf215546Sopenharmony_ci 2171bf215546Sopenharmony_ci 2172bf215546Sopenharmony_ciclass ir_dereference_record : public ir_dereference { 2173bf215546Sopenharmony_cipublic: 2174bf215546Sopenharmony_ci ir_dereference_record(ir_rvalue *value, const char *field); 2175bf215546Sopenharmony_ci 2176bf215546Sopenharmony_ci ir_dereference_record(ir_variable *var, const char *field); 2177bf215546Sopenharmony_ci 2178bf215546Sopenharmony_ci virtual ir_dereference_record *clone(void *mem_ctx, 2179bf215546Sopenharmony_ci struct hash_table *) const; 2180bf215546Sopenharmony_ci 2181bf215546Sopenharmony_ci virtual ir_constant *constant_expression_value(void *mem_ctx, 2182bf215546Sopenharmony_ci struct hash_table *variable_context = NULL); 2183bf215546Sopenharmony_ci 2184bf215546Sopenharmony_ci /** 2185bf215546Sopenharmony_ci * Get the variable that is ultimately referenced by an r-value 2186bf215546Sopenharmony_ci */ 2187bf215546Sopenharmony_ci virtual ir_variable *variable_referenced() const 2188bf215546Sopenharmony_ci { 2189bf215546Sopenharmony_ci return this->record->variable_referenced(); 2190bf215546Sopenharmony_ci } 2191bf215546Sopenharmony_ci 2192bf215546Sopenharmony_ci virtual int precision() const 2193bf215546Sopenharmony_ci { 2194bf215546Sopenharmony_ci glsl_struct_field *field = record->type->fields.structure + field_idx; 2195bf215546Sopenharmony_ci 2196bf215546Sopenharmony_ci return field->precision; 2197bf215546Sopenharmony_ci } 2198bf215546Sopenharmony_ci 2199bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 2200bf215546Sopenharmony_ci { 2201bf215546Sopenharmony_ci v->visit(this); 2202bf215546Sopenharmony_ci } 2203bf215546Sopenharmony_ci 2204bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 2205bf215546Sopenharmony_ci 2206bf215546Sopenharmony_ci ir_rvalue *record; 2207bf215546Sopenharmony_ci int field_idx; 2208bf215546Sopenharmony_ci}; 2209bf215546Sopenharmony_ci 2210bf215546Sopenharmony_ci 2211bf215546Sopenharmony_ci/** 2212bf215546Sopenharmony_ci * Data stored in an ir_constant 2213bf215546Sopenharmony_ci */ 2214bf215546Sopenharmony_ciunion ir_constant_data { 2215bf215546Sopenharmony_ci unsigned u[16]; 2216bf215546Sopenharmony_ci int i[16]; 2217bf215546Sopenharmony_ci float f[16]; 2218bf215546Sopenharmony_ci bool b[16]; 2219bf215546Sopenharmony_ci double d[16]; 2220bf215546Sopenharmony_ci uint16_t f16[16]; 2221bf215546Sopenharmony_ci uint16_t u16[16]; 2222bf215546Sopenharmony_ci int16_t i16[16]; 2223bf215546Sopenharmony_ci uint64_t u64[16]; 2224bf215546Sopenharmony_ci int64_t i64[16]; 2225bf215546Sopenharmony_ci}; 2226bf215546Sopenharmony_ci 2227bf215546Sopenharmony_ci 2228bf215546Sopenharmony_ciclass ir_constant : public ir_rvalue { 2229bf215546Sopenharmony_cipublic: 2230bf215546Sopenharmony_ci ir_constant(const struct glsl_type *type, const ir_constant_data *data); 2231bf215546Sopenharmony_ci ir_constant(bool b, unsigned vector_elements=1); 2232bf215546Sopenharmony_ci ir_constant(int16_t i16, unsigned vector_elements=1); 2233bf215546Sopenharmony_ci ir_constant(uint16_t u16, unsigned vector_elements=1); 2234bf215546Sopenharmony_ci ir_constant(unsigned int u, unsigned vector_elements=1); 2235bf215546Sopenharmony_ci ir_constant(int i, unsigned vector_elements=1); 2236bf215546Sopenharmony_ci ir_constant(float16_t f16, unsigned vector_elements=1); 2237bf215546Sopenharmony_ci ir_constant(float f, unsigned vector_elements=1); 2238bf215546Sopenharmony_ci ir_constant(double d, unsigned vector_elements=1); 2239bf215546Sopenharmony_ci ir_constant(uint64_t u64, unsigned vector_elements=1); 2240bf215546Sopenharmony_ci ir_constant(int64_t i64, unsigned vector_elements=1); 2241bf215546Sopenharmony_ci 2242bf215546Sopenharmony_ci /** 2243bf215546Sopenharmony_ci * Construct an ir_constant from a list of ir_constant values 2244bf215546Sopenharmony_ci */ 2245bf215546Sopenharmony_ci ir_constant(const struct glsl_type *type, exec_list *values); 2246bf215546Sopenharmony_ci 2247bf215546Sopenharmony_ci /** 2248bf215546Sopenharmony_ci * Construct an ir_constant from a scalar component of another ir_constant 2249bf215546Sopenharmony_ci * 2250bf215546Sopenharmony_ci * The new \c ir_constant inherits the type of the component from the 2251bf215546Sopenharmony_ci * source constant. 2252bf215546Sopenharmony_ci * 2253bf215546Sopenharmony_ci * \note 2254bf215546Sopenharmony_ci * In the case of a matrix constant, the new constant is a scalar, \b not 2255bf215546Sopenharmony_ci * a vector. 2256bf215546Sopenharmony_ci */ 2257bf215546Sopenharmony_ci ir_constant(const ir_constant *c, unsigned i); 2258bf215546Sopenharmony_ci 2259bf215546Sopenharmony_ci /** 2260bf215546Sopenharmony_ci * Return a new ir_constant of the specified type containing all zeros. 2261bf215546Sopenharmony_ci */ 2262bf215546Sopenharmony_ci static ir_constant *zero(void *mem_ctx, const glsl_type *type); 2263bf215546Sopenharmony_ci 2264bf215546Sopenharmony_ci virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const; 2265bf215546Sopenharmony_ci 2266bf215546Sopenharmony_ci virtual ir_constant *constant_expression_value(void *mem_ctx, 2267bf215546Sopenharmony_ci struct hash_table *variable_context = NULL); 2268bf215546Sopenharmony_ci 2269bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 2270bf215546Sopenharmony_ci { 2271bf215546Sopenharmony_ci v->visit(this); 2272bf215546Sopenharmony_ci } 2273bf215546Sopenharmony_ci 2274bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 2275bf215546Sopenharmony_ci 2276bf215546Sopenharmony_ci virtual bool equals(const ir_instruction *ir, 2277bf215546Sopenharmony_ci enum ir_node_type ignore = ir_type_unset) const; 2278bf215546Sopenharmony_ci 2279bf215546Sopenharmony_ci /** 2280bf215546Sopenharmony_ci * Get a particular component of a constant as a specific type 2281bf215546Sopenharmony_ci * 2282bf215546Sopenharmony_ci * This is useful, for example, to get a value from an integer constant 2283bf215546Sopenharmony_ci * as a float or bool. This appears frequently when constructors are 2284bf215546Sopenharmony_ci * called with all constant parameters. 2285bf215546Sopenharmony_ci */ 2286bf215546Sopenharmony_ci /*@{*/ 2287bf215546Sopenharmony_ci bool get_bool_component(unsigned i) const; 2288bf215546Sopenharmony_ci float get_float_component(unsigned i) const; 2289bf215546Sopenharmony_ci uint16_t get_float16_component(unsigned i) const; 2290bf215546Sopenharmony_ci double get_double_component(unsigned i) const; 2291bf215546Sopenharmony_ci int16_t get_int16_component(unsigned i) const; 2292bf215546Sopenharmony_ci uint16_t get_uint16_component(unsigned i) const; 2293bf215546Sopenharmony_ci int get_int_component(unsigned i) const; 2294bf215546Sopenharmony_ci unsigned get_uint_component(unsigned i) const; 2295bf215546Sopenharmony_ci int64_t get_int64_component(unsigned i) const; 2296bf215546Sopenharmony_ci uint64_t get_uint64_component(unsigned i) const; 2297bf215546Sopenharmony_ci /*@}*/ 2298bf215546Sopenharmony_ci 2299bf215546Sopenharmony_ci ir_constant *get_array_element(unsigned i) const; 2300bf215546Sopenharmony_ci 2301bf215546Sopenharmony_ci ir_constant *get_record_field(int idx); 2302bf215546Sopenharmony_ci 2303bf215546Sopenharmony_ci /** 2304bf215546Sopenharmony_ci * Copy the values on another constant at a given offset. 2305bf215546Sopenharmony_ci * 2306bf215546Sopenharmony_ci * The offset is ignored for array or struct copies, it's only for 2307bf215546Sopenharmony_ci * scalars or vectors into vectors or matrices. 2308bf215546Sopenharmony_ci * 2309bf215546Sopenharmony_ci * With identical types on both sides and zero offset it's clone() 2310bf215546Sopenharmony_ci * without creating a new object. 2311bf215546Sopenharmony_ci */ 2312bf215546Sopenharmony_ci 2313bf215546Sopenharmony_ci void copy_offset(ir_constant *src, int offset); 2314bf215546Sopenharmony_ci 2315bf215546Sopenharmony_ci /** 2316bf215546Sopenharmony_ci * Copy the values on another constant at a given offset and 2317bf215546Sopenharmony_ci * following an assign-like mask. 2318bf215546Sopenharmony_ci * 2319bf215546Sopenharmony_ci * The mask is ignored for scalars. 2320bf215546Sopenharmony_ci * 2321bf215546Sopenharmony_ci * Note that this function only handles what assign can handle, 2322bf215546Sopenharmony_ci * i.e. at most a vector as source and a column of a matrix as 2323bf215546Sopenharmony_ci * destination. 2324bf215546Sopenharmony_ci */ 2325bf215546Sopenharmony_ci 2326bf215546Sopenharmony_ci void copy_masked_offset(ir_constant *src, int offset, unsigned int mask); 2327bf215546Sopenharmony_ci 2328bf215546Sopenharmony_ci /** 2329bf215546Sopenharmony_ci * Determine whether a constant has the same value as another constant 2330bf215546Sopenharmony_ci * 2331bf215546Sopenharmony_ci * \sa ir_constant::is_zero, ir_constant::is_one, 2332bf215546Sopenharmony_ci * ir_constant::is_negative_one 2333bf215546Sopenharmony_ci */ 2334bf215546Sopenharmony_ci bool has_value(const ir_constant *) const; 2335bf215546Sopenharmony_ci 2336bf215546Sopenharmony_ci /** 2337bf215546Sopenharmony_ci * Return true if this ir_constant represents the given value. 2338bf215546Sopenharmony_ci * 2339bf215546Sopenharmony_ci * For vectors, this checks that each component is the given value. 2340bf215546Sopenharmony_ci */ 2341bf215546Sopenharmony_ci virtual bool is_value(float f, int i) const; 2342bf215546Sopenharmony_ci virtual bool is_zero() const; 2343bf215546Sopenharmony_ci virtual bool is_one() const; 2344bf215546Sopenharmony_ci virtual bool is_negative_one() const; 2345bf215546Sopenharmony_ci 2346bf215546Sopenharmony_ci /** 2347bf215546Sopenharmony_ci * Return true for constants that could be stored as 16-bit unsigned values. 2348bf215546Sopenharmony_ci * 2349bf215546Sopenharmony_ci * Note that this will return true even for signed integer ir_constants, as 2350bf215546Sopenharmony_ci * long as the value is non-negative and fits in 16-bits. 2351bf215546Sopenharmony_ci */ 2352bf215546Sopenharmony_ci virtual bool is_uint16_constant() const; 2353bf215546Sopenharmony_ci 2354bf215546Sopenharmony_ci /** 2355bf215546Sopenharmony_ci * Value of the constant. 2356bf215546Sopenharmony_ci * 2357bf215546Sopenharmony_ci * The field used to back the values supplied by the constant is determined 2358bf215546Sopenharmony_ci * by the type associated with the \c ir_instruction. Constants may be 2359bf215546Sopenharmony_ci * scalars, vectors, or matrices. 2360bf215546Sopenharmony_ci */ 2361bf215546Sopenharmony_ci union ir_constant_data value; 2362bf215546Sopenharmony_ci 2363bf215546Sopenharmony_ci /* Array elements and structure fields */ 2364bf215546Sopenharmony_ci ir_constant **const_elements; 2365bf215546Sopenharmony_ci 2366bf215546Sopenharmony_ciprivate: 2367bf215546Sopenharmony_ci /** 2368bf215546Sopenharmony_ci * Parameterless constructor only used by the clone method 2369bf215546Sopenharmony_ci */ 2370bf215546Sopenharmony_ci ir_constant(void); 2371bf215546Sopenharmony_ci}; 2372bf215546Sopenharmony_ci 2373bf215546Sopenharmony_ci/** 2374bf215546Sopenharmony_ci * IR instruction to emit a vertex in a geometry shader. 2375bf215546Sopenharmony_ci */ 2376bf215546Sopenharmony_ciclass ir_emit_vertex : public ir_instruction { 2377bf215546Sopenharmony_cipublic: 2378bf215546Sopenharmony_ci ir_emit_vertex(ir_rvalue *stream) 2379bf215546Sopenharmony_ci : ir_instruction(ir_type_emit_vertex), 2380bf215546Sopenharmony_ci stream(stream) 2381bf215546Sopenharmony_ci { 2382bf215546Sopenharmony_ci assert(stream); 2383bf215546Sopenharmony_ci } 2384bf215546Sopenharmony_ci 2385bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 2386bf215546Sopenharmony_ci { 2387bf215546Sopenharmony_ci v->visit(this); 2388bf215546Sopenharmony_ci } 2389bf215546Sopenharmony_ci 2390bf215546Sopenharmony_ci virtual ir_emit_vertex *clone(void *mem_ctx, struct hash_table *ht) const 2391bf215546Sopenharmony_ci { 2392bf215546Sopenharmony_ci return new(mem_ctx) ir_emit_vertex(this->stream->clone(mem_ctx, ht)); 2393bf215546Sopenharmony_ci } 2394bf215546Sopenharmony_ci 2395bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 2396bf215546Sopenharmony_ci 2397bf215546Sopenharmony_ci int stream_id() const 2398bf215546Sopenharmony_ci { 2399bf215546Sopenharmony_ci return stream->as_constant()->value.i[0]; 2400bf215546Sopenharmony_ci } 2401bf215546Sopenharmony_ci 2402bf215546Sopenharmony_ci ir_rvalue *stream; 2403bf215546Sopenharmony_ci}; 2404bf215546Sopenharmony_ci 2405bf215546Sopenharmony_ci/** 2406bf215546Sopenharmony_ci * IR instruction to complete the current primitive and start a new one in a 2407bf215546Sopenharmony_ci * geometry shader. 2408bf215546Sopenharmony_ci */ 2409bf215546Sopenharmony_ciclass ir_end_primitive : public ir_instruction { 2410bf215546Sopenharmony_cipublic: 2411bf215546Sopenharmony_ci ir_end_primitive(ir_rvalue *stream) 2412bf215546Sopenharmony_ci : ir_instruction(ir_type_end_primitive), 2413bf215546Sopenharmony_ci stream(stream) 2414bf215546Sopenharmony_ci { 2415bf215546Sopenharmony_ci assert(stream); 2416bf215546Sopenharmony_ci } 2417bf215546Sopenharmony_ci 2418bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 2419bf215546Sopenharmony_ci { 2420bf215546Sopenharmony_ci v->visit(this); 2421bf215546Sopenharmony_ci } 2422bf215546Sopenharmony_ci 2423bf215546Sopenharmony_ci virtual ir_end_primitive *clone(void *mem_ctx, struct hash_table *ht) const 2424bf215546Sopenharmony_ci { 2425bf215546Sopenharmony_ci return new(mem_ctx) ir_end_primitive(this->stream->clone(mem_ctx, ht)); 2426bf215546Sopenharmony_ci } 2427bf215546Sopenharmony_ci 2428bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 2429bf215546Sopenharmony_ci 2430bf215546Sopenharmony_ci int stream_id() const 2431bf215546Sopenharmony_ci { 2432bf215546Sopenharmony_ci return stream->as_constant()->value.i[0]; 2433bf215546Sopenharmony_ci } 2434bf215546Sopenharmony_ci 2435bf215546Sopenharmony_ci ir_rvalue *stream; 2436bf215546Sopenharmony_ci}; 2437bf215546Sopenharmony_ci 2438bf215546Sopenharmony_ci/** 2439bf215546Sopenharmony_ci * IR instruction for tessellation control and compute shader barrier. 2440bf215546Sopenharmony_ci */ 2441bf215546Sopenharmony_ciclass ir_barrier : public ir_instruction { 2442bf215546Sopenharmony_cipublic: 2443bf215546Sopenharmony_ci ir_barrier() 2444bf215546Sopenharmony_ci : ir_instruction(ir_type_barrier) 2445bf215546Sopenharmony_ci { 2446bf215546Sopenharmony_ci } 2447bf215546Sopenharmony_ci 2448bf215546Sopenharmony_ci virtual void accept(ir_visitor *v) 2449bf215546Sopenharmony_ci { 2450bf215546Sopenharmony_ci v->visit(this); 2451bf215546Sopenharmony_ci } 2452bf215546Sopenharmony_ci 2453bf215546Sopenharmony_ci virtual ir_barrier *clone(void *mem_ctx, struct hash_table *) const 2454bf215546Sopenharmony_ci { 2455bf215546Sopenharmony_ci return new(mem_ctx) ir_barrier(); 2456bf215546Sopenharmony_ci } 2457bf215546Sopenharmony_ci 2458bf215546Sopenharmony_ci virtual ir_visitor_status accept(ir_hierarchical_visitor *); 2459bf215546Sopenharmony_ci}; 2460bf215546Sopenharmony_ci 2461bf215546Sopenharmony_ci/*@}*/ 2462bf215546Sopenharmony_ci 2463bf215546Sopenharmony_ci/** 2464bf215546Sopenharmony_ci * Apply a visitor to each IR node in a list 2465bf215546Sopenharmony_ci */ 2466bf215546Sopenharmony_civoid 2467bf215546Sopenharmony_civisit_exec_list(exec_list *list, ir_visitor *visitor); 2468bf215546Sopenharmony_ci 2469bf215546Sopenharmony_ci/** 2470bf215546Sopenharmony_ci * Validate invariants on each IR node in a list 2471bf215546Sopenharmony_ci */ 2472bf215546Sopenharmony_civoid validate_ir_tree(exec_list *instructions); 2473bf215546Sopenharmony_ci 2474bf215546Sopenharmony_cistruct _mesa_glsl_parse_state; 2475bf215546Sopenharmony_cistruct gl_shader_program; 2476bf215546Sopenharmony_ci 2477bf215546Sopenharmony_ci/** 2478bf215546Sopenharmony_ci * Detect whether an unlinked shader contains static recursion 2479bf215546Sopenharmony_ci * 2480bf215546Sopenharmony_ci * If the list of instructions is determined to contain static recursion, 2481bf215546Sopenharmony_ci * \c _mesa_glsl_error will be called to emit error messages for each function 2482bf215546Sopenharmony_ci * that is in the recursion cycle. 2483bf215546Sopenharmony_ci */ 2484bf215546Sopenharmony_civoid 2485bf215546Sopenharmony_cidetect_recursion_unlinked(struct _mesa_glsl_parse_state *state, 2486bf215546Sopenharmony_ci exec_list *instructions); 2487bf215546Sopenharmony_ci 2488bf215546Sopenharmony_ci/** 2489bf215546Sopenharmony_ci * Detect whether a linked shader contains static recursion 2490bf215546Sopenharmony_ci * 2491bf215546Sopenharmony_ci * If the list of instructions is determined to contain static recursion, 2492bf215546Sopenharmony_ci * \c link_error_printf will be called to emit error messages for each function 2493bf215546Sopenharmony_ci * that is in the recursion cycle. In addition, 2494bf215546Sopenharmony_ci * \c gl_shader_program::LinkStatus will be set to false. 2495bf215546Sopenharmony_ci */ 2496bf215546Sopenharmony_civoid 2497bf215546Sopenharmony_cidetect_recursion_linked(struct gl_shader_program *prog, 2498bf215546Sopenharmony_ci exec_list *instructions); 2499bf215546Sopenharmony_ci 2500bf215546Sopenharmony_ci/** 2501bf215546Sopenharmony_ci * Make a clone of each IR instruction in a list 2502bf215546Sopenharmony_ci * 2503bf215546Sopenharmony_ci * \param in List of IR instructions that are to be cloned 2504bf215546Sopenharmony_ci * \param out List to hold the cloned instructions 2505bf215546Sopenharmony_ci */ 2506bf215546Sopenharmony_civoid 2507bf215546Sopenharmony_ciclone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in); 2508bf215546Sopenharmony_ci 2509bf215546Sopenharmony_ciextern void 2510bf215546Sopenharmony_ci_mesa_glsl_initialize_variables(exec_list *instructions, 2511bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state); 2512bf215546Sopenharmony_ci 2513bf215546Sopenharmony_ciextern void 2514bf215546Sopenharmony_cireparent_ir(exec_list *list, void *mem_ctx); 2515bf215546Sopenharmony_ci 2516bf215546Sopenharmony_ciextern void 2517bf215546Sopenharmony_cido_set_program_inouts(exec_list *instructions, struct gl_program *prog, 2518bf215546Sopenharmony_ci gl_shader_stage shader_stage); 2519bf215546Sopenharmony_ci 2520bf215546Sopenharmony_ciextern char * 2521bf215546Sopenharmony_ciprototype_string(const glsl_type *return_type, const char *name, 2522bf215546Sopenharmony_ci exec_list *parameters); 2523bf215546Sopenharmony_ci 2524bf215546Sopenharmony_ciconst char * 2525bf215546Sopenharmony_cimode_string(const ir_variable *var); 2526bf215546Sopenharmony_ci 2527bf215546Sopenharmony_ci/** 2528bf215546Sopenharmony_ci * Built-in / reserved GL variables names start with "gl_" 2529bf215546Sopenharmony_ci */ 2530bf215546Sopenharmony_cistatic inline bool 2531bf215546Sopenharmony_ciis_gl_identifier(const char *s) 2532bf215546Sopenharmony_ci{ 2533bf215546Sopenharmony_ci return s && s[0] == 'g' && s[1] == 'l' && s[2] == '_'; 2534bf215546Sopenharmony_ci} 2535bf215546Sopenharmony_ci 2536bf215546Sopenharmony_ciextern "C" { 2537bf215546Sopenharmony_ci#endif /* __cplusplus */ 2538bf215546Sopenharmony_ci 2539bf215546Sopenharmony_ciextern void _mesa_print_ir(FILE *f, struct exec_list *instructions, 2540bf215546Sopenharmony_ci struct _mesa_glsl_parse_state *state); 2541bf215546Sopenharmony_ci 2542bf215546Sopenharmony_ciextern void 2543bf215546Sopenharmony_cifprint_ir(FILE *f, const void *instruction); 2544bf215546Sopenharmony_ci 2545bf215546Sopenharmony_ciextern const struct gl_builtin_uniform_desc * 2546bf215546Sopenharmony_ci_mesa_glsl_get_builtin_uniform_desc(const char *name); 2547bf215546Sopenharmony_ci 2548bf215546Sopenharmony_ci#ifdef __cplusplus 2549bf215546Sopenharmony_ci} /* extern "C" */ 2550bf215546Sopenharmony_ci#endif 2551bf215546Sopenharmony_ci 2552bf215546Sopenharmony_ciunsigned 2553bf215546Sopenharmony_civertices_per_prim(GLenum prim); 2554bf215546Sopenharmony_ci 2555bf215546Sopenharmony_ci#endif /* IR_H */ 2556