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