gallivm: fetch immediates to correct type (v2)
[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 case GLSL_TYPE_BOOL:
717 data.b[c] = op[0]->value.b[c] == op[1]->value.b[c];
718 break;
719 default:
720 assert(0);
721 }
722 }
723 break;
724 case ir_binop_nequal:
725 assert(op[0]->type == op[1]->type);
726 for (unsigned c = 0; c < components; c++) {
727 switch (op[0]->type->base_type) {
728 case GLSL_TYPE_UINT:
729 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
730 break;
731 case GLSL_TYPE_INT:
732 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
733 break;
734 case GLSL_TYPE_FLOAT:
735 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
736 break;
737 case GLSL_TYPE_BOOL:
738 data.b[c] = op[0]->value.b[c] != op[1]->value.b[c];
739 break;
740 default:
741 assert(0);
742 }
743 }
744 break;
745 case ir_binop_all_equal:
746 data.b[0] = op[0]->has_value(op[1]);
747 break;
748 case ir_binop_any_nequal:
749 data.b[0] = !op[0]->has_value(op[1]);
750 break;
751
752 case ir_binop_lshift:
753 for (unsigned c = 0, c0 = 0, c1 = 0;
754 c < components;
755 c0 += c0_inc, c1 += c1_inc, c++) {
756
757 if (op[0]->type->base_type == GLSL_TYPE_INT &&
758 op[1]->type->base_type == GLSL_TYPE_INT) {
759 data.i[c] = op[0]->value.i[c0] << op[1]->value.i[c1];
760
761 } else if (op[0]->type->base_type == GLSL_TYPE_INT &&
762 op[1]->type->base_type == GLSL_TYPE_UINT) {
763 data.i[c] = op[0]->value.i[c0] << op[1]->value.u[c1];
764
765 } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
766 op[1]->type->base_type == GLSL_TYPE_INT) {
767 data.u[c] = op[0]->value.u[c0] << op[1]->value.i[c1];
768
769 } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
770 op[1]->type->base_type == GLSL_TYPE_UINT) {
771 data.u[c] = op[0]->value.u[c0] << op[1]->value.u[c1];
772 }
773 }
774 break;
775
776 case ir_binop_rshift:
777 for (unsigned c = 0, c0 = 0, c1 = 0;
778 c < components;
779 c0 += c0_inc, c1 += c1_inc, c++) {
780
781 if (op[0]->type->base_type == GLSL_TYPE_INT &&
782 op[1]->type->base_type == GLSL_TYPE_INT) {
783 data.i[c] = op[0]->value.i[c0] >> op[1]->value.i[c1];
784
785 } else if (op[0]->type->base_type == GLSL_TYPE_INT &&
786 op[1]->type->base_type == GLSL_TYPE_UINT) {
787 data.i[c] = op[0]->value.i[c0] >> op[1]->value.u[c1];
788
789 } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
790 op[1]->type->base_type == GLSL_TYPE_INT) {
791 data.u[c] = op[0]->value.u[c0] >> op[1]->value.i[c1];
792
793 } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
794 op[1]->type->base_type == GLSL_TYPE_UINT) {
795 data.u[c] = op[0]->value.u[c0] >> op[1]->value.u[c1];
796 }
797 }
798 break;
799
800 case ir_binop_bit_and:
801 for (unsigned c = 0, c0 = 0, c1 = 0;
802 c < components;
803 c0 += c0_inc, c1 += c1_inc, c++) {
804
805 switch (op[0]->type->base_type) {
806 case GLSL_TYPE_INT:
807 data.i[c] = op[0]->value.i[c0] & op[1]->value.i[c1];
808 break;
809 case GLSL_TYPE_UINT:
810 data.u[c] = op[0]->value.u[c0] & op[1]->value.u[c1];
811 break;
812 default:
813 assert(0);
814 }
815 }
816 break;
817
818 case ir_binop_bit_or:
819 for (unsigned c = 0, c0 = 0, c1 = 0;
820 c < components;
821 c0 += c0_inc, c1 += c1_inc, c++) {
822
823 switch (op[0]->type->base_type) {
824 case GLSL_TYPE_INT:
825 data.i[c] = op[0]->value.i[c0] | op[1]->value.i[c1];
826 break;
827 case GLSL_TYPE_UINT:
828 data.u[c] = op[0]->value.u[c0] | op[1]->value.u[c1];
829 break;
830 default:
831 assert(0);
832 }
833 }
834 break;
835
836 case ir_binop_bit_xor:
837 for (unsigned c = 0, c0 = 0, c1 = 0;
838 c < components;
839 c0 += c0_inc, c1 += c1_inc, c++) {
840
841 switch (op[0]->type->base_type) {
842 case GLSL_TYPE_INT:
843 data.i[c] = op[0]->value.i[c0] ^ op[1]->value.i[c1];
844 break;
845 case GLSL_TYPE_UINT:
846 data.u[c] = op[0]->value.u[c0] ^ op[1]->value.u[c1];
847 break;
848 default:
849 assert(0);
850 }
851 }
852 break;
853
854 case ir_quadop_vector:
855 for (unsigned c = 0; c < this->type->vector_elements; c++) {
856 switch (this->type->base_type) {
857 case GLSL_TYPE_INT:
858 data.i[c] = op[c]->value.i[0];
859 break;
860 case GLSL_TYPE_UINT:
861 data.u[c] = op[c]->value.u[0];
862 break;
863 case GLSL_TYPE_FLOAT:
864 data.f[c] = op[c]->value.f[0];
865 break;
866 default:
867 assert(0);
868 }
869 }
870 break;
871
872 default:
873 /* FINISHME: Should handle all expression types. */
874 return NULL;
875 }
876
877 return new(ctx) ir_constant(this->type, &data);
878 }
879
880
881 ir_constant *
882 ir_texture::constant_expression_value()
883 {
884 /* texture lookups aren't constant expressions */
885 return NULL;
886 }
887
888
889 ir_constant *
890 ir_swizzle::constant_expression_value()
891 {
892 ir_constant *v = this->val->constant_expression_value();
893
894 if (v != NULL) {
895 ir_constant_data data = { { 0 } };
896
897 const unsigned swiz_idx[4] = {
898 this->mask.x, this->mask.y, this->mask.z, this->mask.w
899 };
900
901 for (unsigned i = 0; i < this->mask.num_components; i++) {
902 switch (v->type->base_type) {
903 case GLSL_TYPE_UINT:
904 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
905 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
906 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
907 default: assert(!"Should not get here."); break;
908 }
909 }
910
911 void *ctx = ralloc_parent(this);
912 return new(ctx) ir_constant(this->type, &data);
913 }
914 return NULL;
915 }
916
917
918 ir_constant *
919 ir_dereference_variable::constant_expression_value()
920 {
921 /* This may occur during compile and var->type is glsl_type::error_type */
922 if (!var)
923 return NULL;
924
925 /* The constant_value of a uniform variable is its initializer,
926 * not the lifetime constant value of the uniform.
927 */
928 if (var->mode == ir_var_uniform)
929 return NULL;
930
931 if (!var->constant_value)
932 return NULL;
933
934 return var->constant_value->clone(ralloc_parent(var), NULL);
935 }
936
937
938 ir_constant *
939 ir_dereference_array::constant_expression_value()
940 {
941 ir_constant *array = this->array->constant_expression_value();
942 ir_constant *idx = this->array_index->constant_expression_value();
943
944 if ((array != NULL) && (idx != NULL)) {
945 void *ctx = ralloc_parent(this);
946 if (array->type->is_matrix()) {
947 /* Array access of a matrix results in a vector.
948 */
949 const unsigned column = idx->value.u[0];
950
951 const glsl_type *const column_type = array->type->column_type();
952
953 /* Offset in the constant matrix to the first element of the column
954 * to be extracted.
955 */
956 const unsigned mat_idx = column * column_type->vector_elements;
957
958 ir_constant_data data = { { 0 } };
959
960 switch (column_type->base_type) {
961 case GLSL_TYPE_UINT:
962 case GLSL_TYPE_INT:
963 for (unsigned i = 0; i < column_type->vector_elements; i++)
964 data.u[i] = array->value.u[mat_idx + i];
965
966 break;
967
968 case GLSL_TYPE_FLOAT:
969 for (unsigned i = 0; i < column_type->vector_elements; i++)
970 data.f[i] = array->value.f[mat_idx + i];
971
972 break;
973
974 default:
975 assert(!"Should not get here.");
976 break;
977 }
978
979 return new(ctx) ir_constant(column_type, &data);
980 } else if (array->type->is_vector()) {
981 const unsigned component = idx->value.u[0];
982
983 return new(ctx) ir_constant(array, component);
984 } else {
985 const unsigned index = idx->value.u[0];
986 return array->get_array_element(index)->clone(ctx, NULL);
987 }
988 }
989 return NULL;
990 }
991
992
993 ir_constant *
994 ir_dereference_record::constant_expression_value()
995 {
996 ir_constant *v = this->record->constant_expression_value();
997
998 return (v != NULL) ? v->get_record_field(this->field) : NULL;
999 }
1000
1001
1002 ir_constant *
1003 ir_assignment::constant_expression_value()
1004 {
1005 /* FINISHME: Handle CEs involving assignment (return RHS) */
1006 return NULL;
1007 }
1008
1009
1010 ir_constant *
1011 ir_constant::constant_expression_value()
1012 {
1013 return this;
1014 }
1015
1016
1017 ir_constant *
1018 ir_call::constant_expression_value()
1019 {
1020 if (this->type == glsl_type::error_type)
1021 return NULL;
1022
1023 /* From the GLSL 1.20 spec, page 23:
1024 * "Function calls to user-defined functions (non-built-in functions)
1025 * cannot be used to form constant expressions."
1026 */
1027 if (!this->callee->is_builtin)
1028 return NULL;
1029
1030 unsigned num_parameters = 0;
1031
1032 /* Check if all parameters are constant */
1033 ir_constant *op[3];
1034 foreach_list(n, &this->actual_parameters) {
1035 ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value();
1036 if (constant == NULL)
1037 return NULL;
1038
1039 op[num_parameters] = constant;
1040
1041 assert(num_parameters < 3);
1042 num_parameters++;
1043 }
1044
1045 /* Individual cases below can either:
1046 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
1047 * - Fill "data" with appopriate constant data
1048 * - Return an ir_constant directly.
1049 */
1050 void *mem_ctx = ralloc_parent(this);
1051 ir_expression *expr = NULL;
1052
1053 ir_constant_data data;
1054 memset(&data, 0, sizeof(data));
1055
1056 const char *callee = this->callee_name();
1057 if (strcmp(callee, "abs") == 0) {
1058 expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL);
1059 } else if (strcmp(callee, "all") == 0) {
1060 assert(op[0]->type->is_boolean());
1061 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1062 if (!op[0]->value.b[c])
1063 return new(mem_ctx) ir_constant(false);
1064 }
1065 return new(mem_ctx) ir_constant(true);
1066 } else if (strcmp(callee, "any") == 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(true);
1071 }
1072 return new(mem_ctx) ir_constant(false);
1073 } else if (strcmp(callee, "acos") == 0) {
1074 assert(op[0]->type->is_float());
1075 for (unsigned c = 0; c < op[0]->type->components(); c++)
1076 data.f[c] = acosf(op[0]->value.f[c]);
1077 } else if (strcmp(callee, "acosh") == 0) {
1078 assert(op[0]->type->is_float());
1079 for (unsigned c = 0; c < op[0]->type->components(); c++)
1080 data.f[c] = acoshf(op[0]->value.f[c]);
1081 } else if (strcmp(callee, "asin") == 0) {
1082 assert(op[0]->type->is_float());
1083 for (unsigned c = 0; c < op[0]->type->components(); c++)
1084 data.f[c] = asinf(op[0]->value.f[c]);
1085 } else if (strcmp(callee, "asinh") == 0) {
1086 assert(op[0]->type->is_float());
1087 for (unsigned c = 0; c < op[0]->type->components(); c++)
1088 data.f[c] = asinhf(op[0]->value.f[c]);
1089 } else if (strcmp(callee, "atan") == 0) {
1090 assert(op[0]->type->is_float());
1091 if (num_parameters == 2) {
1092 assert(op[1]->type->is_float());
1093 for (unsigned c = 0; c < op[0]->type->components(); c++)
1094 data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]);
1095 } else {
1096 for (unsigned c = 0; c < op[0]->type->components(); c++)
1097 data.f[c] = atanf(op[0]->value.f[c]);
1098 }
1099 } else if (strcmp(callee, "atanh") == 0) {
1100 assert(op[0]->type->is_float());
1101 for (unsigned c = 0; c < op[0]->type->components(); c++)
1102 data.f[c] = atanhf(op[0]->value.f[c]);
1103 } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) {
1104 return ir_constant::zero(mem_ctx, this->type);
1105 } else if (strcmp(callee, "ceil") == 0) {
1106 expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL);
1107 } else if (strcmp(callee, "clamp") == 0) {
1108 assert(num_parameters == 3);
1109 unsigned c1_inc = op[1]->type->is_scalar() ? 0 : 1;
1110 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
1111 for (unsigned c = 0, c1 = 0, c2 = 0;
1112 c < op[0]->type->components();
1113 c1 += c1_inc, c2 += c2_inc, c++) {
1114
1115 switch (op[0]->type->base_type) {
1116 case GLSL_TYPE_UINT:
1117 data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1],
1118 op[2]->value.u[c2]);
1119 break;
1120 case GLSL_TYPE_INT:
1121 data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1],
1122 op[2]->value.i[c2]);
1123 break;
1124 case GLSL_TYPE_FLOAT:
1125 data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1],
1126 op[2]->value.f[c2]);
1127 break;
1128 default:
1129 assert(!"Should not get here.");
1130 }
1131 }
1132 } else if (strcmp(callee, "cos") == 0) {
1133 expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL);
1134 } else if (strcmp(callee, "cosh") == 0) {
1135 assert(op[0]->type->is_float());
1136 for (unsigned c = 0; c < op[0]->type->components(); c++)
1137 data.f[c] = coshf(op[0]->value.f[c]);
1138 } else if (strcmp(callee, "cross") == 0) {
1139 assert(op[0]->type == glsl_type::vec3_type);
1140 assert(op[1]->type == glsl_type::vec3_type);
1141 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
1142 op[1]->value.f[1] * op[0]->value.f[2]);
1143 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
1144 op[1]->value.f[2] * op[0]->value.f[0]);
1145 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
1146 op[1]->value.f[0] * op[0]->value.f[1]);
1147 } else if (strcmp(callee, "degrees") == 0) {
1148 assert(op[0]->type->is_float());
1149 for (unsigned c = 0; c < op[0]->type->components(); c++)
1150 data.f[c] = 180.0F / M_PI * op[0]->value.f[c];
1151 } else if (strcmp(callee, "distance") == 0) {
1152 assert(op[0]->type->is_float() && op[1]->type->is_float());
1153 float length_squared = 0.0;
1154 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1155 float t = op[0]->value.f[c] - op[1]->value.f[c];
1156 length_squared += t * t;
1157 }
1158 return new(mem_ctx) ir_constant(sqrtf(length_squared));
1159 } else if (strcmp(callee, "dot") == 0) {
1160 return new(mem_ctx) ir_constant(dot(op[0], op[1]));
1161 } else if (strcmp(callee, "equal") == 0) {
1162 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1163 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1164 switch (op[0]->type->base_type) {
1165 case GLSL_TYPE_UINT:
1166 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
1167 break;
1168 case GLSL_TYPE_INT:
1169 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
1170 break;
1171 case GLSL_TYPE_FLOAT:
1172 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
1173 break;
1174 case GLSL_TYPE_BOOL:
1175 data.b[c] = op[0]->value.b[c] == op[1]->value.b[c];
1176 break;
1177 default:
1178 assert(!"Should not get here.");
1179 }
1180 }
1181 } else if (strcmp(callee, "exp") == 0) {
1182 expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL);
1183 } else if (strcmp(callee, "exp2") == 0) {
1184 expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL);
1185 } else if (strcmp(callee, "faceforward") == 0) {
1186 if (dot(op[2], op[1]) < 0)
1187 return op[0];
1188 for (unsigned c = 0; c < op[0]->type->components(); c++)
1189 data.f[c] = -op[0]->value.f[c];
1190 } else if (strcmp(callee, "floor") == 0) {
1191 expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL);
1192 } else if (strcmp(callee, "fract") == 0) {
1193 expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL);
1194 } else if (strcmp(callee, "fwidth") == 0) {
1195 return ir_constant::zero(mem_ctx, this->type);
1196 } else if (strcmp(callee, "greaterThan") == 0) {
1197 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1198 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1199 switch (op[0]->type->base_type) {
1200 case GLSL_TYPE_UINT:
1201 data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
1202 break;
1203 case GLSL_TYPE_INT:
1204 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
1205 break;
1206 case GLSL_TYPE_FLOAT:
1207 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
1208 break;
1209 default:
1210 assert(!"Should not get here.");
1211 }
1212 }
1213 } else if (strcmp(callee, "greaterThanEqual") == 0) {
1214 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1215 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1216 switch (op[0]->type->base_type) {
1217 case GLSL_TYPE_UINT:
1218 data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c];
1219 break;
1220 case GLSL_TYPE_INT:
1221 data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c];
1222 break;
1223 case GLSL_TYPE_FLOAT:
1224 data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c];
1225 break;
1226 default:
1227 assert(!"Should not get here.");
1228 }
1229 }
1230 } else if (strcmp(callee, "inversesqrt") == 0) {
1231 expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL);
1232 } else if (strcmp(callee, "length") == 0) {
1233 return new(mem_ctx) ir_constant(sqrtf(dot(op[0], op[0])));
1234 } else if (strcmp(callee, "lessThan") == 0) {
1235 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1236 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1237 switch (op[0]->type->base_type) {
1238 case GLSL_TYPE_UINT:
1239 data.b[c] = op[0]->value.u[c] < op[1]->value.u[c];
1240 break;
1241 case GLSL_TYPE_INT:
1242 data.b[c] = op[0]->value.i[c] < op[1]->value.i[c];
1243 break;
1244 case GLSL_TYPE_FLOAT:
1245 data.b[c] = op[0]->value.f[c] < op[1]->value.f[c];
1246 break;
1247 default:
1248 assert(!"Should not get here.");
1249 }
1250 }
1251 } else if (strcmp(callee, "lessThanEqual") == 0) {
1252 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1253 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1254 switch (op[0]->type->base_type) {
1255 case GLSL_TYPE_UINT:
1256 data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c];
1257 break;
1258 case GLSL_TYPE_INT:
1259 data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c];
1260 break;
1261 case GLSL_TYPE_FLOAT:
1262 data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c];
1263 break;
1264 default:
1265 assert(!"Should not get here.");
1266 }
1267 }
1268 } else if (strcmp(callee, "log") == 0) {
1269 expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL);
1270 } else if (strcmp(callee, "log2") == 0) {
1271 expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL);
1272 } else if (strcmp(callee, "matrixCompMult") == 0) {
1273 assert(op[0]->type->is_float() && op[1]->type->is_float());
1274 for (unsigned c = 0; c < op[0]->type->components(); c++)
1275 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
1276 } else if (strcmp(callee, "max") == 0) {
1277 expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]);
1278 } else if (strcmp(callee, "min") == 0) {
1279 expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]);
1280 } else if (strcmp(callee, "mix") == 0) {
1281 assert(op[0]->type->is_float() && op[1]->type->is_float());
1282 if (op[2]->type->is_float()) {
1283 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
1284 unsigned components = op[0]->type->components();
1285 for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) {
1286 data.f[c] = op[0]->value.f[c] * (1 - op[2]->value.f[c2]) +
1287 op[1]->value.f[c] * op[2]->value.f[c2];
1288 }
1289 } else {
1290 assert(op[2]->type->is_boolean());
1291 for (unsigned c = 0; c < op[0]->type->components(); c++)
1292 data.f[c] = op[op[2]->value.b[c] ? 1 : 0]->value.f[c];
1293 }
1294 } else if (strcmp(callee, "mod") == 0) {
1295 expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]);
1296 } else if (strcmp(callee, "normalize") == 0) {
1297 assert(op[0]->type->is_float());
1298 float length = sqrtf(dot(op[0], op[0]));
1299
1300 if (length == 0)
1301 return ir_constant::zero(mem_ctx, this->type);
1302
1303 for (unsigned c = 0; c < op[0]->type->components(); c++)
1304 data.f[c] = op[0]->value.f[c] / length;
1305 } else if (strcmp(callee, "not") == 0) {
1306 expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL);
1307 } else if (strcmp(callee, "notEqual") == 0) {
1308 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1309 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1310 switch (op[0]->type->base_type) {
1311 case GLSL_TYPE_UINT:
1312 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
1313 break;
1314 case GLSL_TYPE_INT:
1315 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
1316 break;
1317 case GLSL_TYPE_FLOAT:
1318 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
1319 break;
1320 case GLSL_TYPE_BOOL:
1321 data.b[c] = op[0]->value.b[c] != op[1]->value.b[c];
1322 break;
1323 default:
1324 assert(!"Should not get here.");
1325 }
1326 }
1327 } else if (strcmp(callee, "outerProduct") == 0) {
1328 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
1329 const unsigned m = op[0]->type->vector_elements;
1330 const unsigned n = op[1]->type->vector_elements;
1331 for (unsigned j = 0; j < n; j++) {
1332 for (unsigned i = 0; i < m; i++) {
1333 data.f[i+m*j] = op[0]->value.f[i] * op[1]->value.f[j];
1334 }
1335 }
1336 } else if (strcmp(callee, "pow") == 0) {
1337 expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]);
1338 } else if (strcmp(callee, "radians") == 0) {
1339 assert(op[0]->type->is_float());
1340 for (unsigned c = 0; c < op[0]->type->components(); c++)
1341 data.f[c] = M_PI / 180.0F * op[0]->value.f[c];
1342 } else if (strcmp(callee, "reflect") == 0) {
1343 assert(op[0]->type->is_float());
1344 float dot_NI = dot(op[1], op[0]);
1345 for (unsigned c = 0; c < op[0]->type->components(); c++)
1346 data.f[c] = op[0]->value.f[c] - 2 * dot_NI * op[1]->value.f[c];
1347 } else if (strcmp(callee, "refract") == 0) {
1348 const float eta = op[2]->value.f[0];
1349 const float dot_NI = dot(op[1], op[0]);
1350 const float k = 1.0F - eta * eta * (1.0F - dot_NI * dot_NI);
1351 if (k < 0.0) {
1352 return ir_constant::zero(mem_ctx, this->type);
1353 } else {
1354 for (unsigned c = 0; c < type->components(); c++) {
1355 data.f[c] = eta * op[0]->value.f[c] - (eta * dot_NI + sqrtf(k))
1356 * op[1]->value.f[c];
1357 }
1358 }
1359 } else if (strcmp(callee, "round") == 0 ||
1360 strcmp(callee, "roundEven") == 0) {
1361 expr = new(mem_ctx) ir_expression(ir_unop_round_even, op[0]);
1362 } else if (strcmp(callee, "sign") == 0) {
1363 expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
1364 } else if (strcmp(callee, "sin") == 0) {
1365 expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL);
1366 } else if (strcmp(callee, "sinh") == 0) {
1367 assert(op[0]->type->is_float());
1368 for (unsigned c = 0; c < op[0]->type->components(); c++)
1369 data.f[c] = sinhf(op[0]->value.f[c]);
1370 } else if (strcmp(callee, "smoothstep") == 0) {
1371 assert(num_parameters == 3);
1372 assert(op[1]->type == op[0]->type);
1373 unsigned edge_inc = op[0]->type->is_scalar() ? 0 : 1;
1374 for (unsigned c = 0, e = 0; c < type->components(); e += edge_inc, c++) {
1375 const float edge0 = op[0]->value.f[e];
1376 const float edge1 = op[1]->value.f[e];
1377 if (edge0 == edge1) {
1378 data.f[c] = 0.0; /* Avoid a crash - results are undefined anyway */
1379 } else {
1380 const float numerator = op[2]->value.f[c] - edge0;
1381 const float denominator = edge1 - edge0;
1382 const float t = CLAMP(numerator/denominator, 0, 1);
1383 data.f[c] = t * t * (3 - 2 * t);
1384 }
1385 }
1386 } else if (strcmp(callee, "sqrt") == 0) {
1387 expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL);
1388 } else if (strcmp(callee, "step") == 0) {
1389 assert(op[0]->type->is_float() && op[1]->type->is_float());
1390 /* op[0] (edge) may be either a scalar or a vector */
1391 const unsigned c0_inc = op[0]->type->is_scalar() ? 0 : 1;
1392 for (unsigned c = 0, c0 = 0; c < type->components(); c0 += c0_inc, c++)
1393 data.f[c] = (op[1]->value.f[c] < op[0]->value.f[c0]) ? 0.0F : 1.0F;
1394 } else if (strcmp(callee, "tan") == 0) {
1395 assert(op[0]->type->is_float());
1396 for (unsigned c = 0; c < op[0]->type->components(); c++)
1397 data.f[c] = tanf(op[0]->value.f[c]);
1398 } else if (strcmp(callee, "tanh") == 0) {
1399 assert(op[0]->type->is_float());
1400 for (unsigned c = 0; c < op[0]->type->components(); c++)
1401 data.f[c] = tanhf(op[0]->value.f[c]);
1402 } else if (strcmp(callee, "transpose") == 0) {
1403 assert(op[0]->type->is_matrix());
1404 const unsigned n = op[0]->type->vector_elements;
1405 const unsigned m = op[0]->type->matrix_columns;
1406 for (unsigned j = 0; j < m; j++) {
1407 for (unsigned i = 0; i < n; i++) {
1408 data.f[m*i+j] += op[0]->value.f[i+n*j];
1409 }
1410 }
1411 } else if (strcmp(callee, "trunc") == 0) {
1412 expr = new(mem_ctx) ir_expression(ir_unop_trunc, op[0]);
1413 } else {
1414 /* Unsupported builtin - some are not allowed in constant expressions. */
1415 return NULL;
1416 }
1417
1418 if (expr != NULL)
1419 return expr->constant_expression_value();
1420
1421 return new(mem_ctx) ir_constant(this->type, &data);
1422 }