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