101e04c3fSmrg/* -*- c++ -*- */ 201e04c3fSmrg/* 301e04c3fSmrg * Copyright © 2010 Intel Corporation 401e04c3fSmrg * 501e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 601e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 701e04c3fSmrg * to deal in the Software without restriction, including without limitation 801e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 901e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 1001e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1101e04c3fSmrg * 1201e04c3fSmrg * The above copyright notice and this permission notice (including the next 1301e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1401e04c3fSmrg * Software. 1501e04c3fSmrg * 1601e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1701e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1801e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1901e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2001e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2101e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2201e04c3fSmrg * DEALINGS IN THE SOFTWARE. 2301e04c3fSmrg */ 2401e04c3fSmrg 2501e04c3fSmrg#ifndef IR_H 2601e04c3fSmrg#define IR_H 2701e04c3fSmrg 2801e04c3fSmrg#include <stdio.h> 2901e04c3fSmrg#include <stdlib.h> 3001e04c3fSmrg 3101e04c3fSmrg#include "util/ralloc.h" 327ec681f3Smrg#include "util/format/u_format.h" 337ec681f3Smrg#include "util/half_float.h" 3401e04c3fSmrg#include "compiler/glsl_types.h" 3501e04c3fSmrg#include "list.h" 3601e04c3fSmrg#include "ir_visitor.h" 3701e04c3fSmrg#include "ir_hierarchical_visitor.h" 3801e04c3fSmrg 3901e04c3fSmrg#ifdef __cplusplus 4001e04c3fSmrg 4101e04c3fSmrg/** 4201e04c3fSmrg * \defgroup IR Intermediate representation nodes 4301e04c3fSmrg * 4401e04c3fSmrg * @{ 4501e04c3fSmrg */ 4601e04c3fSmrg 4701e04c3fSmrg/** 4801e04c3fSmrg * Class tags 4901e04c3fSmrg * 5001e04c3fSmrg * Each concrete class derived from \c ir_instruction has a value in this 5101e04c3fSmrg * enumerant. The value for the type is stored in \c ir_instruction::ir_type 5201e04c3fSmrg * by the constructor. While using type tags is not very C++, it is extremely 5301e04c3fSmrg * convenient. For example, during debugging you can simply inspect 5401e04c3fSmrg * \c ir_instruction::ir_type to find out the actual type of the object. 5501e04c3fSmrg * 5601e04c3fSmrg * In addition, it is possible to use a switch-statement based on \c 5701e04c3fSmrg * \c ir_instruction::ir_type to select different behavior for different object 5801e04c3fSmrg * types. For functions that have only slight differences for several object 5901e04c3fSmrg * types, this allows writing very straightforward, readable code. 6001e04c3fSmrg */ 6101e04c3fSmrgenum ir_node_type { 6201e04c3fSmrg ir_type_dereference_array, 6301e04c3fSmrg ir_type_dereference_record, 6401e04c3fSmrg ir_type_dereference_variable, 6501e04c3fSmrg ir_type_constant, 6601e04c3fSmrg ir_type_expression, 6701e04c3fSmrg ir_type_swizzle, 6801e04c3fSmrg ir_type_texture, 6901e04c3fSmrg ir_type_variable, 7001e04c3fSmrg ir_type_assignment, 7101e04c3fSmrg ir_type_call, 7201e04c3fSmrg ir_type_function, 7301e04c3fSmrg ir_type_function_signature, 7401e04c3fSmrg ir_type_if, 7501e04c3fSmrg ir_type_loop, 7601e04c3fSmrg ir_type_loop_jump, 7701e04c3fSmrg ir_type_return, 7801e04c3fSmrg ir_type_discard, 797ec681f3Smrg ir_type_demote, 8001e04c3fSmrg ir_type_emit_vertex, 8101e04c3fSmrg ir_type_end_primitive, 8201e04c3fSmrg ir_type_barrier, 8301e04c3fSmrg ir_type_max, /**< maximum ir_type enum number, for validation */ 8401e04c3fSmrg ir_type_unset = ir_type_max 8501e04c3fSmrg}; 8601e04c3fSmrg 8701e04c3fSmrg 8801e04c3fSmrg/** 8901e04c3fSmrg * Base class of all IR instructions 9001e04c3fSmrg */ 9101e04c3fSmrgclass ir_instruction : public exec_node { 9201e04c3fSmrgpublic: 9301e04c3fSmrg enum ir_node_type ir_type; 9401e04c3fSmrg 9501e04c3fSmrg /** 9601e04c3fSmrg * GCC 4.7+ and clang warn when deleting an ir_instruction unless 9701e04c3fSmrg * there's a virtual destructor present. Because we almost 9801e04c3fSmrg * universally use ralloc for our memory management of 9901e04c3fSmrg * ir_instructions, the destructor doesn't need to do any work. 10001e04c3fSmrg */ 10101e04c3fSmrg virtual ~ir_instruction() 10201e04c3fSmrg { 10301e04c3fSmrg } 10401e04c3fSmrg 10501e04c3fSmrg /** ir_print_visitor helper for debugging. */ 10601e04c3fSmrg void print(void) const; 10701e04c3fSmrg void fprint(FILE *f) const; 10801e04c3fSmrg 10901e04c3fSmrg virtual void accept(ir_visitor *) = 0; 11001e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *) = 0; 11101e04c3fSmrg virtual ir_instruction *clone(void *mem_ctx, 11201e04c3fSmrg struct hash_table *ht) const = 0; 11301e04c3fSmrg 11401e04c3fSmrg bool is_rvalue() const 11501e04c3fSmrg { 11601e04c3fSmrg return ir_type == ir_type_dereference_array || 11701e04c3fSmrg ir_type == ir_type_dereference_record || 11801e04c3fSmrg ir_type == ir_type_dereference_variable || 11901e04c3fSmrg ir_type == ir_type_constant || 12001e04c3fSmrg ir_type == ir_type_expression || 12101e04c3fSmrg ir_type == ir_type_swizzle || 12201e04c3fSmrg ir_type == ir_type_texture; 12301e04c3fSmrg } 12401e04c3fSmrg 12501e04c3fSmrg bool is_dereference() const 12601e04c3fSmrg { 12701e04c3fSmrg return ir_type == ir_type_dereference_array || 12801e04c3fSmrg ir_type == ir_type_dereference_record || 12901e04c3fSmrg ir_type == ir_type_dereference_variable; 13001e04c3fSmrg } 13101e04c3fSmrg 13201e04c3fSmrg bool is_jump() const 13301e04c3fSmrg { 13401e04c3fSmrg return ir_type == ir_type_loop_jump || 13501e04c3fSmrg ir_type == ir_type_return || 13601e04c3fSmrg ir_type == ir_type_discard; 13701e04c3fSmrg } 13801e04c3fSmrg 13901e04c3fSmrg /** 14001e04c3fSmrg * \name IR instruction downcast functions 14101e04c3fSmrg * 14201e04c3fSmrg * These functions either cast the object to a derived class or return 14301e04c3fSmrg * \c NULL if the object's type does not match the specified derived class. 14401e04c3fSmrg * Additional downcast functions will be added as needed. 14501e04c3fSmrg */ 14601e04c3fSmrg /*@{*/ 14701e04c3fSmrg #define AS_BASE(TYPE) \ 14801e04c3fSmrg class ir_##TYPE *as_##TYPE() \ 14901e04c3fSmrg { \ 15001e04c3fSmrg assume(this != NULL); \ 15101e04c3fSmrg return is_##TYPE() ? (ir_##TYPE *) this : NULL; \ 15201e04c3fSmrg } \ 15301e04c3fSmrg const class ir_##TYPE *as_##TYPE() const \ 15401e04c3fSmrg { \ 15501e04c3fSmrg assume(this != NULL); \ 15601e04c3fSmrg return is_##TYPE() ? (ir_##TYPE *) this : NULL; \ 15701e04c3fSmrg } 15801e04c3fSmrg 15901e04c3fSmrg AS_BASE(rvalue) 16001e04c3fSmrg AS_BASE(dereference) 16101e04c3fSmrg AS_BASE(jump) 16201e04c3fSmrg #undef AS_BASE 16301e04c3fSmrg 16401e04c3fSmrg #define AS_CHILD(TYPE) \ 16501e04c3fSmrg class ir_##TYPE * as_##TYPE() \ 16601e04c3fSmrg { \ 16701e04c3fSmrg assume(this != NULL); \ 16801e04c3fSmrg return ir_type == ir_type_##TYPE ? (ir_##TYPE *) this : NULL; \ 16901e04c3fSmrg } \ 17001e04c3fSmrg const class ir_##TYPE * as_##TYPE() const \ 17101e04c3fSmrg { \ 17201e04c3fSmrg assume(this != NULL); \ 17301e04c3fSmrg return ir_type == ir_type_##TYPE ? (const ir_##TYPE *) this : NULL; \ 17401e04c3fSmrg } 17501e04c3fSmrg AS_CHILD(variable) 17601e04c3fSmrg AS_CHILD(function) 17701e04c3fSmrg AS_CHILD(dereference_array) 17801e04c3fSmrg AS_CHILD(dereference_variable) 17901e04c3fSmrg AS_CHILD(dereference_record) 18001e04c3fSmrg AS_CHILD(expression) 18101e04c3fSmrg AS_CHILD(loop) 18201e04c3fSmrg AS_CHILD(assignment) 18301e04c3fSmrg AS_CHILD(call) 18401e04c3fSmrg AS_CHILD(return) 18501e04c3fSmrg AS_CHILD(if) 18601e04c3fSmrg AS_CHILD(swizzle) 18701e04c3fSmrg AS_CHILD(texture) 18801e04c3fSmrg AS_CHILD(constant) 18901e04c3fSmrg AS_CHILD(discard) 19001e04c3fSmrg #undef AS_CHILD 19101e04c3fSmrg /*@}*/ 19201e04c3fSmrg 19301e04c3fSmrg /** 19401e04c3fSmrg * IR equality method: Return true if the referenced instruction would 19501e04c3fSmrg * return the same value as this one. 19601e04c3fSmrg * 19701e04c3fSmrg * This intended to be used for CSE and algebraic optimizations, on rvalues 19801e04c3fSmrg * in particular. No support for other instruction types (assignments, 19901e04c3fSmrg * jumps, calls, etc.) is planned. 20001e04c3fSmrg */ 20101e04c3fSmrg virtual bool equals(const ir_instruction *ir, 20201e04c3fSmrg enum ir_node_type ignore = ir_type_unset) const; 20301e04c3fSmrg 20401e04c3fSmrgprotected: 20501e04c3fSmrg ir_instruction(enum ir_node_type t) 20601e04c3fSmrg : ir_type(t) 20701e04c3fSmrg { 20801e04c3fSmrg } 20901e04c3fSmrg 21001e04c3fSmrgprivate: 21101e04c3fSmrg ir_instruction() 21201e04c3fSmrg { 21301e04c3fSmrg assert(!"Should not get here."); 21401e04c3fSmrg } 21501e04c3fSmrg}; 21601e04c3fSmrg 21701e04c3fSmrg 21801e04c3fSmrg/** 21901e04c3fSmrg * The base class for all "values"/expression trees. 22001e04c3fSmrg */ 22101e04c3fSmrgclass ir_rvalue : public ir_instruction { 22201e04c3fSmrgpublic: 22301e04c3fSmrg const struct glsl_type *type; 22401e04c3fSmrg 22501e04c3fSmrg virtual ir_rvalue *clone(void *mem_ctx, struct hash_table *) const; 22601e04c3fSmrg 22701e04c3fSmrg virtual void accept(ir_visitor *v) 22801e04c3fSmrg { 22901e04c3fSmrg v->visit(this); 23001e04c3fSmrg } 23101e04c3fSmrg 23201e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 23301e04c3fSmrg 23401e04c3fSmrg virtual ir_constant *constant_expression_value(void *mem_ctx, 23501e04c3fSmrg struct hash_table *variable_context = NULL); 23601e04c3fSmrg 23701e04c3fSmrg ir_rvalue *as_rvalue_to_saturate(); 23801e04c3fSmrg 2397e102996Smaya virtual bool is_lvalue(const struct _mesa_glsl_parse_state * = NULL) const 24001e04c3fSmrg { 24101e04c3fSmrg return false; 24201e04c3fSmrg } 24301e04c3fSmrg 24401e04c3fSmrg /** 24501e04c3fSmrg * Get the variable that is ultimately referenced by an r-value 24601e04c3fSmrg */ 24701e04c3fSmrg virtual ir_variable *variable_referenced() const 24801e04c3fSmrg { 24901e04c3fSmrg return NULL; 25001e04c3fSmrg } 25101e04c3fSmrg 25201e04c3fSmrg 25301e04c3fSmrg /** 25401e04c3fSmrg * If an r-value is a reference to a whole variable, get that variable 25501e04c3fSmrg * 25601e04c3fSmrg * \return 25701e04c3fSmrg * Pointer to a variable that is completely dereferenced by the r-value. If 25801e04c3fSmrg * the r-value is not a dereference or the dereference does not access the 25901e04c3fSmrg * entire variable (i.e., it's just one array element, struct field), \c NULL 26001e04c3fSmrg * is returned. 26101e04c3fSmrg */ 26201e04c3fSmrg virtual ir_variable *whole_variable_referenced() 26301e04c3fSmrg { 26401e04c3fSmrg return NULL; 26501e04c3fSmrg } 26601e04c3fSmrg 26701e04c3fSmrg /** 26801e04c3fSmrg * Determine if an r-value has the value zero 26901e04c3fSmrg * 27001e04c3fSmrg * The base implementation of this function always returns \c false. The 27101e04c3fSmrg * \c ir_constant class over-rides this function to return \c true \b only 27201e04c3fSmrg * for vector and scalar types that have all elements set to the value 27301e04c3fSmrg * zero (or \c false for booleans). 27401e04c3fSmrg * 27501e04c3fSmrg * \sa ir_constant::has_value, ir_rvalue::is_one, ir_rvalue::is_negative_one 27601e04c3fSmrg */ 27701e04c3fSmrg virtual bool is_zero() const; 27801e04c3fSmrg 27901e04c3fSmrg /** 28001e04c3fSmrg * Determine if an r-value has the value one 28101e04c3fSmrg * 28201e04c3fSmrg * The base implementation of this function always returns \c false. The 28301e04c3fSmrg * \c ir_constant class over-rides this function to return \c true \b only 28401e04c3fSmrg * for vector and scalar types that have all elements set to the value 28501e04c3fSmrg * one (or \c true for booleans). 28601e04c3fSmrg * 28701e04c3fSmrg * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_negative_one 28801e04c3fSmrg */ 28901e04c3fSmrg virtual bool is_one() const; 29001e04c3fSmrg 29101e04c3fSmrg /** 29201e04c3fSmrg * Determine if an r-value has the value negative one 29301e04c3fSmrg * 29401e04c3fSmrg * The base implementation of this function always returns \c false. The 29501e04c3fSmrg * \c ir_constant class over-rides this function to return \c true \b only 29601e04c3fSmrg * for vector and scalar types that have all elements set to the value 29701e04c3fSmrg * negative one. For boolean types, the result is always \c false. 29801e04c3fSmrg * 29901e04c3fSmrg * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_one 30001e04c3fSmrg */ 30101e04c3fSmrg virtual bool is_negative_one() const; 30201e04c3fSmrg 30301e04c3fSmrg /** 30401e04c3fSmrg * Determine if an r-value is an unsigned integer constant which can be 30501e04c3fSmrg * stored in 16 bits. 30601e04c3fSmrg * 30701e04c3fSmrg * \sa ir_constant::is_uint16_constant. 30801e04c3fSmrg */ 30901e04c3fSmrg virtual bool is_uint16_constant() const { return false; } 31001e04c3fSmrg 31101e04c3fSmrg /** 31201e04c3fSmrg * Return a generic value of error_type. 31301e04c3fSmrg * 31401e04c3fSmrg * Allocation will be performed with 'mem_ctx' as ralloc owner. 31501e04c3fSmrg */ 31601e04c3fSmrg static ir_rvalue *error_value(void *mem_ctx); 31701e04c3fSmrg 31801e04c3fSmrgprotected: 31901e04c3fSmrg ir_rvalue(enum ir_node_type t); 32001e04c3fSmrg}; 32101e04c3fSmrg 32201e04c3fSmrg 32301e04c3fSmrg/** 32401e04c3fSmrg * Variable storage classes 32501e04c3fSmrg */ 32601e04c3fSmrgenum ir_variable_mode { 32701e04c3fSmrg ir_var_auto = 0, /**< Function local variables and globals. */ 32801e04c3fSmrg ir_var_uniform, /**< Variable declared as a uniform. */ 32901e04c3fSmrg ir_var_shader_storage, /**< Variable declared as an ssbo. */ 33001e04c3fSmrg ir_var_shader_shared, /**< Variable declared as shared. */ 33101e04c3fSmrg ir_var_shader_in, 33201e04c3fSmrg ir_var_shader_out, 33301e04c3fSmrg ir_var_function_in, 33401e04c3fSmrg ir_var_function_out, 33501e04c3fSmrg ir_var_function_inout, 33601e04c3fSmrg ir_var_const_in, /**< "in" param that must be a constant expression */ 33701e04c3fSmrg ir_var_system_value, /**< Ex: front-face, instance-id, etc. */ 33801e04c3fSmrg ir_var_temporary, /**< Temporary variable generated during compilation. */ 33901e04c3fSmrg ir_var_mode_count /**< Number of variable modes */ 34001e04c3fSmrg}; 34101e04c3fSmrg 34201e04c3fSmrg/** 34301e04c3fSmrg * Enum keeping track of how a variable was declared. For error checking of 34401e04c3fSmrg * the gl_PerVertex redeclaration rules. 34501e04c3fSmrg */ 34601e04c3fSmrgenum ir_var_declaration_type { 34701e04c3fSmrg /** 34801e04c3fSmrg * Normal declaration (for most variables, this means an explicit 34901e04c3fSmrg * declaration. Exception: temporaries are always implicitly declared, but 35001e04c3fSmrg * they still use ir_var_declared_normally). 35101e04c3fSmrg * 35201e04c3fSmrg * Note: an ir_variable that represents a named interface block uses 35301e04c3fSmrg * ir_var_declared_normally. 35401e04c3fSmrg */ 35501e04c3fSmrg ir_var_declared_normally = 0, 35601e04c3fSmrg 35701e04c3fSmrg /** 35801e04c3fSmrg * Variable was explicitly declared (or re-declared) in an unnamed 35901e04c3fSmrg * interface block. 36001e04c3fSmrg */ 36101e04c3fSmrg ir_var_declared_in_block, 36201e04c3fSmrg 36301e04c3fSmrg /** 36401e04c3fSmrg * Variable is an implicitly declared built-in that has not been explicitly 36501e04c3fSmrg * re-declared by the shader. 36601e04c3fSmrg */ 36701e04c3fSmrg ir_var_declared_implicitly, 36801e04c3fSmrg 36901e04c3fSmrg /** 37001e04c3fSmrg * Variable is implicitly generated by the compiler and should not be 37101e04c3fSmrg * visible via the API. 37201e04c3fSmrg */ 37301e04c3fSmrg ir_var_hidden, 37401e04c3fSmrg}; 37501e04c3fSmrg 37601e04c3fSmrg/** 37701e04c3fSmrg * \brief Layout qualifiers for gl_FragDepth. 37801e04c3fSmrg * 37901e04c3fSmrg * The AMD/ARB_conservative_depth extensions allow gl_FragDepth to be redeclared 38001e04c3fSmrg * with a layout qualifier. 38101e04c3fSmrg */ 38201e04c3fSmrgenum ir_depth_layout { 38301e04c3fSmrg ir_depth_layout_none, /**< No depth layout is specified. */ 38401e04c3fSmrg ir_depth_layout_any, 38501e04c3fSmrg ir_depth_layout_greater, 38601e04c3fSmrg ir_depth_layout_less, 38701e04c3fSmrg ir_depth_layout_unchanged 38801e04c3fSmrg}; 38901e04c3fSmrg 39001e04c3fSmrg/** 39101e04c3fSmrg * \brief Convert depth layout qualifier to string. 39201e04c3fSmrg */ 39301e04c3fSmrgconst char* 39401e04c3fSmrgdepth_layout_string(ir_depth_layout layout); 39501e04c3fSmrg 39601e04c3fSmrg/** 39701e04c3fSmrg * Description of built-in state associated with a uniform 39801e04c3fSmrg * 39901e04c3fSmrg * \sa ir_variable::state_slots 40001e04c3fSmrg */ 40101e04c3fSmrgstruct ir_state_slot { 40201e04c3fSmrg gl_state_index16 tokens[STATE_LENGTH]; 40301e04c3fSmrg int swizzle; 40401e04c3fSmrg}; 40501e04c3fSmrg 40601e04c3fSmrg 40701e04c3fSmrg/** 40801e04c3fSmrg * Get the string value for an interpolation qualifier 40901e04c3fSmrg * 41001e04c3fSmrg * \return The string that would be used in a shader to specify \c 41101e04c3fSmrg * mode will be returned. 41201e04c3fSmrg * 41301e04c3fSmrg * This function is used to generate error messages of the form "shader 41401e04c3fSmrg * uses %s interpolation qualifier", so in the case where there is no 41501e04c3fSmrg * interpolation qualifier, it returns "no". 41601e04c3fSmrg * 41701e04c3fSmrg * This function should only be used on a shader input or output variable. 41801e04c3fSmrg */ 41901e04c3fSmrgconst char *interpolation_string(unsigned interpolation); 42001e04c3fSmrg 42101e04c3fSmrg 42201e04c3fSmrgclass ir_variable : public ir_instruction { 42301e04c3fSmrgpublic: 42401e04c3fSmrg ir_variable(const struct glsl_type *, const char *, ir_variable_mode); 42501e04c3fSmrg 42601e04c3fSmrg virtual ir_variable *clone(void *mem_ctx, struct hash_table *ht) const; 42701e04c3fSmrg 42801e04c3fSmrg virtual void accept(ir_visitor *v) 42901e04c3fSmrg { 43001e04c3fSmrg v->visit(this); 43101e04c3fSmrg } 43201e04c3fSmrg 43301e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 43401e04c3fSmrg 43501e04c3fSmrg 43601e04c3fSmrg /** 43701e04c3fSmrg * Determine whether or not a variable is part of a uniform or 43801e04c3fSmrg * shader storage block. 43901e04c3fSmrg */ 44001e04c3fSmrg inline bool is_in_buffer_block() const 44101e04c3fSmrg { 44201e04c3fSmrg return (this->data.mode == ir_var_uniform || 44301e04c3fSmrg this->data.mode == ir_var_shader_storage) && 44401e04c3fSmrg this->interface_type != NULL; 44501e04c3fSmrg } 44601e04c3fSmrg 44701e04c3fSmrg /** 44801e04c3fSmrg * Determine whether or not a variable is part of a shader storage block. 44901e04c3fSmrg */ 45001e04c3fSmrg inline bool is_in_shader_storage_block() const 45101e04c3fSmrg { 45201e04c3fSmrg return this->data.mode == ir_var_shader_storage && 45301e04c3fSmrg this->interface_type != NULL; 45401e04c3fSmrg } 45501e04c3fSmrg 45601e04c3fSmrg /** 45701e04c3fSmrg * Determine whether or not a variable is the declaration of an interface 45801e04c3fSmrg * block 45901e04c3fSmrg * 46001e04c3fSmrg * For the first declaration below, there will be an \c ir_variable named 46101e04c3fSmrg * "instance" whose type and whose instance_type will be the same 46201e04c3fSmrg * \c glsl_type. For the second declaration, there will be an \c ir_variable 46301e04c3fSmrg * named "f" whose type is float and whose instance_type is B2. 46401e04c3fSmrg * 46501e04c3fSmrg * "instance" is an interface instance variable, but "f" is not. 46601e04c3fSmrg * 46701e04c3fSmrg * uniform B1 { 46801e04c3fSmrg * float f; 46901e04c3fSmrg * } instance; 47001e04c3fSmrg * 47101e04c3fSmrg * uniform B2 { 47201e04c3fSmrg * float f; 47301e04c3fSmrg * }; 47401e04c3fSmrg */ 47501e04c3fSmrg inline bool is_interface_instance() const 47601e04c3fSmrg { 47701e04c3fSmrg return this->type->without_array() == this->interface_type; 47801e04c3fSmrg } 47901e04c3fSmrg 48001e04c3fSmrg /** 48101e04c3fSmrg * Return whether this variable contains a bindless sampler/image. 48201e04c3fSmrg */ 48301e04c3fSmrg inline bool contains_bindless() const 48401e04c3fSmrg { 48501e04c3fSmrg if (!this->type->contains_sampler() && !this->type->contains_image()) 48601e04c3fSmrg return false; 48701e04c3fSmrg 48801e04c3fSmrg return this->data.bindless || this->data.mode != ir_var_uniform; 48901e04c3fSmrg } 49001e04c3fSmrg 49101e04c3fSmrg /** 49201e04c3fSmrg * Set this->interface_type on a newly created variable. 49301e04c3fSmrg */ 49401e04c3fSmrg void init_interface_type(const struct glsl_type *type) 49501e04c3fSmrg { 49601e04c3fSmrg assert(this->interface_type == NULL); 49701e04c3fSmrg this->interface_type = type; 49801e04c3fSmrg if (this->is_interface_instance()) { 49901e04c3fSmrg this->u.max_ifc_array_access = 50001e04c3fSmrg ralloc_array(this, int, type->length); 50101e04c3fSmrg for (unsigned i = 0; i < type->length; i++) { 50201e04c3fSmrg this->u.max_ifc_array_access[i] = -1; 50301e04c3fSmrg } 50401e04c3fSmrg } 50501e04c3fSmrg } 50601e04c3fSmrg 50701e04c3fSmrg /** 50801e04c3fSmrg * Change this->interface_type on a variable that previously had a 50901e04c3fSmrg * different, but compatible, interface_type. This is used during linking 51001e04c3fSmrg * to set the size of arrays in interface blocks. 51101e04c3fSmrg */ 51201e04c3fSmrg void change_interface_type(const struct glsl_type *type) 51301e04c3fSmrg { 51401e04c3fSmrg if (this->u.max_ifc_array_access != NULL) { 51501e04c3fSmrg /* max_ifc_array_access has already been allocated, so make sure the 51601e04c3fSmrg * new interface has the same number of fields as the old one. 51701e04c3fSmrg */ 51801e04c3fSmrg assert(this->interface_type->length == type->length); 51901e04c3fSmrg } 52001e04c3fSmrg this->interface_type = type; 52101e04c3fSmrg } 52201e04c3fSmrg 52301e04c3fSmrg /** 52401e04c3fSmrg * Change this->interface_type on a variable that previously had a 52501e04c3fSmrg * different, and incompatible, interface_type. This is used during 52601e04c3fSmrg * compilation to handle redeclaration of the built-in gl_PerVertex 52701e04c3fSmrg * interface block. 52801e04c3fSmrg */ 52901e04c3fSmrg void reinit_interface_type(const struct glsl_type *type) 53001e04c3fSmrg { 53101e04c3fSmrg if (this->u.max_ifc_array_access != NULL) { 53201e04c3fSmrg#ifndef NDEBUG 53301e04c3fSmrg /* Redeclaring gl_PerVertex is only allowed if none of the built-ins 53401e04c3fSmrg * it defines have been accessed yet; so it's safe to throw away the 53501e04c3fSmrg * old max_ifc_array_access pointer, since all of its values are 53601e04c3fSmrg * zero. 53701e04c3fSmrg */ 53801e04c3fSmrg for (unsigned i = 0; i < this->interface_type->length; i++) 53901e04c3fSmrg assert(this->u.max_ifc_array_access[i] == -1); 54001e04c3fSmrg#endif 54101e04c3fSmrg ralloc_free(this->u.max_ifc_array_access); 54201e04c3fSmrg this->u.max_ifc_array_access = NULL; 54301e04c3fSmrg } 54401e04c3fSmrg this->interface_type = NULL; 54501e04c3fSmrg init_interface_type(type); 54601e04c3fSmrg } 54701e04c3fSmrg 54801e04c3fSmrg const glsl_type *get_interface_type() const 54901e04c3fSmrg { 55001e04c3fSmrg return this->interface_type; 55101e04c3fSmrg } 55201e04c3fSmrg 55301e04c3fSmrg enum glsl_interface_packing get_interface_type_packing() const 55401e04c3fSmrg { 55501e04c3fSmrg return this->interface_type->get_interface_packing(); 55601e04c3fSmrg } 55701e04c3fSmrg /** 55801e04c3fSmrg * Get the max_ifc_array_access pointer 55901e04c3fSmrg * 5607ec681f3Smrg * A "set" function is not needed because the array is dynamically allocated 56101e04c3fSmrg * as necessary. 56201e04c3fSmrg */ 56301e04c3fSmrg inline int *get_max_ifc_array_access() 56401e04c3fSmrg { 56501e04c3fSmrg assert(this->data._num_state_slots == 0); 56601e04c3fSmrg return this->u.max_ifc_array_access; 56701e04c3fSmrg } 56801e04c3fSmrg 56901e04c3fSmrg inline unsigned get_num_state_slots() const 57001e04c3fSmrg { 57101e04c3fSmrg assert(!this->is_interface_instance() 57201e04c3fSmrg || this->data._num_state_slots == 0); 57301e04c3fSmrg return this->data._num_state_slots; 57401e04c3fSmrg } 57501e04c3fSmrg 57601e04c3fSmrg inline void set_num_state_slots(unsigned n) 57701e04c3fSmrg { 57801e04c3fSmrg assert(!this->is_interface_instance() 57901e04c3fSmrg || n == 0); 58001e04c3fSmrg this->data._num_state_slots = n; 58101e04c3fSmrg } 58201e04c3fSmrg 58301e04c3fSmrg inline ir_state_slot *get_state_slots() 58401e04c3fSmrg { 58501e04c3fSmrg return this->is_interface_instance() ? NULL : this->u.state_slots; 58601e04c3fSmrg } 58701e04c3fSmrg 58801e04c3fSmrg inline const ir_state_slot *get_state_slots() const 58901e04c3fSmrg { 59001e04c3fSmrg return this->is_interface_instance() ? NULL : this->u.state_slots; 59101e04c3fSmrg } 59201e04c3fSmrg 59301e04c3fSmrg inline ir_state_slot *allocate_state_slots(unsigned n) 59401e04c3fSmrg { 59501e04c3fSmrg assert(!this->is_interface_instance()); 59601e04c3fSmrg 59701e04c3fSmrg this->u.state_slots = ralloc_array(this, ir_state_slot, n); 59801e04c3fSmrg this->data._num_state_slots = 0; 59901e04c3fSmrg 60001e04c3fSmrg if (this->u.state_slots != NULL) 60101e04c3fSmrg this->data._num_state_slots = n; 60201e04c3fSmrg 60301e04c3fSmrg return this->u.state_slots; 60401e04c3fSmrg } 60501e04c3fSmrg 60601e04c3fSmrg inline bool is_interpolation_flat() const 60701e04c3fSmrg { 60801e04c3fSmrg return this->data.interpolation == INTERP_MODE_FLAT || 60901e04c3fSmrg this->type->contains_integer() || 61001e04c3fSmrg this->type->contains_double(); 61101e04c3fSmrg } 61201e04c3fSmrg 61301e04c3fSmrg inline bool is_name_ralloced() const 61401e04c3fSmrg { 61501e04c3fSmrg return this->name != ir_variable::tmp_name && 61601e04c3fSmrg this->name != this->name_storage; 61701e04c3fSmrg } 61801e04c3fSmrg 61901e04c3fSmrg /** 62001e04c3fSmrg * Enable emitting extension warnings for this variable 62101e04c3fSmrg */ 62201e04c3fSmrg void enable_extension_warning(const char *extension); 62301e04c3fSmrg 62401e04c3fSmrg /** 62501e04c3fSmrg * Get the extension warning string for this variable 62601e04c3fSmrg * 62701e04c3fSmrg * If warnings are not enabled, \c NULL is returned. 62801e04c3fSmrg */ 62901e04c3fSmrg const char *get_extension_warning() const; 63001e04c3fSmrg 63101e04c3fSmrg /** 63201e04c3fSmrg * Declared type of the variable 63301e04c3fSmrg */ 63401e04c3fSmrg const struct glsl_type *type; 63501e04c3fSmrg 63601e04c3fSmrg /** 63701e04c3fSmrg * Declared name of the variable 63801e04c3fSmrg */ 63901e04c3fSmrg const char *name; 64001e04c3fSmrg 64101e04c3fSmrgprivate: 64201e04c3fSmrg /** 64301e04c3fSmrg * If the name length fits into name_storage, it's used, otherwise 64401e04c3fSmrg * the name is ralloc'd. shader-db mining showed that 70% of variables 64501e04c3fSmrg * fit here. This is a win over ralloc where only ralloc_header has 64601e04c3fSmrg * 20 bytes on 64-bit (28 bytes with DEBUG), and we can also skip malloc. 64701e04c3fSmrg */ 64801e04c3fSmrg char name_storage[16]; 64901e04c3fSmrg 65001e04c3fSmrgpublic: 65101e04c3fSmrg struct ir_variable_data { 65201e04c3fSmrg 65301e04c3fSmrg /** 65401e04c3fSmrg * Is the variable read-only? 65501e04c3fSmrg * 65601e04c3fSmrg * This is set for variables declared as \c const, shader inputs, 65701e04c3fSmrg * and uniforms. 65801e04c3fSmrg */ 65901e04c3fSmrg unsigned read_only:1; 66001e04c3fSmrg unsigned centroid:1; 66101e04c3fSmrg unsigned sample:1; 66201e04c3fSmrg unsigned patch:1; 663993e1d59Smrg /** 664993e1d59Smrg * Was an 'invariant' qualifier explicitly set in the shader? 665993e1d59Smrg * 666993e1d59Smrg * This is used to cross validate qualifiers. 667993e1d59Smrg */ 668993e1d59Smrg unsigned explicit_invariant:1; 669993e1d59Smrg /** 670993e1d59Smrg * Is the variable invariant? 671993e1d59Smrg * 672993e1d59Smrg * It can happen either by having the 'invariant' qualifier 673993e1d59Smrg * explicitly set in the shader or by being used in calculations 674993e1d59Smrg * of other invariant variables. 675993e1d59Smrg */ 67601e04c3fSmrg unsigned invariant:1; 67701e04c3fSmrg unsigned precise:1; 67801e04c3fSmrg 67901e04c3fSmrg /** 68001e04c3fSmrg * Has this variable been used for reading or writing? 68101e04c3fSmrg * 68201e04c3fSmrg * Several GLSL semantic checks require knowledge of whether or not a 68301e04c3fSmrg * variable has been used. For example, it is an error to redeclare a 68401e04c3fSmrg * variable as invariant after it has been used. 68501e04c3fSmrg * 68601e04c3fSmrg * This is maintained in the ast_to_hir.cpp path and during linking, 68701e04c3fSmrg * but not in Mesa's fixed function or ARB program paths. 68801e04c3fSmrg */ 68901e04c3fSmrg unsigned used:1; 69001e04c3fSmrg 69101e04c3fSmrg /** 69201e04c3fSmrg * Has this variable been statically assigned? 69301e04c3fSmrg * 69401e04c3fSmrg * This answers whether the variable was assigned in any path of 69501e04c3fSmrg * the shader during ast_to_hir. This doesn't answer whether it is 69601e04c3fSmrg * still written after dead code removal, nor is it maintained in 69701e04c3fSmrg * non-ast_to_hir.cpp (GLSL parsing) paths. 69801e04c3fSmrg */ 69901e04c3fSmrg unsigned assigned:1; 70001e04c3fSmrg 70101e04c3fSmrg /** 70201e04c3fSmrg * When separate shader programs are enabled, only input/outputs between 70301e04c3fSmrg * the stages of a multi-stage separate program can be safely removed 70401e04c3fSmrg * from the shader interface. Other input/outputs must remains active. 70501e04c3fSmrg */ 70601e04c3fSmrg unsigned always_active_io:1; 70701e04c3fSmrg 70801e04c3fSmrg /** 70901e04c3fSmrg * Enum indicating how the variable was declared. See 71001e04c3fSmrg * ir_var_declaration_type. 71101e04c3fSmrg * 71201e04c3fSmrg * This is used to detect certain kinds of illegal variable redeclarations. 71301e04c3fSmrg */ 71401e04c3fSmrg unsigned how_declared:2; 71501e04c3fSmrg 71601e04c3fSmrg /** 71701e04c3fSmrg * Storage class of the variable. 71801e04c3fSmrg * 71901e04c3fSmrg * \sa ir_variable_mode 72001e04c3fSmrg */ 72101e04c3fSmrg unsigned mode:4; 72201e04c3fSmrg 72301e04c3fSmrg /** 72401e04c3fSmrg * Interpolation mode for shader inputs / outputs 72501e04c3fSmrg * 72601e04c3fSmrg * \sa glsl_interp_mode 72701e04c3fSmrg */ 72801e04c3fSmrg unsigned interpolation:2; 72901e04c3fSmrg 73001e04c3fSmrg /** 73101e04c3fSmrg * Was the location explicitly set in the shader? 73201e04c3fSmrg * 73301e04c3fSmrg * If the location is explicitly set in the shader, it \b cannot be changed 73401e04c3fSmrg * by the linker or by the API (e.g., calls to \c glBindAttribLocation have 73501e04c3fSmrg * no effect). 73601e04c3fSmrg */ 73701e04c3fSmrg unsigned explicit_location:1; 73801e04c3fSmrg unsigned explicit_index:1; 73901e04c3fSmrg 74001e04c3fSmrg /** 74101e04c3fSmrg * Was an initial binding explicitly set in the shader? 74201e04c3fSmrg * 74301e04c3fSmrg * If so, constant_value contains an integer ir_constant representing the 74401e04c3fSmrg * initial binding point. 74501e04c3fSmrg */ 74601e04c3fSmrg unsigned explicit_binding:1; 74701e04c3fSmrg 74801e04c3fSmrg /** 74901e04c3fSmrg * Was an initial component explicitly set in the shader? 75001e04c3fSmrg */ 75101e04c3fSmrg unsigned explicit_component:1; 75201e04c3fSmrg 75301e04c3fSmrg /** 75401e04c3fSmrg * Does this variable have an initializer? 75501e04c3fSmrg * 75601e04c3fSmrg * This is used by the linker to cross-validiate initializers of global 75701e04c3fSmrg * variables. 75801e04c3fSmrg */ 75901e04c3fSmrg unsigned has_initializer:1; 76001e04c3fSmrg 7617ec681f3Smrg /** 7627ec681f3Smrg * Is the initializer created by the compiler (glsl_zero_init) 7637ec681f3Smrg */ 7647ec681f3Smrg unsigned is_implicit_initializer:1; 7657ec681f3Smrg 76601e04c3fSmrg /** 76701e04c3fSmrg * Is this variable a generic output or input that has not yet been matched 76801e04c3fSmrg * up to a variable in another stage of the pipeline? 76901e04c3fSmrg * 77001e04c3fSmrg * This is used by the linker as scratch storage while assigning locations 77101e04c3fSmrg * to generic inputs and outputs. 77201e04c3fSmrg */ 77301e04c3fSmrg unsigned is_unmatched_generic_inout:1; 77401e04c3fSmrg 7757ec681f3Smrg /** 7767ec681f3Smrg * Is this varying used by transform feedback? 7777ec681f3Smrg * 7787ec681f3Smrg * This is used by the linker to decide if it's safe to pack the varying. 7797ec681f3Smrg */ 7807ec681f3Smrg unsigned is_xfb:1; 7817ec681f3Smrg 78201e04c3fSmrg /** 78301e04c3fSmrg * Is this varying used only by transform feedback? 78401e04c3fSmrg * 78501e04c3fSmrg * This is used by the linker to decide if its safe to pack the varying. 78601e04c3fSmrg */ 78701e04c3fSmrg unsigned is_xfb_only:1; 78801e04c3fSmrg 78901e04c3fSmrg /** 7907e102996Smaya * Was a transform feedback buffer set in the shader? 79101e04c3fSmrg */ 79201e04c3fSmrg unsigned explicit_xfb_buffer:1; 79301e04c3fSmrg 79401e04c3fSmrg /** 7957e102996Smaya * Was a transform feedback offset set in the shader? 79601e04c3fSmrg */ 79701e04c3fSmrg unsigned explicit_xfb_offset:1; 79801e04c3fSmrg 79901e04c3fSmrg /** 8007e102996Smaya * Was a transform feedback stride set in the shader? 80101e04c3fSmrg */ 80201e04c3fSmrg unsigned explicit_xfb_stride:1; 80301e04c3fSmrg 80401e04c3fSmrg /** 80501e04c3fSmrg * If non-zero, then this variable may be packed along with other variables 80601e04c3fSmrg * into a single varying slot, so this offset should be applied when 80701e04c3fSmrg * accessing components. For example, an offset of 1 means that the x 80801e04c3fSmrg * component of this variable is actually stored in component y of the 80901e04c3fSmrg * location specified by \c location. 81001e04c3fSmrg */ 81101e04c3fSmrg unsigned location_frac:2; 81201e04c3fSmrg 81301e04c3fSmrg /** 81401e04c3fSmrg * Layout of the matrix. Uses glsl_matrix_layout values. 81501e04c3fSmrg */ 81601e04c3fSmrg unsigned matrix_layout:2; 81701e04c3fSmrg 81801e04c3fSmrg /** 81901e04c3fSmrg * Non-zero if this variable was created by lowering a named interface 82001e04c3fSmrg * block. 82101e04c3fSmrg */ 82201e04c3fSmrg unsigned from_named_ifc_block:1; 82301e04c3fSmrg 82401e04c3fSmrg /** 82501e04c3fSmrg * Non-zero if the variable must be a shader input. This is useful for 82601e04c3fSmrg * constraints on function parameters. 82701e04c3fSmrg */ 82801e04c3fSmrg unsigned must_be_shader_input:1; 82901e04c3fSmrg 83001e04c3fSmrg /** 83101e04c3fSmrg * Output index for dual source blending. 83201e04c3fSmrg * 83301e04c3fSmrg * \note 83401e04c3fSmrg * The GLSL spec only allows the values 0 or 1 for the index in \b dual 83501e04c3fSmrg * source blending. 83601e04c3fSmrg */ 83701e04c3fSmrg unsigned index:1; 83801e04c3fSmrg 83901e04c3fSmrg /** 84001e04c3fSmrg * Precision qualifier. 84101e04c3fSmrg * 84201e04c3fSmrg * In desktop GLSL we do not care about precision qualifiers at all, in 84301e04c3fSmrg * fact, the spec says that precision qualifiers are ignored. 84401e04c3fSmrg * 84501e04c3fSmrg * To make things easy, we make it so that this field is always 84601e04c3fSmrg * GLSL_PRECISION_NONE on desktop shaders. This way all the variables 84701e04c3fSmrg * have the same precision value and the checks we add in the compiler 84801e04c3fSmrg * for this field will never break a desktop shader compile. 84901e04c3fSmrg */ 85001e04c3fSmrg unsigned precision:2; 85101e04c3fSmrg 85201e04c3fSmrg /** 85301e04c3fSmrg * \brief Layout qualifier for gl_FragDepth. 85401e04c3fSmrg * 85501e04c3fSmrg * This is not equal to \c ir_depth_layout_none if and only if this 85601e04c3fSmrg * variable is \c gl_FragDepth and a layout qualifier is specified. 85701e04c3fSmrg */ 85801e04c3fSmrg ir_depth_layout depth_layout:3; 85901e04c3fSmrg 86001e04c3fSmrg /** 86101e04c3fSmrg * Memory qualifiers. 86201e04c3fSmrg */ 86301e04c3fSmrg unsigned memory_read_only:1; /**< "readonly" qualifier. */ 86401e04c3fSmrg unsigned memory_write_only:1; /**< "writeonly" qualifier. */ 86501e04c3fSmrg unsigned memory_coherent:1; 86601e04c3fSmrg unsigned memory_volatile:1; 86701e04c3fSmrg unsigned memory_restrict:1; 86801e04c3fSmrg 86901e04c3fSmrg /** 87001e04c3fSmrg * ARB_shader_storage_buffer_object 87101e04c3fSmrg */ 87201e04c3fSmrg unsigned from_ssbo_unsized_array:1; /**< unsized array buffer variable. */ 87301e04c3fSmrg 87401e04c3fSmrg unsigned implicit_sized_array:1; 87501e04c3fSmrg 87601e04c3fSmrg /** 87701e04c3fSmrg * Whether this is a fragment shader output implicitly initialized with 87801e04c3fSmrg * the previous contents of the specified render target at the 87901e04c3fSmrg * framebuffer location corresponding to this shader invocation. 88001e04c3fSmrg */ 88101e04c3fSmrg unsigned fb_fetch_output:1; 88201e04c3fSmrg 88301e04c3fSmrg /** 88401e04c3fSmrg * Non-zero if this variable is considered bindless as defined by 88501e04c3fSmrg * ARB_bindless_texture. 88601e04c3fSmrg */ 88701e04c3fSmrg unsigned bindless:1; 88801e04c3fSmrg 88901e04c3fSmrg /** 89001e04c3fSmrg * Non-zero if this variable is considered bound as defined by 89101e04c3fSmrg * ARB_bindless_texture. 89201e04c3fSmrg */ 89301e04c3fSmrg unsigned bound:1; 89401e04c3fSmrg 8957ec681f3Smrg /** 8967ec681f3Smrg * Non-zero if the variable shall not be implicitly converted during 8977ec681f3Smrg * functions matching. 8987ec681f3Smrg */ 8997ec681f3Smrg unsigned implicit_conversion_prohibited:1; 9007ec681f3Smrg 90101e04c3fSmrg /** 90201e04c3fSmrg * Emit a warning if this variable is accessed. 90301e04c3fSmrg */ 90401e04c3fSmrg private: 90501e04c3fSmrg uint8_t warn_extension_index; 90601e04c3fSmrg 90701e04c3fSmrg public: 9087ec681f3Smrg /** 9097ec681f3Smrg * Image internal format if specified explicitly, otherwise 9107ec681f3Smrg * PIPE_FORMAT_NONE. 9117ec681f3Smrg */ 9127ec681f3Smrg enum pipe_format image_format; 91301e04c3fSmrg 91401e04c3fSmrg private: 91501e04c3fSmrg /** 91601e04c3fSmrg * Number of state slots used 91701e04c3fSmrg * 91801e04c3fSmrg * \note 91901e04c3fSmrg * This could be stored in as few as 7-bits, if necessary. If it is made 92001e04c3fSmrg * smaller, add an assertion to \c ir_variable::allocate_state_slots to 92101e04c3fSmrg * be safe. 92201e04c3fSmrg */ 92301e04c3fSmrg uint16_t _num_state_slots; 92401e04c3fSmrg 92501e04c3fSmrg public: 92601e04c3fSmrg /** 92701e04c3fSmrg * Initial binding point for a sampler, atomic, or UBO. 92801e04c3fSmrg * 92901e04c3fSmrg * For array types, this represents the binding point for the first element. 93001e04c3fSmrg */ 9317ec681f3Smrg uint16_t binding; 93201e04c3fSmrg 93301e04c3fSmrg /** 93401e04c3fSmrg * Storage location of the base of this variable 93501e04c3fSmrg * 93601e04c3fSmrg * The precise meaning of this field depends on the nature of the variable. 93701e04c3fSmrg * 93801e04c3fSmrg * - Vertex shader input: one of the values from \c gl_vert_attrib. 93901e04c3fSmrg * - Vertex shader output: one of the values from \c gl_varying_slot. 94001e04c3fSmrg * - Geometry shader input: one of the values from \c gl_varying_slot. 94101e04c3fSmrg * - Geometry shader output: one of the values from \c gl_varying_slot. 94201e04c3fSmrg * - Fragment shader input: one of the values from \c gl_varying_slot. 94301e04c3fSmrg * - Fragment shader output: one of the values from \c gl_frag_result. 94401e04c3fSmrg * - Uniforms: Per-stage uniform slot number for default uniform block. 94501e04c3fSmrg * - Uniforms: Index within the uniform block definition for UBO members. 94601e04c3fSmrg * - Non-UBO Uniforms: explicit location until linking then reused to 94701e04c3fSmrg * store uniform slot number. 94801e04c3fSmrg * - Other: This field is not currently used. 94901e04c3fSmrg * 95001e04c3fSmrg * If the variable is a uniform, shader input, or shader output, and the 95101e04c3fSmrg * slot has not been assigned, the value will be -1. 95201e04c3fSmrg */ 95301e04c3fSmrg int location; 95401e04c3fSmrg 95501e04c3fSmrg /** 95601e04c3fSmrg * for glsl->tgsi/mesa IR we need to store the index into the 95701e04c3fSmrg * parameters for uniforms, initially the code overloaded location 95801e04c3fSmrg * but this causes problems with indirect samplers and AoA. 95901e04c3fSmrg * This is assigned in _mesa_generate_parameters_list_for_uniforms. 96001e04c3fSmrg */ 96101e04c3fSmrg int param_index; 96201e04c3fSmrg 96301e04c3fSmrg /** 96401e04c3fSmrg * Vertex stream output identifier. 96501e04c3fSmrg * 96601e04c3fSmrg * For packed outputs, bit 31 is set and bits [2*i+1,2*i] indicate the 96701e04c3fSmrg * stream of the i-th component. 96801e04c3fSmrg */ 96901e04c3fSmrg unsigned stream; 97001e04c3fSmrg 97101e04c3fSmrg /** 97201e04c3fSmrg * Atomic, transform feedback or block member offset. 97301e04c3fSmrg */ 97401e04c3fSmrg unsigned offset; 97501e04c3fSmrg 97601e04c3fSmrg /** 97701e04c3fSmrg * Highest element accessed with a constant expression array index 97801e04c3fSmrg * 97901e04c3fSmrg * Not used for non-array variables. -1 is never accessed. 98001e04c3fSmrg */ 98101e04c3fSmrg int max_array_access; 98201e04c3fSmrg 98301e04c3fSmrg /** 98401e04c3fSmrg * Transform feedback buffer. 98501e04c3fSmrg */ 98601e04c3fSmrg unsigned xfb_buffer; 98701e04c3fSmrg 98801e04c3fSmrg /** 98901e04c3fSmrg * Transform feedback stride. 99001e04c3fSmrg */ 99101e04c3fSmrg unsigned xfb_stride; 99201e04c3fSmrg 99301e04c3fSmrg /** 99401e04c3fSmrg * Allow (only) ir_variable direct access private members. 99501e04c3fSmrg */ 99601e04c3fSmrg friend class ir_variable; 99701e04c3fSmrg } data; 99801e04c3fSmrg 99901e04c3fSmrg /** 100001e04c3fSmrg * Value assigned in the initializer of a variable declared "const" 100101e04c3fSmrg */ 100201e04c3fSmrg ir_constant *constant_value; 100301e04c3fSmrg 100401e04c3fSmrg /** 100501e04c3fSmrg * Constant expression assigned in the initializer of the variable 100601e04c3fSmrg * 100701e04c3fSmrg * \warning 100801e04c3fSmrg * This field and \c ::constant_value are distinct. Even if the two fields 100901e04c3fSmrg * refer to constants with the same value, they must point to separate 101001e04c3fSmrg * objects. 101101e04c3fSmrg */ 101201e04c3fSmrg ir_constant *constant_initializer; 101301e04c3fSmrg 101401e04c3fSmrgprivate: 101501e04c3fSmrg static const char *const warn_extension_table[]; 101601e04c3fSmrg 101701e04c3fSmrg union { 101801e04c3fSmrg /** 101901e04c3fSmrg * For variables which satisfy the is_interface_instance() predicate, 102001e04c3fSmrg * this points to an array of integers such that if the ith member of 102101e04c3fSmrg * the interface block is an array, max_ifc_array_access[i] is the 102201e04c3fSmrg * maximum array element of that member that has been accessed. If the 102301e04c3fSmrg * ith member of the interface block is not an array, 102401e04c3fSmrg * max_ifc_array_access[i] is unused. 102501e04c3fSmrg * 102601e04c3fSmrg * For variables whose type is not an interface block, this pointer is 102701e04c3fSmrg * NULL. 102801e04c3fSmrg */ 102901e04c3fSmrg int *max_ifc_array_access; 103001e04c3fSmrg 103101e04c3fSmrg /** 103201e04c3fSmrg * Built-in state that backs this uniform 103301e04c3fSmrg * 103401e04c3fSmrg * Once set at variable creation, \c state_slots must remain invariant. 103501e04c3fSmrg * 103601e04c3fSmrg * If the variable is not a uniform, \c _num_state_slots will be zero 103701e04c3fSmrg * and \c state_slots will be \c NULL. 103801e04c3fSmrg */ 103901e04c3fSmrg ir_state_slot *state_slots; 104001e04c3fSmrg } u; 104101e04c3fSmrg 104201e04c3fSmrg /** 104301e04c3fSmrg * For variables that are in an interface block or are an instance of an 104401e04c3fSmrg * interface block, this is the \c GLSL_TYPE_INTERFACE type for that block. 104501e04c3fSmrg * 104601e04c3fSmrg * \sa ir_variable::location 104701e04c3fSmrg */ 104801e04c3fSmrg const glsl_type *interface_type; 104901e04c3fSmrg 105001e04c3fSmrg /** 105101e04c3fSmrg * Name used for anonymous compiler temporaries 105201e04c3fSmrg */ 105301e04c3fSmrg static const char tmp_name[]; 105401e04c3fSmrg 105501e04c3fSmrgpublic: 105601e04c3fSmrg /** 105701e04c3fSmrg * Should the construct keep names for ir_var_temporary variables? 105801e04c3fSmrg * 105901e04c3fSmrg * When this global is false, names passed to the constructor for 106001e04c3fSmrg * \c ir_var_temporary variables will be dropped. Instead, the variable will 106101e04c3fSmrg * be named "compiler_temp". This name will be in static storage. 106201e04c3fSmrg * 106301e04c3fSmrg * \warning 106401e04c3fSmrg * \b NEVER change the mode of an \c ir_var_temporary. 106501e04c3fSmrg * 106601e04c3fSmrg * \warning 106701e04c3fSmrg * This variable is \b not thread-safe. It is global, \b not 106801e04c3fSmrg * per-context. It begins life false. A context can, at some point, make 106901e04c3fSmrg * it true. From that point on, it will be true forever. This should be 107001e04c3fSmrg * okay since it will only be set true while debugging. 107101e04c3fSmrg */ 107201e04c3fSmrg static bool temporaries_allocate_names; 107301e04c3fSmrg}; 107401e04c3fSmrg 107501e04c3fSmrg/** 107601e04c3fSmrg * A function that returns whether a built-in function is available in the 107701e04c3fSmrg * current shading language (based on version, ES or desktop, and extensions). 107801e04c3fSmrg */ 107901e04c3fSmrgtypedef bool (*builtin_available_predicate)(const _mesa_glsl_parse_state *); 108001e04c3fSmrg 108101e04c3fSmrg#define MAKE_INTRINSIC_FOR_TYPE(op, t) \ 108201e04c3fSmrg ir_intrinsic_generic_ ## op - ir_intrinsic_generic_load + ir_intrinsic_ ## t ## _ ## load 108301e04c3fSmrg 108401e04c3fSmrg#define MAP_INTRINSIC_TO_TYPE(i, t) \ 108501e04c3fSmrg ir_intrinsic_id(int(i) - int(ir_intrinsic_generic_load) + int(ir_intrinsic_ ## t ## _ ## load)) 108601e04c3fSmrg 108701e04c3fSmrgenum ir_intrinsic_id { 108801e04c3fSmrg ir_intrinsic_invalid = 0, 108901e04c3fSmrg 109001e04c3fSmrg /** 109101e04c3fSmrg * \name Generic intrinsics 109201e04c3fSmrg * 109301e04c3fSmrg * Each of these intrinsics has a specific version for shared variables and 109401e04c3fSmrg * SSBOs. 109501e04c3fSmrg */ 109601e04c3fSmrg /*@{*/ 109701e04c3fSmrg ir_intrinsic_generic_load, 109801e04c3fSmrg ir_intrinsic_generic_store, 109901e04c3fSmrg ir_intrinsic_generic_atomic_add, 110001e04c3fSmrg ir_intrinsic_generic_atomic_and, 110101e04c3fSmrg ir_intrinsic_generic_atomic_or, 110201e04c3fSmrg ir_intrinsic_generic_atomic_xor, 110301e04c3fSmrg ir_intrinsic_generic_atomic_min, 110401e04c3fSmrg ir_intrinsic_generic_atomic_max, 110501e04c3fSmrg ir_intrinsic_generic_atomic_exchange, 110601e04c3fSmrg ir_intrinsic_generic_atomic_comp_swap, 110701e04c3fSmrg /*@}*/ 110801e04c3fSmrg 110901e04c3fSmrg ir_intrinsic_atomic_counter_read, 111001e04c3fSmrg ir_intrinsic_atomic_counter_increment, 111101e04c3fSmrg ir_intrinsic_atomic_counter_predecrement, 111201e04c3fSmrg ir_intrinsic_atomic_counter_add, 111301e04c3fSmrg ir_intrinsic_atomic_counter_and, 111401e04c3fSmrg ir_intrinsic_atomic_counter_or, 111501e04c3fSmrg ir_intrinsic_atomic_counter_xor, 111601e04c3fSmrg ir_intrinsic_atomic_counter_min, 111701e04c3fSmrg ir_intrinsic_atomic_counter_max, 111801e04c3fSmrg ir_intrinsic_atomic_counter_exchange, 111901e04c3fSmrg ir_intrinsic_atomic_counter_comp_swap, 112001e04c3fSmrg 112101e04c3fSmrg ir_intrinsic_image_load, 112201e04c3fSmrg ir_intrinsic_image_store, 112301e04c3fSmrg ir_intrinsic_image_atomic_add, 112401e04c3fSmrg ir_intrinsic_image_atomic_and, 112501e04c3fSmrg ir_intrinsic_image_atomic_or, 112601e04c3fSmrg ir_intrinsic_image_atomic_xor, 112701e04c3fSmrg ir_intrinsic_image_atomic_min, 112801e04c3fSmrg ir_intrinsic_image_atomic_max, 112901e04c3fSmrg ir_intrinsic_image_atomic_exchange, 113001e04c3fSmrg ir_intrinsic_image_atomic_comp_swap, 113101e04c3fSmrg ir_intrinsic_image_size, 113201e04c3fSmrg ir_intrinsic_image_samples, 11337ec681f3Smrg ir_intrinsic_image_atomic_inc_wrap, 11347ec681f3Smrg ir_intrinsic_image_atomic_dec_wrap, 113501e04c3fSmrg 113601e04c3fSmrg ir_intrinsic_ssbo_load, 113701e04c3fSmrg ir_intrinsic_ssbo_store = MAKE_INTRINSIC_FOR_TYPE(store, ssbo), 113801e04c3fSmrg ir_intrinsic_ssbo_atomic_add = MAKE_INTRINSIC_FOR_TYPE(atomic_add, ssbo), 113901e04c3fSmrg ir_intrinsic_ssbo_atomic_and = MAKE_INTRINSIC_FOR_TYPE(atomic_and, ssbo), 114001e04c3fSmrg ir_intrinsic_ssbo_atomic_or = MAKE_INTRINSIC_FOR_TYPE(atomic_or, ssbo), 114101e04c3fSmrg ir_intrinsic_ssbo_atomic_xor = MAKE_INTRINSIC_FOR_TYPE(atomic_xor, ssbo), 114201e04c3fSmrg ir_intrinsic_ssbo_atomic_min = MAKE_INTRINSIC_FOR_TYPE(atomic_min, ssbo), 114301e04c3fSmrg ir_intrinsic_ssbo_atomic_max = MAKE_INTRINSIC_FOR_TYPE(atomic_max, ssbo), 114401e04c3fSmrg ir_intrinsic_ssbo_atomic_exchange = MAKE_INTRINSIC_FOR_TYPE(atomic_exchange, ssbo), 114501e04c3fSmrg ir_intrinsic_ssbo_atomic_comp_swap = MAKE_INTRINSIC_FOR_TYPE(atomic_comp_swap, ssbo), 114601e04c3fSmrg 114701e04c3fSmrg ir_intrinsic_memory_barrier, 114801e04c3fSmrg ir_intrinsic_shader_clock, 114901e04c3fSmrg ir_intrinsic_group_memory_barrier, 115001e04c3fSmrg ir_intrinsic_memory_barrier_atomic_counter, 115101e04c3fSmrg ir_intrinsic_memory_barrier_buffer, 115201e04c3fSmrg ir_intrinsic_memory_barrier_image, 115301e04c3fSmrg ir_intrinsic_memory_barrier_shared, 115401e04c3fSmrg ir_intrinsic_begin_invocation_interlock, 115501e04c3fSmrg ir_intrinsic_end_invocation_interlock, 115601e04c3fSmrg 115701e04c3fSmrg ir_intrinsic_vote_all, 115801e04c3fSmrg ir_intrinsic_vote_any, 115901e04c3fSmrg ir_intrinsic_vote_eq, 116001e04c3fSmrg ir_intrinsic_ballot, 116101e04c3fSmrg ir_intrinsic_read_invocation, 116201e04c3fSmrg ir_intrinsic_read_first_invocation, 116301e04c3fSmrg 11647ec681f3Smrg ir_intrinsic_helper_invocation, 11657ec681f3Smrg 116601e04c3fSmrg ir_intrinsic_shared_load, 116701e04c3fSmrg ir_intrinsic_shared_store = MAKE_INTRINSIC_FOR_TYPE(store, shared), 116801e04c3fSmrg ir_intrinsic_shared_atomic_add = MAKE_INTRINSIC_FOR_TYPE(atomic_add, shared), 116901e04c3fSmrg ir_intrinsic_shared_atomic_and = MAKE_INTRINSIC_FOR_TYPE(atomic_and, shared), 117001e04c3fSmrg ir_intrinsic_shared_atomic_or = MAKE_INTRINSIC_FOR_TYPE(atomic_or, shared), 117101e04c3fSmrg ir_intrinsic_shared_atomic_xor = MAKE_INTRINSIC_FOR_TYPE(atomic_xor, shared), 117201e04c3fSmrg ir_intrinsic_shared_atomic_min = MAKE_INTRINSIC_FOR_TYPE(atomic_min, shared), 117301e04c3fSmrg ir_intrinsic_shared_atomic_max = MAKE_INTRINSIC_FOR_TYPE(atomic_max, shared), 117401e04c3fSmrg ir_intrinsic_shared_atomic_exchange = MAKE_INTRINSIC_FOR_TYPE(atomic_exchange, shared), 117501e04c3fSmrg ir_intrinsic_shared_atomic_comp_swap = MAKE_INTRINSIC_FOR_TYPE(atomic_comp_swap, shared), 117601e04c3fSmrg}; 117701e04c3fSmrg 117801e04c3fSmrg/*@{*/ 117901e04c3fSmrg/** 118001e04c3fSmrg * The representation of a function instance; may be the full definition or 118101e04c3fSmrg * simply a prototype. 118201e04c3fSmrg */ 118301e04c3fSmrgclass ir_function_signature : public ir_instruction { 118401e04c3fSmrg /* An ir_function_signature will be part of the list of signatures in 118501e04c3fSmrg * an ir_function. 118601e04c3fSmrg */ 118701e04c3fSmrgpublic: 118801e04c3fSmrg ir_function_signature(const glsl_type *return_type, 118901e04c3fSmrg builtin_available_predicate builtin_avail = NULL); 119001e04c3fSmrg 119101e04c3fSmrg virtual ir_function_signature *clone(void *mem_ctx, 119201e04c3fSmrg struct hash_table *ht) const; 119301e04c3fSmrg ir_function_signature *clone_prototype(void *mem_ctx, 119401e04c3fSmrg struct hash_table *ht) const; 119501e04c3fSmrg 119601e04c3fSmrg virtual void accept(ir_visitor *v) 119701e04c3fSmrg { 119801e04c3fSmrg v->visit(this); 119901e04c3fSmrg } 120001e04c3fSmrg 120101e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 120201e04c3fSmrg 120301e04c3fSmrg /** 120401e04c3fSmrg * Attempt to evaluate this function as a constant expression, 120501e04c3fSmrg * given a list of the actual parameters and the variable context. 120601e04c3fSmrg * Returns NULL for non-built-ins. 120701e04c3fSmrg */ 120801e04c3fSmrg ir_constant *constant_expression_value(void *mem_ctx, 120901e04c3fSmrg exec_list *actual_parameters, 121001e04c3fSmrg struct hash_table *variable_context); 121101e04c3fSmrg 121201e04c3fSmrg /** 121301e04c3fSmrg * Get the name of the function for which this is a signature 121401e04c3fSmrg */ 121501e04c3fSmrg const char *function_name() const; 121601e04c3fSmrg 121701e04c3fSmrg /** 121801e04c3fSmrg * Get a handle to the function for which this is a signature 121901e04c3fSmrg * 122001e04c3fSmrg * There is no setter function, this function returns a \c const pointer, 122101e04c3fSmrg * and \c ir_function_signature::_function is private for a reason. The 122201e04c3fSmrg * only way to make a connection between a function and function signature 122301e04c3fSmrg * is via \c ir_function::add_signature. This helps ensure that certain 122401e04c3fSmrg * invariants (i.e., a function signature is in the list of signatures for 122501e04c3fSmrg * its \c _function) are met. 122601e04c3fSmrg * 122701e04c3fSmrg * \sa ir_function::add_signature 122801e04c3fSmrg */ 122901e04c3fSmrg inline const class ir_function *function() const 123001e04c3fSmrg { 123101e04c3fSmrg return this->_function; 123201e04c3fSmrg } 123301e04c3fSmrg 123401e04c3fSmrg /** 123501e04c3fSmrg * Check whether the qualifiers match between this signature's parameters 123601e04c3fSmrg * and the supplied parameter list. If not, returns the name of the first 123701e04c3fSmrg * parameter with mismatched qualifiers (for use in error messages). 123801e04c3fSmrg */ 123901e04c3fSmrg const char *qualifiers_match(exec_list *params); 124001e04c3fSmrg 124101e04c3fSmrg /** 124201e04c3fSmrg * Replace the current parameter list with the given one. This is useful 124301e04c3fSmrg * if the current information came from a prototype, and either has invalid 124401e04c3fSmrg * or missing parameter names. 124501e04c3fSmrg */ 124601e04c3fSmrg void replace_parameters(exec_list *new_params); 124701e04c3fSmrg 124801e04c3fSmrg /** 124901e04c3fSmrg * Function return type. 125001e04c3fSmrg * 12517ec681f3Smrg * \note The precision qualifier is stored separately in return_precision. 125201e04c3fSmrg */ 125301e04c3fSmrg const struct glsl_type *return_type; 125401e04c3fSmrg 125501e04c3fSmrg /** 125601e04c3fSmrg * List of ir_variable of function parameters. 125701e04c3fSmrg * 125801e04c3fSmrg * This represents the storage. The paramaters passed in a particular 125901e04c3fSmrg * call will be in ir_call::actual_paramaters. 126001e04c3fSmrg */ 126101e04c3fSmrg struct exec_list parameters; 126201e04c3fSmrg 126301e04c3fSmrg /** Whether or not this function has a body (which may be empty). */ 126401e04c3fSmrg unsigned is_defined:1; 126501e04c3fSmrg 12667ec681f3Smrg /* 12677ec681f3Smrg * Precision qualifier for the return type. 12687ec681f3Smrg * 12697ec681f3Smrg * See the comment for ir_variable_data::precision for more details. 12707ec681f3Smrg */ 12717ec681f3Smrg unsigned return_precision:2; 12727ec681f3Smrg 127301e04c3fSmrg /** Whether or not this function signature is a built-in. */ 127401e04c3fSmrg bool is_builtin() const; 127501e04c3fSmrg 127601e04c3fSmrg /** 127701e04c3fSmrg * Whether or not this function is an intrinsic to be implemented 127801e04c3fSmrg * by the driver. 127901e04c3fSmrg */ 128001e04c3fSmrg inline bool is_intrinsic() const 128101e04c3fSmrg { 128201e04c3fSmrg return intrinsic_id != ir_intrinsic_invalid; 128301e04c3fSmrg } 128401e04c3fSmrg 12857ec681f3Smrg /** Identifier for this intrinsic. */ 128601e04c3fSmrg enum ir_intrinsic_id intrinsic_id; 128701e04c3fSmrg 128801e04c3fSmrg /** Whether or not a built-in is available for this shader. */ 128901e04c3fSmrg bool is_builtin_available(const _mesa_glsl_parse_state *state) const; 129001e04c3fSmrg 129101e04c3fSmrg /** Body of instructions in the function. */ 129201e04c3fSmrg struct exec_list body; 129301e04c3fSmrg 129401e04c3fSmrgprivate: 129501e04c3fSmrg /** 129601e04c3fSmrg * A function pointer to a predicate that answers whether a built-in 129701e04c3fSmrg * function is available in the current shader. NULL if not a built-in. 129801e04c3fSmrg */ 129901e04c3fSmrg builtin_available_predicate builtin_avail; 130001e04c3fSmrg 130101e04c3fSmrg /** Function of which this signature is one overload. */ 130201e04c3fSmrg class ir_function *_function; 130301e04c3fSmrg 130401e04c3fSmrg /** Function signature of which this one is a prototype clone */ 130501e04c3fSmrg const ir_function_signature *origin; 130601e04c3fSmrg 130701e04c3fSmrg friend class ir_function; 130801e04c3fSmrg 130901e04c3fSmrg /** 131001e04c3fSmrg * Helper function to run a list of instructions for constant 131101e04c3fSmrg * expression evaluation. 131201e04c3fSmrg * 131301e04c3fSmrg * The hash table represents the values of the visible variables. 131401e04c3fSmrg * There are no scoping issues because the table is indexed on 131501e04c3fSmrg * ir_variable pointers, not variable names. 131601e04c3fSmrg * 131701e04c3fSmrg * Returns false if the expression is not constant, true otherwise, 131801e04c3fSmrg * and the value in *result if result is non-NULL. 131901e04c3fSmrg */ 132001e04c3fSmrg bool constant_expression_evaluate_expression_list(void *mem_ctx, 132101e04c3fSmrg const struct exec_list &body, 132201e04c3fSmrg struct hash_table *variable_context, 132301e04c3fSmrg ir_constant **result); 132401e04c3fSmrg}; 132501e04c3fSmrg 132601e04c3fSmrg 132701e04c3fSmrg/** 132801e04c3fSmrg * Header for tracking multiple overloaded functions with the same name. 132901e04c3fSmrg * Contains a list of ir_function_signatures representing each of the 133001e04c3fSmrg * actual functions. 133101e04c3fSmrg */ 133201e04c3fSmrgclass ir_function : public ir_instruction { 133301e04c3fSmrgpublic: 133401e04c3fSmrg ir_function(const char *name); 133501e04c3fSmrg 133601e04c3fSmrg virtual ir_function *clone(void *mem_ctx, struct hash_table *ht) const; 133701e04c3fSmrg 133801e04c3fSmrg virtual void accept(ir_visitor *v) 133901e04c3fSmrg { 134001e04c3fSmrg v->visit(this); 134101e04c3fSmrg } 134201e04c3fSmrg 134301e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 134401e04c3fSmrg 134501e04c3fSmrg void add_signature(ir_function_signature *sig) 134601e04c3fSmrg { 134701e04c3fSmrg sig->_function = this; 134801e04c3fSmrg this->signatures.push_tail(sig); 134901e04c3fSmrg } 135001e04c3fSmrg 135101e04c3fSmrg /** 135201e04c3fSmrg * Find a signature that matches a set of actual parameters, taking implicit 135301e04c3fSmrg * conversions into account. Also flags whether the match was exact. 135401e04c3fSmrg */ 135501e04c3fSmrg ir_function_signature *matching_signature(_mesa_glsl_parse_state *state, 135601e04c3fSmrg const exec_list *actual_param, 135701e04c3fSmrg bool allow_builtins, 135801e04c3fSmrg bool *match_is_exact); 135901e04c3fSmrg 136001e04c3fSmrg /** 136101e04c3fSmrg * Find a signature that matches a set of actual parameters, taking implicit 136201e04c3fSmrg * conversions into account. 136301e04c3fSmrg */ 136401e04c3fSmrg ir_function_signature *matching_signature(_mesa_glsl_parse_state *state, 136501e04c3fSmrg const exec_list *actual_param, 136601e04c3fSmrg bool allow_builtins); 136701e04c3fSmrg 136801e04c3fSmrg /** 136901e04c3fSmrg * Find a signature that exactly matches a set of actual parameters without 137001e04c3fSmrg * any implicit type conversions. 137101e04c3fSmrg */ 137201e04c3fSmrg ir_function_signature *exact_matching_signature(_mesa_glsl_parse_state *state, 137301e04c3fSmrg const exec_list *actual_ps); 137401e04c3fSmrg 137501e04c3fSmrg /** 137601e04c3fSmrg * Name of the function. 137701e04c3fSmrg */ 137801e04c3fSmrg const char *name; 137901e04c3fSmrg 138001e04c3fSmrg /** Whether or not this function has a signature that isn't a built-in. */ 138101e04c3fSmrg bool has_user_signature(); 138201e04c3fSmrg 138301e04c3fSmrg /** 138401e04c3fSmrg * List of ir_function_signature for each overloaded function with this name. 138501e04c3fSmrg */ 138601e04c3fSmrg struct exec_list signatures; 138701e04c3fSmrg 138801e04c3fSmrg /** 138901e04c3fSmrg * is this function a subroutine type declaration 139001e04c3fSmrg * e.g. subroutine void type1(float arg1); 139101e04c3fSmrg */ 139201e04c3fSmrg bool is_subroutine; 139301e04c3fSmrg 139401e04c3fSmrg /** 139501e04c3fSmrg * is this function associated to a subroutine type 139601e04c3fSmrg * e.g. subroutine (type1, type2) function_name { function_body }; 139701e04c3fSmrg * would have num_subroutine_types 2, 139801e04c3fSmrg * and pointers to the type1 and type2 types. 139901e04c3fSmrg */ 140001e04c3fSmrg int num_subroutine_types; 140101e04c3fSmrg const struct glsl_type **subroutine_types; 140201e04c3fSmrg 140301e04c3fSmrg int subroutine_index; 140401e04c3fSmrg}; 140501e04c3fSmrg 140601e04c3fSmrginline const char *ir_function_signature::function_name() const 140701e04c3fSmrg{ 140801e04c3fSmrg return this->_function->name; 140901e04c3fSmrg} 141001e04c3fSmrg/*@}*/ 141101e04c3fSmrg 141201e04c3fSmrg 141301e04c3fSmrg/** 141401e04c3fSmrg * IR instruction representing high-level if-statements 141501e04c3fSmrg */ 141601e04c3fSmrgclass ir_if : public ir_instruction { 141701e04c3fSmrgpublic: 141801e04c3fSmrg ir_if(ir_rvalue *condition) 141901e04c3fSmrg : ir_instruction(ir_type_if), condition(condition) 142001e04c3fSmrg { 142101e04c3fSmrg } 142201e04c3fSmrg 142301e04c3fSmrg virtual ir_if *clone(void *mem_ctx, struct hash_table *ht) const; 142401e04c3fSmrg 142501e04c3fSmrg virtual void accept(ir_visitor *v) 142601e04c3fSmrg { 142701e04c3fSmrg v->visit(this); 142801e04c3fSmrg } 142901e04c3fSmrg 143001e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 143101e04c3fSmrg 143201e04c3fSmrg ir_rvalue *condition; 143301e04c3fSmrg /** List of ir_instruction for the body of the then branch */ 143401e04c3fSmrg exec_list then_instructions; 143501e04c3fSmrg /** List of ir_instruction for the body of the else branch */ 143601e04c3fSmrg exec_list else_instructions; 143701e04c3fSmrg}; 143801e04c3fSmrg 143901e04c3fSmrg 144001e04c3fSmrg/** 144101e04c3fSmrg * IR instruction representing a high-level loop structure. 144201e04c3fSmrg */ 144301e04c3fSmrgclass ir_loop : public ir_instruction { 144401e04c3fSmrgpublic: 144501e04c3fSmrg ir_loop(); 144601e04c3fSmrg 144701e04c3fSmrg virtual ir_loop *clone(void *mem_ctx, struct hash_table *ht) const; 144801e04c3fSmrg 144901e04c3fSmrg virtual void accept(ir_visitor *v) 145001e04c3fSmrg { 145101e04c3fSmrg v->visit(this); 145201e04c3fSmrg } 145301e04c3fSmrg 145401e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 145501e04c3fSmrg 145601e04c3fSmrg /** List of ir_instruction that make up the body of the loop. */ 145701e04c3fSmrg exec_list body_instructions; 145801e04c3fSmrg}; 145901e04c3fSmrg 146001e04c3fSmrg 146101e04c3fSmrgclass ir_assignment : public ir_instruction { 146201e04c3fSmrgpublic: 146301e04c3fSmrg ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition = NULL); 146401e04c3fSmrg 146501e04c3fSmrg /** 146601e04c3fSmrg * Construct an assignment with an explicit write mask 146701e04c3fSmrg * 146801e04c3fSmrg * \note 146901e04c3fSmrg * Since a write mask is supplied, the LHS must already be a bare 147001e04c3fSmrg * \c ir_dereference. The cannot be any swizzles in the LHS. 147101e04c3fSmrg */ 147201e04c3fSmrg ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, ir_rvalue *condition, 147301e04c3fSmrg unsigned write_mask); 147401e04c3fSmrg 147501e04c3fSmrg virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const; 147601e04c3fSmrg 147701e04c3fSmrg virtual ir_constant *constant_expression_value(void *mem_ctx, 147801e04c3fSmrg struct hash_table *variable_context = NULL); 147901e04c3fSmrg 148001e04c3fSmrg virtual void accept(ir_visitor *v) 148101e04c3fSmrg { 148201e04c3fSmrg v->visit(this); 148301e04c3fSmrg } 148401e04c3fSmrg 148501e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 148601e04c3fSmrg 148701e04c3fSmrg /** 148801e04c3fSmrg * Get a whole variable written by an assignment 148901e04c3fSmrg * 149001e04c3fSmrg * If the LHS of the assignment writes a whole variable, the variable is 149101e04c3fSmrg * returned. Otherwise \c NULL is returned. Examples of whole-variable 149201e04c3fSmrg * assignment are: 149301e04c3fSmrg * 149401e04c3fSmrg * - Assigning to a scalar 149501e04c3fSmrg * - Assigning to all components of a vector 149601e04c3fSmrg * - Whole array (or matrix) assignment 149701e04c3fSmrg * - Whole structure assignment 149801e04c3fSmrg */ 149901e04c3fSmrg ir_variable *whole_variable_written(); 150001e04c3fSmrg 150101e04c3fSmrg /** 150201e04c3fSmrg * Set the LHS of an assignment 150301e04c3fSmrg */ 150401e04c3fSmrg void set_lhs(ir_rvalue *lhs); 150501e04c3fSmrg 150601e04c3fSmrg /** 150701e04c3fSmrg * Left-hand side of the assignment. 150801e04c3fSmrg * 150901e04c3fSmrg * This should be treated as read only. If you need to set the LHS of an 151001e04c3fSmrg * assignment, use \c ir_assignment::set_lhs. 151101e04c3fSmrg */ 151201e04c3fSmrg ir_dereference *lhs; 151301e04c3fSmrg 151401e04c3fSmrg /** 151501e04c3fSmrg * Value being assigned 151601e04c3fSmrg */ 151701e04c3fSmrg ir_rvalue *rhs; 151801e04c3fSmrg 151901e04c3fSmrg /** 152001e04c3fSmrg * Optional condition for the assignment. 152101e04c3fSmrg */ 152201e04c3fSmrg ir_rvalue *condition; 152301e04c3fSmrg 152401e04c3fSmrg 152501e04c3fSmrg /** 152601e04c3fSmrg * Component mask written 152701e04c3fSmrg * 152801e04c3fSmrg * For non-vector types in the LHS, this field will be zero. For vector 152901e04c3fSmrg * types, a bit will be set for each component that is written. Note that 153001e04c3fSmrg * for \c vec2 and \c vec3 types only the lower bits will ever be set. 153101e04c3fSmrg * 153201e04c3fSmrg * A partially-set write mask means that each enabled channel gets 153301e04c3fSmrg * the value from a consecutive channel of the rhs. For example, 153401e04c3fSmrg * to write just .xyw of gl_FrontColor with color: 153501e04c3fSmrg * 153601e04c3fSmrg * (assign (constant bool (1)) (xyw) 153701e04c3fSmrg * (var_ref gl_FragColor) 153801e04c3fSmrg * (swiz xyw (var_ref color))) 153901e04c3fSmrg */ 154001e04c3fSmrg unsigned write_mask:4; 154101e04c3fSmrg}; 154201e04c3fSmrg 154301e04c3fSmrg#include "ir_expression_operation.h" 154401e04c3fSmrg 154501e04c3fSmrgextern const char *const ir_expression_operation_strings[ir_last_opcode + 1]; 154601e04c3fSmrgextern const char *const ir_expression_operation_enum_strings[ir_last_opcode + 1]; 154701e04c3fSmrg 154801e04c3fSmrgclass ir_expression : public ir_rvalue { 154901e04c3fSmrgpublic: 155001e04c3fSmrg ir_expression(int op, const struct glsl_type *type, 155101e04c3fSmrg ir_rvalue *op0, ir_rvalue *op1 = NULL, 155201e04c3fSmrg ir_rvalue *op2 = NULL, ir_rvalue *op3 = NULL); 155301e04c3fSmrg 155401e04c3fSmrg /** 155501e04c3fSmrg * Constructor for unary operation expressions 155601e04c3fSmrg */ 155701e04c3fSmrg ir_expression(int op, ir_rvalue *); 155801e04c3fSmrg 155901e04c3fSmrg /** 156001e04c3fSmrg * Constructor for binary operation expressions 156101e04c3fSmrg */ 156201e04c3fSmrg ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1); 156301e04c3fSmrg 156401e04c3fSmrg /** 156501e04c3fSmrg * Constructor for ternary operation expressions 156601e04c3fSmrg */ 156701e04c3fSmrg ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2); 156801e04c3fSmrg 156901e04c3fSmrg virtual bool equals(const ir_instruction *ir, 157001e04c3fSmrg enum ir_node_type ignore = ir_type_unset) const; 157101e04c3fSmrg 157201e04c3fSmrg virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const; 157301e04c3fSmrg 157401e04c3fSmrg /** 157501e04c3fSmrg * Attempt to constant-fold the expression 157601e04c3fSmrg * 157701e04c3fSmrg * The "variable_context" hash table links ir_variable * to ir_constant * 157801e04c3fSmrg * that represent the variables' values. \c NULL represents an empty 157901e04c3fSmrg * context. 158001e04c3fSmrg * 158101e04c3fSmrg * If the expression cannot be constant folded, this method will return 158201e04c3fSmrg * \c NULL. 158301e04c3fSmrg */ 158401e04c3fSmrg virtual ir_constant *constant_expression_value(void *mem_ctx, 158501e04c3fSmrg struct hash_table *variable_context = NULL); 158601e04c3fSmrg 158701e04c3fSmrg /** 158801e04c3fSmrg * This is only here for ir_reader to used for testing purposes please use 158901e04c3fSmrg * the precomputed num_operands field if you need the number of operands. 159001e04c3fSmrg */ 159101e04c3fSmrg static unsigned get_num_operands(ir_expression_operation); 159201e04c3fSmrg 159301e04c3fSmrg /** 159401e04c3fSmrg * Return whether the expression operates on vectors horizontally. 159501e04c3fSmrg */ 159601e04c3fSmrg bool is_horizontal() const 159701e04c3fSmrg { 159801e04c3fSmrg return operation == ir_binop_all_equal || 159901e04c3fSmrg operation == ir_binop_any_nequal || 160001e04c3fSmrg operation == ir_binop_dot || 160101e04c3fSmrg operation == ir_binop_vector_extract || 160201e04c3fSmrg operation == ir_triop_vector_insert || 160301e04c3fSmrg operation == ir_binop_ubo_load || 160401e04c3fSmrg operation == ir_quadop_vector; 160501e04c3fSmrg } 160601e04c3fSmrg 160701e04c3fSmrg /** 160801e04c3fSmrg * Do a reverse-lookup to translate the given string into an operator. 160901e04c3fSmrg */ 161001e04c3fSmrg static ir_expression_operation get_operator(const char *); 161101e04c3fSmrg 161201e04c3fSmrg virtual void accept(ir_visitor *v) 161301e04c3fSmrg { 161401e04c3fSmrg v->visit(this); 161501e04c3fSmrg } 161601e04c3fSmrg 161701e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 161801e04c3fSmrg 161901e04c3fSmrg virtual ir_variable *variable_referenced() const; 162001e04c3fSmrg 162101e04c3fSmrg /** 162201e04c3fSmrg * Determine the number of operands used by an expression 162301e04c3fSmrg */ 162401e04c3fSmrg void init_num_operands() 162501e04c3fSmrg { 162601e04c3fSmrg if (operation == ir_quadop_vector) { 162701e04c3fSmrg num_operands = this->type->vector_elements; 162801e04c3fSmrg } else { 162901e04c3fSmrg num_operands = get_num_operands(operation); 163001e04c3fSmrg } 163101e04c3fSmrg } 163201e04c3fSmrg 163301e04c3fSmrg ir_expression_operation operation; 163401e04c3fSmrg ir_rvalue *operands[4]; 163501e04c3fSmrg uint8_t num_operands; 163601e04c3fSmrg}; 163701e04c3fSmrg 163801e04c3fSmrg 163901e04c3fSmrg/** 164001e04c3fSmrg * HIR instruction representing a high-level function call, containing a list 164101e04c3fSmrg * of parameters and returning a value in the supplied temporary. 164201e04c3fSmrg */ 164301e04c3fSmrgclass ir_call : public ir_instruction { 164401e04c3fSmrgpublic: 164501e04c3fSmrg ir_call(ir_function_signature *callee, 164601e04c3fSmrg ir_dereference_variable *return_deref, 164701e04c3fSmrg exec_list *actual_parameters) 164801e04c3fSmrg : ir_instruction(ir_type_call), return_deref(return_deref), callee(callee), sub_var(NULL), array_idx(NULL) 164901e04c3fSmrg { 165001e04c3fSmrg assert(callee->return_type != NULL); 165101e04c3fSmrg actual_parameters->move_nodes_to(& this->actual_parameters); 165201e04c3fSmrg } 165301e04c3fSmrg 165401e04c3fSmrg ir_call(ir_function_signature *callee, 165501e04c3fSmrg ir_dereference_variable *return_deref, 165601e04c3fSmrg exec_list *actual_parameters, 165701e04c3fSmrg ir_variable *var, ir_rvalue *array_idx) 165801e04c3fSmrg : ir_instruction(ir_type_call), return_deref(return_deref), callee(callee), sub_var(var), array_idx(array_idx) 165901e04c3fSmrg { 166001e04c3fSmrg assert(callee->return_type != NULL); 166101e04c3fSmrg actual_parameters->move_nodes_to(& this->actual_parameters); 166201e04c3fSmrg } 166301e04c3fSmrg 166401e04c3fSmrg virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const; 166501e04c3fSmrg 166601e04c3fSmrg virtual ir_constant *constant_expression_value(void *mem_ctx, 166701e04c3fSmrg struct hash_table *variable_context = NULL); 166801e04c3fSmrg 166901e04c3fSmrg virtual void accept(ir_visitor *v) 167001e04c3fSmrg { 167101e04c3fSmrg v->visit(this); 167201e04c3fSmrg } 167301e04c3fSmrg 167401e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 167501e04c3fSmrg 167601e04c3fSmrg /** 167701e04c3fSmrg * Get the name of the function being called. 167801e04c3fSmrg */ 167901e04c3fSmrg const char *callee_name() const 168001e04c3fSmrg { 168101e04c3fSmrg return callee->function_name(); 168201e04c3fSmrg } 168301e04c3fSmrg 168401e04c3fSmrg /** 168501e04c3fSmrg * Generates an inline version of the function before @ir, 168601e04c3fSmrg * storing the return value in return_deref. 168701e04c3fSmrg */ 168801e04c3fSmrg void generate_inline(ir_instruction *ir); 168901e04c3fSmrg 169001e04c3fSmrg /** 169101e04c3fSmrg * Storage for the function's return value. 169201e04c3fSmrg * This must be NULL if the return type is void. 169301e04c3fSmrg */ 169401e04c3fSmrg ir_dereference_variable *return_deref; 169501e04c3fSmrg 169601e04c3fSmrg /** 169701e04c3fSmrg * The specific function signature being called. 169801e04c3fSmrg */ 169901e04c3fSmrg ir_function_signature *callee; 170001e04c3fSmrg 170101e04c3fSmrg /* List of ir_rvalue of paramaters passed in this call. */ 170201e04c3fSmrg exec_list actual_parameters; 170301e04c3fSmrg 170401e04c3fSmrg /* 170501e04c3fSmrg * ARB_shader_subroutine support - 170601e04c3fSmrg * the subroutine uniform variable and array index 170701e04c3fSmrg * rvalue to be used in the lowering pass later. 170801e04c3fSmrg */ 170901e04c3fSmrg ir_variable *sub_var; 171001e04c3fSmrg ir_rvalue *array_idx; 171101e04c3fSmrg}; 171201e04c3fSmrg 171301e04c3fSmrg 171401e04c3fSmrg/** 171501e04c3fSmrg * \name Jump-like IR instructions. 171601e04c3fSmrg * 171701e04c3fSmrg * These include \c break, \c continue, \c return, and \c discard. 171801e04c3fSmrg */ 171901e04c3fSmrg/*@{*/ 172001e04c3fSmrgclass ir_jump : public ir_instruction { 172101e04c3fSmrgprotected: 172201e04c3fSmrg ir_jump(enum ir_node_type t) 172301e04c3fSmrg : ir_instruction(t) 172401e04c3fSmrg { 172501e04c3fSmrg } 172601e04c3fSmrg}; 172701e04c3fSmrg 172801e04c3fSmrgclass ir_return : public ir_jump { 172901e04c3fSmrgpublic: 173001e04c3fSmrg ir_return() 173101e04c3fSmrg : ir_jump(ir_type_return), value(NULL) 173201e04c3fSmrg { 173301e04c3fSmrg } 173401e04c3fSmrg 173501e04c3fSmrg ir_return(ir_rvalue *value) 173601e04c3fSmrg : ir_jump(ir_type_return), value(value) 173701e04c3fSmrg { 173801e04c3fSmrg } 173901e04c3fSmrg 174001e04c3fSmrg virtual ir_return *clone(void *mem_ctx, struct hash_table *) const; 174101e04c3fSmrg 174201e04c3fSmrg ir_rvalue *get_value() const 174301e04c3fSmrg { 174401e04c3fSmrg return value; 174501e04c3fSmrg } 174601e04c3fSmrg 174701e04c3fSmrg virtual void accept(ir_visitor *v) 174801e04c3fSmrg { 174901e04c3fSmrg v->visit(this); 175001e04c3fSmrg } 175101e04c3fSmrg 175201e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 175301e04c3fSmrg 175401e04c3fSmrg ir_rvalue *value; 175501e04c3fSmrg}; 175601e04c3fSmrg 175701e04c3fSmrg 175801e04c3fSmrg/** 175901e04c3fSmrg * Jump instructions used inside loops 176001e04c3fSmrg * 176101e04c3fSmrg * These include \c break and \c continue. The \c break within a loop is 176201e04c3fSmrg * different from the \c break within a switch-statement. 176301e04c3fSmrg * 176401e04c3fSmrg * \sa ir_switch_jump 176501e04c3fSmrg */ 176601e04c3fSmrgclass ir_loop_jump : public ir_jump { 176701e04c3fSmrgpublic: 176801e04c3fSmrg enum jump_mode { 176901e04c3fSmrg jump_break, 177001e04c3fSmrg jump_continue 177101e04c3fSmrg }; 177201e04c3fSmrg 177301e04c3fSmrg ir_loop_jump(jump_mode mode) 177401e04c3fSmrg : ir_jump(ir_type_loop_jump) 177501e04c3fSmrg { 177601e04c3fSmrg this->mode = mode; 177701e04c3fSmrg } 177801e04c3fSmrg 177901e04c3fSmrg virtual ir_loop_jump *clone(void *mem_ctx, struct hash_table *) const; 178001e04c3fSmrg 178101e04c3fSmrg virtual void accept(ir_visitor *v) 178201e04c3fSmrg { 178301e04c3fSmrg v->visit(this); 178401e04c3fSmrg } 178501e04c3fSmrg 178601e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 178701e04c3fSmrg 178801e04c3fSmrg bool is_break() const 178901e04c3fSmrg { 179001e04c3fSmrg return mode == jump_break; 179101e04c3fSmrg } 179201e04c3fSmrg 179301e04c3fSmrg bool is_continue() const 179401e04c3fSmrg { 179501e04c3fSmrg return mode == jump_continue; 179601e04c3fSmrg } 179701e04c3fSmrg 179801e04c3fSmrg /** Mode selector for the jump instruction. */ 179901e04c3fSmrg enum jump_mode mode; 180001e04c3fSmrg}; 180101e04c3fSmrg 180201e04c3fSmrg/** 180301e04c3fSmrg * IR instruction representing discard statements. 180401e04c3fSmrg */ 180501e04c3fSmrgclass ir_discard : public ir_jump { 180601e04c3fSmrgpublic: 180701e04c3fSmrg ir_discard() 180801e04c3fSmrg : ir_jump(ir_type_discard) 180901e04c3fSmrg { 181001e04c3fSmrg this->condition = NULL; 181101e04c3fSmrg } 181201e04c3fSmrg 181301e04c3fSmrg ir_discard(ir_rvalue *cond) 181401e04c3fSmrg : ir_jump(ir_type_discard) 181501e04c3fSmrg { 181601e04c3fSmrg this->condition = cond; 181701e04c3fSmrg } 181801e04c3fSmrg 181901e04c3fSmrg virtual ir_discard *clone(void *mem_ctx, struct hash_table *ht) const; 182001e04c3fSmrg 182101e04c3fSmrg virtual void accept(ir_visitor *v) 182201e04c3fSmrg { 182301e04c3fSmrg v->visit(this); 182401e04c3fSmrg } 182501e04c3fSmrg 182601e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 182701e04c3fSmrg 182801e04c3fSmrg ir_rvalue *condition; 182901e04c3fSmrg}; 183001e04c3fSmrg/*@}*/ 183101e04c3fSmrg 183201e04c3fSmrg 18337ec681f3Smrg/** 18347ec681f3Smrg * IR instruction representing demote statements from 18357ec681f3Smrg * GL_EXT_demote_to_helper_invocation. 18367ec681f3Smrg */ 18377ec681f3Smrgclass ir_demote : public ir_instruction { 18387ec681f3Smrgpublic: 18397ec681f3Smrg ir_demote() 18407ec681f3Smrg : ir_instruction(ir_type_demote) 18417ec681f3Smrg { 18427ec681f3Smrg } 18437ec681f3Smrg 18447ec681f3Smrg virtual ir_demote *clone(void *mem_ctx, struct hash_table *ht) const; 18457ec681f3Smrg 18467ec681f3Smrg virtual void accept(ir_visitor *v) 18477ec681f3Smrg { 18487ec681f3Smrg v->visit(this); 18497ec681f3Smrg } 18507ec681f3Smrg 18517ec681f3Smrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 18527ec681f3Smrg}; 18537ec681f3Smrg 18547ec681f3Smrg 185501e04c3fSmrg/** 185601e04c3fSmrg * Texture sampling opcodes used in ir_texture 185701e04c3fSmrg */ 185801e04c3fSmrgenum ir_texture_opcode { 185901e04c3fSmrg ir_tex, /**< Regular texture look-up */ 186001e04c3fSmrg ir_txb, /**< Texture look-up with LOD bias */ 186101e04c3fSmrg ir_txl, /**< Texture look-up with explicit LOD */ 18627ec681f3Smrg ir_txd, /**< Texture look-up with partial derivatives */ 186301e04c3fSmrg ir_txf, /**< Texel fetch with explicit LOD */ 186401e04c3fSmrg ir_txf_ms, /**< Multisample texture fetch */ 186501e04c3fSmrg ir_txs, /**< Texture size */ 186601e04c3fSmrg ir_lod, /**< Texture lod query */ 186701e04c3fSmrg ir_tg4, /**< Texture gather */ 186801e04c3fSmrg ir_query_levels, /**< Texture levels query */ 186901e04c3fSmrg ir_texture_samples, /**< Texture samples query */ 187001e04c3fSmrg ir_samples_identical, /**< Query whether all samples are definitely identical. */ 187101e04c3fSmrg}; 187201e04c3fSmrg 187301e04c3fSmrg 187401e04c3fSmrg/** 187501e04c3fSmrg * IR instruction to sample a texture 187601e04c3fSmrg * 187701e04c3fSmrg * The specific form of the IR instruction depends on the \c mode value 187801e04c3fSmrg * selected from \c ir_texture_opcodes. In the printed IR, these will 187901e04c3fSmrg * appear as: 188001e04c3fSmrg * 188101e04c3fSmrg * Texel offset (0 or an expression) 188201e04c3fSmrg * | Projection divisor 188301e04c3fSmrg * | | Shadow comparator 188401e04c3fSmrg * | | | 188501e04c3fSmrg * v v v 188601e04c3fSmrg * (tex <type> <sampler> <coordinate> 0 1 ( )) 188701e04c3fSmrg * (txb <type> <sampler> <coordinate> 0 1 ( ) <bias>) 188801e04c3fSmrg * (txl <type> <sampler> <coordinate> 0 1 ( ) <lod>) 188901e04c3fSmrg * (txd <type> <sampler> <coordinate> 0 1 ( ) (dPdx dPdy)) 189001e04c3fSmrg * (txf <type> <sampler> <coordinate> 0 <lod>) 189101e04c3fSmrg * (txf_ms 189201e04c3fSmrg * <type> <sampler> <coordinate> <sample_index>) 189301e04c3fSmrg * (txs <type> <sampler> <lod>) 189401e04c3fSmrg * (lod <type> <sampler> <coordinate>) 189501e04c3fSmrg * (tg4 <type> <sampler> <coordinate> <offset> <component>) 189601e04c3fSmrg * (query_levels <type> <sampler>) 189701e04c3fSmrg * (samples_identical <sampler> <coordinate>) 189801e04c3fSmrg */ 189901e04c3fSmrgclass ir_texture : public ir_rvalue { 190001e04c3fSmrgpublic: 190101e04c3fSmrg ir_texture(enum ir_texture_opcode op) 190201e04c3fSmrg : ir_rvalue(ir_type_texture), 190301e04c3fSmrg op(op), sampler(NULL), coordinate(NULL), projector(NULL), 190401e04c3fSmrg shadow_comparator(NULL), offset(NULL) 190501e04c3fSmrg { 190601e04c3fSmrg memset(&lod_info, 0, sizeof(lod_info)); 190701e04c3fSmrg } 190801e04c3fSmrg 190901e04c3fSmrg virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const; 191001e04c3fSmrg 191101e04c3fSmrg virtual ir_constant *constant_expression_value(void *mem_ctx, 191201e04c3fSmrg struct hash_table *variable_context = NULL); 191301e04c3fSmrg 191401e04c3fSmrg virtual void accept(ir_visitor *v) 191501e04c3fSmrg { 191601e04c3fSmrg v->visit(this); 191701e04c3fSmrg } 191801e04c3fSmrg 191901e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 192001e04c3fSmrg 192101e04c3fSmrg virtual bool equals(const ir_instruction *ir, 192201e04c3fSmrg enum ir_node_type ignore = ir_type_unset) const; 192301e04c3fSmrg 192401e04c3fSmrg /** 192501e04c3fSmrg * Return a string representing the ir_texture_opcode. 192601e04c3fSmrg */ 192701e04c3fSmrg const char *opcode_string(); 192801e04c3fSmrg 192901e04c3fSmrg /** Set the sampler and type. */ 193001e04c3fSmrg void set_sampler(ir_dereference *sampler, const glsl_type *type); 193101e04c3fSmrg 193201e04c3fSmrg /** 193301e04c3fSmrg * Do a reverse-lookup to translate a string into an ir_texture_opcode. 193401e04c3fSmrg */ 193501e04c3fSmrg static ir_texture_opcode get_opcode(const char *); 193601e04c3fSmrg 193701e04c3fSmrg enum ir_texture_opcode op; 193801e04c3fSmrg 193901e04c3fSmrg /** Sampler to use for the texture access. */ 194001e04c3fSmrg ir_dereference *sampler; 194101e04c3fSmrg 194201e04c3fSmrg /** Texture coordinate to sample */ 194301e04c3fSmrg ir_rvalue *coordinate; 194401e04c3fSmrg 194501e04c3fSmrg /** 194601e04c3fSmrg * Value used for projective divide. 194701e04c3fSmrg * 194801e04c3fSmrg * If there is no projective divide (the common case), this will be 194901e04c3fSmrg * \c NULL. Optimization passes should check for this to point to a constant 195001e04c3fSmrg * of 1.0 and replace that with \c NULL. 195101e04c3fSmrg */ 195201e04c3fSmrg ir_rvalue *projector; 195301e04c3fSmrg 195401e04c3fSmrg /** 195501e04c3fSmrg * Coordinate used for comparison on shadow look-ups. 195601e04c3fSmrg * 195701e04c3fSmrg * If there is no shadow comparison, this will be \c NULL. For the 195801e04c3fSmrg * \c ir_txf opcode, this *must* be \c NULL. 195901e04c3fSmrg */ 196001e04c3fSmrg ir_rvalue *shadow_comparator; 196101e04c3fSmrg 196201e04c3fSmrg /** Texel offset. */ 196301e04c3fSmrg ir_rvalue *offset; 196401e04c3fSmrg 196501e04c3fSmrg union { 196601e04c3fSmrg ir_rvalue *lod; /**< Floating point LOD */ 196701e04c3fSmrg ir_rvalue *bias; /**< Floating point LOD bias */ 196801e04c3fSmrg ir_rvalue *sample_index; /**< MSAA sample index */ 196901e04c3fSmrg ir_rvalue *component; /**< Gather component selector */ 197001e04c3fSmrg struct { 197101e04c3fSmrg ir_rvalue *dPdx; /**< Partial derivative of coordinate wrt X */ 197201e04c3fSmrg ir_rvalue *dPdy; /**< Partial derivative of coordinate wrt Y */ 197301e04c3fSmrg } grad; 197401e04c3fSmrg } lod_info; 197501e04c3fSmrg}; 197601e04c3fSmrg 197701e04c3fSmrg 197801e04c3fSmrgstruct ir_swizzle_mask { 197901e04c3fSmrg unsigned x:2; 198001e04c3fSmrg unsigned y:2; 198101e04c3fSmrg unsigned z:2; 198201e04c3fSmrg unsigned w:2; 198301e04c3fSmrg 198401e04c3fSmrg /** 198501e04c3fSmrg * Number of components in the swizzle. 198601e04c3fSmrg */ 198701e04c3fSmrg unsigned num_components:3; 198801e04c3fSmrg 198901e04c3fSmrg /** 199001e04c3fSmrg * Does the swizzle contain duplicate components? 199101e04c3fSmrg * 199201e04c3fSmrg * L-value swizzles cannot contain duplicate components. 199301e04c3fSmrg */ 199401e04c3fSmrg unsigned has_duplicates:1; 199501e04c3fSmrg}; 199601e04c3fSmrg 199701e04c3fSmrg 199801e04c3fSmrgclass ir_swizzle : public ir_rvalue { 199901e04c3fSmrgpublic: 200001e04c3fSmrg ir_swizzle(ir_rvalue *, unsigned x, unsigned y, unsigned z, unsigned w, 200101e04c3fSmrg unsigned count); 200201e04c3fSmrg 200301e04c3fSmrg ir_swizzle(ir_rvalue *val, const unsigned *components, unsigned count); 200401e04c3fSmrg 200501e04c3fSmrg ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask); 200601e04c3fSmrg 200701e04c3fSmrg virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const; 200801e04c3fSmrg 200901e04c3fSmrg virtual ir_constant *constant_expression_value(void *mem_ctx, 201001e04c3fSmrg struct hash_table *variable_context = NULL); 201101e04c3fSmrg 201201e04c3fSmrg /** 201301e04c3fSmrg * Construct an ir_swizzle from the textual representation. Can fail. 201401e04c3fSmrg */ 201501e04c3fSmrg static ir_swizzle *create(ir_rvalue *, const char *, unsigned vector_length); 201601e04c3fSmrg 201701e04c3fSmrg virtual void accept(ir_visitor *v) 201801e04c3fSmrg { 201901e04c3fSmrg v->visit(this); 202001e04c3fSmrg } 202101e04c3fSmrg 202201e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 202301e04c3fSmrg 202401e04c3fSmrg virtual bool equals(const ir_instruction *ir, 202501e04c3fSmrg enum ir_node_type ignore = ir_type_unset) const; 202601e04c3fSmrg 202701e04c3fSmrg bool is_lvalue(const struct _mesa_glsl_parse_state *state) const 202801e04c3fSmrg { 202901e04c3fSmrg return val->is_lvalue(state) && !mask.has_duplicates; 203001e04c3fSmrg } 203101e04c3fSmrg 203201e04c3fSmrg /** 203301e04c3fSmrg * Get the variable that is ultimately referenced by an r-value 203401e04c3fSmrg */ 203501e04c3fSmrg virtual ir_variable *variable_referenced() const; 203601e04c3fSmrg 203701e04c3fSmrg ir_rvalue *val; 203801e04c3fSmrg ir_swizzle_mask mask; 203901e04c3fSmrg 204001e04c3fSmrgprivate: 204101e04c3fSmrg /** 204201e04c3fSmrg * Initialize the mask component of a swizzle 204301e04c3fSmrg * 204401e04c3fSmrg * This is used by the \c ir_swizzle constructors. 204501e04c3fSmrg */ 204601e04c3fSmrg void init_mask(const unsigned *components, unsigned count); 204701e04c3fSmrg}; 204801e04c3fSmrg 204901e04c3fSmrg 205001e04c3fSmrgclass ir_dereference : public ir_rvalue { 205101e04c3fSmrgpublic: 205201e04c3fSmrg virtual ir_dereference *clone(void *mem_ctx, struct hash_table *) const = 0; 205301e04c3fSmrg 205401e04c3fSmrg bool is_lvalue(const struct _mesa_glsl_parse_state *state) const; 205501e04c3fSmrg 205601e04c3fSmrg /** 205701e04c3fSmrg * Get the variable that is ultimately referenced by an r-value 205801e04c3fSmrg */ 205901e04c3fSmrg virtual ir_variable *variable_referenced() const = 0; 206001e04c3fSmrg 20617ec681f3Smrg /** 20627ec681f3Smrg * Get the precision. This can either come from the eventual variable that 20637ec681f3Smrg * is dereferenced, or from a record member. 20647ec681f3Smrg */ 20657ec681f3Smrg virtual int precision() const = 0; 20667ec681f3Smrg 206701e04c3fSmrgprotected: 206801e04c3fSmrg ir_dereference(enum ir_node_type t) 206901e04c3fSmrg : ir_rvalue(t) 207001e04c3fSmrg { 207101e04c3fSmrg } 207201e04c3fSmrg}; 207301e04c3fSmrg 207401e04c3fSmrg 207501e04c3fSmrgclass ir_dereference_variable : public ir_dereference { 207601e04c3fSmrgpublic: 207701e04c3fSmrg ir_dereference_variable(ir_variable *var); 207801e04c3fSmrg 207901e04c3fSmrg virtual ir_dereference_variable *clone(void *mem_ctx, 208001e04c3fSmrg struct hash_table *) const; 208101e04c3fSmrg 208201e04c3fSmrg virtual ir_constant *constant_expression_value(void *mem_ctx, 208301e04c3fSmrg struct hash_table *variable_context = NULL); 208401e04c3fSmrg 208501e04c3fSmrg virtual bool equals(const ir_instruction *ir, 208601e04c3fSmrg enum ir_node_type ignore = ir_type_unset) const; 208701e04c3fSmrg 208801e04c3fSmrg /** 208901e04c3fSmrg * Get the variable that is ultimately referenced by an r-value 209001e04c3fSmrg */ 209101e04c3fSmrg virtual ir_variable *variable_referenced() const 209201e04c3fSmrg { 209301e04c3fSmrg return this->var; 209401e04c3fSmrg } 209501e04c3fSmrg 20967ec681f3Smrg virtual int precision() const 20977ec681f3Smrg { 20987ec681f3Smrg return this->var->data.precision; 20997ec681f3Smrg } 21007ec681f3Smrg 210101e04c3fSmrg virtual ir_variable *whole_variable_referenced() 210201e04c3fSmrg { 210301e04c3fSmrg /* ir_dereference_variable objects always dereference the entire 210401e04c3fSmrg * variable. However, if this dereference is dereferenced by anything 21057ec681f3Smrg * else, the complete dereference chain is not a whole-variable 210601e04c3fSmrg * dereference. This method should only be called on the top most 210701e04c3fSmrg * ir_rvalue in a dereference chain. 210801e04c3fSmrg */ 210901e04c3fSmrg return this->var; 211001e04c3fSmrg } 211101e04c3fSmrg 211201e04c3fSmrg virtual void accept(ir_visitor *v) 211301e04c3fSmrg { 211401e04c3fSmrg v->visit(this); 211501e04c3fSmrg } 211601e04c3fSmrg 211701e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 211801e04c3fSmrg 211901e04c3fSmrg /** 212001e04c3fSmrg * Object being dereferenced. 212101e04c3fSmrg */ 212201e04c3fSmrg ir_variable *var; 212301e04c3fSmrg}; 212401e04c3fSmrg 212501e04c3fSmrg 212601e04c3fSmrgclass ir_dereference_array : public ir_dereference { 212701e04c3fSmrgpublic: 212801e04c3fSmrg ir_dereference_array(ir_rvalue *value, ir_rvalue *array_index); 212901e04c3fSmrg 213001e04c3fSmrg ir_dereference_array(ir_variable *var, ir_rvalue *array_index); 213101e04c3fSmrg 213201e04c3fSmrg virtual ir_dereference_array *clone(void *mem_ctx, 213301e04c3fSmrg struct hash_table *) const; 213401e04c3fSmrg 213501e04c3fSmrg virtual ir_constant *constant_expression_value(void *mem_ctx, 213601e04c3fSmrg struct hash_table *variable_context = NULL); 213701e04c3fSmrg 213801e04c3fSmrg virtual bool equals(const ir_instruction *ir, 213901e04c3fSmrg enum ir_node_type ignore = ir_type_unset) const; 214001e04c3fSmrg 214101e04c3fSmrg /** 214201e04c3fSmrg * Get the variable that is ultimately referenced by an r-value 214301e04c3fSmrg */ 214401e04c3fSmrg virtual ir_variable *variable_referenced() const 214501e04c3fSmrg { 214601e04c3fSmrg return this->array->variable_referenced(); 214701e04c3fSmrg } 214801e04c3fSmrg 21497ec681f3Smrg virtual int precision() const 21507ec681f3Smrg { 21517ec681f3Smrg ir_dereference *deref = this->array->as_dereference(); 21527ec681f3Smrg 21537ec681f3Smrg if (deref == NULL) 21547ec681f3Smrg return GLSL_PRECISION_NONE; 21557ec681f3Smrg else 21567ec681f3Smrg return deref->precision(); 21577ec681f3Smrg } 21587ec681f3Smrg 215901e04c3fSmrg virtual void accept(ir_visitor *v) 216001e04c3fSmrg { 216101e04c3fSmrg v->visit(this); 216201e04c3fSmrg } 216301e04c3fSmrg 216401e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 216501e04c3fSmrg 216601e04c3fSmrg ir_rvalue *array; 216701e04c3fSmrg ir_rvalue *array_index; 216801e04c3fSmrg 216901e04c3fSmrgprivate: 217001e04c3fSmrg void set_array(ir_rvalue *value); 217101e04c3fSmrg}; 217201e04c3fSmrg 217301e04c3fSmrg 217401e04c3fSmrgclass ir_dereference_record : public ir_dereference { 217501e04c3fSmrgpublic: 217601e04c3fSmrg ir_dereference_record(ir_rvalue *value, const char *field); 217701e04c3fSmrg 217801e04c3fSmrg ir_dereference_record(ir_variable *var, const char *field); 217901e04c3fSmrg 218001e04c3fSmrg virtual ir_dereference_record *clone(void *mem_ctx, 218101e04c3fSmrg struct hash_table *) const; 218201e04c3fSmrg 218301e04c3fSmrg virtual ir_constant *constant_expression_value(void *mem_ctx, 218401e04c3fSmrg struct hash_table *variable_context = NULL); 218501e04c3fSmrg 218601e04c3fSmrg /** 218701e04c3fSmrg * Get the variable that is ultimately referenced by an r-value 218801e04c3fSmrg */ 218901e04c3fSmrg virtual ir_variable *variable_referenced() const 219001e04c3fSmrg { 219101e04c3fSmrg return this->record->variable_referenced(); 219201e04c3fSmrg } 219301e04c3fSmrg 21947ec681f3Smrg virtual int precision() const 21957ec681f3Smrg { 21967ec681f3Smrg glsl_struct_field *field = record->type->fields.structure + field_idx; 21977ec681f3Smrg 21987ec681f3Smrg return field->precision; 21997ec681f3Smrg } 22007ec681f3Smrg 220101e04c3fSmrg virtual void accept(ir_visitor *v) 220201e04c3fSmrg { 220301e04c3fSmrg v->visit(this); 220401e04c3fSmrg } 220501e04c3fSmrg 220601e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 220701e04c3fSmrg 220801e04c3fSmrg ir_rvalue *record; 220901e04c3fSmrg int field_idx; 221001e04c3fSmrg}; 221101e04c3fSmrg 221201e04c3fSmrg 221301e04c3fSmrg/** 221401e04c3fSmrg * Data stored in an ir_constant 221501e04c3fSmrg */ 221601e04c3fSmrgunion ir_constant_data { 221701e04c3fSmrg unsigned u[16]; 221801e04c3fSmrg int i[16]; 221901e04c3fSmrg float f[16]; 222001e04c3fSmrg bool b[16]; 222101e04c3fSmrg double d[16]; 22227ec681f3Smrg uint16_t f16[16]; 22237ec681f3Smrg uint16_t u16[16]; 22247ec681f3Smrg int16_t i16[16]; 222501e04c3fSmrg uint64_t u64[16]; 222601e04c3fSmrg int64_t i64[16]; 222701e04c3fSmrg}; 222801e04c3fSmrg 222901e04c3fSmrg 223001e04c3fSmrgclass ir_constant : public ir_rvalue { 223101e04c3fSmrgpublic: 223201e04c3fSmrg ir_constant(const struct glsl_type *type, const ir_constant_data *data); 223301e04c3fSmrg ir_constant(bool b, unsigned vector_elements=1); 22347ec681f3Smrg ir_constant(int16_t i16, unsigned vector_elements=1); 22357ec681f3Smrg ir_constant(uint16_t u16, unsigned vector_elements=1); 223601e04c3fSmrg ir_constant(unsigned int u, unsigned vector_elements=1); 223701e04c3fSmrg ir_constant(int i, unsigned vector_elements=1); 22387ec681f3Smrg ir_constant(float16_t f16, unsigned vector_elements=1); 223901e04c3fSmrg ir_constant(float f, unsigned vector_elements=1); 224001e04c3fSmrg ir_constant(double d, unsigned vector_elements=1); 224101e04c3fSmrg ir_constant(uint64_t u64, unsigned vector_elements=1); 224201e04c3fSmrg ir_constant(int64_t i64, unsigned vector_elements=1); 224301e04c3fSmrg 224401e04c3fSmrg /** 224501e04c3fSmrg * Construct an ir_constant from a list of ir_constant values 224601e04c3fSmrg */ 224701e04c3fSmrg ir_constant(const struct glsl_type *type, exec_list *values); 224801e04c3fSmrg 224901e04c3fSmrg /** 225001e04c3fSmrg * Construct an ir_constant from a scalar component of another ir_constant 225101e04c3fSmrg * 225201e04c3fSmrg * The new \c ir_constant inherits the type of the component from the 225301e04c3fSmrg * source constant. 225401e04c3fSmrg * 225501e04c3fSmrg * \note 225601e04c3fSmrg * In the case of a matrix constant, the new constant is a scalar, \b not 225701e04c3fSmrg * a vector. 225801e04c3fSmrg */ 225901e04c3fSmrg ir_constant(const ir_constant *c, unsigned i); 226001e04c3fSmrg 226101e04c3fSmrg /** 226201e04c3fSmrg * Return a new ir_constant of the specified type containing all zeros. 226301e04c3fSmrg */ 226401e04c3fSmrg static ir_constant *zero(void *mem_ctx, const glsl_type *type); 226501e04c3fSmrg 226601e04c3fSmrg virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const; 226701e04c3fSmrg 226801e04c3fSmrg virtual ir_constant *constant_expression_value(void *mem_ctx, 226901e04c3fSmrg struct hash_table *variable_context = NULL); 227001e04c3fSmrg 227101e04c3fSmrg virtual void accept(ir_visitor *v) 227201e04c3fSmrg { 227301e04c3fSmrg v->visit(this); 227401e04c3fSmrg } 227501e04c3fSmrg 227601e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 227701e04c3fSmrg 227801e04c3fSmrg virtual bool equals(const ir_instruction *ir, 227901e04c3fSmrg enum ir_node_type ignore = ir_type_unset) const; 228001e04c3fSmrg 228101e04c3fSmrg /** 228201e04c3fSmrg * Get a particular component of a constant as a specific type 228301e04c3fSmrg * 228401e04c3fSmrg * This is useful, for example, to get a value from an integer constant 228501e04c3fSmrg * as a float or bool. This appears frequently when constructors are 228601e04c3fSmrg * called with all constant parameters. 228701e04c3fSmrg */ 228801e04c3fSmrg /*@{*/ 228901e04c3fSmrg bool get_bool_component(unsigned i) const; 229001e04c3fSmrg float get_float_component(unsigned i) const; 22917ec681f3Smrg uint16_t get_float16_component(unsigned i) const; 229201e04c3fSmrg double get_double_component(unsigned i) const; 22937ec681f3Smrg int16_t get_int16_component(unsigned i) const; 22947ec681f3Smrg uint16_t get_uint16_component(unsigned i) const; 229501e04c3fSmrg int get_int_component(unsigned i) const; 229601e04c3fSmrg unsigned get_uint_component(unsigned i) const; 229701e04c3fSmrg int64_t get_int64_component(unsigned i) const; 229801e04c3fSmrg uint64_t get_uint64_component(unsigned i) const; 229901e04c3fSmrg /*@}*/ 230001e04c3fSmrg 230101e04c3fSmrg ir_constant *get_array_element(unsigned i) const; 230201e04c3fSmrg 230301e04c3fSmrg ir_constant *get_record_field(int idx); 230401e04c3fSmrg 230501e04c3fSmrg /** 230601e04c3fSmrg * Copy the values on another constant at a given offset. 230701e04c3fSmrg * 230801e04c3fSmrg * The offset is ignored for array or struct copies, it's only for 230901e04c3fSmrg * scalars or vectors into vectors or matrices. 231001e04c3fSmrg * 231101e04c3fSmrg * With identical types on both sides and zero offset it's clone() 231201e04c3fSmrg * without creating a new object. 231301e04c3fSmrg */ 231401e04c3fSmrg 231501e04c3fSmrg void copy_offset(ir_constant *src, int offset); 231601e04c3fSmrg 231701e04c3fSmrg /** 231801e04c3fSmrg * Copy the values on another constant at a given offset and 231901e04c3fSmrg * following an assign-like mask. 232001e04c3fSmrg * 232101e04c3fSmrg * The mask is ignored for scalars. 232201e04c3fSmrg * 232301e04c3fSmrg * Note that this function only handles what assign can handle, 232401e04c3fSmrg * i.e. at most a vector as source and a column of a matrix as 232501e04c3fSmrg * destination. 232601e04c3fSmrg */ 232701e04c3fSmrg 232801e04c3fSmrg void copy_masked_offset(ir_constant *src, int offset, unsigned int mask); 232901e04c3fSmrg 233001e04c3fSmrg /** 233101e04c3fSmrg * Determine whether a constant has the same value as another constant 233201e04c3fSmrg * 233301e04c3fSmrg * \sa ir_constant::is_zero, ir_constant::is_one, 233401e04c3fSmrg * ir_constant::is_negative_one 233501e04c3fSmrg */ 233601e04c3fSmrg bool has_value(const ir_constant *) const; 233701e04c3fSmrg 233801e04c3fSmrg /** 233901e04c3fSmrg * Return true if this ir_constant represents the given value. 234001e04c3fSmrg * 234101e04c3fSmrg * For vectors, this checks that each component is the given value. 234201e04c3fSmrg */ 234301e04c3fSmrg virtual bool is_value(float f, int i) const; 234401e04c3fSmrg virtual bool is_zero() const; 234501e04c3fSmrg virtual bool is_one() const; 234601e04c3fSmrg virtual bool is_negative_one() const; 234701e04c3fSmrg 234801e04c3fSmrg /** 234901e04c3fSmrg * Return true for constants that could be stored as 16-bit unsigned values. 235001e04c3fSmrg * 235101e04c3fSmrg * Note that this will return true even for signed integer ir_constants, as 235201e04c3fSmrg * long as the value is non-negative and fits in 16-bits. 235301e04c3fSmrg */ 235401e04c3fSmrg virtual bool is_uint16_constant() const; 235501e04c3fSmrg 235601e04c3fSmrg /** 235701e04c3fSmrg * Value of the constant. 235801e04c3fSmrg * 235901e04c3fSmrg * The field used to back the values supplied by the constant is determined 236001e04c3fSmrg * by the type associated with the \c ir_instruction. Constants may be 236101e04c3fSmrg * scalars, vectors, or matrices. 236201e04c3fSmrg */ 236301e04c3fSmrg union ir_constant_data value; 236401e04c3fSmrg 236501e04c3fSmrg /* Array elements and structure fields */ 236601e04c3fSmrg ir_constant **const_elements; 236701e04c3fSmrg 236801e04c3fSmrgprivate: 236901e04c3fSmrg /** 237001e04c3fSmrg * Parameterless constructor only used by the clone method 237101e04c3fSmrg */ 237201e04c3fSmrg ir_constant(void); 237301e04c3fSmrg}; 237401e04c3fSmrg 237501e04c3fSmrg/** 237601e04c3fSmrg * IR instruction to emit a vertex in a geometry shader. 237701e04c3fSmrg */ 237801e04c3fSmrgclass ir_emit_vertex : public ir_instruction { 237901e04c3fSmrgpublic: 238001e04c3fSmrg ir_emit_vertex(ir_rvalue *stream) 238101e04c3fSmrg : ir_instruction(ir_type_emit_vertex), 238201e04c3fSmrg stream(stream) 238301e04c3fSmrg { 238401e04c3fSmrg assert(stream); 238501e04c3fSmrg } 238601e04c3fSmrg 238701e04c3fSmrg virtual void accept(ir_visitor *v) 238801e04c3fSmrg { 238901e04c3fSmrg v->visit(this); 239001e04c3fSmrg } 239101e04c3fSmrg 239201e04c3fSmrg virtual ir_emit_vertex *clone(void *mem_ctx, struct hash_table *ht) const 239301e04c3fSmrg { 239401e04c3fSmrg return new(mem_ctx) ir_emit_vertex(this->stream->clone(mem_ctx, ht)); 239501e04c3fSmrg } 239601e04c3fSmrg 239701e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 239801e04c3fSmrg 239901e04c3fSmrg int stream_id() const 240001e04c3fSmrg { 240101e04c3fSmrg return stream->as_constant()->value.i[0]; 240201e04c3fSmrg } 240301e04c3fSmrg 240401e04c3fSmrg ir_rvalue *stream; 240501e04c3fSmrg}; 240601e04c3fSmrg 240701e04c3fSmrg/** 240801e04c3fSmrg * IR instruction to complete the current primitive and start a new one in a 240901e04c3fSmrg * geometry shader. 241001e04c3fSmrg */ 241101e04c3fSmrgclass ir_end_primitive : public ir_instruction { 241201e04c3fSmrgpublic: 241301e04c3fSmrg ir_end_primitive(ir_rvalue *stream) 241401e04c3fSmrg : ir_instruction(ir_type_end_primitive), 241501e04c3fSmrg stream(stream) 241601e04c3fSmrg { 241701e04c3fSmrg assert(stream); 241801e04c3fSmrg } 241901e04c3fSmrg 242001e04c3fSmrg virtual void accept(ir_visitor *v) 242101e04c3fSmrg { 242201e04c3fSmrg v->visit(this); 242301e04c3fSmrg } 242401e04c3fSmrg 242501e04c3fSmrg virtual ir_end_primitive *clone(void *mem_ctx, struct hash_table *ht) const 242601e04c3fSmrg { 242701e04c3fSmrg return new(mem_ctx) ir_end_primitive(this->stream->clone(mem_ctx, ht)); 242801e04c3fSmrg } 242901e04c3fSmrg 243001e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 243101e04c3fSmrg 243201e04c3fSmrg int stream_id() const 243301e04c3fSmrg { 243401e04c3fSmrg return stream->as_constant()->value.i[0]; 243501e04c3fSmrg } 243601e04c3fSmrg 243701e04c3fSmrg ir_rvalue *stream; 243801e04c3fSmrg}; 243901e04c3fSmrg 244001e04c3fSmrg/** 244101e04c3fSmrg * IR instruction for tessellation control and compute shader barrier. 244201e04c3fSmrg */ 244301e04c3fSmrgclass ir_barrier : public ir_instruction { 244401e04c3fSmrgpublic: 244501e04c3fSmrg ir_barrier() 244601e04c3fSmrg : ir_instruction(ir_type_barrier) 244701e04c3fSmrg { 244801e04c3fSmrg } 244901e04c3fSmrg 245001e04c3fSmrg virtual void accept(ir_visitor *v) 245101e04c3fSmrg { 245201e04c3fSmrg v->visit(this); 245301e04c3fSmrg } 245401e04c3fSmrg 245501e04c3fSmrg virtual ir_barrier *clone(void *mem_ctx, struct hash_table *) const 245601e04c3fSmrg { 245701e04c3fSmrg return new(mem_ctx) ir_barrier(); 245801e04c3fSmrg } 245901e04c3fSmrg 246001e04c3fSmrg virtual ir_visitor_status accept(ir_hierarchical_visitor *); 246101e04c3fSmrg}; 246201e04c3fSmrg 246301e04c3fSmrg/*@}*/ 246401e04c3fSmrg 246501e04c3fSmrg/** 246601e04c3fSmrg * Apply a visitor to each IR node in a list 246701e04c3fSmrg */ 246801e04c3fSmrgvoid 246901e04c3fSmrgvisit_exec_list(exec_list *list, ir_visitor *visitor); 247001e04c3fSmrg 247101e04c3fSmrg/** 247201e04c3fSmrg * Validate invariants on each IR node in a list 247301e04c3fSmrg */ 247401e04c3fSmrgvoid validate_ir_tree(exec_list *instructions); 247501e04c3fSmrg 247601e04c3fSmrgstruct _mesa_glsl_parse_state; 247701e04c3fSmrgstruct gl_shader_program; 247801e04c3fSmrg 247901e04c3fSmrg/** 248001e04c3fSmrg * Detect whether an unlinked shader contains static recursion 248101e04c3fSmrg * 248201e04c3fSmrg * If the list of instructions is determined to contain static recursion, 248301e04c3fSmrg * \c _mesa_glsl_error will be called to emit error messages for each function 248401e04c3fSmrg * that is in the recursion cycle. 248501e04c3fSmrg */ 248601e04c3fSmrgvoid 248701e04c3fSmrgdetect_recursion_unlinked(struct _mesa_glsl_parse_state *state, 248801e04c3fSmrg exec_list *instructions); 248901e04c3fSmrg 249001e04c3fSmrg/** 249101e04c3fSmrg * Detect whether a linked shader contains static recursion 249201e04c3fSmrg * 249301e04c3fSmrg * If the list of instructions is determined to contain static recursion, 249401e04c3fSmrg * \c link_error_printf will be called to emit error messages for each function 249501e04c3fSmrg * that is in the recursion cycle. In addition, 249601e04c3fSmrg * \c gl_shader_program::LinkStatus will be set to false. 249701e04c3fSmrg */ 249801e04c3fSmrgvoid 249901e04c3fSmrgdetect_recursion_linked(struct gl_shader_program *prog, 250001e04c3fSmrg exec_list *instructions); 250101e04c3fSmrg 250201e04c3fSmrg/** 250301e04c3fSmrg * Make a clone of each IR instruction in a list 250401e04c3fSmrg * 250501e04c3fSmrg * \param in List of IR instructions that are to be cloned 250601e04c3fSmrg * \param out List to hold the cloned instructions 250701e04c3fSmrg */ 250801e04c3fSmrgvoid 250901e04c3fSmrgclone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in); 251001e04c3fSmrg 251101e04c3fSmrgextern void 251201e04c3fSmrg_mesa_glsl_initialize_variables(exec_list *instructions, 251301e04c3fSmrg struct _mesa_glsl_parse_state *state); 251401e04c3fSmrg 251501e04c3fSmrgextern void 251601e04c3fSmrgreparent_ir(exec_list *list, void *mem_ctx); 251701e04c3fSmrg 251801e04c3fSmrgextern void 251901e04c3fSmrgdo_set_program_inouts(exec_list *instructions, struct gl_program *prog, 252001e04c3fSmrg gl_shader_stage shader_stage); 252101e04c3fSmrg 252201e04c3fSmrgextern char * 252301e04c3fSmrgprototype_string(const glsl_type *return_type, const char *name, 252401e04c3fSmrg exec_list *parameters); 252501e04c3fSmrg 252601e04c3fSmrgconst char * 252701e04c3fSmrgmode_string(const ir_variable *var); 252801e04c3fSmrg 252901e04c3fSmrg/** 253001e04c3fSmrg * Built-in / reserved GL variables names start with "gl_" 253101e04c3fSmrg */ 253201e04c3fSmrgstatic inline bool 253301e04c3fSmrgis_gl_identifier(const char *s) 253401e04c3fSmrg{ 253501e04c3fSmrg return s && s[0] == 'g' && s[1] == 'l' && s[2] == '_'; 253601e04c3fSmrg} 253701e04c3fSmrg 253801e04c3fSmrgextern "C" { 253901e04c3fSmrg#endif /* __cplusplus */ 254001e04c3fSmrg 254101e04c3fSmrgextern void _mesa_print_ir(FILE *f, struct exec_list *instructions, 254201e04c3fSmrg struct _mesa_glsl_parse_state *state); 254301e04c3fSmrg 254401e04c3fSmrgextern void 254501e04c3fSmrgfprint_ir(FILE *f, const void *instruction); 254601e04c3fSmrg 254701e04c3fSmrgextern const struct gl_builtin_uniform_desc * 254801e04c3fSmrg_mesa_glsl_get_builtin_uniform_desc(const char *name); 254901e04c3fSmrg 255001e04c3fSmrg#ifdef __cplusplus 255101e04c3fSmrg} /* extern "C" */ 255201e04c3fSmrg#endif 255301e04c3fSmrg 255401e04c3fSmrgunsigned 255501e04c3fSmrgvertices_per_prim(GLenum prim); 255601e04c3fSmrg 255701e04c3fSmrg#endif /* IR_H */ 2558