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