2910b2e162beb1152ad0ddd214c94b437a13be25
[mesa.git] / src / glsl / ir_constant_expression.cpp
1 /*
2 * Copyright © 2010 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 /**
25 * \file ir_constant_expression.cpp
26 * Evaluate and process constant valued expressions
27 *
28 * In GLSL, constant valued expressions are used in several places. These
29 * must be processed and evaluated very early in the compilation process.
30 *
31 * * Sizes of arrays
32 * * Initializers for uniforms
33 * * Initializers for \c const variables
34 */
35
36 #include <math.h>
37 #include "main/core.h" /* for MAX2, MIN2, CLAMP */
38 #include "ir.h"
39 #include "ir_visitor.h"
40 #include "glsl_types.h"
41
42 /* Using C99 rounding functions for roundToEven() implementation is
43 * difficult, because round(), rint, and nearbyint() are affected by
44 * fesetenv(), which the application may have done for its own
45 * purposes. Mesa's IROUND macro is close to what we want, but it
46 * rounds away from 0 on n + 0.5.
47 */
48 static int
49 round_to_even(float val)
50 {
51 int rounded = IROUND(val);
52
53 if (val - floor(val) == 0.5) {
54 if (rounded % 2 != 0)
55 rounded += val > 0 ? -1 : 1;
56 }
57
58 return rounded;
59 }
60
61 static float
62 dot(ir_constant *op0, ir_constant *op1)
63 {
64 assert(op0->type->is_float() && op1->type->is_float());
65
66 float result = 0;
67 for (unsigned c = 0; c < op0->type->components(); c++)
68 result += op0->value.f[c] * op1->value.f[c];
69
70 return result;
71 }
72
73 ir_constant *
74 ir_rvalue::constant_expression_value()
75 {
76 assert(this->type->is_error());
77 return NULL;
78 }
79
80 ir_constant *
81 ir_expression::constant_expression_value()
82 {
83 if (this->type->is_error())
84 return NULL;
85
86 ir_constant *op[Elements(this->operands)] = { NULL, };
87 ir_constant_data data;
88
89 memset(&data, 0, sizeof(data));
90
91 for (unsigned operand = 0; operand < this->get_num_operands(); operand++) {
92 op[operand] = this->operands[operand]->constant_expression_value();
93 if (!op[operand])
94 return NULL;
95 }
96
97 if (op[1] != NULL)
98 assert(op[0]->type->base_type == op[1]->type->base_type ||
99 this->operation == ir_binop_lshift ||
100 this->operation == ir_binop_rshift);
101
102 bool op0_scalar = op[0]->type->is_scalar();
103 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
104
105 /* When iterating over a vector or matrix's components, we want to increase
106 * the loop counter. However, for scalars, we want to stay at 0.
107 */
108 unsigned c0_inc = op0_scalar ? 0 : 1;
109 unsigned c1_inc = op1_scalar ? 0 : 1;
110 unsigned components;
111 if (op1_scalar || !op[1]) {
112 components = op[0]->type->components();
113 } else {
114 components = op[1]->type->components();
115 }
116
117 void *ctx = ralloc_parent(this);
118
119 /* Handle array operations here, rather than below. */
120 if (op[0]->type->is_array()) {
121 assert(op[1] != NULL && op[1]->type->is_array());
122 switch (this->operation) {
123 case ir_binop_all_equal:
124 return new(ctx) ir_constant(op[0]->has_value(op[1]));
125 case ir_binop_any_nequal:
126 return new(ctx) ir_constant(!op[0]->has_value(op[1]));
127 default:
128 break;
129 }
130 return NULL;
131 }
132
133 switch (this->operation) {
134 case ir_unop_bit_not:
135 switch (op[0]->type->base_type) {
136 case GLSL_TYPE_INT:
137 for (unsigned c = 0; c < components; c++)
138 data.i[c] = ~ op[0]->value.i[c];
139 break;
140 case GLSL_TYPE_UINT:
141 for (unsigned c = 0; c < components; c++)
142 data.u[c] = ~ op[0]->value.u[c];
143 break;
144 default:
145 assert(0);
146 }
147 break;
148
149 case ir_unop_logic_not:
150 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
151 for (unsigned c = 0; c < op[0]->type->components(); c++)
152 data.b[c] = !op[0]->value.b[c];
153 break;
154
155 case ir_unop_f2i:
156 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
157 for (unsigned c = 0; c < op[0]->type->components(); c++) {
158 data.i[c] = (int) op[0]->value.f[c];
159 }
160 break;
161 case ir_unop_i2f:
162 assert(op[0]->type->base_type == GLSL_TYPE_INT);
163 for (unsigned c = 0; c < op[0]->type->components(); c++) {
164 data.f[c] = (float) op[0]->value.i[c];
165 }
166 break;
167 case ir_unop_u2f:
168 assert(op[0]->type->base_type == GLSL_TYPE_UINT);
169 for (unsigned c = 0; c < op[0]->type->components(); c++) {
170 data.f[c] = (float) op[0]->value.u[c];
171 }
172 break;
173 case ir_unop_b2f:
174 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
175 for (unsigned c = 0; c < op[0]->type->components(); c++) {
176 data.f[c] = op[0]->value.b[c] ? 1.0F : 0.0F;
177 }
178 break;
179 case ir_unop_f2b:
180 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
181 for (unsigned c = 0; c < op[0]->type->components(); c++) {
182 data.b[c] = op[0]->value.f[c] != 0.0F ? true : false;
183 }
184 break;
185 case ir_unop_b2i:
186 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
187 for (unsigned c = 0; c < op[0]->type->components(); c++) {
188 data.u[c] = op[0]->value.b[c] ? 1 : 0;
189 }
190 break;
191 case ir_unop_i2b:
192 assert(op[0]->type->is_integer());
193 for (unsigned c = 0; c < op[0]->type->components(); c++) {
194 data.b[c] = op[0]->value.u[c] ? true : false;
195 }
196 break;
197 case ir_unop_u2i:
198 assert(op[0]->type->base_type == GLSL_TYPE_UINT);
199 for (unsigned c = 0; c < op[0]->type->components(); c++) {
200 data.i[c] = op[0]->value.u[c];
201 }
202 break;
203 case ir_unop_i2u:
204 assert(op[0]->type->base_type == GLSL_TYPE_INT);
205 for (unsigned c = 0; c < op[0]->type->components(); c++) {
206 data.u[c] = op[0]->value.i[c];
207 }
208 break;
209 case ir_unop_any:
210 assert(op[0]->type->is_boolean());
211 data.b[0] = false;
212 for (unsigned c = 0; c < op[0]->type->components(); c++) {
213 if (op[0]->value.b[c])
214 data.b[0] = true;
215 }
216 break;
217
218 case ir_unop_trunc:
219 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
220 for (unsigned c = 0; c < op[0]->type->components(); c++) {
221 data.f[c] = truncf(op[0]->value.f[c]);
222 }
223 break;
224
225 case ir_unop_round_even:
226 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
227 for (unsigned c = 0; c < op[0]->type->components(); c++) {
228 data.f[c] = round_to_even(op[0]->value.f[c]);
229 }
230 break;
231
232 case ir_unop_ceil:
233 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
234 for (unsigned c = 0; c < op[0]->type->components(); c++) {
235 data.f[c] = ceilf(op[0]->value.f[c]);
236 }
237 break;
238
239 case ir_unop_floor:
240 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
241 for (unsigned c = 0; c < op[0]->type->components(); c++) {
242 data.f[c] = floorf(op[0]->value.f[c]);
243 }
244 break;
245
246 case ir_unop_fract:
247 for (unsigned c = 0; c < op[0]->type->components(); c++) {
248 switch (this->type->base_type) {
249 case GLSL_TYPE_UINT:
250 data.u[c] = 0;
251 break;
252 case GLSL_TYPE_INT:
253 data.i[c] = 0;
254 break;
255 case GLSL_TYPE_FLOAT:
256 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
257 break;
258 default:
259 assert(0);
260 }
261 }
262 break;
263
264 case ir_unop_sin:
265 case ir_unop_sin_reduced:
266 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
267 for (unsigned c = 0; c < op[0]->type->components(); c++) {
268 data.f[c] = sinf(op[0]->value.f[c]);
269 }
270 break;
271
272 case ir_unop_cos:
273 case ir_unop_cos_reduced:
274 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
275 for (unsigned c = 0; c < op[0]->type->components(); c++) {
276 data.f[c] = cosf(op[0]->value.f[c]);
277 }
278 break;
279
280 case ir_unop_neg:
281 for (unsigned c = 0; c < op[0]->type->components(); c++) {
282 switch (this->type->base_type) {
283 case GLSL_TYPE_UINT:
284 data.u[c] = -((int) op[0]->value.u[c]);
285 break;
286 case GLSL_TYPE_INT:
287 data.i[c] = -op[0]->value.i[c];
288 break;
289 case GLSL_TYPE_FLOAT:
290 data.f[c] = -op[0]->value.f[c];
291 break;
292 default:
293 assert(0);
294 }
295 }
296 break;
297
298 case ir_unop_abs:
299 for (unsigned c = 0; c < op[0]->type->components(); c++) {
300 switch (this->type->base_type) {
301 case GLSL_TYPE_UINT:
302 data.u[c] = op[0]->value.u[c];
303 break;
304 case GLSL_TYPE_INT:
305 data.i[c] = op[0]->value.i[c];
306 if (data.i[c] < 0)
307 data.i[c] = -data.i[c];
308 break;
309 case GLSL_TYPE_FLOAT:
310 data.f[c] = fabs(op[0]->value.f[c]);
311 break;
312 default:
313 assert(0);
314 }
315 }
316 break;
317
318 case ir_unop_sign:
319 for (unsigned c = 0; c < op[0]->type->components(); c++) {
320 switch (this->type->base_type) {
321 case GLSL_TYPE_UINT:
322 data.u[c] = op[0]->value.i[c] > 0;
323 break;
324 case GLSL_TYPE_INT:
325 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
326 break;
327 case GLSL_TYPE_FLOAT:
328 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
329 break;
330 default:
331 assert(0);
332 }
333 }
334 break;
335
336 case ir_unop_rcp:
337 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
338 for (unsigned c = 0; c < op[0]->type->components(); c++) {
339 switch (this->type->base_type) {
340 case GLSL_TYPE_UINT:
341 if (op[0]->value.u[c] != 0.0)
342 data.u[c] = 1 / op[0]->value.u[c];
343 break;
344 case GLSL_TYPE_INT:
345 if (op[0]->value.i[c] != 0.0)
346 data.i[c] = 1 / op[0]->value.i[c];
347 break;
348 case GLSL_TYPE_FLOAT:
349 if (op[0]->value.f[c] != 0.0)
350 data.f[c] = 1.0F / op[0]->value.f[c];
351 break;
352 default:
353 assert(0);
354 }
355 }
356 break;
357
358 case ir_unop_rsq:
359 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
360 for (unsigned c = 0; c < op[0]->type->components(); c++) {
361 data.f[c] = 1.0F / sqrtf(op[0]->value.f[c]);
362 }
363 break;
364
365 case ir_unop_sqrt:
366 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
367 for (unsigned c = 0; c < op[0]->type->components(); c++) {
368 data.f[c] = sqrtf(op[0]->value.f[c]);
369 }
370 break;
371
372 case ir_unop_exp:
373 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
374 for (unsigned c = 0; c < op[0]->type->components(); c++) {
375 data.f[c] = expf(op[0]->value.f[c]);
376 }
377 break;
378
379 case ir_unop_exp2:
380 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
381 for (unsigned c = 0; c < op[0]->type->components(); c++) {
382 data.f[c] = exp2f(op[0]->value.f[c]);
383 }
384 break;
385
386 case ir_unop_log:
387 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
388 for (unsigned c = 0; c < op[0]->type->components(); c++) {
389 data.f[c] = logf(op[0]->value.f[c]);
390 }
391 break;
392
393 case ir_unop_log2:
394 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
395 for (unsigned c = 0; c < op[0]->type->components(); c++) {
396 data.f[c] = log2f(op[0]->value.f[c]);
397 }
398 break;
399
400 case ir_unop_dFdx:
401 case ir_unop_dFdy:
402 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
403 for (unsigned c = 0; c < op[0]->type->components(); c++) {
404 data.f[c] = 0.0;
405 }
406 break;
407
408 case ir_binop_pow:
409 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
410 for (unsigned c = 0; c < op[0]->type->components(); c++) {
411 data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]);
412 }
413 break;
414
415 case ir_binop_dot:
416 data.f[0] = dot(op[0], op[1]);
417 break;
418
419 case ir_binop_min:
420 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
421 for (unsigned c = 0, c0 = 0, c1 = 0;
422 c < components;
423 c0 += c0_inc, c1 += c1_inc, c++) {
424
425 switch (op[0]->type->base_type) {
426 case GLSL_TYPE_UINT:
427 data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]);
428 break;
429 case GLSL_TYPE_INT:
430 data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]);
431 break;
432 case GLSL_TYPE_FLOAT:
433 data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]);
434 break;
435 default:
436 assert(0);
437 }
438 }
439
440 break;
441 case ir_binop_max:
442 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
443 for (unsigned c = 0, c0 = 0, c1 = 0;
444 c < components;
445 c0 += c0_inc, c1 += c1_inc, c++) {
446
447 switch (op[0]->type->base_type) {
448 case GLSL_TYPE_UINT:
449 data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]);
450 break;
451 case GLSL_TYPE_INT:
452 data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]);
453 break;
454 case GLSL_TYPE_FLOAT:
455 data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]);
456 break;
457 default:
458 assert(0);
459 }
460 }
461 break;
462
463 case ir_binop_add:
464 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
465 for (unsigned c = 0, c0 = 0, c1 = 0;
466 c < components;
467 c0 += c0_inc, c1 += c1_inc, c++) {
468
469 switch (op[0]->type->base_type) {
470 case GLSL_TYPE_UINT:
471 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
472 break;
473 case GLSL_TYPE_INT:
474 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
475 break;
476 case GLSL_TYPE_FLOAT:
477 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
478 break;
479 default:
480 assert(0);
481 }
482 }
483
484 break;
485 case ir_binop_sub:
486 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
487 for (unsigned c = 0, c0 = 0, c1 = 0;
488 c < components;
489 c0 += c0_inc, c1 += c1_inc, c++) {
490
491 switch (op[0]->type->base_type) {
492 case GLSL_TYPE_UINT:
493 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
494 break;
495 case GLSL_TYPE_INT:
496 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
497 break;
498 case GLSL_TYPE_FLOAT:
499 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
500 break;
501 default:
502 assert(0);
503 }
504 }
505
506 break;
507 case ir_binop_mul:
508 /* Check for equal types, or unequal types involving scalars */
509 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
510 || op0_scalar || op1_scalar) {
511 for (unsigned c = 0, c0 = 0, c1 = 0;
512 c < components;
513 c0 += c0_inc, c1 += c1_inc, c++) {
514
515 switch (op[0]->type->base_type) {
516 case GLSL_TYPE_UINT:
517 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
518 break;
519 case GLSL_TYPE_INT:
520 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
521 break;
522 case GLSL_TYPE_FLOAT:
523 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
524 break;
525 default:
526 assert(0);
527 }
528 }
529 } else {
530 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
531
532 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
533 * matrix can be a GLSL vector, either N or P can be 1.
534 *
535 * For vec*mat, the vector is treated as a row vector. This
536 * means the vector is a 1-row x M-column matrix.
537 *
538 * For mat*vec, the vector is treated as a column vector. Since
539 * matrix_columns is 1 for vectors, this just works.
540 */
541 const unsigned n = op[0]->type->is_vector()
542 ? 1 : op[0]->type->vector_elements;
543 const unsigned m = op[1]->type->vector_elements;
544 const unsigned p = op[1]->type->matrix_columns;
545 for (unsigned j = 0; j < p; j++) {
546 for (unsigned i = 0; i < n; i++) {
547 for (unsigned k = 0; k < m; k++) {
548 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
549 }
550 }
551 }
552 }
553
554 break;
555 case ir_binop_div:
556 /* FINISHME: Emit warning when division-by-zero is detected. */
557 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
558 for (unsigned c = 0, c0 = 0, c1 = 0;
559 c < components;
560 c0 += c0_inc, c1 += c1_inc, c++) {
561
562 switch (op[0]->type->base_type) {
563 case GLSL_TYPE_UINT:
564 if (op[1]->value.u[c1] == 0) {
565 data.u[c] = 0;
566 } else {
567 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
568 }
569 break;
570 case GLSL_TYPE_INT:
571 if (op[1]->value.i[c1] == 0) {
572 data.i[c] = 0;
573 } else {
574 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
575 }
576 break;
577 case GLSL_TYPE_FLOAT:
578 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
579 break;
580 default:
581 assert(0);
582 }
583 }
584
585 break;
586 case ir_binop_mod:
587 /* FINISHME: Emit warning when division-by-zero is detected. */
588 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
589 for (unsigned c = 0, c0 = 0, c1 = 0;
590 c < components;
591 c0 += c0_inc, c1 += c1_inc, c++) {
592
593 switch (op[0]->type->base_type) {
594 case GLSL_TYPE_UINT:
595 if (op[1]->value.u[c1] == 0) {
596 data.u[c] = 0;
597 } else {
598 data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
599 }
600 break;
601 case GLSL_TYPE_INT:
602 if (op[1]->value.i[c1] == 0) {
603 data.i[c] = 0;
604 } else {
605 data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
606 }
607 break;
608 case GLSL_TYPE_FLOAT:
609 /* We don't use fmod because it rounds toward zero; GLSL specifies
610 * the use of floor.
611 */
612 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]
613 * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
614 break;
615 default:
616 assert(0);
617 }
618 }
619
620 break;
621
622 case ir_binop_logic_and:
623 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
624 for (unsigned c = 0; c < op[0]->type->components(); c++)
625 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
626 break;
627 case ir_binop_logic_xor:
628 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
629 for (unsigned c = 0; c < op[0]->type->components(); c++)
630 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
631 break;
632 case ir_binop_logic_or:
633 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
634 for (unsigned c = 0; c < op[0]->type->components(); c++)
635 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
636 break;
637
638 case ir_binop_less:
639 assert(op[0]->type == op[1]->type);
640 for (unsigned c = 0; c < op[0]->type->components(); c++) {
641 switch (op[0]->type->base_type) {
642 case GLSL_TYPE_UINT:
643 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
644 break;
645 case GLSL_TYPE_INT:
646 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
647 break;
648 case GLSL_TYPE_FLOAT:
649 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
650 break;
651 default:
652 assert(0);
653 }
654 }
655 break;
656 case ir_binop_greater:
657 assert(op[0]->type == op[1]->type);
658 for (unsigned c = 0; c < op[0]->type->components(); c++) {
659 switch (op[0]->type->base_type) {
660 case GLSL_TYPE_UINT:
661 data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
662 break;
663 case GLSL_TYPE_INT:
664 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
665 break;
666 case GLSL_TYPE_FLOAT:
667 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
668 break;
669 default:
670 assert(0);
671 }
672 }
673 break;
674 case ir_binop_lequal:
675 assert(op[0]->type == op[1]->type);
676 for (unsigned c = 0; c < op[0]->type->components(); c++) {
677 switch (op[0]->type->base_type) {
678 case GLSL_TYPE_UINT:
679 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
680 break;
681 case GLSL_TYPE_INT:
682 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
683 break;
684 case GLSL_TYPE_FLOAT:
685 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
686 break;
687 default:
688 assert(0);
689 }
690 }
691 break;
692 case ir_binop_gequal:
693 assert(op[0]->type == op[1]->type);
694 for (unsigned c = 0; c < op[0]->type->components(); c++) {
695 switch (op[0]->type->base_type) {
696 case GLSL_TYPE_UINT:
697 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
698 break;
699 case GLSL_TYPE_INT:
700 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
701 break;
702 case GLSL_TYPE_FLOAT:
703 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
704 break;
705 default:
706 assert(0);
707 }
708 }
709 break;
710 case ir_binop_equal:
711 assert(op[0]->type == op[1]->type);
712 for (unsigned c = 0; c < components; c++) {
713 switch (op[0]->type->base_type) {
714 case GLSL_TYPE_UINT:
715 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
716 break;
717 case GLSL_TYPE_INT:
718 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
719 break;
720 case GLSL_TYPE_FLOAT:
721 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
722 break;
723 case GLSL_TYPE_BOOL:
724 data.b[c] = op[0]->value.b[c] == op[1]->value.b[c];
725 break;
726 default:
727 assert(0);
728 }
729 }
730 break;
731 case ir_binop_nequal:
732 assert(op[0]->type == op[1]->type);
733 for (unsigned c = 0; c < components; c++) {
734 switch (op[0]->type->base_type) {
735 case GLSL_TYPE_UINT:
736 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
737 break;
738 case GLSL_TYPE_INT:
739 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
740 break;
741 case GLSL_TYPE_FLOAT:
742 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
743 break;
744 case GLSL_TYPE_BOOL:
745 data.b[c] = op[0]->value.b[c] != op[1]->value.b[c];
746 break;
747 default:
748 assert(0);
749 }
750 }
751 break;
752 case ir_binop_all_equal:
753 data.b[0] = op[0]->has_value(op[1]);
754 break;
755 case ir_binop_any_nequal:
756 data.b[0] = !op[0]->has_value(op[1]);
757 break;
758
759 case ir_binop_lshift:
760 for (unsigned c = 0, c0 = 0, c1 = 0;
761 c < components;
762 c0 += c0_inc, c1 += c1_inc, c++) {
763
764 if (op[0]->type->base_type == GLSL_TYPE_INT &&
765 op[1]->type->base_type == GLSL_TYPE_INT) {
766 data.i[c] = op[0]->value.i[c0] << op[1]->value.i[c1];
767
768 } else if (op[0]->type->base_type == GLSL_TYPE_INT &&
769 op[1]->type->base_type == GLSL_TYPE_UINT) {
770 data.i[c] = op[0]->value.i[c0] << op[1]->value.u[c1];
771
772 } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
773 op[1]->type->base_type == GLSL_TYPE_INT) {
774 data.u[c] = op[0]->value.u[c0] << op[1]->value.i[c1];
775
776 } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
777 op[1]->type->base_type == GLSL_TYPE_UINT) {
778 data.u[c] = op[0]->value.u[c0] << op[1]->value.u[c1];
779 }
780 }
781 break;
782
783 case ir_binop_rshift:
784 for (unsigned c = 0, c0 = 0, c1 = 0;
785 c < components;
786 c0 += c0_inc, c1 += c1_inc, c++) {
787
788 if (op[0]->type->base_type == GLSL_TYPE_INT &&
789 op[1]->type->base_type == GLSL_TYPE_INT) {
790 data.i[c] = op[0]->value.i[c0] >> op[1]->value.i[c1];
791
792 } else if (op[0]->type->base_type == GLSL_TYPE_INT &&
793 op[1]->type->base_type == GLSL_TYPE_UINT) {
794 data.i[c] = op[0]->value.i[c0] >> op[1]->value.u[c1];
795
796 } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
797 op[1]->type->base_type == GLSL_TYPE_INT) {
798 data.u[c] = op[0]->value.u[c0] >> op[1]->value.i[c1];
799
800 } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
801 op[1]->type->base_type == GLSL_TYPE_UINT) {
802 data.u[c] = op[0]->value.u[c0] >> op[1]->value.u[c1];
803 }
804 }
805 break;
806
807 case ir_binop_bit_and:
808 for (unsigned c = 0, c0 = 0, c1 = 0;
809 c < components;
810 c0 += c0_inc, c1 += c1_inc, c++) {
811
812 switch (op[0]->type->base_type) {
813 case GLSL_TYPE_INT:
814 data.i[c] = op[0]->value.i[c0] & op[1]->value.i[c1];
815 break;
816 case GLSL_TYPE_UINT:
817 data.u[c] = op[0]->value.u[c0] & op[1]->value.u[c1];
818 break;
819 default:
820 assert(0);
821 }
822 }
823 break;
824
825 case ir_binop_bit_or:
826 for (unsigned c = 0, c0 = 0, c1 = 0;
827 c < components;
828 c0 += c0_inc, c1 += c1_inc, c++) {
829
830 switch (op[0]->type->base_type) {
831 case GLSL_TYPE_INT:
832 data.i[c] = op[0]->value.i[c0] | op[1]->value.i[c1];
833 break;
834 case GLSL_TYPE_UINT:
835 data.u[c] = op[0]->value.u[c0] | op[1]->value.u[c1];
836 break;
837 default:
838 assert(0);
839 }
840 }
841 break;
842
843 case ir_binop_bit_xor:
844 for (unsigned c = 0, c0 = 0, c1 = 0;
845 c < components;
846 c0 += c0_inc, c1 += c1_inc, c++) {
847
848 switch (op[0]->type->base_type) {
849 case GLSL_TYPE_INT:
850 data.i[c] = op[0]->value.i[c0] ^ op[1]->value.i[c1];
851 break;
852 case GLSL_TYPE_UINT:
853 data.u[c] = op[0]->value.u[c0] ^ op[1]->value.u[c1];
854 break;
855 default:
856 assert(0);
857 }
858 }
859 break;
860
861 case ir_quadop_vector:
862 for (unsigned c = 0; c < this->type->vector_elements; c++) {
863 switch (this->type->base_type) {
864 case GLSL_TYPE_INT:
865 data.i[c] = op[c]->value.i[0];
866 break;
867 case GLSL_TYPE_UINT:
868 data.u[c] = op[c]->value.u[0];
869 break;
870 case GLSL_TYPE_FLOAT:
871 data.f[c] = op[c]->value.f[0];
872 break;
873 default:
874 assert(0);
875 }
876 }
877 break;
878
879 default:
880 /* FINISHME: Should handle all expression types. */
881 return NULL;
882 }
883
884 return new(ctx) ir_constant(this->type, &data);
885 }
886
887
888 ir_constant *
889 ir_texture::constant_expression_value()
890 {
891 /* texture lookups aren't constant expressions */
892 return NULL;
893 }
894
895
896 ir_constant *
897 ir_swizzle::constant_expression_value()
898 {
899 ir_constant *v = this->val->constant_expression_value();
900
901 if (v != NULL) {
902 ir_constant_data data = { { 0 } };
903
904 const unsigned swiz_idx[4] = {
905 this->mask.x, this->mask.y, this->mask.z, this->mask.w
906 };
907
908 for (unsigned i = 0; i < this->mask.num_components; i++) {
909 switch (v->type->base_type) {
910 case GLSL_TYPE_UINT:
911 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
912 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
913 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
914 default: assert(!"Should not get here."); break;
915 }
916 }
917
918 void *ctx = ralloc_parent(this);
919 return new(ctx) ir_constant(this->type, &data);
920 }
921 return NULL;
922 }
923
924
925 ir_constant *
926 ir_dereference_variable::constant_expression_value()
927 {
928 /* This may occur during compile and var->type is glsl_type::error_type */
929 if (!var)
930 return NULL;
931
932 /* The constant_value of a uniform variable is its initializer,
933 * not the lifetime constant value of the uniform.
934 */
935 if (var->mode == ir_var_uniform)
936 return NULL;
937
938 if (!var->constant_value)
939 return NULL;
940
941 return var->constant_value->clone(ralloc_parent(var), NULL);
942 }
943
944
945 ir_constant *
946 ir_dereference_array::constant_expression_value()
947 {
948 ir_constant *array = this->array->constant_expression_value();
949 ir_constant *idx = this->array_index->constant_expression_value();
950
951 if ((array != NULL) && (idx != NULL)) {
952 void *ctx = ralloc_parent(this);
953 if (array->type->is_matrix()) {
954 /* Array access of a matrix results in a vector.
955 */
956 const unsigned column = idx->value.u[0];
957
958 const glsl_type *const column_type = array->type->column_type();
959
960 /* Offset in the constant matrix to the first element of the column
961 * to be extracted.
962 */
963 const unsigned mat_idx = column * column_type->vector_elements;
964
965 ir_constant_data data = { { 0 } };
966
967 switch (column_type->base_type) {
968 case GLSL_TYPE_UINT:
969 case GLSL_TYPE_INT:
970 for (unsigned i = 0; i < column_type->vector_elements; i++)
971 data.u[i] = array->value.u[mat_idx + i];
972
973 break;
974
975 case GLSL_TYPE_FLOAT:
976 for (unsigned i = 0; i < column_type->vector_elements; i++)
977 data.f[i] = array->value.f[mat_idx + i];
978
979 break;
980
981 default:
982 assert(!"Should not get here.");
983 break;
984 }
985
986 return new(ctx) ir_constant(column_type, &data);
987 } else if (array->type->is_vector()) {
988 const unsigned component = idx->value.u[0];
989
990 return new(ctx) ir_constant(array, component);
991 } else {
992 const unsigned index = idx->value.u[0];
993 return array->get_array_element(index)->clone(ctx, NULL);
994 }
995 }
996 return NULL;
997 }
998
999
1000 ir_constant *
1001 ir_dereference_record::constant_expression_value()
1002 {
1003 ir_constant *v = this->record->constant_expression_value();
1004
1005 return (v != NULL) ? v->get_record_field(this->field) : NULL;
1006 }
1007
1008
1009 ir_constant *
1010 ir_assignment::constant_expression_value()
1011 {
1012 /* FINISHME: Handle CEs involving assignment (return RHS) */
1013 return NULL;
1014 }
1015
1016
1017 ir_constant *
1018 ir_constant::constant_expression_value()
1019 {
1020 return this;
1021 }
1022
1023
1024 ir_constant *
1025 ir_call::constant_expression_value()
1026 {
1027 if (this->type == glsl_type::error_type)
1028 return NULL;
1029
1030 /* From the GLSL 1.20 spec, page 23:
1031 * "Function calls to user-defined functions (non-built-in functions)
1032 * cannot be used to form constant expressions."
1033 */
1034 if (!this->callee->is_builtin)
1035 return NULL;
1036
1037 unsigned num_parameters = 0;
1038
1039 /* Check if all parameters are constant */
1040 ir_constant *op[3];
1041 foreach_list(n, &this->actual_parameters) {
1042 ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value();
1043 if (constant == NULL)
1044 return NULL;
1045
1046 op[num_parameters] = constant;
1047
1048 assert(num_parameters < 3);
1049 num_parameters++;
1050 }
1051
1052 /* Individual cases below can either:
1053 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
1054 * - Fill "data" with appopriate constant data
1055 * - Return an ir_constant directly.
1056 */
1057 void *mem_ctx = ralloc_parent(this);
1058 ir_expression *expr = NULL;
1059
1060 ir_constant_data data;
1061 memset(&data, 0, sizeof(data));
1062
1063 const char *callee = this->callee_name();
1064 if (strcmp(callee, "abs") == 0) {
1065 expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL);
1066 } else if (strcmp(callee, "all") == 0) {
1067 assert(op[0]->type->is_boolean());
1068 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1069 if (!op[0]->value.b[c])
1070 return new(mem_ctx) ir_constant(false);
1071 }
1072 return new(mem_ctx) ir_constant(true);
1073 } else if (strcmp(callee, "any") == 0) {
1074 assert(op[0]->type->is_boolean());
1075 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1076 if (op[0]->value.b[c])
1077 return new(mem_ctx) ir_constant(true);
1078 }
1079 return new(mem_ctx) ir_constant(false);
1080 } else if (strcmp(callee, "acos") == 0) {
1081 assert(op[0]->type->is_float());
1082 for (unsigned c = 0; c < op[0]->type->components(); c++)
1083 data.f[c] = acosf(op[0]->value.f[c]);
1084 } else if (strcmp(callee, "acosh") == 0) {
1085 assert(op[0]->type->is_float());
1086 for (unsigned c = 0; c < op[0]->type->components(); c++)
1087 data.f[c] = acoshf(op[0]->value.f[c]);
1088 } else if (strcmp(callee, "asin") == 0) {
1089 assert(op[0]->type->is_float());
1090 for (unsigned c = 0; c < op[0]->type->components(); c++)
1091 data.f[c] = asinf(op[0]->value.f[c]);
1092 } else if (strcmp(callee, "asinh") == 0) {
1093 assert(op[0]->type->is_float());
1094 for (unsigned c = 0; c < op[0]->type->components(); c++)
1095 data.f[c] = asinhf(op[0]->value.f[c]);
1096 } else if (strcmp(callee, "atan") == 0) {
1097 assert(op[0]->type->is_float());
1098 if (num_parameters == 2) {
1099 assert(op[1]->type->is_float());
1100 for (unsigned c = 0; c < op[0]->type->components(); c++)
1101 data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]);
1102 } else {
1103 for (unsigned c = 0; c < op[0]->type->components(); c++)
1104 data.f[c] = atanf(op[0]->value.f[c]);
1105 }
1106 } else if (strcmp(callee, "atanh") == 0) {
1107 assert(op[0]->type->is_float());
1108 for (unsigned c = 0; c < op[0]->type->components(); c++)
1109 data.f[c] = atanhf(op[0]->value.f[c]);
1110 } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) {
1111 return ir_constant::zero(mem_ctx, this->type);
1112 } else if (strcmp(callee, "ceil") == 0) {
1113 expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL);
1114 } else if (strcmp(callee, "clamp") == 0) {
1115 assert(num_parameters == 3);
1116 unsigned c1_inc = op[1]->type->is_scalar() ? 0 : 1;
1117 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
1118 for (unsigned c = 0, c1 = 0, c2 = 0;
1119 c < op[0]->type->components();
1120 c1 += c1_inc, c2 += c2_inc, c++) {
1121
1122 switch (op[0]->type->base_type) {
1123 case GLSL_TYPE_UINT:
1124 data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1],
1125 op[2]->value.u[c2]);
1126 break;
1127 case GLSL_TYPE_INT:
1128 data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1],
1129 op[2]->value.i[c2]);
1130 break;
1131 case GLSL_TYPE_FLOAT:
1132 data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1],
1133 op[2]->value.f[c2]);
1134 break;
1135 default:
1136 assert(!"Should not get here.");
1137 }
1138 }
1139 } else if (strcmp(callee, "cos") == 0) {
1140 expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL);
1141 } else if (strcmp(callee, "cosh") == 0) {
1142 assert(op[0]->type->is_float());
1143 for (unsigned c = 0; c < op[0]->type->components(); c++)
1144 data.f[c] = coshf(op[0]->value.f[c]);
1145 } else if (strcmp(callee, "cross") == 0) {
1146 assert(op[0]->type == glsl_type::vec3_type);
1147 assert(op[1]->type == glsl_type::vec3_type);
1148 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
1149 op[1]->value.f[1] * op[0]->value.f[2]);
1150 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
1151 op[1]->value.f[2] * op[0]->value.f[0]);
1152 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
1153 op[1]->value.f[0] * op[0]->value.f[1]);
1154 } else if (strcmp(callee, "degrees") == 0) {
1155 assert(op[0]->type->is_float());
1156 for (unsigned c = 0; c < op[0]->type->components(); c++)
1157 data.f[c] = 180.0F / M_PI * op[0]->value.f[c];
1158 } else if (strcmp(callee, "distance") == 0) {
1159 assert(op[0]->type->is_float() && op[1]->type->is_float());
1160 float length_squared = 0.0;
1161 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1162 float t = op[0]->value.f[c] - op[1]->value.f[c];
1163 length_squared += t * t;
1164 }
1165 return new(mem_ctx) ir_constant(sqrtf(length_squared));
1166 } else if (strcmp(callee, "dot") == 0) {
1167 return new(mem_ctx) ir_constant(dot(op[0], op[1]));
1168 } else if (strcmp(callee, "equal") == 0) {
1169 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1170 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1171 switch (op[0]->type->base_type) {
1172 case GLSL_TYPE_UINT:
1173 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
1174 break;
1175 case GLSL_TYPE_INT:
1176 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
1177 break;
1178 case GLSL_TYPE_FLOAT:
1179 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
1180 break;
1181 case GLSL_TYPE_BOOL:
1182 data.b[c] = op[0]->value.b[c] == op[1]->value.b[c];
1183 break;
1184 default:
1185 assert(!"Should not get here.");
1186 }
1187 }
1188 } else if (strcmp(callee, "exp") == 0) {
1189 expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL);
1190 } else if (strcmp(callee, "exp2") == 0) {
1191 expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL);
1192 } else if (strcmp(callee, "faceforward") == 0) {
1193 if (dot(op[2], op[1]) < 0)
1194 return op[0];
1195 for (unsigned c = 0; c < op[0]->type->components(); c++)
1196 data.f[c] = -op[0]->value.f[c];
1197 } else if (strcmp(callee, "floor") == 0) {
1198 expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL);
1199 } else if (strcmp(callee, "fract") == 0) {
1200 expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL);
1201 } else if (strcmp(callee, "fwidth") == 0) {
1202 return ir_constant::zero(mem_ctx, this->type);
1203 } else if (strcmp(callee, "greaterThan") == 0) {
1204 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1205 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1206 switch (op[0]->type->base_type) {
1207 case GLSL_TYPE_UINT:
1208 data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
1209 break;
1210 case GLSL_TYPE_INT:
1211 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
1212 break;
1213 case GLSL_TYPE_FLOAT:
1214 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
1215 break;
1216 default:
1217 assert(!"Should not get here.");
1218 }
1219 }
1220 } else if (strcmp(callee, "greaterThanEqual") == 0) {
1221 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1222 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1223 switch (op[0]->type->base_type) {
1224 case GLSL_TYPE_UINT:
1225 data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c];
1226 break;
1227 case GLSL_TYPE_INT:
1228 data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c];
1229 break;
1230 case GLSL_TYPE_FLOAT:
1231 data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c];
1232 break;
1233 default:
1234 assert(!"Should not get here.");
1235 }
1236 }
1237 } else if (strcmp(callee, "inversesqrt") == 0) {
1238 expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL);
1239 } else if (strcmp(callee, "length") == 0) {
1240 return new(mem_ctx) ir_constant(sqrtf(dot(op[0], op[0])));
1241 } else if (strcmp(callee, "lessThan") == 0) {
1242 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1243 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1244 switch (op[0]->type->base_type) {
1245 case GLSL_TYPE_UINT:
1246 data.b[c] = op[0]->value.u[c] < op[1]->value.u[c];
1247 break;
1248 case GLSL_TYPE_INT:
1249 data.b[c] = op[0]->value.i[c] < op[1]->value.i[c];
1250 break;
1251 case GLSL_TYPE_FLOAT:
1252 data.b[c] = op[0]->value.f[c] < op[1]->value.f[c];
1253 break;
1254 default:
1255 assert(!"Should not get here.");
1256 }
1257 }
1258 } else if (strcmp(callee, "lessThanEqual") == 0) {
1259 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1260 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1261 switch (op[0]->type->base_type) {
1262 case GLSL_TYPE_UINT:
1263 data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c];
1264 break;
1265 case GLSL_TYPE_INT:
1266 data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c];
1267 break;
1268 case GLSL_TYPE_FLOAT:
1269 data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c];
1270 break;
1271 default:
1272 assert(!"Should not get here.");
1273 }
1274 }
1275 } else if (strcmp(callee, "log") == 0) {
1276 expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL);
1277 } else if (strcmp(callee, "log2") == 0) {
1278 expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL);
1279 } else if (strcmp(callee, "matrixCompMult") == 0) {
1280 assert(op[0]->type->is_float() && op[1]->type->is_float());
1281 for (unsigned c = 0; c < op[0]->type->components(); c++)
1282 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
1283 } else if (strcmp(callee, "max") == 0) {
1284 expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]);
1285 } else if (strcmp(callee, "min") == 0) {
1286 expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]);
1287 } else if (strcmp(callee, "mix") == 0) {
1288 assert(op[0]->type->is_float() && op[1]->type->is_float());
1289 if (op[2]->type->is_float()) {
1290 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
1291 unsigned components = op[0]->type->components();
1292 for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) {
1293 data.f[c] = op[0]->value.f[c] * (1 - op[2]->value.f[c2]) +
1294 op[1]->value.f[c] * op[2]->value.f[c2];
1295 }
1296 } else {
1297 assert(op[2]->type->is_boolean());
1298 for (unsigned c = 0; c < op[0]->type->components(); c++)
1299 data.f[c] = op[op[2]->value.b[c] ? 1 : 0]->value.f[c];
1300 }
1301 } else if (strcmp(callee, "mod") == 0) {
1302 expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]);
1303 } else if (strcmp(callee, "normalize") == 0) {
1304 assert(op[0]->type->is_float());
1305 float length = sqrtf(dot(op[0], op[0]));
1306
1307 if (length == 0)
1308 return ir_constant::zero(mem_ctx, this->type);
1309
1310 for (unsigned c = 0; c < op[0]->type->components(); c++)
1311 data.f[c] = op[0]->value.f[c] / length;
1312 } else if (strcmp(callee, "not") == 0) {
1313 expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL);
1314 } else if (strcmp(callee, "notEqual") == 0) {
1315 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1316 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1317 switch (op[0]->type->base_type) {
1318 case GLSL_TYPE_UINT:
1319 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
1320 break;
1321 case GLSL_TYPE_INT:
1322 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
1323 break;
1324 case GLSL_TYPE_FLOAT:
1325 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
1326 break;
1327 case GLSL_TYPE_BOOL:
1328 data.b[c] = op[0]->value.b[c] != op[1]->value.b[c];
1329 break;
1330 default:
1331 assert(!"Should not get here.");
1332 }
1333 }
1334 } else if (strcmp(callee, "outerProduct") == 0) {
1335 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
1336 const unsigned m = op[0]->type->vector_elements;
1337 const unsigned n = op[1]->type->vector_elements;
1338 for (unsigned j = 0; j < n; j++) {
1339 for (unsigned i = 0; i < m; i++) {
1340 data.f[i+m*j] = op[0]->value.f[i] * op[1]->value.f[j];
1341 }
1342 }
1343 } else if (strcmp(callee, "pow") == 0) {
1344 expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]);
1345 } else if (strcmp(callee, "radians") == 0) {
1346 assert(op[0]->type->is_float());
1347 for (unsigned c = 0; c < op[0]->type->components(); c++)
1348 data.f[c] = M_PI / 180.0F * op[0]->value.f[c];
1349 } else if (strcmp(callee, "reflect") == 0) {
1350 assert(op[0]->type->is_float());
1351 float dot_NI = dot(op[1], op[0]);
1352 for (unsigned c = 0; c < op[0]->type->components(); c++)
1353 data.f[c] = op[0]->value.f[c] - 2 * dot_NI * op[1]->value.f[c];
1354 } else if (strcmp(callee, "refract") == 0) {
1355 const float eta = op[2]->value.f[0];
1356 const float dot_NI = dot(op[1], op[0]);
1357 const float k = 1.0F - eta * eta * (1.0F - dot_NI * dot_NI);
1358 if (k < 0.0) {
1359 return ir_constant::zero(mem_ctx, this->type);
1360 } else {
1361 for (unsigned c = 0; c < type->components(); c++) {
1362 data.f[c] = eta * op[0]->value.f[c] - (eta * dot_NI + sqrtf(k))
1363 * op[1]->value.f[c];
1364 }
1365 }
1366 } else if (strcmp(callee, "round") == 0 ||
1367 strcmp(callee, "roundEven") == 0) {
1368 expr = new(mem_ctx) ir_expression(ir_unop_round_even, op[0]);
1369 } else if (strcmp(callee, "sign") == 0) {
1370 expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
1371 } else if (strcmp(callee, "sin") == 0) {
1372 expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL);
1373 } else if (strcmp(callee, "sinh") == 0) {
1374 assert(op[0]->type->is_float());
1375 for (unsigned c = 0; c < op[0]->type->components(); c++)
1376 data.f[c] = sinhf(op[0]->value.f[c]);
1377 } else if (strcmp(callee, "smoothstep") == 0) {
1378 assert(num_parameters == 3);
1379 assert(op[1]->type == op[0]->type);
1380 unsigned edge_inc = op[0]->type->is_scalar() ? 0 : 1;
1381 for (unsigned c = 0, e = 0; c < type->components(); e += edge_inc, c++) {
1382 const float edge0 = op[0]->value.f[e];
1383 const float edge1 = op[1]->value.f[e];
1384 if (edge0 == edge1) {
1385 data.f[c] = 0.0; /* Avoid a crash - results are undefined anyway */
1386 } else {
1387 const float numerator = op[2]->value.f[c] - edge0;
1388 const float denominator = edge1 - edge0;
1389 const float t = CLAMP(numerator/denominator, 0, 1);
1390 data.f[c] = t * t * (3 - 2 * t);
1391 }
1392 }
1393 } else if (strcmp(callee, "sqrt") == 0) {
1394 expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL);
1395 } else if (strcmp(callee, "step") == 0) {
1396 assert(op[0]->type->is_float() && op[1]->type->is_float());
1397 /* op[0] (edge) may be either a scalar or a vector */
1398 const unsigned c0_inc = op[0]->type->is_scalar() ? 0 : 1;
1399 for (unsigned c = 0, c0 = 0; c < type->components(); c0 += c0_inc, c++)
1400 data.f[c] = (op[1]->value.f[c] < op[0]->value.f[c0]) ? 0.0F : 1.0F;
1401 } else if (strcmp(callee, "tan") == 0) {
1402 assert(op[0]->type->is_float());
1403 for (unsigned c = 0; c < op[0]->type->components(); c++)
1404 data.f[c] = tanf(op[0]->value.f[c]);
1405 } else if (strcmp(callee, "tanh") == 0) {
1406 assert(op[0]->type->is_float());
1407 for (unsigned c = 0; c < op[0]->type->components(); c++)
1408 data.f[c] = tanhf(op[0]->value.f[c]);
1409 } else if (strcmp(callee, "transpose") == 0) {
1410 assert(op[0]->type->is_matrix());
1411 const unsigned n = op[0]->type->vector_elements;
1412 const unsigned m = op[0]->type->matrix_columns;
1413 for (unsigned j = 0; j < m; j++) {
1414 for (unsigned i = 0; i < n; i++) {
1415 data.f[m*i+j] += op[0]->value.f[i+n*j];
1416 }
1417 }
1418 } else if (strcmp(callee, "trunc") == 0) {
1419 expr = new(mem_ctx) ir_expression(ir_unop_trunc, op[0]);
1420 } else {
1421 /* Unsupported builtin - some are not allowed in constant expressions. */
1422 return NULL;
1423 }
1424
1425 if (expr != NULL)
1426 return expr->constant_expression_value();
1427
1428 return new(mem_ctx) ir_constant(this->type, &data);
1429 }