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