1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2010 Intel Corporation
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21*61046927SAndroid Build Coastguard Worker * DEALINGS IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker #include <string.h>
24*61046927SAndroid Build Coastguard Worker #include "ir.h"
25*61046927SAndroid Build Coastguard Worker #include "util/half_float.h"
26*61046927SAndroid Build Coastguard Worker #include "util/bitscan.h"
27*61046927SAndroid Build Coastguard Worker #include "compiler/glsl_types.h"
28*61046927SAndroid Build Coastguard Worker #include "glsl_parser_extras.h"
29*61046927SAndroid Build Coastguard Worker
30*61046927SAndroid Build Coastguard Worker
ir_rvalue(enum ir_node_type t)31*61046927SAndroid Build Coastguard Worker ir_rvalue::ir_rvalue(enum ir_node_type t)
32*61046927SAndroid Build Coastguard Worker : ir_instruction(t)
33*61046927SAndroid Build Coastguard Worker {
34*61046927SAndroid Build Coastguard Worker this->type = &glsl_type_builtin_error;
35*61046927SAndroid Build Coastguard Worker }
36*61046927SAndroid Build Coastguard Worker
is_zero() const37*61046927SAndroid Build Coastguard Worker bool ir_rvalue::is_zero() const
38*61046927SAndroid Build Coastguard Worker {
39*61046927SAndroid Build Coastguard Worker return false;
40*61046927SAndroid Build Coastguard Worker }
41*61046927SAndroid Build Coastguard Worker
is_one() const42*61046927SAndroid Build Coastguard Worker bool ir_rvalue::is_one() const
43*61046927SAndroid Build Coastguard Worker {
44*61046927SAndroid Build Coastguard Worker return false;
45*61046927SAndroid Build Coastguard Worker }
46*61046927SAndroid Build Coastguard Worker
is_negative_one() const47*61046927SAndroid Build Coastguard Worker bool ir_rvalue::is_negative_one() const
48*61046927SAndroid Build Coastguard Worker {
49*61046927SAndroid Build Coastguard Worker return false;
50*61046927SAndroid Build Coastguard Worker }
51*61046927SAndroid Build Coastguard Worker
52*61046927SAndroid Build Coastguard Worker /**
53*61046927SAndroid Build Coastguard Worker * Modify the swizzle make to move one component to another
54*61046927SAndroid Build Coastguard Worker *
55*61046927SAndroid Build Coastguard Worker * \param m IR swizzle to be modified
56*61046927SAndroid Build Coastguard Worker * \param from Component in the RHS that is to be swizzled
57*61046927SAndroid Build Coastguard Worker * \param to Desired swizzle location of \c from
58*61046927SAndroid Build Coastguard Worker */
59*61046927SAndroid Build Coastguard Worker static void
update_rhs_swizzle(ir_swizzle_mask & m,unsigned from,unsigned to)60*61046927SAndroid Build Coastguard Worker update_rhs_swizzle(ir_swizzle_mask &m, unsigned from, unsigned to)
61*61046927SAndroid Build Coastguard Worker {
62*61046927SAndroid Build Coastguard Worker switch (to) {
63*61046927SAndroid Build Coastguard Worker case 0: m.x = from; break;
64*61046927SAndroid Build Coastguard Worker case 1: m.y = from; break;
65*61046927SAndroid Build Coastguard Worker case 2: m.z = from; break;
66*61046927SAndroid Build Coastguard Worker case 3: m.w = from; break;
67*61046927SAndroid Build Coastguard Worker default: assert(!"Should not get here.");
68*61046927SAndroid Build Coastguard Worker }
69*61046927SAndroid Build Coastguard Worker }
70*61046927SAndroid Build Coastguard Worker
71*61046927SAndroid Build Coastguard Worker void
set_lhs(ir_rvalue * lhs)72*61046927SAndroid Build Coastguard Worker ir_assignment::set_lhs(ir_rvalue *lhs)
73*61046927SAndroid Build Coastguard Worker {
74*61046927SAndroid Build Coastguard Worker void *mem_ctx = this;
75*61046927SAndroid Build Coastguard Worker bool swizzled = false;
76*61046927SAndroid Build Coastguard Worker
77*61046927SAndroid Build Coastguard Worker while (lhs != NULL) {
78*61046927SAndroid Build Coastguard Worker ir_swizzle *swiz = lhs->as_swizzle();
79*61046927SAndroid Build Coastguard Worker
80*61046927SAndroid Build Coastguard Worker if (swiz == NULL)
81*61046927SAndroid Build Coastguard Worker break;
82*61046927SAndroid Build Coastguard Worker
83*61046927SAndroid Build Coastguard Worker unsigned write_mask = 0;
84*61046927SAndroid Build Coastguard Worker ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 };
85*61046927SAndroid Build Coastguard Worker
86*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < swiz->mask.num_components; i++) {
87*61046927SAndroid Build Coastguard Worker unsigned c = 0;
88*61046927SAndroid Build Coastguard Worker
89*61046927SAndroid Build Coastguard Worker switch (i) {
90*61046927SAndroid Build Coastguard Worker case 0: c = swiz->mask.x; break;
91*61046927SAndroid Build Coastguard Worker case 1: c = swiz->mask.y; break;
92*61046927SAndroid Build Coastguard Worker case 2: c = swiz->mask.z; break;
93*61046927SAndroid Build Coastguard Worker case 3: c = swiz->mask.w; break;
94*61046927SAndroid Build Coastguard Worker default: assert(!"Should not get here.");
95*61046927SAndroid Build Coastguard Worker }
96*61046927SAndroid Build Coastguard Worker
97*61046927SAndroid Build Coastguard Worker write_mask |= (((this->write_mask >> i) & 1) << c);
98*61046927SAndroid Build Coastguard Worker update_rhs_swizzle(rhs_swiz, i, c);
99*61046927SAndroid Build Coastguard Worker rhs_swiz.num_components = swiz->val->type->vector_elements;
100*61046927SAndroid Build Coastguard Worker }
101*61046927SAndroid Build Coastguard Worker
102*61046927SAndroid Build Coastguard Worker this->write_mask = write_mask;
103*61046927SAndroid Build Coastguard Worker lhs = swiz->val;
104*61046927SAndroid Build Coastguard Worker
105*61046927SAndroid Build Coastguard Worker this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz);
106*61046927SAndroid Build Coastguard Worker swizzled = true;
107*61046927SAndroid Build Coastguard Worker }
108*61046927SAndroid Build Coastguard Worker
109*61046927SAndroid Build Coastguard Worker if (swizzled) {
110*61046927SAndroid Build Coastguard Worker /* Now, RHS channels line up with the LHS writemask. Collapse it
111*61046927SAndroid Build Coastguard Worker * to just the channels that will be written.
112*61046927SAndroid Build Coastguard Worker */
113*61046927SAndroid Build Coastguard Worker ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 };
114*61046927SAndroid Build Coastguard Worker int rhs_chan = 0;
115*61046927SAndroid Build Coastguard Worker for (int i = 0; i < 4; i++) {
116*61046927SAndroid Build Coastguard Worker if (write_mask & (1 << i))
117*61046927SAndroid Build Coastguard Worker update_rhs_swizzle(rhs_swiz, i, rhs_chan++);
118*61046927SAndroid Build Coastguard Worker }
119*61046927SAndroid Build Coastguard Worker rhs_swiz.num_components = rhs_chan;
120*61046927SAndroid Build Coastguard Worker this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz);
121*61046927SAndroid Build Coastguard Worker }
122*61046927SAndroid Build Coastguard Worker
123*61046927SAndroid Build Coastguard Worker assert((lhs == NULL) || lhs->as_dereference());
124*61046927SAndroid Build Coastguard Worker
125*61046927SAndroid Build Coastguard Worker this->lhs = (ir_dereference *) lhs;
126*61046927SAndroid Build Coastguard Worker }
127*61046927SAndroid Build Coastguard Worker
128*61046927SAndroid Build Coastguard Worker ir_variable *
whole_variable_written()129*61046927SAndroid Build Coastguard Worker ir_assignment::whole_variable_written()
130*61046927SAndroid Build Coastguard Worker {
131*61046927SAndroid Build Coastguard Worker ir_variable *v = this->lhs->whole_variable_referenced();
132*61046927SAndroid Build Coastguard Worker
133*61046927SAndroid Build Coastguard Worker if (v == NULL)
134*61046927SAndroid Build Coastguard Worker return NULL;
135*61046927SAndroid Build Coastguard Worker
136*61046927SAndroid Build Coastguard Worker if (glsl_type_is_scalar(v->type))
137*61046927SAndroid Build Coastguard Worker return v;
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Worker if (glsl_type_is_vector(v->type)) {
140*61046927SAndroid Build Coastguard Worker const unsigned mask = (1U << v->type->vector_elements) - 1;
141*61046927SAndroid Build Coastguard Worker
142*61046927SAndroid Build Coastguard Worker if (mask != this->write_mask)
143*61046927SAndroid Build Coastguard Worker return NULL;
144*61046927SAndroid Build Coastguard Worker }
145*61046927SAndroid Build Coastguard Worker
146*61046927SAndroid Build Coastguard Worker /* Either all the vector components are assigned or the variable is some
147*61046927SAndroid Build Coastguard Worker * composite type (and the whole thing is assigned.
148*61046927SAndroid Build Coastguard Worker */
149*61046927SAndroid Build Coastguard Worker return v;
150*61046927SAndroid Build Coastguard Worker }
151*61046927SAndroid Build Coastguard Worker
ir_assignment(ir_dereference * lhs,ir_rvalue * rhs,unsigned write_mask)152*61046927SAndroid Build Coastguard Worker ir_assignment::ir_assignment(ir_dereference *lhs, ir_rvalue *rhs,
153*61046927SAndroid Build Coastguard Worker unsigned write_mask)
154*61046927SAndroid Build Coastguard Worker : ir_instruction(ir_type_assignment)
155*61046927SAndroid Build Coastguard Worker {
156*61046927SAndroid Build Coastguard Worker this->rhs = rhs;
157*61046927SAndroid Build Coastguard Worker this->lhs = lhs;
158*61046927SAndroid Build Coastguard Worker this->write_mask = write_mask;
159*61046927SAndroid Build Coastguard Worker
160*61046927SAndroid Build Coastguard Worker if (glsl_type_is_scalar(lhs->type) || glsl_type_is_vector(lhs->type))
161*61046927SAndroid Build Coastguard Worker assert(util_bitcount(write_mask) == this->rhs->type->vector_elements);
162*61046927SAndroid Build Coastguard Worker }
163*61046927SAndroid Build Coastguard Worker
ir_assignment(ir_rvalue * lhs,ir_rvalue * rhs)164*61046927SAndroid Build Coastguard Worker ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs)
165*61046927SAndroid Build Coastguard Worker : ir_instruction(ir_type_assignment)
166*61046927SAndroid Build Coastguard Worker {
167*61046927SAndroid Build Coastguard Worker this->rhs = rhs;
168*61046927SAndroid Build Coastguard Worker
169*61046927SAndroid Build Coastguard Worker /* If the RHS is a vector type, assume that all components of the vector
170*61046927SAndroid Build Coastguard Worker * type are being written to the LHS. The write mask comes from the RHS
171*61046927SAndroid Build Coastguard Worker * because we can have a case where the LHS is a vec4 and the RHS is a
172*61046927SAndroid Build Coastguard Worker * vec3. In that case, the assignment is:
173*61046927SAndroid Build Coastguard Worker *
174*61046927SAndroid Build Coastguard Worker * (assign (...) (xyz) (var_ref lhs) (var_ref rhs))
175*61046927SAndroid Build Coastguard Worker */
176*61046927SAndroid Build Coastguard Worker if (glsl_type_is_vector(rhs->type))
177*61046927SAndroid Build Coastguard Worker this->write_mask = (1U << rhs->type->vector_elements) - 1;
178*61046927SAndroid Build Coastguard Worker else if (glsl_type_is_scalar(rhs->type))
179*61046927SAndroid Build Coastguard Worker this->write_mask = 1;
180*61046927SAndroid Build Coastguard Worker else
181*61046927SAndroid Build Coastguard Worker this->write_mask = 0;
182*61046927SAndroid Build Coastguard Worker
183*61046927SAndroid Build Coastguard Worker this->set_lhs(lhs);
184*61046927SAndroid Build Coastguard Worker }
185*61046927SAndroid Build Coastguard Worker
ir_expression(int op,const struct glsl_type * type,ir_rvalue * op0,ir_rvalue * op1,ir_rvalue * op2,ir_rvalue * op3)186*61046927SAndroid Build Coastguard Worker ir_expression::ir_expression(int op, const struct glsl_type *type,
187*61046927SAndroid Build Coastguard Worker ir_rvalue *op0, ir_rvalue *op1,
188*61046927SAndroid Build Coastguard Worker ir_rvalue *op2, ir_rvalue *op3)
189*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_expression)
190*61046927SAndroid Build Coastguard Worker {
191*61046927SAndroid Build Coastguard Worker this->type = type;
192*61046927SAndroid Build Coastguard Worker this->operation = ir_expression_operation(op);
193*61046927SAndroid Build Coastguard Worker this->operands[0] = op0;
194*61046927SAndroid Build Coastguard Worker this->operands[1] = op1;
195*61046927SAndroid Build Coastguard Worker this->operands[2] = op2;
196*61046927SAndroid Build Coastguard Worker this->operands[3] = op3;
197*61046927SAndroid Build Coastguard Worker init_num_operands();
198*61046927SAndroid Build Coastguard Worker
199*61046927SAndroid Build Coastguard Worker #ifndef NDEBUG
200*61046927SAndroid Build Coastguard Worker for (unsigned i = num_operands; i < 4; i++) {
201*61046927SAndroid Build Coastguard Worker assert(this->operands[i] == NULL);
202*61046927SAndroid Build Coastguard Worker }
203*61046927SAndroid Build Coastguard Worker
204*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_operands; i++) {
205*61046927SAndroid Build Coastguard Worker assert(this->operands[i] != NULL);
206*61046927SAndroid Build Coastguard Worker }
207*61046927SAndroid Build Coastguard Worker #endif
208*61046927SAndroid Build Coastguard Worker }
209*61046927SAndroid Build Coastguard Worker
ir_expression(int op,ir_rvalue * op0)210*61046927SAndroid Build Coastguard Worker ir_expression::ir_expression(int op, ir_rvalue *op0)
211*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_expression)
212*61046927SAndroid Build Coastguard Worker {
213*61046927SAndroid Build Coastguard Worker this->operation = ir_expression_operation(op);
214*61046927SAndroid Build Coastguard Worker this->operands[0] = op0;
215*61046927SAndroid Build Coastguard Worker this->operands[1] = NULL;
216*61046927SAndroid Build Coastguard Worker this->operands[2] = NULL;
217*61046927SAndroid Build Coastguard Worker this->operands[3] = NULL;
218*61046927SAndroid Build Coastguard Worker
219*61046927SAndroid Build Coastguard Worker assert(op <= ir_last_unop);
220*61046927SAndroid Build Coastguard Worker init_num_operands();
221*61046927SAndroid Build Coastguard Worker assert(num_operands == 1);
222*61046927SAndroid Build Coastguard Worker assert(this->operands[0]);
223*61046927SAndroid Build Coastguard Worker
224*61046927SAndroid Build Coastguard Worker switch (this->operation) {
225*61046927SAndroid Build Coastguard Worker case ir_unop_bit_not:
226*61046927SAndroid Build Coastguard Worker case ir_unop_logic_not:
227*61046927SAndroid Build Coastguard Worker case ir_unop_neg:
228*61046927SAndroid Build Coastguard Worker case ir_unop_abs:
229*61046927SAndroid Build Coastguard Worker case ir_unop_sign:
230*61046927SAndroid Build Coastguard Worker case ir_unop_rcp:
231*61046927SAndroid Build Coastguard Worker case ir_unop_rsq:
232*61046927SAndroid Build Coastguard Worker case ir_unop_sqrt:
233*61046927SAndroid Build Coastguard Worker case ir_unop_exp:
234*61046927SAndroid Build Coastguard Worker case ir_unop_log:
235*61046927SAndroid Build Coastguard Worker case ir_unop_exp2:
236*61046927SAndroid Build Coastguard Worker case ir_unop_log2:
237*61046927SAndroid Build Coastguard Worker case ir_unop_trunc:
238*61046927SAndroid Build Coastguard Worker case ir_unop_ceil:
239*61046927SAndroid Build Coastguard Worker case ir_unop_floor:
240*61046927SAndroid Build Coastguard Worker case ir_unop_fract:
241*61046927SAndroid Build Coastguard Worker case ir_unop_round_even:
242*61046927SAndroid Build Coastguard Worker case ir_unop_sin:
243*61046927SAndroid Build Coastguard Worker case ir_unop_cos:
244*61046927SAndroid Build Coastguard Worker case ir_unop_dFdx:
245*61046927SAndroid Build Coastguard Worker case ir_unop_dFdx_coarse:
246*61046927SAndroid Build Coastguard Worker case ir_unop_dFdx_fine:
247*61046927SAndroid Build Coastguard Worker case ir_unop_dFdy:
248*61046927SAndroid Build Coastguard Worker case ir_unop_dFdy_coarse:
249*61046927SAndroid Build Coastguard Worker case ir_unop_dFdy_fine:
250*61046927SAndroid Build Coastguard Worker case ir_unop_bitfield_reverse:
251*61046927SAndroid Build Coastguard Worker case ir_unop_interpolate_at_centroid:
252*61046927SAndroid Build Coastguard Worker case ir_unop_clz:
253*61046927SAndroid Build Coastguard Worker case ir_unop_saturate:
254*61046927SAndroid Build Coastguard Worker case ir_unop_atan:
255*61046927SAndroid Build Coastguard Worker this->type = op0->type;
256*61046927SAndroid Build Coastguard Worker break;
257*61046927SAndroid Build Coastguard Worker
258*61046927SAndroid Build Coastguard Worker case ir_unop_f162i:
259*61046927SAndroid Build Coastguard Worker case ir_unop_f2i:
260*61046927SAndroid Build Coastguard Worker case ir_unop_b2i:
261*61046927SAndroid Build Coastguard Worker case ir_unop_u2i:
262*61046927SAndroid Build Coastguard Worker case ir_unop_d2i:
263*61046927SAndroid Build Coastguard Worker case ir_unop_bitcast_f2i:
264*61046927SAndroid Build Coastguard Worker case ir_unop_bit_count:
265*61046927SAndroid Build Coastguard Worker case ir_unop_find_msb:
266*61046927SAndroid Build Coastguard Worker case ir_unop_find_lsb:
267*61046927SAndroid Build Coastguard Worker case ir_unop_subroutine_to_int:
268*61046927SAndroid Build Coastguard Worker case ir_unop_i642i:
269*61046927SAndroid Build Coastguard Worker case ir_unop_u642i:
270*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_INT, op0->type->vector_elements, 1);
271*61046927SAndroid Build Coastguard Worker break;
272*61046927SAndroid Build Coastguard Worker
273*61046927SAndroid Build Coastguard Worker case ir_unop_b2f:
274*61046927SAndroid Build Coastguard Worker case ir_unop_i2f:
275*61046927SAndroid Build Coastguard Worker case ir_unop_u2f:
276*61046927SAndroid Build Coastguard Worker case ir_unop_d2f:
277*61046927SAndroid Build Coastguard Worker case ir_unop_f162f:
278*61046927SAndroid Build Coastguard Worker case ir_unop_bitcast_i2f:
279*61046927SAndroid Build Coastguard Worker case ir_unop_bitcast_u2f:
280*61046927SAndroid Build Coastguard Worker case ir_unop_i642f:
281*61046927SAndroid Build Coastguard Worker case ir_unop_u642f:
282*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_FLOAT, op0->type->vector_elements, 1);
283*61046927SAndroid Build Coastguard Worker break;
284*61046927SAndroid Build Coastguard Worker
285*61046927SAndroid Build Coastguard Worker case ir_unop_f2f16:
286*61046927SAndroid Build Coastguard Worker case ir_unop_f2fmp:
287*61046927SAndroid Build Coastguard Worker case ir_unop_b2f16:
288*61046927SAndroid Build Coastguard Worker case ir_unop_i2f16:
289*61046927SAndroid Build Coastguard Worker case ir_unop_u2f16:
290*61046927SAndroid Build Coastguard Worker case ir_unop_d2f16:
291*61046927SAndroid Build Coastguard Worker case ir_unop_i642f16:
292*61046927SAndroid Build Coastguard Worker case ir_unop_u642f16:
293*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_FLOAT16, op0->type->vector_elements, 1);
294*61046927SAndroid Build Coastguard Worker break;
295*61046927SAndroid Build Coastguard Worker
296*61046927SAndroid Build Coastguard Worker case ir_unop_i2imp:
297*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_INT16, op0->type->vector_elements, 1);
298*61046927SAndroid Build Coastguard Worker break;
299*61046927SAndroid Build Coastguard Worker
300*61046927SAndroid Build Coastguard Worker case ir_unop_i2i:
301*61046927SAndroid Build Coastguard Worker if (op0->type->base_type == GLSL_TYPE_INT) {
302*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_INT16, op0->type->vector_elements, 1);
303*61046927SAndroid Build Coastguard Worker } else {
304*61046927SAndroid Build Coastguard Worker assert(op0->type->base_type == GLSL_TYPE_INT16);
305*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_INT, op0->type->vector_elements, 1);
306*61046927SAndroid Build Coastguard Worker }
307*61046927SAndroid Build Coastguard Worker break;
308*61046927SAndroid Build Coastguard Worker
309*61046927SAndroid Build Coastguard Worker case ir_unop_u2u:
310*61046927SAndroid Build Coastguard Worker if (op0->type->base_type == GLSL_TYPE_UINT) {
311*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_UINT16, op0->type->vector_elements, 1);
312*61046927SAndroid Build Coastguard Worker } else {
313*61046927SAndroid Build Coastguard Worker assert(op0->type->base_type == GLSL_TYPE_UINT16);
314*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_UINT, op0->type->vector_elements, 1);
315*61046927SAndroid Build Coastguard Worker }
316*61046927SAndroid Build Coastguard Worker break;
317*61046927SAndroid Build Coastguard Worker
318*61046927SAndroid Build Coastguard Worker case ir_unop_u2ump:
319*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_UINT16, op0->type->vector_elements, 1);
320*61046927SAndroid Build Coastguard Worker break;
321*61046927SAndroid Build Coastguard Worker
322*61046927SAndroid Build Coastguard Worker case ir_unop_f2b:
323*61046927SAndroid Build Coastguard Worker case ir_unop_i2b:
324*61046927SAndroid Build Coastguard Worker case ir_unop_d2b:
325*61046927SAndroid Build Coastguard Worker case ir_unop_f162b:
326*61046927SAndroid Build Coastguard Worker case ir_unop_i642b:
327*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_BOOL, op0->type->vector_elements, 1);
328*61046927SAndroid Build Coastguard Worker break;
329*61046927SAndroid Build Coastguard Worker
330*61046927SAndroid Build Coastguard Worker case ir_unop_f162d:
331*61046927SAndroid Build Coastguard Worker case ir_unop_f2d:
332*61046927SAndroid Build Coastguard Worker case ir_unop_i2d:
333*61046927SAndroid Build Coastguard Worker case ir_unop_u2d:
334*61046927SAndroid Build Coastguard Worker case ir_unop_i642d:
335*61046927SAndroid Build Coastguard Worker case ir_unop_u642d:
336*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_DOUBLE, op0->type->vector_elements, 1);
337*61046927SAndroid Build Coastguard Worker break;
338*61046927SAndroid Build Coastguard Worker
339*61046927SAndroid Build Coastguard Worker case ir_unop_i2u:
340*61046927SAndroid Build Coastguard Worker case ir_unop_f162u:
341*61046927SAndroid Build Coastguard Worker case ir_unop_f2u:
342*61046927SAndroid Build Coastguard Worker case ir_unop_d2u:
343*61046927SAndroid Build Coastguard Worker case ir_unop_bitcast_f2u:
344*61046927SAndroid Build Coastguard Worker case ir_unop_i642u:
345*61046927SAndroid Build Coastguard Worker case ir_unop_u642u:
346*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_UINT, op0->type->vector_elements, 1);
347*61046927SAndroid Build Coastguard Worker break;
348*61046927SAndroid Build Coastguard Worker
349*61046927SAndroid Build Coastguard Worker case ir_unop_i2i64:
350*61046927SAndroid Build Coastguard Worker case ir_unop_u2i64:
351*61046927SAndroid Build Coastguard Worker case ir_unop_b2i64:
352*61046927SAndroid Build Coastguard Worker case ir_unop_f162i64:
353*61046927SAndroid Build Coastguard Worker case ir_unop_f2i64:
354*61046927SAndroid Build Coastguard Worker case ir_unop_d2i64:
355*61046927SAndroid Build Coastguard Worker case ir_unop_u642i64:
356*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_INT64, op0->type->vector_elements, 1);
357*61046927SAndroid Build Coastguard Worker break;
358*61046927SAndroid Build Coastguard Worker
359*61046927SAndroid Build Coastguard Worker case ir_unop_i2u64:
360*61046927SAndroid Build Coastguard Worker case ir_unop_u2u64:
361*61046927SAndroid Build Coastguard Worker case ir_unop_f162u64:
362*61046927SAndroid Build Coastguard Worker case ir_unop_f2u64:
363*61046927SAndroid Build Coastguard Worker case ir_unop_d2u64:
364*61046927SAndroid Build Coastguard Worker case ir_unop_i642u64:
365*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_UINT64, op0->type->vector_elements, 1);
366*61046927SAndroid Build Coastguard Worker break;
367*61046927SAndroid Build Coastguard Worker
368*61046927SAndroid Build Coastguard Worker case ir_unop_unpack_double_2x32:
369*61046927SAndroid Build Coastguard Worker case ir_unop_unpack_uint_2x32:
370*61046927SAndroid Build Coastguard Worker this->type = &glsl_type_builtin_uvec2;
371*61046927SAndroid Build Coastguard Worker break;
372*61046927SAndroid Build Coastguard Worker
373*61046927SAndroid Build Coastguard Worker case ir_unop_unpack_int_2x32:
374*61046927SAndroid Build Coastguard Worker this->type = &glsl_type_builtin_ivec2;
375*61046927SAndroid Build Coastguard Worker break;
376*61046927SAndroid Build Coastguard Worker
377*61046927SAndroid Build Coastguard Worker case ir_unop_pack_snorm_2x16:
378*61046927SAndroid Build Coastguard Worker case ir_unop_pack_snorm_4x8:
379*61046927SAndroid Build Coastguard Worker case ir_unop_pack_unorm_2x16:
380*61046927SAndroid Build Coastguard Worker case ir_unop_pack_unorm_4x8:
381*61046927SAndroid Build Coastguard Worker case ir_unop_pack_half_2x16:
382*61046927SAndroid Build Coastguard Worker this->type = &glsl_type_builtin_uint;
383*61046927SAndroid Build Coastguard Worker break;
384*61046927SAndroid Build Coastguard Worker
385*61046927SAndroid Build Coastguard Worker case ir_unop_pack_double_2x32:
386*61046927SAndroid Build Coastguard Worker this->type = &glsl_type_builtin_double;
387*61046927SAndroid Build Coastguard Worker break;
388*61046927SAndroid Build Coastguard Worker
389*61046927SAndroid Build Coastguard Worker case ir_unop_pack_int_2x32:
390*61046927SAndroid Build Coastguard Worker this->type = &glsl_type_builtin_int64_t;
391*61046927SAndroid Build Coastguard Worker break;
392*61046927SAndroid Build Coastguard Worker
393*61046927SAndroid Build Coastguard Worker case ir_unop_pack_uint_2x32:
394*61046927SAndroid Build Coastguard Worker this->type = &glsl_type_builtin_uint64_t;
395*61046927SAndroid Build Coastguard Worker break;
396*61046927SAndroid Build Coastguard Worker
397*61046927SAndroid Build Coastguard Worker case ir_unop_unpack_snorm_2x16:
398*61046927SAndroid Build Coastguard Worker case ir_unop_unpack_unorm_2x16:
399*61046927SAndroid Build Coastguard Worker case ir_unop_unpack_half_2x16:
400*61046927SAndroid Build Coastguard Worker this->type = &glsl_type_builtin_vec2;
401*61046927SAndroid Build Coastguard Worker break;
402*61046927SAndroid Build Coastguard Worker
403*61046927SAndroid Build Coastguard Worker case ir_unop_unpack_snorm_4x8:
404*61046927SAndroid Build Coastguard Worker case ir_unop_unpack_unorm_4x8:
405*61046927SAndroid Build Coastguard Worker this->type = &glsl_type_builtin_vec4;
406*61046927SAndroid Build Coastguard Worker break;
407*61046927SAndroid Build Coastguard Worker
408*61046927SAndroid Build Coastguard Worker case ir_unop_unpack_sampler_2x32:
409*61046927SAndroid Build Coastguard Worker case ir_unop_unpack_image_2x32:
410*61046927SAndroid Build Coastguard Worker this->type = &glsl_type_builtin_uvec2;
411*61046927SAndroid Build Coastguard Worker break;
412*61046927SAndroid Build Coastguard Worker
413*61046927SAndroid Build Coastguard Worker case ir_unop_pack_sampler_2x32:
414*61046927SAndroid Build Coastguard Worker case ir_unop_pack_image_2x32:
415*61046927SAndroid Build Coastguard Worker this->type = op0->type;
416*61046927SAndroid Build Coastguard Worker break;
417*61046927SAndroid Build Coastguard Worker
418*61046927SAndroid Build Coastguard Worker case ir_unop_frexp_sig:
419*61046927SAndroid Build Coastguard Worker this->type = op0->type;
420*61046927SAndroid Build Coastguard Worker break;
421*61046927SAndroid Build Coastguard Worker case ir_unop_frexp_exp:
422*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_INT, op0->type->vector_elements, 1);
423*61046927SAndroid Build Coastguard Worker break;
424*61046927SAndroid Build Coastguard Worker
425*61046927SAndroid Build Coastguard Worker case ir_unop_get_buffer_size:
426*61046927SAndroid Build Coastguard Worker case ir_unop_ssbo_unsized_array_length:
427*61046927SAndroid Build Coastguard Worker case ir_unop_implicitly_sized_array_length:
428*61046927SAndroid Build Coastguard Worker this->type = &glsl_type_builtin_int;
429*61046927SAndroid Build Coastguard Worker break;
430*61046927SAndroid Build Coastguard Worker
431*61046927SAndroid Build Coastguard Worker case ir_unop_bitcast_i642d:
432*61046927SAndroid Build Coastguard Worker case ir_unop_bitcast_u642d:
433*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_DOUBLE, op0->type->vector_elements, 1);
434*61046927SAndroid Build Coastguard Worker break;
435*61046927SAndroid Build Coastguard Worker
436*61046927SAndroid Build Coastguard Worker case ir_unop_bitcast_d2i64:
437*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_INT64, op0->type->vector_elements, 1);
438*61046927SAndroid Build Coastguard Worker break;
439*61046927SAndroid Build Coastguard Worker case ir_unop_bitcast_d2u64:
440*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_UINT64, op0->type->vector_elements, 1);
441*61046927SAndroid Build Coastguard Worker break;
442*61046927SAndroid Build Coastguard Worker
443*61046927SAndroid Build Coastguard Worker default:
444*61046927SAndroid Build Coastguard Worker assert(!"not reached: missing automatic type setup for ir_expression");
445*61046927SAndroid Build Coastguard Worker this->type = op0->type;
446*61046927SAndroid Build Coastguard Worker break;
447*61046927SAndroid Build Coastguard Worker }
448*61046927SAndroid Build Coastguard Worker }
449*61046927SAndroid Build Coastguard Worker
ir_expression(int op,ir_rvalue * op0,ir_rvalue * op1)450*61046927SAndroid Build Coastguard Worker ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
451*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_expression)
452*61046927SAndroid Build Coastguard Worker {
453*61046927SAndroid Build Coastguard Worker this->operation = ir_expression_operation(op);
454*61046927SAndroid Build Coastguard Worker this->operands[0] = op0;
455*61046927SAndroid Build Coastguard Worker this->operands[1] = op1;
456*61046927SAndroid Build Coastguard Worker this->operands[2] = NULL;
457*61046927SAndroid Build Coastguard Worker this->operands[3] = NULL;
458*61046927SAndroid Build Coastguard Worker
459*61046927SAndroid Build Coastguard Worker assert(op > ir_last_unop);
460*61046927SAndroid Build Coastguard Worker init_num_operands();
461*61046927SAndroid Build Coastguard Worker assert(num_operands == 2);
462*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_operands; i++) {
463*61046927SAndroid Build Coastguard Worker assert(this->operands[i] != NULL);
464*61046927SAndroid Build Coastguard Worker }
465*61046927SAndroid Build Coastguard Worker
466*61046927SAndroid Build Coastguard Worker switch (this->operation) {
467*61046927SAndroid Build Coastguard Worker case ir_binop_all_equal:
468*61046927SAndroid Build Coastguard Worker case ir_binop_any_nequal:
469*61046927SAndroid Build Coastguard Worker this->type = &glsl_type_builtin_bool;
470*61046927SAndroid Build Coastguard Worker break;
471*61046927SAndroid Build Coastguard Worker
472*61046927SAndroid Build Coastguard Worker case ir_binop_add:
473*61046927SAndroid Build Coastguard Worker case ir_binop_sub:
474*61046927SAndroid Build Coastguard Worker case ir_binop_min:
475*61046927SAndroid Build Coastguard Worker case ir_binop_max:
476*61046927SAndroid Build Coastguard Worker case ir_binop_pow:
477*61046927SAndroid Build Coastguard Worker case ir_binop_mul:
478*61046927SAndroid Build Coastguard Worker case ir_binop_div:
479*61046927SAndroid Build Coastguard Worker case ir_binop_mod:
480*61046927SAndroid Build Coastguard Worker case ir_binop_atan2:
481*61046927SAndroid Build Coastguard Worker if (glsl_type_is_scalar(op0->type)) {
482*61046927SAndroid Build Coastguard Worker this->type = op1->type;
483*61046927SAndroid Build Coastguard Worker } else if (glsl_type_is_scalar(op1->type)) {
484*61046927SAndroid Build Coastguard Worker this->type = op0->type;
485*61046927SAndroid Build Coastguard Worker } else {
486*61046927SAndroid Build Coastguard Worker if (this->operation == ir_binop_mul) {
487*61046927SAndroid Build Coastguard Worker this->type = glsl_get_mul_type(op0->type, op1->type);
488*61046927SAndroid Build Coastguard Worker } else {
489*61046927SAndroid Build Coastguard Worker assert(op0->type == op1->type);
490*61046927SAndroid Build Coastguard Worker this->type = op0->type;
491*61046927SAndroid Build Coastguard Worker }
492*61046927SAndroid Build Coastguard Worker }
493*61046927SAndroid Build Coastguard Worker break;
494*61046927SAndroid Build Coastguard Worker
495*61046927SAndroid Build Coastguard Worker case ir_binop_logic_and:
496*61046927SAndroid Build Coastguard Worker case ir_binop_logic_xor:
497*61046927SAndroid Build Coastguard Worker case ir_binop_logic_or:
498*61046927SAndroid Build Coastguard Worker case ir_binop_bit_and:
499*61046927SAndroid Build Coastguard Worker case ir_binop_bit_xor:
500*61046927SAndroid Build Coastguard Worker case ir_binop_bit_or:
501*61046927SAndroid Build Coastguard Worker assert(!glsl_type_is_matrix(op0->type));
502*61046927SAndroid Build Coastguard Worker assert(!glsl_type_is_matrix(op1->type));
503*61046927SAndroid Build Coastguard Worker if (glsl_type_is_scalar(op0->type)) {
504*61046927SAndroid Build Coastguard Worker this->type = op1->type;
505*61046927SAndroid Build Coastguard Worker } else if (glsl_type_is_scalar(op1->type)) {
506*61046927SAndroid Build Coastguard Worker this->type = op0->type;
507*61046927SAndroid Build Coastguard Worker } else {
508*61046927SAndroid Build Coastguard Worker assert(op0->type->vector_elements == op1->type->vector_elements);
509*61046927SAndroid Build Coastguard Worker this->type = op0->type;
510*61046927SAndroid Build Coastguard Worker }
511*61046927SAndroid Build Coastguard Worker break;
512*61046927SAndroid Build Coastguard Worker
513*61046927SAndroid Build Coastguard Worker case ir_binop_equal:
514*61046927SAndroid Build Coastguard Worker case ir_binop_nequal:
515*61046927SAndroid Build Coastguard Worker case ir_binop_gequal:
516*61046927SAndroid Build Coastguard Worker case ir_binop_less:
517*61046927SAndroid Build Coastguard Worker assert(op0->type == op1->type);
518*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_BOOL, op0->type->vector_elements, 1);
519*61046927SAndroid Build Coastguard Worker break;
520*61046927SAndroid Build Coastguard Worker
521*61046927SAndroid Build Coastguard Worker case ir_binop_dot:
522*61046927SAndroid Build Coastguard Worker this->type = glsl_get_base_glsl_type(op0->type);
523*61046927SAndroid Build Coastguard Worker break;
524*61046927SAndroid Build Coastguard Worker
525*61046927SAndroid Build Coastguard Worker case ir_binop_imul_high:
526*61046927SAndroid Build Coastguard Worker case ir_binop_mul_32x16:
527*61046927SAndroid Build Coastguard Worker case ir_binop_carry:
528*61046927SAndroid Build Coastguard Worker case ir_binop_borrow:
529*61046927SAndroid Build Coastguard Worker case ir_binop_lshift:
530*61046927SAndroid Build Coastguard Worker case ir_binop_rshift:
531*61046927SAndroid Build Coastguard Worker case ir_binop_ldexp:
532*61046927SAndroid Build Coastguard Worker case ir_binop_interpolate_at_offset:
533*61046927SAndroid Build Coastguard Worker case ir_binop_interpolate_at_sample:
534*61046927SAndroid Build Coastguard Worker this->type = op0->type;
535*61046927SAndroid Build Coastguard Worker break;
536*61046927SAndroid Build Coastguard Worker
537*61046927SAndroid Build Coastguard Worker case ir_binop_add_sat:
538*61046927SAndroid Build Coastguard Worker case ir_binop_sub_sat:
539*61046927SAndroid Build Coastguard Worker case ir_binop_avg:
540*61046927SAndroid Build Coastguard Worker case ir_binop_avg_round:
541*61046927SAndroid Build Coastguard Worker assert(op0->type == op1->type);
542*61046927SAndroid Build Coastguard Worker this->type = op0->type;
543*61046927SAndroid Build Coastguard Worker break;
544*61046927SAndroid Build Coastguard Worker
545*61046927SAndroid Build Coastguard Worker case ir_binop_abs_sub: {
546*61046927SAndroid Build Coastguard Worker enum glsl_base_type base;
547*61046927SAndroid Build Coastguard Worker
548*61046927SAndroid Build Coastguard Worker assert(op0->type == op1->type);
549*61046927SAndroid Build Coastguard Worker
550*61046927SAndroid Build Coastguard Worker switch (op0->type->base_type) {
551*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT:
552*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT:
553*61046927SAndroid Build Coastguard Worker base = GLSL_TYPE_UINT;
554*61046927SAndroid Build Coastguard Worker break;
555*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT8:
556*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT8:
557*61046927SAndroid Build Coastguard Worker base = GLSL_TYPE_UINT8;
558*61046927SAndroid Build Coastguard Worker break;
559*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:
560*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16:
561*61046927SAndroid Build Coastguard Worker base = GLSL_TYPE_UINT16;
562*61046927SAndroid Build Coastguard Worker break;
563*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64:
564*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64:
565*61046927SAndroid Build Coastguard Worker base = GLSL_TYPE_UINT64;
566*61046927SAndroid Build Coastguard Worker break;
567*61046927SAndroid Build Coastguard Worker default:
568*61046927SAndroid Build Coastguard Worker unreachable("Invalid base type.");
569*61046927SAndroid Build Coastguard Worker }
570*61046927SAndroid Build Coastguard Worker
571*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(base, op0->type->vector_elements, 1);
572*61046927SAndroid Build Coastguard Worker break;
573*61046927SAndroid Build Coastguard Worker }
574*61046927SAndroid Build Coastguard Worker
575*61046927SAndroid Build Coastguard Worker case ir_binop_vector_extract:
576*61046927SAndroid Build Coastguard Worker this->type = glsl_get_scalar_type(op0->type);
577*61046927SAndroid Build Coastguard Worker break;
578*61046927SAndroid Build Coastguard Worker
579*61046927SAndroid Build Coastguard Worker default:
580*61046927SAndroid Build Coastguard Worker assert(!"not reached: missing automatic type setup for ir_expression");
581*61046927SAndroid Build Coastguard Worker this->type = &glsl_type_builtin_float;
582*61046927SAndroid Build Coastguard Worker }
583*61046927SAndroid Build Coastguard Worker }
584*61046927SAndroid Build Coastguard Worker
ir_expression(int op,ir_rvalue * op0,ir_rvalue * op1,ir_rvalue * op2)585*61046927SAndroid Build Coastguard Worker ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1,
586*61046927SAndroid Build Coastguard Worker ir_rvalue *op2)
587*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_expression)
588*61046927SAndroid Build Coastguard Worker {
589*61046927SAndroid Build Coastguard Worker this->operation = ir_expression_operation(op);
590*61046927SAndroid Build Coastguard Worker this->operands[0] = op0;
591*61046927SAndroid Build Coastguard Worker this->operands[1] = op1;
592*61046927SAndroid Build Coastguard Worker this->operands[2] = op2;
593*61046927SAndroid Build Coastguard Worker this->operands[3] = NULL;
594*61046927SAndroid Build Coastguard Worker
595*61046927SAndroid Build Coastguard Worker assert(op > ir_last_binop && op <= ir_last_triop);
596*61046927SAndroid Build Coastguard Worker init_num_operands();
597*61046927SAndroid Build Coastguard Worker assert(num_operands == 3);
598*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_operands; i++) {
599*61046927SAndroid Build Coastguard Worker assert(this->operands[i] != NULL);
600*61046927SAndroid Build Coastguard Worker }
601*61046927SAndroid Build Coastguard Worker
602*61046927SAndroid Build Coastguard Worker switch (this->operation) {
603*61046927SAndroid Build Coastguard Worker case ir_triop_fma:
604*61046927SAndroid Build Coastguard Worker case ir_triop_lrp:
605*61046927SAndroid Build Coastguard Worker case ir_triop_bitfield_extract:
606*61046927SAndroid Build Coastguard Worker case ir_triop_vector_insert:
607*61046927SAndroid Build Coastguard Worker this->type = op0->type;
608*61046927SAndroid Build Coastguard Worker break;
609*61046927SAndroid Build Coastguard Worker
610*61046927SAndroid Build Coastguard Worker case ir_triop_csel:
611*61046927SAndroid Build Coastguard Worker this->type = op1->type;
612*61046927SAndroid Build Coastguard Worker break;
613*61046927SAndroid Build Coastguard Worker
614*61046927SAndroid Build Coastguard Worker default:
615*61046927SAndroid Build Coastguard Worker assert(!"not reached: missing automatic type setup for ir_expression");
616*61046927SAndroid Build Coastguard Worker this->type = &glsl_type_builtin_float;
617*61046927SAndroid Build Coastguard Worker }
618*61046927SAndroid Build Coastguard Worker }
619*61046927SAndroid Build Coastguard Worker
620*61046927SAndroid Build Coastguard Worker /**
621*61046927SAndroid Build Coastguard Worker * This is only here for ir_reader to used for testing purposes. Please use
622*61046927SAndroid Build Coastguard Worker * the precomputed num_operands field if you need the number of operands.
623*61046927SAndroid Build Coastguard Worker */
624*61046927SAndroid Build Coastguard Worker unsigned
get_num_operands(ir_expression_operation op)625*61046927SAndroid Build Coastguard Worker ir_expression::get_num_operands(ir_expression_operation op)
626*61046927SAndroid Build Coastguard Worker {
627*61046927SAndroid Build Coastguard Worker assert(op <= ir_last_opcode);
628*61046927SAndroid Build Coastguard Worker
629*61046927SAndroid Build Coastguard Worker if (op <= ir_last_unop)
630*61046927SAndroid Build Coastguard Worker return 1;
631*61046927SAndroid Build Coastguard Worker
632*61046927SAndroid Build Coastguard Worker if (op <= ir_last_binop)
633*61046927SAndroid Build Coastguard Worker return 2;
634*61046927SAndroid Build Coastguard Worker
635*61046927SAndroid Build Coastguard Worker if (op <= ir_last_triop)
636*61046927SAndroid Build Coastguard Worker return 3;
637*61046927SAndroid Build Coastguard Worker
638*61046927SAndroid Build Coastguard Worker if (op <= ir_last_quadop)
639*61046927SAndroid Build Coastguard Worker return 4;
640*61046927SAndroid Build Coastguard Worker
641*61046927SAndroid Build Coastguard Worker unreachable("Could not calculate number of operands");
642*61046927SAndroid Build Coastguard Worker }
643*61046927SAndroid Build Coastguard Worker
644*61046927SAndroid Build Coastguard Worker #include "ir_expression_operation_strings.h"
645*61046927SAndroid Build Coastguard Worker
646*61046927SAndroid Build Coastguard Worker const char*
depth_layout_string(ir_depth_layout layout)647*61046927SAndroid Build Coastguard Worker depth_layout_string(ir_depth_layout layout)
648*61046927SAndroid Build Coastguard Worker {
649*61046927SAndroid Build Coastguard Worker switch(layout) {
650*61046927SAndroid Build Coastguard Worker case ir_depth_layout_none: return "";
651*61046927SAndroid Build Coastguard Worker case ir_depth_layout_any: return "depth_any";
652*61046927SAndroid Build Coastguard Worker case ir_depth_layout_greater: return "depth_greater";
653*61046927SAndroid Build Coastguard Worker case ir_depth_layout_less: return "depth_less";
654*61046927SAndroid Build Coastguard Worker case ir_depth_layout_unchanged: return "depth_unchanged";
655*61046927SAndroid Build Coastguard Worker
656*61046927SAndroid Build Coastguard Worker default:
657*61046927SAndroid Build Coastguard Worker assert(0);
658*61046927SAndroid Build Coastguard Worker return "";
659*61046927SAndroid Build Coastguard Worker }
660*61046927SAndroid Build Coastguard Worker }
661*61046927SAndroid Build Coastguard Worker
662*61046927SAndroid Build Coastguard Worker ir_expression_operation
get_operator(const char * str)663*61046927SAndroid Build Coastguard Worker ir_expression::get_operator(const char *str)
664*61046927SAndroid Build Coastguard Worker {
665*61046927SAndroid Build Coastguard Worker for (int op = 0; op <= int(ir_last_opcode); op++) {
666*61046927SAndroid Build Coastguard Worker if (strcmp(str, ir_expression_operation_strings[op]) == 0)
667*61046927SAndroid Build Coastguard Worker return (ir_expression_operation) op;
668*61046927SAndroid Build Coastguard Worker }
669*61046927SAndroid Build Coastguard Worker return (ir_expression_operation) -1;
670*61046927SAndroid Build Coastguard Worker }
671*61046927SAndroid Build Coastguard Worker
672*61046927SAndroid Build Coastguard Worker ir_variable *
variable_referenced() const673*61046927SAndroid Build Coastguard Worker ir_expression::variable_referenced() const
674*61046927SAndroid Build Coastguard Worker {
675*61046927SAndroid Build Coastguard Worker switch (operation) {
676*61046927SAndroid Build Coastguard Worker case ir_binop_vector_extract:
677*61046927SAndroid Build Coastguard Worker case ir_triop_vector_insert:
678*61046927SAndroid Build Coastguard Worker /* We get these for things like a[0] where a is a vector type. In these
679*61046927SAndroid Build Coastguard Worker * cases we want variable_referenced() to return the actual vector
680*61046927SAndroid Build Coastguard Worker * variable this is wrapping.
681*61046927SAndroid Build Coastguard Worker */
682*61046927SAndroid Build Coastguard Worker return operands[0]->variable_referenced();
683*61046927SAndroid Build Coastguard Worker default:
684*61046927SAndroid Build Coastguard Worker return ir_rvalue::variable_referenced();
685*61046927SAndroid Build Coastguard Worker }
686*61046927SAndroid Build Coastguard Worker }
687*61046927SAndroid Build Coastguard Worker
ir_constant()688*61046927SAndroid Build Coastguard Worker ir_constant::ir_constant()
689*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_constant)
690*61046927SAndroid Build Coastguard Worker {
691*61046927SAndroid Build Coastguard Worker this->const_elements = NULL;
692*61046927SAndroid Build Coastguard Worker }
693*61046927SAndroid Build Coastguard Worker
ir_constant(const struct glsl_type * type,const ir_constant_data * data)694*61046927SAndroid Build Coastguard Worker ir_constant::ir_constant(const struct glsl_type *type,
695*61046927SAndroid Build Coastguard Worker const ir_constant_data *data)
696*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_constant)
697*61046927SAndroid Build Coastguard Worker {
698*61046927SAndroid Build Coastguard Worker this->const_elements = NULL;
699*61046927SAndroid Build Coastguard Worker
700*61046927SAndroid Build Coastguard Worker assert((type->base_type >= GLSL_TYPE_UINT)
701*61046927SAndroid Build Coastguard Worker && (type->base_type <= GLSL_TYPE_IMAGE));
702*61046927SAndroid Build Coastguard Worker
703*61046927SAndroid Build Coastguard Worker this->type = type;
704*61046927SAndroid Build Coastguard Worker memcpy(& this->value, data, sizeof(this->value));
705*61046927SAndroid Build Coastguard Worker }
706*61046927SAndroid Build Coastguard Worker
ir_constant(float16_t f16,unsigned vector_elements)707*61046927SAndroid Build Coastguard Worker ir_constant::ir_constant(float16_t f16, unsigned vector_elements)
708*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_constant)
709*61046927SAndroid Build Coastguard Worker {
710*61046927SAndroid Build Coastguard Worker this->const_elements = NULL;
711*61046927SAndroid Build Coastguard Worker assert(vector_elements <= 4);
712*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_FLOAT16, vector_elements, 1);
713*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < vector_elements; i++) {
714*61046927SAndroid Build Coastguard Worker this->value.f16[i] = f16.bits;
715*61046927SAndroid Build Coastguard Worker }
716*61046927SAndroid Build Coastguard Worker for (unsigned i = vector_elements; i < 16; i++) {
717*61046927SAndroid Build Coastguard Worker this->value.f[i] = 0;
718*61046927SAndroid Build Coastguard Worker }
719*61046927SAndroid Build Coastguard Worker }
720*61046927SAndroid Build Coastguard Worker
ir_constant(float f,unsigned vector_elements)721*61046927SAndroid Build Coastguard Worker ir_constant::ir_constant(float f, unsigned vector_elements)
722*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_constant)
723*61046927SAndroid Build Coastguard Worker {
724*61046927SAndroid Build Coastguard Worker this->const_elements = NULL;
725*61046927SAndroid Build Coastguard Worker assert(vector_elements <= 4);
726*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_FLOAT, vector_elements, 1);
727*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < vector_elements; i++) {
728*61046927SAndroid Build Coastguard Worker this->value.f[i] = f;
729*61046927SAndroid Build Coastguard Worker }
730*61046927SAndroid Build Coastguard Worker for (unsigned i = vector_elements; i < 16; i++) {
731*61046927SAndroid Build Coastguard Worker this->value.f[i] = 0;
732*61046927SAndroid Build Coastguard Worker }
733*61046927SAndroid Build Coastguard Worker }
734*61046927SAndroid Build Coastguard Worker
ir_constant(double d,unsigned vector_elements)735*61046927SAndroid Build Coastguard Worker ir_constant::ir_constant(double d, unsigned vector_elements)
736*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_constant)
737*61046927SAndroid Build Coastguard Worker {
738*61046927SAndroid Build Coastguard Worker this->const_elements = NULL;
739*61046927SAndroid Build Coastguard Worker assert(vector_elements <= 4);
740*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_DOUBLE, vector_elements, 1);
741*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < vector_elements; i++) {
742*61046927SAndroid Build Coastguard Worker this->value.d[i] = d;
743*61046927SAndroid Build Coastguard Worker }
744*61046927SAndroid Build Coastguard Worker for (unsigned i = vector_elements; i < 16; i++) {
745*61046927SAndroid Build Coastguard Worker this->value.d[i] = 0.0;
746*61046927SAndroid Build Coastguard Worker }
747*61046927SAndroid Build Coastguard Worker }
748*61046927SAndroid Build Coastguard Worker
ir_constant(int16_t i16,unsigned vector_elements)749*61046927SAndroid Build Coastguard Worker ir_constant::ir_constant(int16_t i16, unsigned vector_elements)
750*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_constant)
751*61046927SAndroid Build Coastguard Worker {
752*61046927SAndroid Build Coastguard Worker this->const_elements = NULL;
753*61046927SAndroid Build Coastguard Worker assert(vector_elements <= 4);
754*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_INT16, vector_elements, 1);
755*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < vector_elements; i++) {
756*61046927SAndroid Build Coastguard Worker this->value.i16[i] = i16;
757*61046927SAndroid Build Coastguard Worker }
758*61046927SAndroid Build Coastguard Worker for (unsigned i = vector_elements; i < 16; i++) {
759*61046927SAndroid Build Coastguard Worker this->value.i16[i] = 0;
760*61046927SAndroid Build Coastguard Worker }
761*61046927SAndroid Build Coastguard Worker }
762*61046927SAndroid Build Coastguard Worker
ir_constant(uint16_t u16,unsigned vector_elements)763*61046927SAndroid Build Coastguard Worker ir_constant::ir_constant(uint16_t u16, unsigned vector_elements)
764*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_constant)
765*61046927SAndroid Build Coastguard Worker {
766*61046927SAndroid Build Coastguard Worker this->const_elements = NULL;
767*61046927SAndroid Build Coastguard Worker assert(vector_elements <= 4);
768*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_UINT16, vector_elements, 1);
769*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < vector_elements; i++) {
770*61046927SAndroid Build Coastguard Worker this->value.u16[i] = u16;
771*61046927SAndroid Build Coastguard Worker }
772*61046927SAndroid Build Coastguard Worker for (unsigned i = vector_elements; i < 16; i++) {
773*61046927SAndroid Build Coastguard Worker this->value.u16[i] = 0;
774*61046927SAndroid Build Coastguard Worker }
775*61046927SAndroid Build Coastguard Worker }
776*61046927SAndroid Build Coastguard Worker
ir_constant(unsigned int u,unsigned vector_elements)777*61046927SAndroid Build Coastguard Worker ir_constant::ir_constant(unsigned int u, unsigned vector_elements)
778*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_constant)
779*61046927SAndroid Build Coastguard Worker {
780*61046927SAndroid Build Coastguard Worker this->const_elements = NULL;
781*61046927SAndroid Build Coastguard Worker assert(vector_elements <= 4);
782*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_UINT, vector_elements, 1);
783*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < vector_elements; i++) {
784*61046927SAndroid Build Coastguard Worker this->value.u[i] = u;
785*61046927SAndroid Build Coastguard Worker }
786*61046927SAndroid Build Coastguard Worker for (unsigned i = vector_elements; i < 16; i++) {
787*61046927SAndroid Build Coastguard Worker this->value.u[i] = 0;
788*61046927SAndroid Build Coastguard Worker }
789*61046927SAndroid Build Coastguard Worker }
790*61046927SAndroid Build Coastguard Worker
ir_constant(int integer,unsigned vector_elements)791*61046927SAndroid Build Coastguard Worker ir_constant::ir_constant(int integer, unsigned vector_elements)
792*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_constant)
793*61046927SAndroid Build Coastguard Worker {
794*61046927SAndroid Build Coastguard Worker this->const_elements = NULL;
795*61046927SAndroid Build Coastguard Worker assert(vector_elements <= 4);
796*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_INT, vector_elements, 1);
797*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < vector_elements; i++) {
798*61046927SAndroid Build Coastguard Worker this->value.i[i] = integer;
799*61046927SAndroid Build Coastguard Worker }
800*61046927SAndroid Build Coastguard Worker for (unsigned i = vector_elements; i < 16; i++) {
801*61046927SAndroid Build Coastguard Worker this->value.i[i] = 0;
802*61046927SAndroid Build Coastguard Worker }
803*61046927SAndroid Build Coastguard Worker }
804*61046927SAndroid Build Coastguard Worker
ir_constant(uint64_t u64,unsigned vector_elements)805*61046927SAndroid Build Coastguard Worker ir_constant::ir_constant(uint64_t u64, unsigned vector_elements)
806*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_constant)
807*61046927SAndroid Build Coastguard Worker {
808*61046927SAndroid Build Coastguard Worker this->const_elements = NULL;
809*61046927SAndroid Build Coastguard Worker assert(vector_elements <= 4);
810*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_UINT64, vector_elements, 1);
811*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < vector_elements; i++) {
812*61046927SAndroid Build Coastguard Worker this->value.u64[i] = u64;
813*61046927SAndroid Build Coastguard Worker }
814*61046927SAndroid Build Coastguard Worker for (unsigned i = vector_elements; i < 16; i++) {
815*61046927SAndroid Build Coastguard Worker this->value.u64[i] = 0;
816*61046927SAndroid Build Coastguard Worker }
817*61046927SAndroid Build Coastguard Worker }
818*61046927SAndroid Build Coastguard Worker
ir_constant(int64_t int64,unsigned vector_elements)819*61046927SAndroid Build Coastguard Worker ir_constant::ir_constant(int64_t int64, unsigned vector_elements)
820*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_constant)
821*61046927SAndroid Build Coastguard Worker {
822*61046927SAndroid Build Coastguard Worker this->const_elements = NULL;
823*61046927SAndroid Build Coastguard Worker assert(vector_elements <= 4);
824*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_INT64, vector_elements, 1);
825*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < vector_elements; i++) {
826*61046927SAndroid Build Coastguard Worker this->value.i64[i] = int64;
827*61046927SAndroid Build Coastguard Worker }
828*61046927SAndroid Build Coastguard Worker for (unsigned i = vector_elements; i < 16; i++) {
829*61046927SAndroid Build Coastguard Worker this->value.i64[i] = 0;
830*61046927SAndroid Build Coastguard Worker }
831*61046927SAndroid Build Coastguard Worker }
832*61046927SAndroid Build Coastguard Worker
ir_constant(bool b,unsigned vector_elements)833*61046927SAndroid Build Coastguard Worker ir_constant::ir_constant(bool b, unsigned vector_elements)
834*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_constant)
835*61046927SAndroid Build Coastguard Worker {
836*61046927SAndroid Build Coastguard Worker this->const_elements = NULL;
837*61046927SAndroid Build Coastguard Worker assert(vector_elements <= 4);
838*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(GLSL_TYPE_BOOL, vector_elements, 1);
839*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < vector_elements; i++) {
840*61046927SAndroid Build Coastguard Worker this->value.b[i] = b;
841*61046927SAndroid Build Coastguard Worker }
842*61046927SAndroid Build Coastguard Worker for (unsigned i = vector_elements; i < 16; i++) {
843*61046927SAndroid Build Coastguard Worker this->value.b[i] = false;
844*61046927SAndroid Build Coastguard Worker }
845*61046927SAndroid Build Coastguard Worker }
846*61046927SAndroid Build Coastguard Worker
ir_constant(const ir_constant * c,unsigned i)847*61046927SAndroid Build Coastguard Worker ir_constant::ir_constant(const ir_constant *c, unsigned i)
848*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_constant)
849*61046927SAndroid Build Coastguard Worker {
850*61046927SAndroid Build Coastguard Worker this->const_elements = NULL;
851*61046927SAndroid Build Coastguard Worker this->type = glsl_get_base_glsl_type(c->type);
852*61046927SAndroid Build Coastguard Worker
853*61046927SAndroid Build Coastguard Worker /* Section 5.11 (Out-of-Bounds Accesses) of the GLSL 4.60 spec says:
854*61046927SAndroid Build Coastguard Worker *
855*61046927SAndroid Build Coastguard Worker * In the subsections described above for array, vector, matrix and
856*61046927SAndroid Build Coastguard Worker * structure accesses, any out-of-bounds access produced undefined
857*61046927SAndroid Build Coastguard Worker * behavior....Out-of-bounds reads return undefined values, which
858*61046927SAndroid Build Coastguard Worker * include values from other variables of the active program or zero.
859*61046927SAndroid Build Coastguard Worker *
860*61046927SAndroid Build Coastguard Worker * GL_KHR_robustness and GL_ARB_robustness encourage us to return zero.
861*61046927SAndroid Build Coastguard Worker */
862*61046927SAndroid Build Coastguard Worker if (i >= c->type->vector_elements) {
863*61046927SAndroid Build Coastguard Worker this->value = { { 0 } };
864*61046927SAndroid Build Coastguard Worker return;
865*61046927SAndroid Build Coastguard Worker }
866*61046927SAndroid Build Coastguard Worker
867*61046927SAndroid Build Coastguard Worker switch (this->type->base_type) {
868*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16: this->value.u16[0] = c->value.u16[i]; break;
869*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16: this->value.i16[0] = c->value.i16[i]; break;
870*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT: this->value.u[0] = c->value.u[i]; break;
871*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT: this->value.i[0] = c->value.i[i]; break;
872*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT: this->value.f[0] = c->value.f[i]; break;
873*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16: this->value.f16[0] = c->value.f16[i]; break;
874*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL: this->value.b[0] = c->value.b[i]; break;
875*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE: this->value.d[0] = c->value.d[i]; break;
876*61046927SAndroid Build Coastguard Worker default: assert(!"Should not get here."); break;
877*61046927SAndroid Build Coastguard Worker }
878*61046927SAndroid Build Coastguard Worker }
879*61046927SAndroid Build Coastguard Worker
ir_constant(const struct glsl_type * type,exec_list * value_list)880*61046927SAndroid Build Coastguard Worker ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
881*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_constant)
882*61046927SAndroid Build Coastguard Worker {
883*61046927SAndroid Build Coastguard Worker this->const_elements = NULL;
884*61046927SAndroid Build Coastguard Worker this->type = type;
885*61046927SAndroid Build Coastguard Worker
886*61046927SAndroid Build Coastguard Worker assert(glsl_type_is_scalar(type) || glsl_type_is_vector(type) || glsl_type_is_matrix(type)
887*61046927SAndroid Build Coastguard Worker || glsl_type_is_struct(type) || glsl_type_is_array(type));
888*61046927SAndroid Build Coastguard Worker
889*61046927SAndroid Build Coastguard Worker /* If the constant is a record, the types of each of the entries in
890*61046927SAndroid Build Coastguard Worker * value_list must be a 1-for-1 match with the structure components. Each
891*61046927SAndroid Build Coastguard Worker * entry must also be a constant. Just move the nodes from the value_list
892*61046927SAndroid Build Coastguard Worker * to the list in the ir_constant.
893*61046927SAndroid Build Coastguard Worker */
894*61046927SAndroid Build Coastguard Worker if (glsl_type_is_array(type) || glsl_type_is_struct(type)) {
895*61046927SAndroid Build Coastguard Worker this->const_elements = ralloc_array(this, ir_constant *, type->length);
896*61046927SAndroid Build Coastguard Worker unsigned i = 0;
897*61046927SAndroid Build Coastguard Worker foreach_in_list(ir_constant, value, value_list) {
898*61046927SAndroid Build Coastguard Worker assert(value->as_constant() != NULL);
899*61046927SAndroid Build Coastguard Worker
900*61046927SAndroid Build Coastguard Worker this->const_elements[i++] = value;
901*61046927SAndroid Build Coastguard Worker }
902*61046927SAndroid Build Coastguard Worker return;
903*61046927SAndroid Build Coastguard Worker }
904*61046927SAndroid Build Coastguard Worker
905*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < 16; i++) {
906*61046927SAndroid Build Coastguard Worker this->value.u[i] = 0;
907*61046927SAndroid Build Coastguard Worker }
908*61046927SAndroid Build Coastguard Worker
909*61046927SAndroid Build Coastguard Worker ir_constant *value = (ir_constant *) (value_list->get_head_raw());
910*61046927SAndroid Build Coastguard Worker
911*61046927SAndroid Build Coastguard Worker /* Constructors with exactly one scalar argument are special for vectors
912*61046927SAndroid Build Coastguard Worker * and matrices. For vectors, the scalar value is replicated to fill all
913*61046927SAndroid Build Coastguard Worker * the components. For matrices, the scalar fills the components of the
914*61046927SAndroid Build Coastguard Worker * diagonal while the rest is filled with 0.
915*61046927SAndroid Build Coastguard Worker */
916*61046927SAndroid Build Coastguard Worker if (glsl_type_is_scalar(value->type) && value->next->is_tail_sentinel()) {
917*61046927SAndroid Build Coastguard Worker if (glsl_type_is_matrix(type)) {
918*61046927SAndroid Build Coastguard Worker /* Matrix - fill diagonal (rest is already set to 0) */
919*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < type->matrix_columns; i++) {
920*61046927SAndroid Build Coastguard Worker switch (type->base_type) {
921*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT:
922*61046927SAndroid Build Coastguard Worker this->value.f[i * type->vector_elements + i] =
923*61046927SAndroid Build Coastguard Worker value->value.f[0];
924*61046927SAndroid Build Coastguard Worker break;
925*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE:
926*61046927SAndroid Build Coastguard Worker this->value.d[i * type->vector_elements + i] =
927*61046927SAndroid Build Coastguard Worker value->value.d[0];
928*61046927SAndroid Build Coastguard Worker break;
929*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16:
930*61046927SAndroid Build Coastguard Worker this->value.f16[i * type->vector_elements + i] =
931*61046927SAndroid Build Coastguard Worker value->value.f16[0];
932*61046927SAndroid Build Coastguard Worker break;
933*61046927SAndroid Build Coastguard Worker default:
934*61046927SAndroid Build Coastguard Worker assert(!"unexpected matrix base type");
935*61046927SAndroid Build Coastguard Worker }
936*61046927SAndroid Build Coastguard Worker }
937*61046927SAndroid Build Coastguard Worker } else {
938*61046927SAndroid Build Coastguard Worker /* Vector or scalar - fill all components */
939*61046927SAndroid Build Coastguard Worker switch (type->base_type) {
940*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:
941*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16:
942*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < glsl_get_components(type); i++)
943*61046927SAndroid Build Coastguard Worker this->value.u16[i] = value->value.u16[0];
944*61046927SAndroid Build Coastguard Worker break;
945*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT:
946*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT:
947*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < glsl_get_components(type); i++)
948*61046927SAndroid Build Coastguard Worker this->value.u[i] = value->value.u[0];
949*61046927SAndroid Build Coastguard Worker break;
950*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT:
951*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < glsl_get_components(type); i++)
952*61046927SAndroid Build Coastguard Worker this->value.f[i] = value->value.f[0];
953*61046927SAndroid Build Coastguard Worker break;
954*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16:
955*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < glsl_get_components(type); i++)
956*61046927SAndroid Build Coastguard Worker this->value.f16[i] = value->value.f16[0];
957*61046927SAndroid Build Coastguard Worker break;
958*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE:
959*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < glsl_get_components(type); i++)
960*61046927SAndroid Build Coastguard Worker this->value.d[i] = value->value.d[0];
961*61046927SAndroid Build Coastguard Worker break;
962*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64:
963*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64:
964*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < glsl_get_components(type); i++)
965*61046927SAndroid Build Coastguard Worker this->value.u64[i] = value->value.u64[0];
966*61046927SAndroid Build Coastguard Worker break;
967*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL:
968*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < glsl_get_components(type); i++)
969*61046927SAndroid Build Coastguard Worker this->value.b[i] = value->value.b[0];
970*61046927SAndroid Build Coastguard Worker break;
971*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SAMPLER:
972*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_IMAGE:
973*61046927SAndroid Build Coastguard Worker this->value.u64[0] = value->value.u64[0];
974*61046927SAndroid Build Coastguard Worker break;
975*61046927SAndroid Build Coastguard Worker default:
976*61046927SAndroid Build Coastguard Worker assert(!"Should not get here.");
977*61046927SAndroid Build Coastguard Worker break;
978*61046927SAndroid Build Coastguard Worker }
979*61046927SAndroid Build Coastguard Worker }
980*61046927SAndroid Build Coastguard Worker return;
981*61046927SAndroid Build Coastguard Worker }
982*61046927SAndroid Build Coastguard Worker
983*61046927SAndroid Build Coastguard Worker if (glsl_type_is_matrix(type) && glsl_type_is_matrix(value->type)) {
984*61046927SAndroid Build Coastguard Worker assert(value->next->is_tail_sentinel());
985*61046927SAndroid Build Coastguard Worker
986*61046927SAndroid Build Coastguard Worker /* From section 5.4.2 of the GLSL 1.20 spec:
987*61046927SAndroid Build Coastguard Worker * "If a matrix is constructed from a matrix, then each component
988*61046927SAndroid Build Coastguard Worker * (column i, row j) in the result that has a corresponding component
989*61046927SAndroid Build Coastguard Worker * (column i, row j) in the argument will be initialized from there."
990*61046927SAndroid Build Coastguard Worker */
991*61046927SAndroid Build Coastguard Worker unsigned cols = MIN2(type->matrix_columns, value->type->matrix_columns);
992*61046927SAndroid Build Coastguard Worker unsigned rows = MIN2(type->vector_elements, value->type->vector_elements);
993*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < cols; i++) {
994*61046927SAndroid Build Coastguard Worker for (unsigned j = 0; j < rows; j++) {
995*61046927SAndroid Build Coastguard Worker const unsigned src = i * value->type->vector_elements + j;
996*61046927SAndroid Build Coastguard Worker const unsigned dst = i * type->vector_elements + j;
997*61046927SAndroid Build Coastguard Worker this->value.f[dst] = value->value.f[src];
998*61046927SAndroid Build Coastguard Worker }
999*61046927SAndroid Build Coastguard Worker }
1000*61046927SAndroid Build Coastguard Worker
1001*61046927SAndroid Build Coastguard Worker /* "All other components will be initialized to the identity matrix." */
1002*61046927SAndroid Build Coastguard Worker for (unsigned i = cols; i < type->matrix_columns; i++)
1003*61046927SAndroid Build Coastguard Worker this->value.f[i * type->vector_elements + i] = 1.0;
1004*61046927SAndroid Build Coastguard Worker
1005*61046927SAndroid Build Coastguard Worker return;
1006*61046927SAndroid Build Coastguard Worker }
1007*61046927SAndroid Build Coastguard Worker
1008*61046927SAndroid Build Coastguard Worker /* Use each component from each entry in the value_list to initialize one
1009*61046927SAndroid Build Coastguard Worker * component of the constant being constructed.
1010*61046927SAndroid Build Coastguard Worker */
1011*61046927SAndroid Build Coastguard Worker unsigned i = 0;
1012*61046927SAndroid Build Coastguard Worker for (;;) {
1013*61046927SAndroid Build Coastguard Worker assert(value->as_constant() != NULL);
1014*61046927SAndroid Build Coastguard Worker assert(!value->is_tail_sentinel());
1015*61046927SAndroid Build Coastguard Worker
1016*61046927SAndroid Build Coastguard Worker for (unsigned j = 0; j < glsl_get_components(value->type); j++) {
1017*61046927SAndroid Build Coastguard Worker switch (type->base_type) {
1018*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:
1019*61046927SAndroid Build Coastguard Worker this->value.u16[i] = value->get_uint16_component(j);
1020*61046927SAndroid Build Coastguard Worker break;
1021*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16:
1022*61046927SAndroid Build Coastguard Worker this->value.i16[i] = value->get_int16_component(j);
1023*61046927SAndroid Build Coastguard Worker break;
1024*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT:
1025*61046927SAndroid Build Coastguard Worker this->value.u[i] = value->get_uint_component(j);
1026*61046927SAndroid Build Coastguard Worker break;
1027*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT:
1028*61046927SAndroid Build Coastguard Worker this->value.i[i] = value->get_int_component(j);
1029*61046927SAndroid Build Coastguard Worker break;
1030*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT:
1031*61046927SAndroid Build Coastguard Worker this->value.f[i] = value->get_float_component(j);
1032*61046927SAndroid Build Coastguard Worker break;
1033*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16:
1034*61046927SAndroid Build Coastguard Worker this->value.f16[i] = value->get_float16_component(j);
1035*61046927SAndroid Build Coastguard Worker break;
1036*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL:
1037*61046927SAndroid Build Coastguard Worker this->value.b[i] = value->get_bool_component(j);
1038*61046927SAndroid Build Coastguard Worker break;
1039*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE:
1040*61046927SAndroid Build Coastguard Worker this->value.d[i] = value->get_double_component(j);
1041*61046927SAndroid Build Coastguard Worker break;
1042*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64:
1043*61046927SAndroid Build Coastguard Worker this->value.u64[i] = value->get_uint64_component(j);
1044*61046927SAndroid Build Coastguard Worker break;
1045*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64:
1046*61046927SAndroid Build Coastguard Worker this->value.i64[i] = value->get_int64_component(j);
1047*61046927SAndroid Build Coastguard Worker break;
1048*61046927SAndroid Build Coastguard Worker default:
1049*61046927SAndroid Build Coastguard Worker /* FINISHME: What to do? Exceptions are not the answer.
1050*61046927SAndroid Build Coastguard Worker */
1051*61046927SAndroid Build Coastguard Worker break;
1052*61046927SAndroid Build Coastguard Worker }
1053*61046927SAndroid Build Coastguard Worker
1054*61046927SAndroid Build Coastguard Worker i++;
1055*61046927SAndroid Build Coastguard Worker if (i >= glsl_get_components(type))
1056*61046927SAndroid Build Coastguard Worker break;
1057*61046927SAndroid Build Coastguard Worker }
1058*61046927SAndroid Build Coastguard Worker
1059*61046927SAndroid Build Coastguard Worker if (i >= glsl_get_components(type))
1060*61046927SAndroid Build Coastguard Worker break; /* avoid downcasting a list sentinel */
1061*61046927SAndroid Build Coastguard Worker value = (ir_constant *) value->next;
1062*61046927SAndroid Build Coastguard Worker }
1063*61046927SAndroid Build Coastguard Worker }
1064*61046927SAndroid Build Coastguard Worker
1065*61046927SAndroid Build Coastguard Worker ir_constant *
zero(void * mem_ctx,const glsl_type * type)1066*61046927SAndroid Build Coastguard Worker ir_constant::zero(void *mem_ctx, const glsl_type *type)
1067*61046927SAndroid Build Coastguard Worker {
1068*61046927SAndroid Build Coastguard Worker assert(glsl_type_is_scalar(type) || glsl_type_is_vector(type) || glsl_type_is_matrix(type)
1069*61046927SAndroid Build Coastguard Worker || glsl_type_is_struct(type) || glsl_type_is_array(type));
1070*61046927SAndroid Build Coastguard Worker
1071*61046927SAndroid Build Coastguard Worker ir_constant *c = new(mem_ctx) ir_constant;
1072*61046927SAndroid Build Coastguard Worker c->type = type;
1073*61046927SAndroid Build Coastguard Worker memset(&c->value, 0, sizeof(c->value));
1074*61046927SAndroid Build Coastguard Worker
1075*61046927SAndroid Build Coastguard Worker if (glsl_type_is_array(type)) {
1076*61046927SAndroid Build Coastguard Worker c->const_elements = ralloc_array(c, ir_constant *, type->length);
1077*61046927SAndroid Build Coastguard Worker
1078*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < type->length; i++)
1079*61046927SAndroid Build Coastguard Worker c->const_elements[i] = ir_constant::zero(c, type->fields.array);
1080*61046927SAndroid Build Coastguard Worker }
1081*61046927SAndroid Build Coastguard Worker
1082*61046927SAndroid Build Coastguard Worker if (glsl_type_is_struct(type)) {
1083*61046927SAndroid Build Coastguard Worker c->const_elements = ralloc_array(c, ir_constant *, type->length);
1084*61046927SAndroid Build Coastguard Worker
1085*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < type->length; i++) {
1086*61046927SAndroid Build Coastguard Worker c->const_elements[i] =
1087*61046927SAndroid Build Coastguard Worker ir_constant::zero(mem_ctx, type->fields.structure[i].type);
1088*61046927SAndroid Build Coastguard Worker }
1089*61046927SAndroid Build Coastguard Worker }
1090*61046927SAndroid Build Coastguard Worker
1091*61046927SAndroid Build Coastguard Worker return c;
1092*61046927SAndroid Build Coastguard Worker }
1093*61046927SAndroid Build Coastguard Worker
1094*61046927SAndroid Build Coastguard Worker bool
get_bool_component(unsigned i) const1095*61046927SAndroid Build Coastguard Worker ir_constant::get_bool_component(unsigned i) const
1096*61046927SAndroid Build Coastguard Worker {
1097*61046927SAndroid Build Coastguard Worker switch (this->type->base_type) {
1098*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:return this->value.u16[i] != 0;
1099*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16: return this->value.i16[i] != 0;
1100*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT: return this->value.u[i] != 0;
1101*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT: return this->value.i[i] != 0;
1102*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0;
1103*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16: return ((int)_mesa_half_to_float(this->value.f16[i])) != 0;
1104*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL: return this->value.b[i];
1105*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE: return this->value.d[i] != 0.0;
1106*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SAMPLER:
1107*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_IMAGE:
1108*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64: return this->value.u64[i] != 0;
1109*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64: return this->value.i64[i] != 0;
1110*61046927SAndroid Build Coastguard Worker default: assert(!"Should not get here."); break;
1111*61046927SAndroid Build Coastguard Worker }
1112*61046927SAndroid Build Coastguard Worker
1113*61046927SAndroid Build Coastguard Worker /* Must return something to make the compiler happy. This is clearly an
1114*61046927SAndroid Build Coastguard Worker * error case.
1115*61046927SAndroid Build Coastguard Worker */
1116*61046927SAndroid Build Coastguard Worker return false;
1117*61046927SAndroid Build Coastguard Worker }
1118*61046927SAndroid Build Coastguard Worker
1119*61046927SAndroid Build Coastguard Worker float
get_float_component(unsigned i) const1120*61046927SAndroid Build Coastguard Worker ir_constant::get_float_component(unsigned i) const
1121*61046927SAndroid Build Coastguard Worker {
1122*61046927SAndroid Build Coastguard Worker switch (this->type->base_type) {
1123*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:return (float) this->value.u16[i];
1124*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16: return (float) this->value.i16[i];
1125*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT: return (float) this->value.u[i];
1126*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT: return (float) this->value.i[i];
1127*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT: return this->value.f[i];
1128*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16: return _mesa_half_to_float(this->value.f16[i]);
1129*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL: return this->value.b[i] ? 1.0f : 0.0f;
1130*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE: return (float) this->value.d[i];
1131*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SAMPLER:
1132*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_IMAGE:
1133*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64: return (float) this->value.u64[i];
1134*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64: return (float) this->value.i64[i];
1135*61046927SAndroid Build Coastguard Worker default: assert(!"Should not get here."); break;
1136*61046927SAndroid Build Coastguard Worker }
1137*61046927SAndroid Build Coastguard Worker
1138*61046927SAndroid Build Coastguard Worker /* Must return something to make the compiler happy. This is clearly an
1139*61046927SAndroid Build Coastguard Worker * error case.
1140*61046927SAndroid Build Coastguard Worker */
1141*61046927SAndroid Build Coastguard Worker return 0.0;
1142*61046927SAndroid Build Coastguard Worker }
1143*61046927SAndroid Build Coastguard Worker
1144*61046927SAndroid Build Coastguard Worker uint16_t
get_float16_component(unsigned i) const1145*61046927SAndroid Build Coastguard Worker ir_constant::get_float16_component(unsigned i) const
1146*61046927SAndroid Build Coastguard Worker {
1147*61046927SAndroid Build Coastguard Worker if (this->type->base_type == GLSL_TYPE_FLOAT16)
1148*61046927SAndroid Build Coastguard Worker return this->value.f16[i];
1149*61046927SAndroid Build Coastguard Worker else
1150*61046927SAndroid Build Coastguard Worker return _mesa_float_to_half(get_float_component(i));
1151*61046927SAndroid Build Coastguard Worker }
1152*61046927SAndroid Build Coastguard Worker
1153*61046927SAndroid Build Coastguard Worker double
get_double_component(unsigned i) const1154*61046927SAndroid Build Coastguard Worker ir_constant::get_double_component(unsigned i) const
1155*61046927SAndroid Build Coastguard Worker {
1156*61046927SAndroid Build Coastguard Worker switch (this->type->base_type) {
1157*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:return (double) this->value.u16[i];
1158*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16: return (double) this->value.i16[i];
1159*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT: return (double) this->value.u[i];
1160*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT: return (double) this->value.i[i];
1161*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT: return (double) this->value.f[i];
1162*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16: return (double) _mesa_half_to_float(this->value.f16[i]);
1163*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL: return this->value.b[i] ? 1.0 : 0.0;
1164*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE: return this->value.d[i];
1165*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SAMPLER:
1166*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_IMAGE:
1167*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64: return (double) this->value.u64[i];
1168*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64: return (double) this->value.i64[i];
1169*61046927SAndroid Build Coastguard Worker default: assert(!"Should not get here."); break;
1170*61046927SAndroid Build Coastguard Worker }
1171*61046927SAndroid Build Coastguard Worker
1172*61046927SAndroid Build Coastguard Worker /* Must return something to make the compiler happy. This is clearly an
1173*61046927SAndroid Build Coastguard Worker * error case.
1174*61046927SAndroid Build Coastguard Worker */
1175*61046927SAndroid Build Coastguard Worker return 0.0;
1176*61046927SAndroid Build Coastguard Worker }
1177*61046927SAndroid Build Coastguard Worker
1178*61046927SAndroid Build Coastguard Worker int16_t
get_int16_component(unsigned i) const1179*61046927SAndroid Build Coastguard Worker ir_constant::get_int16_component(unsigned i) const
1180*61046927SAndroid Build Coastguard Worker {
1181*61046927SAndroid Build Coastguard Worker switch (this->type->base_type) {
1182*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:return this->value.u16[i];
1183*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16: return this->value.i16[i];
1184*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT: return this->value.u[i];
1185*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT: return this->value.i[i];
1186*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT: return (int16_t) this->value.f[i];
1187*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16: return (int16_t) _mesa_half_to_float(this->value.f16[i]);
1188*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0;
1189*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE: return (int16_t) this->value.d[i];
1190*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SAMPLER:
1191*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_IMAGE:
1192*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64: return (int16_t) this->value.u64[i];
1193*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64: return (int16_t) this->value.i64[i];
1194*61046927SAndroid Build Coastguard Worker default: assert(!"Should not get here."); break;
1195*61046927SAndroid Build Coastguard Worker }
1196*61046927SAndroid Build Coastguard Worker
1197*61046927SAndroid Build Coastguard Worker /* Must return something to make the compiler happy. This is clearly an
1198*61046927SAndroid Build Coastguard Worker * error case.
1199*61046927SAndroid Build Coastguard Worker */
1200*61046927SAndroid Build Coastguard Worker return 0;
1201*61046927SAndroid Build Coastguard Worker }
1202*61046927SAndroid Build Coastguard Worker
1203*61046927SAndroid Build Coastguard Worker uint16_t
get_uint16_component(unsigned i) const1204*61046927SAndroid Build Coastguard Worker ir_constant::get_uint16_component(unsigned i) const
1205*61046927SAndroid Build Coastguard Worker {
1206*61046927SAndroid Build Coastguard Worker switch (this->type->base_type) {
1207*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:return this->value.u16[i];
1208*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16: return this->value.i16[i];
1209*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT: return this->value.u[i];
1210*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT: return this->value.i[i];
1211*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT: return (uint16_t) this->value.f[i];
1212*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16: return (uint16_t) _mesa_half_to_float(this->value.f16[i]);
1213*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0;
1214*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE: return (uint16_t) this->value.d[i];
1215*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SAMPLER:
1216*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_IMAGE:
1217*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64: return (uint16_t) this->value.u64[i];
1218*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64: return (uint16_t) this->value.i64[i];
1219*61046927SAndroid Build Coastguard Worker default: assert(!"Should not get here."); break;
1220*61046927SAndroid Build Coastguard Worker }
1221*61046927SAndroid Build Coastguard Worker
1222*61046927SAndroid Build Coastguard Worker /* Must return something to make the compiler happy. This is clearly an
1223*61046927SAndroid Build Coastguard Worker * error case.
1224*61046927SAndroid Build Coastguard Worker */
1225*61046927SAndroid Build Coastguard Worker return 0;
1226*61046927SAndroid Build Coastguard Worker }
1227*61046927SAndroid Build Coastguard Worker
1228*61046927SAndroid Build Coastguard Worker int
get_int_component(unsigned i) const1229*61046927SAndroid Build Coastguard Worker ir_constant::get_int_component(unsigned i) const
1230*61046927SAndroid Build Coastguard Worker {
1231*61046927SAndroid Build Coastguard Worker switch (this->type->base_type) {
1232*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:return this->value.u16[i];
1233*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16: return this->value.i16[i];
1234*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT: return this->value.u[i];
1235*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT: return this->value.i[i];
1236*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT: return (int) this->value.f[i];
1237*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16: return (int) _mesa_half_to_float(this->value.f16[i]);
1238*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0;
1239*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE: return (int) this->value.d[i];
1240*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SAMPLER:
1241*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_IMAGE:
1242*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64: return (int) this->value.u64[i];
1243*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64: return (int) this->value.i64[i];
1244*61046927SAndroid Build Coastguard Worker default: assert(!"Should not get here."); break;
1245*61046927SAndroid Build Coastguard Worker }
1246*61046927SAndroid Build Coastguard Worker
1247*61046927SAndroid Build Coastguard Worker /* Must return something to make the compiler happy. This is clearly an
1248*61046927SAndroid Build Coastguard Worker * error case.
1249*61046927SAndroid Build Coastguard Worker */
1250*61046927SAndroid Build Coastguard Worker return 0;
1251*61046927SAndroid Build Coastguard Worker }
1252*61046927SAndroid Build Coastguard Worker
1253*61046927SAndroid Build Coastguard Worker unsigned
get_uint_component(unsigned i) const1254*61046927SAndroid Build Coastguard Worker ir_constant::get_uint_component(unsigned i) const
1255*61046927SAndroid Build Coastguard Worker {
1256*61046927SAndroid Build Coastguard Worker switch (this->type->base_type) {
1257*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:return this->value.u16[i];
1258*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16: return this->value.i16[i];
1259*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT: return this->value.u[i];
1260*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT: return this->value.i[i];
1261*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i];
1262*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16: return (unsigned) _mesa_half_to_float(this->value.f16[i]);
1263*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0;
1264*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE: return (unsigned) this->value.d[i];
1265*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SAMPLER:
1266*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_IMAGE:
1267*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64: return (unsigned) this->value.u64[i];
1268*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64: return (unsigned) this->value.i64[i];
1269*61046927SAndroid Build Coastguard Worker default: assert(!"Should not get here."); break;
1270*61046927SAndroid Build Coastguard Worker }
1271*61046927SAndroid Build Coastguard Worker
1272*61046927SAndroid Build Coastguard Worker /* Must return something to make the compiler happy. This is clearly an
1273*61046927SAndroid Build Coastguard Worker * error case.
1274*61046927SAndroid Build Coastguard Worker */
1275*61046927SAndroid Build Coastguard Worker return 0;
1276*61046927SAndroid Build Coastguard Worker }
1277*61046927SAndroid Build Coastguard Worker
1278*61046927SAndroid Build Coastguard Worker int64_t
get_int64_component(unsigned i) const1279*61046927SAndroid Build Coastguard Worker ir_constant::get_int64_component(unsigned i) const
1280*61046927SAndroid Build Coastguard Worker {
1281*61046927SAndroid Build Coastguard Worker switch (this->type->base_type) {
1282*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:return this->value.u16[i];
1283*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16: return this->value.i16[i];
1284*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT: return this->value.u[i];
1285*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT: return this->value.i[i];
1286*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT: return (int64_t) this->value.f[i];
1287*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16: return (int64_t) _mesa_half_to_float(this->value.f16[i]);
1288*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0;
1289*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE: return (int64_t) this->value.d[i];
1290*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SAMPLER:
1291*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_IMAGE:
1292*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64: return (int64_t) this->value.u64[i];
1293*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64: return this->value.i64[i];
1294*61046927SAndroid Build Coastguard Worker default: assert(!"Should not get here."); break;
1295*61046927SAndroid Build Coastguard Worker }
1296*61046927SAndroid Build Coastguard Worker
1297*61046927SAndroid Build Coastguard Worker /* Must return something to make the compiler happy. This is clearly an
1298*61046927SAndroid Build Coastguard Worker * error case.
1299*61046927SAndroid Build Coastguard Worker */
1300*61046927SAndroid Build Coastguard Worker return 0;
1301*61046927SAndroid Build Coastguard Worker }
1302*61046927SAndroid Build Coastguard Worker
1303*61046927SAndroid Build Coastguard Worker uint64_t
get_uint64_component(unsigned i) const1304*61046927SAndroid Build Coastguard Worker ir_constant::get_uint64_component(unsigned i) const
1305*61046927SAndroid Build Coastguard Worker {
1306*61046927SAndroid Build Coastguard Worker switch (this->type->base_type) {
1307*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:return this->value.u16[i];
1308*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16: return this->value.i16[i];
1309*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT: return this->value.u[i];
1310*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT: return this->value.i[i];
1311*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT: return (uint64_t) this->value.f[i];
1312*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16: return (uint64_t) _mesa_half_to_float(this->value.f16[i]);
1313*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0;
1314*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE: return (uint64_t) this->value.d[i];
1315*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SAMPLER:
1316*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_IMAGE:
1317*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64: return this->value.u64[i];
1318*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64: return (uint64_t) this->value.i64[i];
1319*61046927SAndroid Build Coastguard Worker default: assert(!"Should not get here."); break;
1320*61046927SAndroid Build Coastguard Worker }
1321*61046927SAndroid Build Coastguard Worker
1322*61046927SAndroid Build Coastguard Worker /* Must return something to make the compiler happy. This is clearly an
1323*61046927SAndroid Build Coastguard Worker * error case.
1324*61046927SAndroid Build Coastguard Worker */
1325*61046927SAndroid Build Coastguard Worker return 0;
1326*61046927SAndroid Build Coastguard Worker }
1327*61046927SAndroid Build Coastguard Worker
1328*61046927SAndroid Build Coastguard Worker ir_constant *
get_array_element(unsigned i) const1329*61046927SAndroid Build Coastguard Worker ir_constant::get_array_element(unsigned i) const
1330*61046927SAndroid Build Coastguard Worker {
1331*61046927SAndroid Build Coastguard Worker assert(glsl_type_is_array(this->type));
1332*61046927SAndroid Build Coastguard Worker
1333*61046927SAndroid Build Coastguard Worker /* From page 35 (page 41 of the PDF) of the GLSL 1.20 spec:
1334*61046927SAndroid Build Coastguard Worker *
1335*61046927SAndroid Build Coastguard Worker * "Behavior is undefined if a shader subscripts an array with an index
1336*61046927SAndroid Build Coastguard Worker * less than 0 or greater than or equal to the size the array was
1337*61046927SAndroid Build Coastguard Worker * declared with."
1338*61046927SAndroid Build Coastguard Worker *
1339*61046927SAndroid Build Coastguard Worker * Most out-of-bounds accesses are removed before things could get this far.
1340*61046927SAndroid Build Coastguard Worker * There are cases where non-constant array index values can get constant
1341*61046927SAndroid Build Coastguard Worker * folded.
1342*61046927SAndroid Build Coastguard Worker */
1343*61046927SAndroid Build Coastguard Worker if (int(i) < 0)
1344*61046927SAndroid Build Coastguard Worker i = 0;
1345*61046927SAndroid Build Coastguard Worker else if (i >= this->type->length)
1346*61046927SAndroid Build Coastguard Worker i = this->type->length - 1;
1347*61046927SAndroid Build Coastguard Worker
1348*61046927SAndroid Build Coastguard Worker return const_elements[i];
1349*61046927SAndroid Build Coastguard Worker }
1350*61046927SAndroid Build Coastguard Worker
1351*61046927SAndroid Build Coastguard Worker ir_constant *
get_record_field(int idx)1352*61046927SAndroid Build Coastguard Worker ir_constant::get_record_field(int idx)
1353*61046927SAndroid Build Coastguard Worker {
1354*61046927SAndroid Build Coastguard Worker assert(glsl_type_is_struct(this->type));
1355*61046927SAndroid Build Coastguard Worker assert(idx >= 0 && (unsigned) idx < this->type->length);
1356*61046927SAndroid Build Coastguard Worker
1357*61046927SAndroid Build Coastguard Worker return const_elements[idx];
1358*61046927SAndroid Build Coastguard Worker }
1359*61046927SAndroid Build Coastguard Worker
1360*61046927SAndroid Build Coastguard Worker void
copy_offset(ir_constant * src,int offset)1361*61046927SAndroid Build Coastguard Worker ir_constant::copy_offset(ir_constant *src, int offset)
1362*61046927SAndroid Build Coastguard Worker {
1363*61046927SAndroid Build Coastguard Worker switch (this->type->base_type) {
1364*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:
1365*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16:
1366*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT:
1367*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT:
1368*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT:
1369*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16:
1370*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE:
1371*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SAMPLER:
1372*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_IMAGE:
1373*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64:
1374*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64:
1375*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL: {
1376*61046927SAndroid Build Coastguard Worker unsigned int size = glsl_get_components(src->type);
1377*61046927SAndroid Build Coastguard Worker assert (size <= glsl_get_components(this->type) - offset);
1378*61046927SAndroid Build Coastguard Worker for (unsigned int i=0; i<size; i++) {
1379*61046927SAndroid Build Coastguard Worker switch (this->type->base_type) {
1380*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:
1381*61046927SAndroid Build Coastguard Worker value.u16[i+offset] = src->get_uint16_component(i);
1382*61046927SAndroid Build Coastguard Worker break;
1383*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16:
1384*61046927SAndroid Build Coastguard Worker value.i16[i+offset] = src->get_int16_component(i);
1385*61046927SAndroid Build Coastguard Worker break;
1386*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT:
1387*61046927SAndroid Build Coastguard Worker value.u[i+offset] = src->get_uint_component(i);
1388*61046927SAndroid Build Coastguard Worker break;
1389*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT:
1390*61046927SAndroid Build Coastguard Worker value.i[i+offset] = src->get_int_component(i);
1391*61046927SAndroid Build Coastguard Worker break;
1392*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT:
1393*61046927SAndroid Build Coastguard Worker value.f[i+offset] = src->get_float_component(i);
1394*61046927SAndroid Build Coastguard Worker break;
1395*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16:
1396*61046927SAndroid Build Coastguard Worker value.f16[i+offset] = src->get_float16_component(i);
1397*61046927SAndroid Build Coastguard Worker break;
1398*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL:
1399*61046927SAndroid Build Coastguard Worker value.b[i+offset] = src->get_bool_component(i);
1400*61046927SAndroid Build Coastguard Worker break;
1401*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE:
1402*61046927SAndroid Build Coastguard Worker value.d[i+offset] = src->get_double_component(i);
1403*61046927SAndroid Build Coastguard Worker break;
1404*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SAMPLER:
1405*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_IMAGE:
1406*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64:
1407*61046927SAndroid Build Coastguard Worker value.u64[i+offset] = src->get_uint64_component(i);
1408*61046927SAndroid Build Coastguard Worker break;
1409*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64:
1410*61046927SAndroid Build Coastguard Worker value.i64[i+offset] = src->get_int64_component(i);
1411*61046927SAndroid Build Coastguard Worker break;
1412*61046927SAndroid Build Coastguard Worker default: // Shut up the compiler
1413*61046927SAndroid Build Coastguard Worker break;
1414*61046927SAndroid Build Coastguard Worker }
1415*61046927SAndroid Build Coastguard Worker }
1416*61046927SAndroid Build Coastguard Worker break;
1417*61046927SAndroid Build Coastguard Worker }
1418*61046927SAndroid Build Coastguard Worker
1419*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_STRUCT:
1420*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_ARRAY: {
1421*61046927SAndroid Build Coastguard Worker assert (src->type == this->type);
1422*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < this->type->length; i++) {
1423*61046927SAndroid Build Coastguard Worker this->const_elements[i] = src->const_elements[i]->clone(this, NULL);
1424*61046927SAndroid Build Coastguard Worker }
1425*61046927SAndroid Build Coastguard Worker break;
1426*61046927SAndroid Build Coastguard Worker }
1427*61046927SAndroid Build Coastguard Worker
1428*61046927SAndroid Build Coastguard Worker default:
1429*61046927SAndroid Build Coastguard Worker assert(!"Should not get here.");
1430*61046927SAndroid Build Coastguard Worker break;
1431*61046927SAndroid Build Coastguard Worker }
1432*61046927SAndroid Build Coastguard Worker }
1433*61046927SAndroid Build Coastguard Worker
1434*61046927SAndroid Build Coastguard Worker void
copy_masked_offset(ir_constant * src,int offset,unsigned int mask)1435*61046927SAndroid Build Coastguard Worker ir_constant::copy_masked_offset(ir_constant *src, int offset, unsigned int mask)
1436*61046927SAndroid Build Coastguard Worker {
1437*61046927SAndroid Build Coastguard Worker assert (!glsl_type_is_array(type) && !glsl_type_is_struct(type));
1438*61046927SAndroid Build Coastguard Worker
1439*61046927SAndroid Build Coastguard Worker if (!glsl_type_is_vector(type) && !glsl_type_is_matrix(type)) {
1440*61046927SAndroid Build Coastguard Worker offset = 0;
1441*61046927SAndroid Build Coastguard Worker mask = 1;
1442*61046927SAndroid Build Coastguard Worker }
1443*61046927SAndroid Build Coastguard Worker
1444*61046927SAndroid Build Coastguard Worker int id = 0;
1445*61046927SAndroid Build Coastguard Worker for (int i=0; i<4; i++) {
1446*61046927SAndroid Build Coastguard Worker if (mask & (1 << i)) {
1447*61046927SAndroid Build Coastguard Worker switch (this->type->base_type) {
1448*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:
1449*61046927SAndroid Build Coastguard Worker value.u16[i+offset] = src->get_uint16_component(id++);
1450*61046927SAndroid Build Coastguard Worker break;
1451*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16:
1452*61046927SAndroid Build Coastguard Worker value.i16[i+offset] = src->get_int16_component(id++);
1453*61046927SAndroid Build Coastguard Worker break;
1454*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT:
1455*61046927SAndroid Build Coastguard Worker value.u[i+offset] = src->get_uint_component(id++);
1456*61046927SAndroid Build Coastguard Worker break;
1457*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT:
1458*61046927SAndroid Build Coastguard Worker value.i[i+offset] = src->get_int_component(id++);
1459*61046927SAndroid Build Coastguard Worker break;
1460*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT:
1461*61046927SAndroid Build Coastguard Worker value.f[i+offset] = src->get_float_component(id++);
1462*61046927SAndroid Build Coastguard Worker break;
1463*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16:
1464*61046927SAndroid Build Coastguard Worker value.f16[i+offset] = src->get_float16_component(id++);
1465*61046927SAndroid Build Coastguard Worker break;
1466*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL:
1467*61046927SAndroid Build Coastguard Worker value.b[i+offset] = src->get_bool_component(id++);
1468*61046927SAndroid Build Coastguard Worker break;
1469*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE:
1470*61046927SAndroid Build Coastguard Worker value.d[i+offset] = src->get_double_component(id++);
1471*61046927SAndroid Build Coastguard Worker break;
1472*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SAMPLER:
1473*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_IMAGE:
1474*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64:
1475*61046927SAndroid Build Coastguard Worker value.u64[i+offset] = src->get_uint64_component(id++);
1476*61046927SAndroid Build Coastguard Worker break;
1477*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64:
1478*61046927SAndroid Build Coastguard Worker value.i64[i+offset] = src->get_int64_component(id++);
1479*61046927SAndroid Build Coastguard Worker break;
1480*61046927SAndroid Build Coastguard Worker default:
1481*61046927SAndroid Build Coastguard Worker assert(!"Should not get here.");
1482*61046927SAndroid Build Coastguard Worker return;
1483*61046927SAndroid Build Coastguard Worker }
1484*61046927SAndroid Build Coastguard Worker }
1485*61046927SAndroid Build Coastguard Worker }
1486*61046927SAndroid Build Coastguard Worker }
1487*61046927SAndroid Build Coastguard Worker
1488*61046927SAndroid Build Coastguard Worker bool
has_value(const ir_constant * c) const1489*61046927SAndroid Build Coastguard Worker ir_constant::has_value(const ir_constant *c) const
1490*61046927SAndroid Build Coastguard Worker {
1491*61046927SAndroid Build Coastguard Worker if (this->type != c->type)
1492*61046927SAndroid Build Coastguard Worker return false;
1493*61046927SAndroid Build Coastguard Worker
1494*61046927SAndroid Build Coastguard Worker if (glsl_type_is_array(this->type) || glsl_type_is_struct(this->type)) {
1495*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < this->type->length; i++) {
1496*61046927SAndroid Build Coastguard Worker if (!this->const_elements[i]->has_value(c->const_elements[i]))
1497*61046927SAndroid Build Coastguard Worker return false;
1498*61046927SAndroid Build Coastguard Worker }
1499*61046927SAndroid Build Coastguard Worker return true;
1500*61046927SAndroid Build Coastguard Worker }
1501*61046927SAndroid Build Coastguard Worker
1502*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < glsl_get_components(this->type); i++) {
1503*61046927SAndroid Build Coastguard Worker switch (this->type->base_type) {
1504*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:
1505*61046927SAndroid Build Coastguard Worker if (this->value.u16[i] != c->value.u16[i])
1506*61046927SAndroid Build Coastguard Worker return false;
1507*61046927SAndroid Build Coastguard Worker break;
1508*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16:
1509*61046927SAndroid Build Coastguard Worker if (this->value.i16[i] != c->value.i16[i])
1510*61046927SAndroid Build Coastguard Worker return false;
1511*61046927SAndroid Build Coastguard Worker break;
1512*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT:
1513*61046927SAndroid Build Coastguard Worker if (this->value.u[i] != c->value.u[i])
1514*61046927SAndroid Build Coastguard Worker return false;
1515*61046927SAndroid Build Coastguard Worker break;
1516*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT:
1517*61046927SAndroid Build Coastguard Worker if (this->value.i[i] != c->value.i[i])
1518*61046927SAndroid Build Coastguard Worker return false;
1519*61046927SAndroid Build Coastguard Worker break;
1520*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT:
1521*61046927SAndroid Build Coastguard Worker if (this->value.f[i] != c->value.f[i])
1522*61046927SAndroid Build Coastguard Worker return false;
1523*61046927SAndroid Build Coastguard Worker break;
1524*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16:
1525*61046927SAndroid Build Coastguard Worker /* Convert to float to make sure NaN and ±0.0 compares correctly */
1526*61046927SAndroid Build Coastguard Worker if (_mesa_half_to_float(this->value.f16[i]) !=
1527*61046927SAndroid Build Coastguard Worker _mesa_half_to_float(c->value.f16[i]))
1528*61046927SAndroid Build Coastguard Worker return false;
1529*61046927SAndroid Build Coastguard Worker break;
1530*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL:
1531*61046927SAndroid Build Coastguard Worker if (this->value.b[i] != c->value.b[i])
1532*61046927SAndroid Build Coastguard Worker return false;
1533*61046927SAndroid Build Coastguard Worker break;
1534*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE:
1535*61046927SAndroid Build Coastguard Worker if (this->value.d[i] != c->value.d[i])
1536*61046927SAndroid Build Coastguard Worker return false;
1537*61046927SAndroid Build Coastguard Worker break;
1538*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SAMPLER:
1539*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_IMAGE:
1540*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64:
1541*61046927SAndroid Build Coastguard Worker if (this->value.u64[i] != c->value.u64[i])
1542*61046927SAndroid Build Coastguard Worker return false;
1543*61046927SAndroid Build Coastguard Worker break;
1544*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64:
1545*61046927SAndroid Build Coastguard Worker if (this->value.i64[i] != c->value.i64[i])
1546*61046927SAndroid Build Coastguard Worker return false;
1547*61046927SAndroid Build Coastguard Worker break;
1548*61046927SAndroid Build Coastguard Worker default:
1549*61046927SAndroid Build Coastguard Worker assert(!"Should not get here.");
1550*61046927SAndroid Build Coastguard Worker return false;
1551*61046927SAndroid Build Coastguard Worker }
1552*61046927SAndroid Build Coastguard Worker }
1553*61046927SAndroid Build Coastguard Worker
1554*61046927SAndroid Build Coastguard Worker return true;
1555*61046927SAndroid Build Coastguard Worker }
1556*61046927SAndroid Build Coastguard Worker
1557*61046927SAndroid Build Coastguard Worker bool
is_value(float f,int i) const1558*61046927SAndroid Build Coastguard Worker ir_constant::is_value(float f, int i) const
1559*61046927SAndroid Build Coastguard Worker {
1560*61046927SAndroid Build Coastguard Worker if (!glsl_type_is_scalar(this->type) && !glsl_type_is_vector(this->type))
1561*61046927SAndroid Build Coastguard Worker return false;
1562*61046927SAndroid Build Coastguard Worker
1563*61046927SAndroid Build Coastguard Worker /* Only accept boolean values for 0/1. */
1564*61046927SAndroid Build Coastguard Worker if (int(bool(i)) != i && glsl_type_is_boolean(this->type))
1565*61046927SAndroid Build Coastguard Worker return false;
1566*61046927SAndroid Build Coastguard Worker
1567*61046927SAndroid Build Coastguard Worker for (unsigned c = 0; c < this->type->vector_elements; c++) {
1568*61046927SAndroid Build Coastguard Worker switch (this->type->base_type) {
1569*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT:
1570*61046927SAndroid Build Coastguard Worker if (this->value.f[c] != f)
1571*61046927SAndroid Build Coastguard Worker return false;
1572*61046927SAndroid Build Coastguard Worker break;
1573*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT16:
1574*61046927SAndroid Build Coastguard Worker if (_mesa_half_to_float(this->value.f16[c]) != f)
1575*61046927SAndroid Build Coastguard Worker return false;
1576*61046927SAndroid Build Coastguard Worker break;
1577*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT16:
1578*61046927SAndroid Build Coastguard Worker if (this->value.i16[c] != int16_t(i))
1579*61046927SAndroid Build Coastguard Worker return false;
1580*61046927SAndroid Build Coastguard Worker break;
1581*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT16:
1582*61046927SAndroid Build Coastguard Worker if (this->value.u16[c] != uint16_t(i))
1583*61046927SAndroid Build Coastguard Worker return false;
1584*61046927SAndroid Build Coastguard Worker break;
1585*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT:
1586*61046927SAndroid Build Coastguard Worker if (this->value.i[c] != i)
1587*61046927SAndroid Build Coastguard Worker return false;
1588*61046927SAndroid Build Coastguard Worker break;
1589*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT:
1590*61046927SAndroid Build Coastguard Worker if (this->value.u[c] != unsigned(i))
1591*61046927SAndroid Build Coastguard Worker return false;
1592*61046927SAndroid Build Coastguard Worker break;
1593*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_BOOL:
1594*61046927SAndroid Build Coastguard Worker if (this->value.b[c] != bool(i))
1595*61046927SAndroid Build Coastguard Worker return false;
1596*61046927SAndroid Build Coastguard Worker break;
1597*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_DOUBLE:
1598*61046927SAndroid Build Coastguard Worker if (this->value.d[c] != double(f))
1599*61046927SAndroid Build Coastguard Worker return false;
1600*61046927SAndroid Build Coastguard Worker break;
1601*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_SAMPLER:
1602*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_IMAGE:
1603*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT64:
1604*61046927SAndroid Build Coastguard Worker if (this->value.u64[c] != uint64_t(i))
1605*61046927SAndroid Build Coastguard Worker return false;
1606*61046927SAndroid Build Coastguard Worker break;
1607*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT64:
1608*61046927SAndroid Build Coastguard Worker if (this->value.i64[c] != i)
1609*61046927SAndroid Build Coastguard Worker return false;
1610*61046927SAndroid Build Coastguard Worker break;
1611*61046927SAndroid Build Coastguard Worker default:
1612*61046927SAndroid Build Coastguard Worker /* The only other base types are structures, arrays, and samplers.
1613*61046927SAndroid Build Coastguard Worker * Samplers cannot be constants, and the others should have been
1614*61046927SAndroid Build Coastguard Worker * filtered out above.
1615*61046927SAndroid Build Coastguard Worker */
1616*61046927SAndroid Build Coastguard Worker assert(!"Should not get here.");
1617*61046927SAndroid Build Coastguard Worker return false;
1618*61046927SAndroid Build Coastguard Worker }
1619*61046927SAndroid Build Coastguard Worker }
1620*61046927SAndroid Build Coastguard Worker
1621*61046927SAndroid Build Coastguard Worker return true;
1622*61046927SAndroid Build Coastguard Worker }
1623*61046927SAndroid Build Coastguard Worker
1624*61046927SAndroid Build Coastguard Worker bool
is_zero() const1625*61046927SAndroid Build Coastguard Worker ir_constant::is_zero() const
1626*61046927SAndroid Build Coastguard Worker {
1627*61046927SAndroid Build Coastguard Worker return is_value(0.0, 0);
1628*61046927SAndroid Build Coastguard Worker }
1629*61046927SAndroid Build Coastguard Worker
1630*61046927SAndroid Build Coastguard Worker bool
is_one() const1631*61046927SAndroid Build Coastguard Worker ir_constant::is_one() const
1632*61046927SAndroid Build Coastguard Worker {
1633*61046927SAndroid Build Coastguard Worker return is_value(1.0, 1);
1634*61046927SAndroid Build Coastguard Worker }
1635*61046927SAndroid Build Coastguard Worker
1636*61046927SAndroid Build Coastguard Worker bool
is_negative_one() const1637*61046927SAndroid Build Coastguard Worker ir_constant::is_negative_one() const
1638*61046927SAndroid Build Coastguard Worker {
1639*61046927SAndroid Build Coastguard Worker return is_value(-1.0, -1);
1640*61046927SAndroid Build Coastguard Worker }
1641*61046927SAndroid Build Coastguard Worker
1642*61046927SAndroid Build Coastguard Worker bool
is_uint16_constant() const1643*61046927SAndroid Build Coastguard Worker ir_constant::is_uint16_constant() const
1644*61046927SAndroid Build Coastguard Worker {
1645*61046927SAndroid Build Coastguard Worker if (!glsl_type_is_integer_32(type))
1646*61046927SAndroid Build Coastguard Worker return false;
1647*61046927SAndroid Build Coastguard Worker
1648*61046927SAndroid Build Coastguard Worker return value.u[0] < (1 << 16);
1649*61046927SAndroid Build Coastguard Worker }
1650*61046927SAndroid Build Coastguard Worker
ir_loop()1651*61046927SAndroid Build Coastguard Worker ir_loop::ir_loop()
1652*61046927SAndroid Build Coastguard Worker : ir_instruction(ir_type_loop)
1653*61046927SAndroid Build Coastguard Worker {
1654*61046927SAndroid Build Coastguard Worker }
1655*61046927SAndroid Build Coastguard Worker
1656*61046927SAndroid Build Coastguard Worker
ir_dereference_variable(ir_variable * var)1657*61046927SAndroid Build Coastguard Worker ir_dereference_variable::ir_dereference_variable(ir_variable *var)
1658*61046927SAndroid Build Coastguard Worker : ir_dereference(ir_type_dereference_variable)
1659*61046927SAndroid Build Coastguard Worker {
1660*61046927SAndroid Build Coastguard Worker assert(var != NULL);
1661*61046927SAndroid Build Coastguard Worker
1662*61046927SAndroid Build Coastguard Worker this->var = var;
1663*61046927SAndroid Build Coastguard Worker this->type = var->type;
1664*61046927SAndroid Build Coastguard Worker }
1665*61046927SAndroid Build Coastguard Worker
1666*61046927SAndroid Build Coastguard Worker
ir_dereference_array(ir_rvalue * value,ir_rvalue * array_index)1667*61046927SAndroid Build Coastguard Worker ir_dereference_array::ir_dereference_array(ir_rvalue *value,
1668*61046927SAndroid Build Coastguard Worker ir_rvalue *array_index)
1669*61046927SAndroid Build Coastguard Worker : ir_dereference(ir_type_dereference_array)
1670*61046927SAndroid Build Coastguard Worker {
1671*61046927SAndroid Build Coastguard Worker this->array_index = array_index;
1672*61046927SAndroid Build Coastguard Worker this->set_array(value);
1673*61046927SAndroid Build Coastguard Worker }
1674*61046927SAndroid Build Coastguard Worker
1675*61046927SAndroid Build Coastguard Worker
ir_dereference_array(ir_variable * var,ir_rvalue * array_index)1676*61046927SAndroid Build Coastguard Worker ir_dereference_array::ir_dereference_array(ir_variable *var,
1677*61046927SAndroid Build Coastguard Worker ir_rvalue *array_index)
1678*61046927SAndroid Build Coastguard Worker : ir_dereference(ir_type_dereference_array)
1679*61046927SAndroid Build Coastguard Worker {
1680*61046927SAndroid Build Coastguard Worker void *ctx = ralloc_parent(var);
1681*61046927SAndroid Build Coastguard Worker
1682*61046927SAndroid Build Coastguard Worker this->array_index = array_index;
1683*61046927SAndroid Build Coastguard Worker this->set_array(new(ctx) ir_dereference_variable(var));
1684*61046927SAndroid Build Coastguard Worker }
1685*61046927SAndroid Build Coastguard Worker
1686*61046927SAndroid Build Coastguard Worker
1687*61046927SAndroid Build Coastguard Worker void
set_array(ir_rvalue * value)1688*61046927SAndroid Build Coastguard Worker ir_dereference_array::set_array(ir_rvalue *value)
1689*61046927SAndroid Build Coastguard Worker {
1690*61046927SAndroid Build Coastguard Worker assert(value != NULL);
1691*61046927SAndroid Build Coastguard Worker
1692*61046927SAndroid Build Coastguard Worker this->array = value;
1693*61046927SAndroid Build Coastguard Worker
1694*61046927SAndroid Build Coastguard Worker const glsl_type *const vt = this->array->type;
1695*61046927SAndroid Build Coastguard Worker
1696*61046927SAndroid Build Coastguard Worker if (glsl_type_is_array(vt)) {
1697*61046927SAndroid Build Coastguard Worker type = vt->fields.array;
1698*61046927SAndroid Build Coastguard Worker } else if (glsl_type_is_matrix(vt)) {
1699*61046927SAndroid Build Coastguard Worker type = glsl_get_column_type(vt);
1700*61046927SAndroid Build Coastguard Worker } else if (glsl_type_is_vector(vt)) {
1701*61046927SAndroid Build Coastguard Worker type = glsl_get_base_glsl_type(vt);
1702*61046927SAndroid Build Coastguard Worker }
1703*61046927SAndroid Build Coastguard Worker }
1704*61046927SAndroid Build Coastguard Worker
1705*61046927SAndroid Build Coastguard Worker
ir_dereference_record(ir_rvalue * value,const char * field)1706*61046927SAndroid Build Coastguard Worker ir_dereference_record::ir_dereference_record(ir_rvalue *value,
1707*61046927SAndroid Build Coastguard Worker const char *field)
1708*61046927SAndroid Build Coastguard Worker : ir_dereference(ir_type_dereference_record)
1709*61046927SAndroid Build Coastguard Worker {
1710*61046927SAndroid Build Coastguard Worker assert(value != NULL);
1711*61046927SAndroid Build Coastguard Worker
1712*61046927SAndroid Build Coastguard Worker this->record = value;
1713*61046927SAndroid Build Coastguard Worker this->type = glsl_get_field_type(this->record->type, field);
1714*61046927SAndroid Build Coastguard Worker this->field_idx = glsl_get_field_index(this->record->type, field);
1715*61046927SAndroid Build Coastguard Worker }
1716*61046927SAndroid Build Coastguard Worker
1717*61046927SAndroid Build Coastguard Worker
ir_dereference_record(ir_variable * var,const char * field)1718*61046927SAndroid Build Coastguard Worker ir_dereference_record::ir_dereference_record(ir_variable *var,
1719*61046927SAndroid Build Coastguard Worker const char *field)
1720*61046927SAndroid Build Coastguard Worker : ir_dereference(ir_type_dereference_record)
1721*61046927SAndroid Build Coastguard Worker {
1722*61046927SAndroid Build Coastguard Worker void *ctx = ralloc_parent(var);
1723*61046927SAndroid Build Coastguard Worker
1724*61046927SAndroid Build Coastguard Worker this->record = new(ctx) ir_dereference_variable(var);
1725*61046927SAndroid Build Coastguard Worker this->type = glsl_get_field_type(this->record->type, field);
1726*61046927SAndroid Build Coastguard Worker this->field_idx = glsl_get_field_index(this->record->type, field);
1727*61046927SAndroid Build Coastguard Worker }
1728*61046927SAndroid Build Coastguard Worker
1729*61046927SAndroid Build Coastguard Worker bool
is_lvalue(const struct _mesa_glsl_parse_state * state) const1730*61046927SAndroid Build Coastguard Worker ir_dereference::is_lvalue(const struct _mesa_glsl_parse_state *state) const
1731*61046927SAndroid Build Coastguard Worker {
1732*61046927SAndroid Build Coastguard Worker ir_variable *var = this->variable_referenced();
1733*61046927SAndroid Build Coastguard Worker
1734*61046927SAndroid Build Coastguard Worker /* Every l-value dereference chain eventually ends in a variable.
1735*61046927SAndroid Build Coastguard Worker */
1736*61046927SAndroid Build Coastguard Worker if ((var == NULL) || var->data.read_only)
1737*61046927SAndroid Build Coastguard Worker return false;
1738*61046927SAndroid Build Coastguard Worker
1739*61046927SAndroid Build Coastguard Worker /* From section 4.1.7 of the ARB_bindless_texture spec:
1740*61046927SAndroid Build Coastguard Worker *
1741*61046927SAndroid Build Coastguard Worker * "Samplers can be used as l-values, so can be assigned into and used as
1742*61046927SAndroid Build Coastguard Worker * "out" and "inout" function parameters."
1743*61046927SAndroid Build Coastguard Worker *
1744*61046927SAndroid Build Coastguard Worker * From section 4.1.X of the ARB_bindless_texture spec:
1745*61046927SAndroid Build Coastguard Worker *
1746*61046927SAndroid Build Coastguard Worker * "Images can be used as l-values, so can be assigned into and used as
1747*61046927SAndroid Build Coastguard Worker * "out" and "inout" function parameters."
1748*61046927SAndroid Build Coastguard Worker */
1749*61046927SAndroid Build Coastguard Worker if ((!state || state->has_bindless()) &&
1750*61046927SAndroid Build Coastguard Worker (glsl_contains_sampler(this->type) || glsl_type_contains_image(this->type)))
1751*61046927SAndroid Build Coastguard Worker return true;
1752*61046927SAndroid Build Coastguard Worker
1753*61046927SAndroid Build Coastguard Worker /* From section 4.1.7 of the GLSL 4.40 spec:
1754*61046927SAndroid Build Coastguard Worker *
1755*61046927SAndroid Build Coastguard Worker * "Opaque variables cannot be treated as l-values; hence cannot
1756*61046927SAndroid Build Coastguard Worker * be used as out or inout function parameters, nor can they be
1757*61046927SAndroid Build Coastguard Worker * assigned into."
1758*61046927SAndroid Build Coastguard Worker */
1759*61046927SAndroid Build Coastguard Worker if (glsl_contains_opaque(this->type))
1760*61046927SAndroid Build Coastguard Worker return false;
1761*61046927SAndroid Build Coastguard Worker
1762*61046927SAndroid Build Coastguard Worker return true;
1763*61046927SAndroid Build Coastguard Worker }
1764*61046927SAndroid Build Coastguard Worker
1765*61046927SAndroid Build Coastguard Worker
1766*61046927SAndroid Build Coastguard Worker static const char * const tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs", "lod", "tg4", "query_levels", "texture_samples", "samples_identical" };
1767*61046927SAndroid Build Coastguard Worker
opcode_string()1768*61046927SAndroid Build Coastguard Worker const char *ir_texture::opcode_string()
1769*61046927SAndroid Build Coastguard Worker {
1770*61046927SAndroid Build Coastguard Worker assert((unsigned int) op < ARRAY_SIZE(tex_opcode_strs));
1771*61046927SAndroid Build Coastguard Worker return tex_opcode_strs[op];
1772*61046927SAndroid Build Coastguard Worker }
1773*61046927SAndroid Build Coastguard Worker
1774*61046927SAndroid Build Coastguard Worker ir_texture_opcode
get_opcode(const char * str)1775*61046927SAndroid Build Coastguard Worker ir_texture::get_opcode(const char *str)
1776*61046927SAndroid Build Coastguard Worker {
1777*61046927SAndroid Build Coastguard Worker const int count = sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]);
1778*61046927SAndroid Build Coastguard Worker for (int op = 0; op < count; op++) {
1779*61046927SAndroid Build Coastguard Worker if (strcmp(str, tex_opcode_strs[op]) == 0)
1780*61046927SAndroid Build Coastguard Worker return (ir_texture_opcode) op;
1781*61046927SAndroid Build Coastguard Worker }
1782*61046927SAndroid Build Coastguard Worker return (ir_texture_opcode) -1;
1783*61046927SAndroid Build Coastguard Worker }
1784*61046927SAndroid Build Coastguard Worker
1785*61046927SAndroid Build Coastguard Worker
1786*61046927SAndroid Build Coastguard Worker void
set_sampler(ir_dereference * sampler,const glsl_type * type)1787*61046927SAndroid Build Coastguard Worker ir_texture::set_sampler(ir_dereference *sampler, const glsl_type *type)
1788*61046927SAndroid Build Coastguard Worker {
1789*61046927SAndroid Build Coastguard Worker assert(sampler != NULL);
1790*61046927SAndroid Build Coastguard Worker assert(type != NULL);
1791*61046927SAndroid Build Coastguard Worker this->sampler = sampler;
1792*61046927SAndroid Build Coastguard Worker
1793*61046927SAndroid Build Coastguard Worker if (this->is_sparse) {
1794*61046927SAndroid Build Coastguard Worker /* code holds residency info */
1795*61046927SAndroid Build Coastguard Worker glsl_struct_field fields[2] = {
1796*61046927SAndroid Build Coastguard Worker glsl_struct_field(&glsl_type_builtin_int, "code"),
1797*61046927SAndroid Build Coastguard Worker glsl_struct_field(type, "texel"),
1798*61046927SAndroid Build Coastguard Worker };
1799*61046927SAndroid Build Coastguard Worker this->type = glsl_struct_type(fields, 2, "struct", false /* packed */);
1800*61046927SAndroid Build Coastguard Worker } else
1801*61046927SAndroid Build Coastguard Worker this->type = type;
1802*61046927SAndroid Build Coastguard Worker
1803*61046927SAndroid Build Coastguard Worker if (this->op == ir_txs || this->op == ir_query_levels ||
1804*61046927SAndroid Build Coastguard Worker this->op == ir_texture_samples) {
1805*61046927SAndroid Build Coastguard Worker assert(type->base_type == GLSL_TYPE_INT);
1806*61046927SAndroid Build Coastguard Worker } else if (this->op == ir_lod) {
1807*61046927SAndroid Build Coastguard Worker assert(type->vector_elements == 2);
1808*61046927SAndroid Build Coastguard Worker assert(glsl_type_is_float(type));
1809*61046927SAndroid Build Coastguard Worker } else if (this->op == ir_samples_identical) {
1810*61046927SAndroid Build Coastguard Worker assert(type == &glsl_type_builtin_bool);
1811*61046927SAndroid Build Coastguard Worker assert(glsl_type_is_sampler(sampler->type));
1812*61046927SAndroid Build Coastguard Worker assert(sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS);
1813*61046927SAndroid Build Coastguard Worker } else {
1814*61046927SAndroid Build Coastguard Worker assert(sampler->type->sampled_type == (int) type->base_type);
1815*61046927SAndroid Build Coastguard Worker if (sampler->type->sampler_shadow)
1816*61046927SAndroid Build Coastguard Worker assert(type->vector_elements == 4 || type->vector_elements == 1);
1817*61046927SAndroid Build Coastguard Worker else
1818*61046927SAndroid Build Coastguard Worker assert(type->vector_elements == 4);
1819*61046927SAndroid Build Coastguard Worker }
1820*61046927SAndroid Build Coastguard Worker }
1821*61046927SAndroid Build Coastguard Worker
1822*61046927SAndroid Build Coastguard Worker
1823*61046927SAndroid Build Coastguard Worker void
init_mask(const unsigned * comp,unsigned count)1824*61046927SAndroid Build Coastguard Worker ir_swizzle::init_mask(const unsigned *comp, unsigned count)
1825*61046927SAndroid Build Coastguard Worker {
1826*61046927SAndroid Build Coastguard Worker assert((count >= 1) && (count <= 4));
1827*61046927SAndroid Build Coastguard Worker
1828*61046927SAndroid Build Coastguard Worker memset(&this->mask, 0, sizeof(this->mask));
1829*61046927SAndroid Build Coastguard Worker this->mask.num_components = count;
1830*61046927SAndroid Build Coastguard Worker
1831*61046927SAndroid Build Coastguard Worker unsigned dup_mask = 0;
1832*61046927SAndroid Build Coastguard Worker switch (count) {
1833*61046927SAndroid Build Coastguard Worker case 4:
1834*61046927SAndroid Build Coastguard Worker assert(comp[3] <= 3);
1835*61046927SAndroid Build Coastguard Worker dup_mask |= (1U << comp[3])
1836*61046927SAndroid Build Coastguard Worker & ((1U << comp[0]) | (1U << comp[1]) | (1U << comp[2]));
1837*61046927SAndroid Build Coastguard Worker this->mask.w = comp[3];
1838*61046927SAndroid Build Coastguard Worker
1839*61046927SAndroid Build Coastguard Worker case 3:
1840*61046927SAndroid Build Coastguard Worker assert(comp[2] <= 3);
1841*61046927SAndroid Build Coastguard Worker dup_mask |= (1U << comp[2])
1842*61046927SAndroid Build Coastguard Worker & ((1U << comp[0]) | (1U << comp[1]));
1843*61046927SAndroid Build Coastguard Worker this->mask.z = comp[2];
1844*61046927SAndroid Build Coastguard Worker
1845*61046927SAndroid Build Coastguard Worker case 2:
1846*61046927SAndroid Build Coastguard Worker assert(comp[1] <= 3);
1847*61046927SAndroid Build Coastguard Worker dup_mask |= (1U << comp[1])
1848*61046927SAndroid Build Coastguard Worker & ((1U << comp[0]));
1849*61046927SAndroid Build Coastguard Worker this->mask.y = comp[1];
1850*61046927SAndroid Build Coastguard Worker
1851*61046927SAndroid Build Coastguard Worker case 1:
1852*61046927SAndroid Build Coastguard Worker assert(comp[0] <= 3);
1853*61046927SAndroid Build Coastguard Worker this->mask.x = comp[0];
1854*61046927SAndroid Build Coastguard Worker }
1855*61046927SAndroid Build Coastguard Worker
1856*61046927SAndroid Build Coastguard Worker this->mask.has_duplicates = dup_mask != 0;
1857*61046927SAndroid Build Coastguard Worker
1858*61046927SAndroid Build Coastguard Worker /* Based on the number of elements in the swizzle and the base type
1859*61046927SAndroid Build Coastguard Worker * (i.e., float, int, unsigned, or bool) of the vector being swizzled,
1860*61046927SAndroid Build Coastguard Worker * generate the type of the resulting value.
1861*61046927SAndroid Build Coastguard Worker */
1862*61046927SAndroid Build Coastguard Worker type = glsl_simple_type(val->type->base_type, mask.num_components, 1);
1863*61046927SAndroid Build Coastguard Worker }
1864*61046927SAndroid Build Coastguard Worker
ir_swizzle(ir_rvalue * val,unsigned x,unsigned y,unsigned z,unsigned w,unsigned count)1865*61046927SAndroid Build Coastguard Worker ir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z,
1866*61046927SAndroid Build Coastguard Worker unsigned w, unsigned count)
1867*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_swizzle), val(val)
1868*61046927SAndroid Build Coastguard Worker {
1869*61046927SAndroid Build Coastguard Worker const unsigned components[4] = { x, y, z, w };
1870*61046927SAndroid Build Coastguard Worker this->init_mask(components, count);
1871*61046927SAndroid Build Coastguard Worker }
1872*61046927SAndroid Build Coastguard Worker
ir_swizzle(ir_rvalue * val,const unsigned * comp,unsigned count)1873*61046927SAndroid Build Coastguard Worker ir_swizzle::ir_swizzle(ir_rvalue *val, const unsigned *comp,
1874*61046927SAndroid Build Coastguard Worker unsigned count)
1875*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_swizzle), val(val)
1876*61046927SAndroid Build Coastguard Worker {
1877*61046927SAndroid Build Coastguard Worker this->init_mask(comp, count);
1878*61046927SAndroid Build Coastguard Worker }
1879*61046927SAndroid Build Coastguard Worker
ir_swizzle(ir_rvalue * val,ir_swizzle_mask mask)1880*61046927SAndroid Build Coastguard Worker ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask)
1881*61046927SAndroid Build Coastguard Worker : ir_rvalue(ir_type_swizzle), val(val), mask(mask)
1882*61046927SAndroid Build Coastguard Worker {
1883*61046927SAndroid Build Coastguard Worker this->type = glsl_simple_type(val->type->base_type, mask.num_components, 1);
1884*61046927SAndroid Build Coastguard Worker }
1885*61046927SAndroid Build Coastguard Worker
1886*61046927SAndroid Build Coastguard Worker #define X 1
1887*61046927SAndroid Build Coastguard Worker #define R 5
1888*61046927SAndroid Build Coastguard Worker #define S 9
1889*61046927SAndroid Build Coastguard Worker #define I 13
1890*61046927SAndroid Build Coastguard Worker
1891*61046927SAndroid Build Coastguard Worker ir_swizzle *
create(ir_rvalue * val,const char * str,unsigned vector_length)1892*61046927SAndroid Build Coastguard Worker ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length)
1893*61046927SAndroid Build Coastguard Worker {
1894*61046927SAndroid Build Coastguard Worker void *ctx = ralloc_parent(val);
1895*61046927SAndroid Build Coastguard Worker
1896*61046927SAndroid Build Coastguard Worker /* For each possible swizzle character, this table encodes the value in
1897*61046927SAndroid Build Coastguard Worker * \c idx_map that represents the 0th element of the vector. For invalid
1898*61046927SAndroid Build Coastguard Worker * swizzle characters (e.g., 'k'), a special value is used that will allow
1899*61046927SAndroid Build Coastguard Worker * detection of errors.
1900*61046927SAndroid Build Coastguard Worker */
1901*61046927SAndroid Build Coastguard Worker static const unsigned char base_idx[26] = {
1902*61046927SAndroid Build Coastguard Worker /* a b c d e f g h i j k l m */
1903*61046927SAndroid Build Coastguard Worker R, R, I, I, I, I, R, I, I, I, I, I, I,
1904*61046927SAndroid Build Coastguard Worker /* n o p q r s t u v w x y z */
1905*61046927SAndroid Build Coastguard Worker I, I, S, S, R, S, S, I, I, X, X, X, X
1906*61046927SAndroid Build Coastguard Worker };
1907*61046927SAndroid Build Coastguard Worker
1908*61046927SAndroid Build Coastguard Worker /* Each valid swizzle character has an entry in the previous table. This
1909*61046927SAndroid Build Coastguard Worker * table encodes the base index encoded in the previous table plus the actual
1910*61046927SAndroid Build Coastguard Worker * index of the swizzle character. When processing swizzles, the first
1911*61046927SAndroid Build Coastguard Worker * character in the string is indexed in the previous table. Each character
1912*61046927SAndroid Build Coastguard Worker * in the string is indexed in this table, and the value found there has the
1913*61046927SAndroid Build Coastguard Worker * value form the first table subtracted. The result must be on the range
1914*61046927SAndroid Build Coastguard Worker * [0,3].
1915*61046927SAndroid Build Coastguard Worker *
1916*61046927SAndroid Build Coastguard Worker * For example, the string "wzyx" will get X from the first table. Each of
1917*61046927SAndroid Build Coastguard Worker * the charcaters will get X+3, X+2, X+1, and X+0 from this table. After
1918*61046927SAndroid Build Coastguard Worker * subtraction, the swizzle values are { 3, 2, 1, 0 }.
1919*61046927SAndroid Build Coastguard Worker *
1920*61046927SAndroid Build Coastguard Worker * The string "wzrg" will get X from the first table. Each of the characters
1921*61046927SAndroid Build Coastguard Worker * will get X+3, X+2, R+0, and R+1 from this table. After subtraction, the
1922*61046927SAndroid Build Coastguard Worker * swizzle values are { 3, 2, 4, 5 }. Since 4 and 5 are outside the range
1923*61046927SAndroid Build Coastguard Worker * [0,3], the error is detected.
1924*61046927SAndroid Build Coastguard Worker */
1925*61046927SAndroid Build Coastguard Worker static const unsigned char idx_map[26] = {
1926*61046927SAndroid Build Coastguard Worker /* a b c d e f g h i j k l m */
1927*61046927SAndroid Build Coastguard Worker R+3, R+2, 0, 0, 0, 0, R+1, 0, 0, 0, 0, 0, 0,
1928*61046927SAndroid Build Coastguard Worker /* n o p q r s t u v w x y z */
1929*61046927SAndroid Build Coastguard Worker 0, 0, S+2, S+3, R+0, S+0, S+1, 0, 0, X+3, X+0, X+1, X+2
1930*61046927SAndroid Build Coastguard Worker };
1931*61046927SAndroid Build Coastguard Worker
1932*61046927SAndroid Build Coastguard Worker int swiz_idx[4] = { 0, 0, 0, 0 };
1933*61046927SAndroid Build Coastguard Worker unsigned i;
1934*61046927SAndroid Build Coastguard Worker
1935*61046927SAndroid Build Coastguard Worker
1936*61046927SAndroid Build Coastguard Worker /* Validate the first character in the swizzle string and look up the base
1937*61046927SAndroid Build Coastguard Worker * index value as described above.
1938*61046927SAndroid Build Coastguard Worker */
1939*61046927SAndroid Build Coastguard Worker if ((str[0] < 'a') || (str[0] > 'z'))
1940*61046927SAndroid Build Coastguard Worker return NULL;
1941*61046927SAndroid Build Coastguard Worker
1942*61046927SAndroid Build Coastguard Worker const unsigned base = base_idx[str[0] - 'a'];
1943*61046927SAndroid Build Coastguard Worker
1944*61046927SAndroid Build Coastguard Worker
1945*61046927SAndroid Build Coastguard Worker for (i = 0; (i < 4) && (str[i] != '\0'); i++) {
1946*61046927SAndroid Build Coastguard Worker /* Validate the next character, and, as described above, convert it to a
1947*61046927SAndroid Build Coastguard Worker * swizzle index.
1948*61046927SAndroid Build Coastguard Worker */
1949*61046927SAndroid Build Coastguard Worker if ((str[i] < 'a') || (str[i] > 'z'))
1950*61046927SAndroid Build Coastguard Worker return NULL;
1951*61046927SAndroid Build Coastguard Worker
1952*61046927SAndroid Build Coastguard Worker swiz_idx[i] = idx_map[str[i] - 'a'] - base;
1953*61046927SAndroid Build Coastguard Worker if ((swiz_idx[i] < 0) || (swiz_idx[i] >= (int) vector_length))
1954*61046927SAndroid Build Coastguard Worker return NULL;
1955*61046927SAndroid Build Coastguard Worker }
1956*61046927SAndroid Build Coastguard Worker
1957*61046927SAndroid Build Coastguard Worker if (str[i] != '\0')
1958*61046927SAndroid Build Coastguard Worker return NULL;
1959*61046927SAndroid Build Coastguard Worker
1960*61046927SAndroid Build Coastguard Worker return new(ctx) ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2],
1961*61046927SAndroid Build Coastguard Worker swiz_idx[3], i);
1962*61046927SAndroid Build Coastguard Worker }
1963*61046927SAndroid Build Coastguard Worker
1964*61046927SAndroid Build Coastguard Worker #undef X
1965*61046927SAndroid Build Coastguard Worker #undef R
1966*61046927SAndroid Build Coastguard Worker #undef S
1967*61046927SAndroid Build Coastguard Worker #undef I
1968*61046927SAndroid Build Coastguard Worker
1969*61046927SAndroid Build Coastguard Worker ir_variable *
variable_referenced() const1970*61046927SAndroid Build Coastguard Worker ir_swizzle::variable_referenced() const
1971*61046927SAndroid Build Coastguard Worker {
1972*61046927SAndroid Build Coastguard Worker return this->val->variable_referenced();
1973*61046927SAndroid Build Coastguard Worker }
1974*61046927SAndroid Build Coastguard Worker
1975*61046927SAndroid Build Coastguard Worker
1976*61046927SAndroid Build Coastguard Worker bool ir_variable::temporaries_allocate_names = false;
1977*61046927SAndroid Build Coastguard Worker
1978*61046927SAndroid Build Coastguard Worker const char ir_variable::tmp_name[] = "compiler_temp";
1979*61046927SAndroid Build Coastguard Worker
ir_variable(const struct glsl_type * type,const char * name,ir_variable_mode mode)1980*61046927SAndroid Build Coastguard Worker ir_variable::ir_variable(const struct glsl_type *type, const char *name,
1981*61046927SAndroid Build Coastguard Worker ir_variable_mode mode)
1982*61046927SAndroid Build Coastguard Worker : ir_instruction(ir_type_variable)
1983*61046927SAndroid Build Coastguard Worker {
1984*61046927SAndroid Build Coastguard Worker this->type = type;
1985*61046927SAndroid Build Coastguard Worker
1986*61046927SAndroid Build Coastguard Worker if (mode == ir_var_temporary && !ir_variable::temporaries_allocate_names)
1987*61046927SAndroid Build Coastguard Worker name = NULL;
1988*61046927SAndroid Build Coastguard Worker
1989*61046927SAndroid Build Coastguard Worker /* The ir_variable clone method may call this constructor with name set to
1990*61046927SAndroid Build Coastguard Worker * tmp_name.
1991*61046927SAndroid Build Coastguard Worker */
1992*61046927SAndroid Build Coastguard Worker assert(name != NULL
1993*61046927SAndroid Build Coastguard Worker || mode == ir_var_temporary
1994*61046927SAndroid Build Coastguard Worker || mode == ir_var_function_in
1995*61046927SAndroid Build Coastguard Worker || mode == ir_var_function_out
1996*61046927SAndroid Build Coastguard Worker || mode == ir_var_function_inout);
1997*61046927SAndroid Build Coastguard Worker assert(name != ir_variable::tmp_name
1998*61046927SAndroid Build Coastguard Worker || mode == ir_var_temporary);
1999*61046927SAndroid Build Coastguard Worker if (mode == ir_var_temporary
2000*61046927SAndroid Build Coastguard Worker && (name == NULL || name == ir_variable::tmp_name)) {
2001*61046927SAndroid Build Coastguard Worker this->name = ir_variable::tmp_name;
2002*61046927SAndroid Build Coastguard Worker } else if (name == NULL ||
2003*61046927SAndroid Build Coastguard Worker strlen(name) < ARRAY_SIZE(this->name_storage)) {
2004*61046927SAndroid Build Coastguard Worker strcpy(this->name_storage, name ? name : "");
2005*61046927SAndroid Build Coastguard Worker this->name = this->name_storage;
2006*61046927SAndroid Build Coastguard Worker } else {
2007*61046927SAndroid Build Coastguard Worker this->name = ralloc_strdup(this, name);
2008*61046927SAndroid Build Coastguard Worker }
2009*61046927SAndroid Build Coastguard Worker
2010*61046927SAndroid Build Coastguard Worker this->u.max_ifc_array_access = NULL;
2011*61046927SAndroid Build Coastguard Worker
2012*61046927SAndroid Build Coastguard Worker this->data.explicit_location = false;
2013*61046927SAndroid Build Coastguard Worker this->data.explicit_index = false;
2014*61046927SAndroid Build Coastguard Worker this->data.explicit_binding = false;
2015*61046927SAndroid Build Coastguard Worker this->data.explicit_component = false;
2016*61046927SAndroid Build Coastguard Worker this->data.has_initializer = false;
2017*61046927SAndroid Build Coastguard Worker this->data.is_implicit_initializer = false;
2018*61046927SAndroid Build Coastguard Worker this->data.is_xfb = false;
2019*61046927SAndroid Build Coastguard Worker this->data.is_xfb_only = false;
2020*61046927SAndroid Build Coastguard Worker this->data.explicit_xfb_buffer = false;
2021*61046927SAndroid Build Coastguard Worker this->data.explicit_xfb_offset = false;
2022*61046927SAndroid Build Coastguard Worker this->data.explicit_xfb_stride = false;
2023*61046927SAndroid Build Coastguard Worker this->data.location = -1;
2024*61046927SAndroid Build Coastguard Worker this->data.location_frac = 0;
2025*61046927SAndroid Build Coastguard Worker this->data.matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED;
2026*61046927SAndroid Build Coastguard Worker this->data.from_named_ifc_block = false;
2027*61046927SAndroid Build Coastguard Worker this->data.must_be_shader_input = false;
2028*61046927SAndroid Build Coastguard Worker this->data.index = 0;
2029*61046927SAndroid Build Coastguard Worker this->data.binding = 0;
2030*61046927SAndroid Build Coastguard Worker this->data.warn_extension_index = 0;
2031*61046927SAndroid Build Coastguard Worker this->constant_value = NULL;
2032*61046927SAndroid Build Coastguard Worker this->constant_initializer = NULL;
2033*61046927SAndroid Build Coastguard Worker this->data.depth_layout = ir_depth_layout_none;
2034*61046927SAndroid Build Coastguard Worker this->data.used = false;
2035*61046927SAndroid Build Coastguard Worker this->data.assigned = false;
2036*61046927SAndroid Build Coastguard Worker this->data.read_only = false;
2037*61046927SAndroid Build Coastguard Worker this->data.centroid = false;
2038*61046927SAndroid Build Coastguard Worker this->data.sample = false;
2039*61046927SAndroid Build Coastguard Worker this->data.patch = false;
2040*61046927SAndroid Build Coastguard Worker this->data.explicit_invariant = false;
2041*61046927SAndroid Build Coastguard Worker this->data.invariant = false;
2042*61046927SAndroid Build Coastguard Worker this->data.precise = false;
2043*61046927SAndroid Build Coastguard Worker this->data.how_declared =
2044*61046927SAndroid Build Coastguard Worker mode == ir_var_temporary ? ir_var_hidden : ir_var_declared_normally;
2045*61046927SAndroid Build Coastguard Worker this->data.mode = mode;
2046*61046927SAndroid Build Coastguard Worker this->data.interpolation = INTERP_MODE_NONE;
2047*61046927SAndroid Build Coastguard Worker this->data.max_array_access = -1;
2048*61046927SAndroid Build Coastguard Worker this->data.offset = 0;
2049*61046927SAndroid Build Coastguard Worker this->data.precision = GLSL_PRECISION_NONE;
2050*61046927SAndroid Build Coastguard Worker this->data.memory_read_only = false;
2051*61046927SAndroid Build Coastguard Worker this->data.memory_write_only = false;
2052*61046927SAndroid Build Coastguard Worker this->data.memory_coherent = false;
2053*61046927SAndroid Build Coastguard Worker this->data.memory_volatile = false;
2054*61046927SAndroid Build Coastguard Worker this->data.memory_restrict = false;
2055*61046927SAndroid Build Coastguard Worker this->data.from_ssbo_unsized_array = false;
2056*61046927SAndroid Build Coastguard Worker this->data.implicit_sized_array = false;
2057*61046927SAndroid Build Coastguard Worker this->data.fb_fetch_output = false;
2058*61046927SAndroid Build Coastguard Worker this->data.bindless = false;
2059*61046927SAndroid Build Coastguard Worker this->data.bound = false;
2060*61046927SAndroid Build Coastguard Worker this->data.image_format = PIPE_FORMAT_NONE;
2061*61046927SAndroid Build Coastguard Worker this->data._num_state_slots = 0;
2062*61046927SAndroid Build Coastguard Worker this->data.param_index = 0;
2063*61046927SAndroid Build Coastguard Worker this->data.stream = 0;
2064*61046927SAndroid Build Coastguard Worker this->data.xfb_buffer = -1;
2065*61046927SAndroid Build Coastguard Worker this->data.xfb_stride = -1;
2066*61046927SAndroid Build Coastguard Worker this->data.implicit_conversion_prohibited = false;
2067*61046927SAndroid Build Coastguard Worker
2068*61046927SAndroid Build Coastguard Worker this->interface_type = NULL;
2069*61046927SAndroid Build Coastguard Worker
2070*61046927SAndroid Build Coastguard Worker if (type != NULL) {
2071*61046927SAndroid Build Coastguard Worker if (glsl_type_is_interface(type))
2072*61046927SAndroid Build Coastguard Worker this->init_interface_type(type);
2073*61046927SAndroid Build Coastguard Worker else if (glsl_type_is_interface(glsl_without_array(type)))
2074*61046927SAndroid Build Coastguard Worker this->init_interface_type(glsl_without_array(type));
2075*61046927SAndroid Build Coastguard Worker }
2076*61046927SAndroid Build Coastguard Worker }
2077*61046927SAndroid Build Coastguard Worker
2078*61046927SAndroid Build Coastguard Worker const char *const ir_variable::warn_extension_table[] = {
2079*61046927SAndroid Build Coastguard Worker "",
2080*61046927SAndroid Build Coastguard Worker "GL_ARB_shader_stencil_export",
2081*61046927SAndroid Build Coastguard Worker "GL_AMD_shader_stencil_export",
2082*61046927SAndroid Build Coastguard Worker };
2083*61046927SAndroid Build Coastguard Worker
2084*61046927SAndroid Build Coastguard Worker void
enable_extension_warning(const char * extension)2085*61046927SAndroid Build Coastguard Worker ir_variable::enable_extension_warning(const char *extension)
2086*61046927SAndroid Build Coastguard Worker {
2087*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(warn_extension_table); i++) {
2088*61046927SAndroid Build Coastguard Worker if (strcmp(warn_extension_table[i], extension) == 0) {
2089*61046927SAndroid Build Coastguard Worker this->data.warn_extension_index = i;
2090*61046927SAndroid Build Coastguard Worker return;
2091*61046927SAndroid Build Coastguard Worker }
2092*61046927SAndroid Build Coastguard Worker }
2093*61046927SAndroid Build Coastguard Worker
2094*61046927SAndroid Build Coastguard Worker assert(!"Should not get here.");
2095*61046927SAndroid Build Coastguard Worker this->data.warn_extension_index = 0;
2096*61046927SAndroid Build Coastguard Worker }
2097*61046927SAndroid Build Coastguard Worker
2098*61046927SAndroid Build Coastguard Worker const char *
get_extension_warning() const2099*61046927SAndroid Build Coastguard Worker ir_variable::get_extension_warning() const
2100*61046927SAndroid Build Coastguard Worker {
2101*61046927SAndroid Build Coastguard Worker return this->data.warn_extension_index == 0
2102*61046927SAndroid Build Coastguard Worker ? NULL : warn_extension_table[this->data.warn_extension_index];
2103*61046927SAndroid Build Coastguard Worker }
2104*61046927SAndroid Build Coastguard Worker
ir_function_signature(const glsl_type * return_type,builtin_available_predicate b)2105*61046927SAndroid Build Coastguard Worker ir_function_signature::ir_function_signature(const glsl_type *return_type,
2106*61046927SAndroid Build Coastguard Worker builtin_available_predicate b)
2107*61046927SAndroid Build Coastguard Worker : ir_instruction(ir_type_function_signature),
2108*61046927SAndroid Build Coastguard Worker return_type(return_type), is_defined(false),
2109*61046927SAndroid Build Coastguard Worker return_precision(GLSL_PRECISION_NONE),
2110*61046927SAndroid Build Coastguard Worker intrinsic_id(ir_intrinsic_invalid), builtin_avail(b), _function(NULL)
2111*61046927SAndroid Build Coastguard Worker {
2112*61046927SAndroid Build Coastguard Worker this->origin = NULL;
2113*61046927SAndroid Build Coastguard Worker }
2114*61046927SAndroid Build Coastguard Worker
2115*61046927SAndroid Build Coastguard Worker
2116*61046927SAndroid Build Coastguard Worker bool
is_builtin() const2117*61046927SAndroid Build Coastguard Worker ir_function_signature::is_builtin() const
2118*61046927SAndroid Build Coastguard Worker {
2119*61046927SAndroid Build Coastguard Worker return builtin_avail != NULL;
2120*61046927SAndroid Build Coastguard Worker }
2121*61046927SAndroid Build Coastguard Worker
2122*61046927SAndroid Build Coastguard Worker
2123*61046927SAndroid Build Coastguard Worker bool
is_builtin_available(const _mesa_glsl_parse_state * state) const2124*61046927SAndroid Build Coastguard Worker ir_function_signature::is_builtin_available(const _mesa_glsl_parse_state *state) const
2125*61046927SAndroid Build Coastguard Worker {
2126*61046927SAndroid Build Coastguard Worker /* We can't call the predicate without a state pointer, so just say that
2127*61046927SAndroid Build Coastguard Worker * the signature is available. At compile time, we need the filtering,
2128*61046927SAndroid Build Coastguard Worker * but also receive a valid state pointer. At link time, we're resolving
2129*61046927SAndroid Build Coastguard Worker * imported built-in prototypes to their definitions, which will always
2130*61046927SAndroid Build Coastguard Worker * be an exact match. So we can skip the filtering.
2131*61046927SAndroid Build Coastguard Worker */
2132*61046927SAndroid Build Coastguard Worker if (state == NULL)
2133*61046927SAndroid Build Coastguard Worker return true;
2134*61046927SAndroid Build Coastguard Worker
2135*61046927SAndroid Build Coastguard Worker assert(builtin_avail != NULL);
2136*61046927SAndroid Build Coastguard Worker return builtin_avail(state);
2137*61046927SAndroid Build Coastguard Worker }
2138*61046927SAndroid Build Coastguard Worker
2139*61046927SAndroid Build Coastguard Worker
2140*61046927SAndroid Build Coastguard Worker static bool
modes_match(unsigned a,unsigned b)2141*61046927SAndroid Build Coastguard Worker modes_match(unsigned a, unsigned b)
2142*61046927SAndroid Build Coastguard Worker {
2143*61046927SAndroid Build Coastguard Worker if (a == b)
2144*61046927SAndroid Build Coastguard Worker return true;
2145*61046927SAndroid Build Coastguard Worker
2146*61046927SAndroid Build Coastguard Worker /* Accept "in" vs. "const in" */
2147*61046927SAndroid Build Coastguard Worker if ((a == ir_var_const_in && b == ir_var_function_in) ||
2148*61046927SAndroid Build Coastguard Worker (b == ir_var_const_in && a == ir_var_function_in))
2149*61046927SAndroid Build Coastguard Worker return true;
2150*61046927SAndroid Build Coastguard Worker
2151*61046927SAndroid Build Coastguard Worker return false;
2152*61046927SAndroid Build Coastguard Worker }
2153*61046927SAndroid Build Coastguard Worker
2154*61046927SAndroid Build Coastguard Worker
2155*61046927SAndroid Build Coastguard Worker const char *
qualifiers_match(exec_list * params)2156*61046927SAndroid Build Coastguard Worker ir_function_signature::qualifiers_match(exec_list *params)
2157*61046927SAndroid Build Coastguard Worker {
2158*61046927SAndroid Build Coastguard Worker /* check that the qualifiers match. */
2159*61046927SAndroid Build Coastguard Worker foreach_two_lists(a_node, &this->parameters, b_node, params) {
2160*61046927SAndroid Build Coastguard Worker ir_variable *a = (ir_variable *) a_node;
2161*61046927SAndroid Build Coastguard Worker ir_variable *b = (ir_variable *) b_node;
2162*61046927SAndroid Build Coastguard Worker
2163*61046927SAndroid Build Coastguard Worker if (a->data.read_only != b->data.read_only ||
2164*61046927SAndroid Build Coastguard Worker !modes_match(a->data.mode, b->data.mode) ||
2165*61046927SAndroid Build Coastguard Worker a->data.interpolation != b->data.interpolation ||
2166*61046927SAndroid Build Coastguard Worker a->data.centroid != b->data.centroid ||
2167*61046927SAndroid Build Coastguard Worker a->data.sample != b->data.sample ||
2168*61046927SAndroid Build Coastguard Worker a->data.patch != b->data.patch ||
2169*61046927SAndroid Build Coastguard Worker a->data.memory_read_only != b->data.memory_read_only ||
2170*61046927SAndroid Build Coastguard Worker a->data.memory_write_only != b->data.memory_write_only ||
2171*61046927SAndroid Build Coastguard Worker a->data.memory_coherent != b->data.memory_coherent ||
2172*61046927SAndroid Build Coastguard Worker a->data.memory_volatile != b->data.memory_volatile ||
2173*61046927SAndroid Build Coastguard Worker a->data.memory_restrict != b->data.memory_restrict) {
2174*61046927SAndroid Build Coastguard Worker
2175*61046927SAndroid Build Coastguard Worker /* parameter a's qualifiers don't match */
2176*61046927SAndroid Build Coastguard Worker return a->name;
2177*61046927SAndroid Build Coastguard Worker }
2178*61046927SAndroid Build Coastguard Worker }
2179*61046927SAndroid Build Coastguard Worker return NULL;
2180*61046927SAndroid Build Coastguard Worker }
2181*61046927SAndroid Build Coastguard Worker
2182*61046927SAndroid Build Coastguard Worker
2183*61046927SAndroid Build Coastguard Worker void
replace_parameters(exec_list * new_params)2184*61046927SAndroid Build Coastguard Worker ir_function_signature::replace_parameters(exec_list *new_params)
2185*61046927SAndroid Build Coastguard Worker {
2186*61046927SAndroid Build Coastguard Worker /* Destroy all of the previous parameter information. If the previous
2187*61046927SAndroid Build Coastguard Worker * parameter information comes from the function prototype, it may either
2188*61046927SAndroid Build Coastguard Worker * specify incorrect parameter names or not have names at all.
2189*61046927SAndroid Build Coastguard Worker */
2190*61046927SAndroid Build Coastguard Worker new_params->move_nodes_to(¶meters);
2191*61046927SAndroid Build Coastguard Worker }
2192*61046927SAndroid Build Coastguard Worker
2193*61046927SAndroid Build Coastguard Worker
ir_function(const char * name)2194*61046927SAndroid Build Coastguard Worker ir_function::ir_function(const char *name)
2195*61046927SAndroid Build Coastguard Worker : ir_instruction(ir_type_function)
2196*61046927SAndroid Build Coastguard Worker {
2197*61046927SAndroid Build Coastguard Worker this->subroutine_index = -1;
2198*61046927SAndroid Build Coastguard Worker this->name = ralloc_strdup(this, name);
2199*61046927SAndroid Build Coastguard Worker }
2200*61046927SAndroid Build Coastguard Worker
2201*61046927SAndroid Build Coastguard Worker
2202*61046927SAndroid Build Coastguard Worker bool
has_user_signature()2203*61046927SAndroid Build Coastguard Worker ir_function::has_user_signature()
2204*61046927SAndroid Build Coastguard Worker {
2205*61046927SAndroid Build Coastguard Worker foreach_in_list(ir_function_signature, sig, &this->signatures) {
2206*61046927SAndroid Build Coastguard Worker if (!sig->is_builtin())
2207*61046927SAndroid Build Coastguard Worker return true;
2208*61046927SAndroid Build Coastguard Worker }
2209*61046927SAndroid Build Coastguard Worker return false;
2210*61046927SAndroid Build Coastguard Worker }
2211*61046927SAndroid Build Coastguard Worker
2212*61046927SAndroid Build Coastguard Worker
2213*61046927SAndroid Build Coastguard Worker ir_rvalue *
error_value(void * mem_ctx)2214*61046927SAndroid Build Coastguard Worker ir_rvalue::error_value(void *mem_ctx)
2215*61046927SAndroid Build Coastguard Worker {
2216*61046927SAndroid Build Coastguard Worker ir_rvalue *v = new(mem_ctx) ir_rvalue(ir_type_error);
2217*61046927SAndroid Build Coastguard Worker
2218*61046927SAndroid Build Coastguard Worker v->type = &glsl_type_builtin_error;
2219*61046927SAndroid Build Coastguard Worker return v;
2220*61046927SAndroid Build Coastguard Worker }
2221*61046927SAndroid Build Coastguard Worker
2222*61046927SAndroid Build Coastguard Worker
2223*61046927SAndroid Build Coastguard Worker void
visit_exec_list(exec_list * list,ir_visitor * visitor)2224*61046927SAndroid Build Coastguard Worker visit_exec_list(exec_list *list, ir_visitor *visitor)
2225*61046927SAndroid Build Coastguard Worker {
2226*61046927SAndroid Build Coastguard Worker foreach_in_list(ir_instruction, node, list) {
2227*61046927SAndroid Build Coastguard Worker node->accept(visitor);
2228*61046927SAndroid Build Coastguard Worker }
2229*61046927SAndroid Build Coastguard Worker }
2230*61046927SAndroid Build Coastguard Worker
2231*61046927SAndroid Build Coastguard Worker void
visit_exec_list_safe(exec_list * list,ir_visitor * visitor)2232*61046927SAndroid Build Coastguard Worker visit_exec_list_safe(exec_list *list, ir_visitor *visitor)
2233*61046927SAndroid Build Coastguard Worker {
2234*61046927SAndroid Build Coastguard Worker foreach_in_list_safe(ir_instruction, node, list) {
2235*61046927SAndroid Build Coastguard Worker node->accept(visitor);
2236*61046927SAndroid Build Coastguard Worker }
2237*61046927SAndroid Build Coastguard Worker }
2238*61046927SAndroid Build Coastguard Worker
2239*61046927SAndroid Build Coastguard Worker
2240*61046927SAndroid Build Coastguard Worker static void
steal_memory(ir_instruction * ir,void * new_ctx)2241*61046927SAndroid Build Coastguard Worker steal_memory(ir_instruction *ir, void *new_ctx)
2242*61046927SAndroid Build Coastguard Worker {
2243*61046927SAndroid Build Coastguard Worker ir_variable *var = ir->as_variable();
2244*61046927SAndroid Build Coastguard Worker ir_function *fn = ir->as_function();
2245*61046927SAndroid Build Coastguard Worker ir_constant *constant = ir->as_constant();
2246*61046927SAndroid Build Coastguard Worker if (var != NULL && var->constant_value != NULL)
2247*61046927SAndroid Build Coastguard Worker steal_memory(var->constant_value, ir);
2248*61046927SAndroid Build Coastguard Worker
2249*61046927SAndroid Build Coastguard Worker if (var != NULL && var->constant_initializer != NULL)
2250*61046927SAndroid Build Coastguard Worker steal_memory(var->constant_initializer, ir);
2251*61046927SAndroid Build Coastguard Worker
2252*61046927SAndroid Build Coastguard Worker if (fn != NULL && fn->subroutine_types)
2253*61046927SAndroid Build Coastguard Worker ralloc_steal(new_ctx, fn->subroutine_types);
2254*61046927SAndroid Build Coastguard Worker
2255*61046927SAndroid Build Coastguard Worker /* The components of aggregate constants are not visited by the normal
2256*61046927SAndroid Build Coastguard Worker * visitor, so steal their values by hand.
2257*61046927SAndroid Build Coastguard Worker */
2258*61046927SAndroid Build Coastguard Worker if (constant != NULL &&
2259*61046927SAndroid Build Coastguard Worker (glsl_type_is_array(constant->type) || glsl_type_is_struct(constant->type))) {
2260*61046927SAndroid Build Coastguard Worker for (unsigned int i = 0; i < constant->type->length; i++) {
2261*61046927SAndroid Build Coastguard Worker steal_memory(constant->const_elements[i], ir);
2262*61046927SAndroid Build Coastguard Worker }
2263*61046927SAndroid Build Coastguard Worker }
2264*61046927SAndroid Build Coastguard Worker
2265*61046927SAndroid Build Coastguard Worker ralloc_steal(new_ctx, ir);
2266*61046927SAndroid Build Coastguard Worker }
2267*61046927SAndroid Build Coastguard Worker
2268*61046927SAndroid Build Coastguard Worker
2269*61046927SAndroid Build Coastguard Worker void
reparent_ir(exec_list * list,void * mem_ctx)2270*61046927SAndroid Build Coastguard Worker reparent_ir(exec_list *list, void *mem_ctx)
2271*61046927SAndroid Build Coastguard Worker {
2272*61046927SAndroid Build Coastguard Worker foreach_in_list(ir_instruction, node, list) {
2273*61046927SAndroid Build Coastguard Worker visit_tree(node, steal_memory, mem_ctx);
2274*61046927SAndroid Build Coastguard Worker }
2275*61046927SAndroid Build Coastguard Worker }
2276*61046927SAndroid Build Coastguard Worker
2277*61046927SAndroid Build Coastguard Worker enum mesa_prim
gl_to_mesa_prim(GLenum prim)2278*61046927SAndroid Build Coastguard Worker gl_to_mesa_prim(GLenum prim)
2279*61046927SAndroid Build Coastguard Worker {
2280*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(GL_POINTS == MESA_PRIM_POINTS);
2281*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(GL_LINES == MESA_PRIM_LINES);
2282*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(GL_LINES_ADJACENCY == MESA_PRIM_LINES_ADJACENCY);
2283*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(GL_LINE_STRIP == MESA_PRIM_LINE_STRIP);
2284*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(GL_TRIANGLES == MESA_PRIM_TRIANGLES);
2285*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(GL_TRIANGLES_ADJACENCY == MESA_PRIM_TRIANGLES_ADJACENCY);
2286*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(GL_TRIANGLE_STRIP == MESA_PRIM_TRIANGLE_STRIP);
2287*61046927SAndroid Build Coastguard Worker
2288*61046927SAndroid Build Coastguard Worker return (enum mesa_prim)prim;
2289*61046927SAndroid Build Coastguard Worker }
2290*61046927SAndroid Build Coastguard Worker
2291*61046927SAndroid Build Coastguard Worker /**
2292*61046927SAndroid Build Coastguard Worker * Generate a string describing the mode of a variable
2293*61046927SAndroid Build Coastguard Worker */
2294*61046927SAndroid Build Coastguard Worker const char *
mode_string(const ir_variable * var)2295*61046927SAndroid Build Coastguard Worker mode_string(const ir_variable *var)
2296*61046927SAndroid Build Coastguard Worker {
2297*61046927SAndroid Build Coastguard Worker switch (var->data.mode) {
2298*61046927SAndroid Build Coastguard Worker case ir_var_auto:
2299*61046927SAndroid Build Coastguard Worker return (var->data.read_only) ? "global constant" : "global variable";
2300*61046927SAndroid Build Coastguard Worker
2301*61046927SAndroid Build Coastguard Worker case ir_var_uniform:
2302*61046927SAndroid Build Coastguard Worker return "uniform";
2303*61046927SAndroid Build Coastguard Worker
2304*61046927SAndroid Build Coastguard Worker case ir_var_shader_storage:
2305*61046927SAndroid Build Coastguard Worker return "buffer";
2306*61046927SAndroid Build Coastguard Worker
2307*61046927SAndroid Build Coastguard Worker case ir_var_shader_in:
2308*61046927SAndroid Build Coastguard Worker return "shader input";
2309*61046927SAndroid Build Coastguard Worker
2310*61046927SAndroid Build Coastguard Worker case ir_var_shader_out:
2311*61046927SAndroid Build Coastguard Worker return "shader output";
2312*61046927SAndroid Build Coastguard Worker
2313*61046927SAndroid Build Coastguard Worker case ir_var_function_in:
2314*61046927SAndroid Build Coastguard Worker case ir_var_const_in:
2315*61046927SAndroid Build Coastguard Worker return "function input";
2316*61046927SAndroid Build Coastguard Worker
2317*61046927SAndroid Build Coastguard Worker case ir_var_function_out:
2318*61046927SAndroid Build Coastguard Worker return "function output";
2319*61046927SAndroid Build Coastguard Worker
2320*61046927SAndroid Build Coastguard Worker case ir_var_function_inout:
2321*61046927SAndroid Build Coastguard Worker return "function inout";
2322*61046927SAndroid Build Coastguard Worker
2323*61046927SAndroid Build Coastguard Worker case ir_var_system_value:
2324*61046927SAndroid Build Coastguard Worker return "shader input";
2325*61046927SAndroid Build Coastguard Worker
2326*61046927SAndroid Build Coastguard Worker case ir_var_temporary:
2327*61046927SAndroid Build Coastguard Worker return "compiler temporary";
2328*61046927SAndroid Build Coastguard Worker
2329*61046927SAndroid Build Coastguard Worker case ir_var_mode_count:
2330*61046927SAndroid Build Coastguard Worker break;
2331*61046927SAndroid Build Coastguard Worker }
2332*61046927SAndroid Build Coastguard Worker
2333*61046927SAndroid Build Coastguard Worker assert(!"Should not get here.");
2334*61046927SAndroid Build Coastguard Worker return "invalid variable";
2335*61046927SAndroid Build Coastguard Worker }
2336