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