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