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