glsl: Add a constant_referenced method to ir_dereference*
[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 void
927 ir_dereference_variable::constant_referenced(struct hash_table *variable_context,
928 ir_constant *&store, int &offset) const
929 {
930 if (variable_context) {
931 store = (ir_constant *)hash_table_find(variable_context, var);
932 offset = 0;
933 } else {
934 store = NULL;
935 offset = 0;
936 }
937 }
938
939 ir_constant *
940 ir_dereference_variable::constant_expression_value(struct hash_table *variable_context)
941 {
942 /* This may occur during compile and var->type is glsl_type::error_type */
943 if (!var)
944 return NULL;
945
946 /* Give priority to the context hashtable, if it exists */
947 if (variable_context) {
948 ir_constant *value = (ir_constant *)hash_table_find(variable_context, var);
949 if(value)
950 return value;
951 }
952
953 /* The constant_value of a uniform variable is its initializer,
954 * not the lifetime constant value of the uniform.
955 */
956 if (var->mode == ir_var_uniform)
957 return NULL;
958
959 if (!var->constant_value)
960 return NULL;
961
962 return var->constant_value->clone(ralloc_parent(var), NULL);
963 }
964
965
966 void
967 ir_dereference_array::constant_referenced(struct hash_table *variable_context,
968 ir_constant *&store, int &offset) const
969 {
970 ir_constant *index_c = array_index->constant_expression_value(variable_context);
971
972 if (!index_c || !index_c->type->is_scalar() || !index_c->type->is_integer()) {
973 store = 0;
974 offset = 0;
975 return;
976 }
977
978 int index = index_c->type->base_type == GLSL_TYPE_INT ?
979 index_c->get_int_component(0) :
980 index_c->get_uint_component(0);
981
982 ir_constant *substore;
983 int suboffset;
984 const ir_dereference *deref = array->as_dereference();
985 if (!deref) {
986 store = 0;
987 offset = 0;
988 return;
989 }
990
991 deref->constant_referenced(variable_context, substore, suboffset);
992
993 if (!substore) {
994 store = 0;
995 offset = 0;
996 return;
997 }
998
999 const glsl_type *vt = substore->type;
1000 if (vt->is_array()) {
1001 store = substore->get_array_element(index);
1002 offset = 0;
1003 return;
1004 }
1005 if (vt->is_matrix()) {
1006 store = substore;
1007 offset = index * vt->vector_elements;
1008 return;
1009 }
1010 if (vt->is_vector()) {
1011 store = substore;
1012 offset = suboffset + index;
1013 return;
1014 }
1015
1016 store = 0;
1017 offset = 0;
1018 }
1019
1020 ir_constant *
1021 ir_dereference_array::constant_expression_value(struct hash_table *variable_context)
1022 {
1023 ir_constant *array = this->array->constant_expression_value(variable_context);
1024 ir_constant *idx = this->array_index->constant_expression_value(variable_context);
1025
1026 if ((array != NULL) && (idx != NULL)) {
1027 void *ctx = ralloc_parent(this);
1028 if (array->type->is_matrix()) {
1029 /* Array access of a matrix results in a vector.
1030 */
1031 const unsigned column = idx->value.u[0];
1032
1033 const glsl_type *const column_type = array->type->column_type();
1034
1035 /* Offset in the constant matrix to the first element of the column
1036 * to be extracted.
1037 */
1038 const unsigned mat_idx = column * column_type->vector_elements;
1039
1040 ir_constant_data data = { { 0 } };
1041
1042 switch (column_type->base_type) {
1043 case GLSL_TYPE_UINT:
1044 case GLSL_TYPE_INT:
1045 for (unsigned i = 0; i < column_type->vector_elements; i++)
1046 data.u[i] = array->value.u[mat_idx + i];
1047
1048 break;
1049
1050 case GLSL_TYPE_FLOAT:
1051 for (unsigned i = 0; i < column_type->vector_elements; i++)
1052 data.f[i] = array->value.f[mat_idx + i];
1053
1054 break;
1055
1056 default:
1057 assert(!"Should not get here.");
1058 break;
1059 }
1060
1061 return new(ctx) ir_constant(column_type, &data);
1062 } else if (array->type->is_vector()) {
1063 const unsigned component = idx->value.u[0];
1064
1065 return new(ctx) ir_constant(array, component);
1066 } else {
1067 const unsigned index = idx->value.u[0];
1068 return array->get_array_element(index)->clone(ctx, NULL);
1069 }
1070 }
1071 return NULL;
1072 }
1073
1074
1075 void
1076 ir_dereference_record::constant_referenced(struct hash_table *variable_context,
1077 ir_constant *&store, int &offset) const
1078 {
1079 ir_constant *substore;
1080 int suboffset;
1081 const ir_dereference *deref = record->as_dereference();
1082 if (!deref) {
1083 store = 0;
1084 offset = 0;
1085 return;
1086 }
1087
1088 deref->constant_referenced(variable_context, substore, suboffset);
1089
1090 if (!substore) {
1091 store = 0;
1092 offset = 0;
1093 return;
1094 }
1095
1096 store = substore->get_record_field(field);
1097 offset = 0;
1098 }
1099
1100 ir_constant *
1101 ir_dereference_record::constant_expression_value(struct hash_table *variable_context)
1102 {
1103 ir_constant *v = this->record->constant_expression_value();
1104
1105 return (v != NULL) ? v->get_record_field(this->field) : NULL;
1106 }
1107
1108
1109 ir_constant *
1110 ir_assignment::constant_expression_value(struct hash_table *variable_context)
1111 {
1112 /* FINISHME: Handle CEs involving assignment (return RHS) */
1113 return NULL;
1114 }
1115
1116
1117 ir_constant *
1118 ir_constant::constant_expression_value(struct hash_table *variable_context)
1119 {
1120 return this;
1121 }
1122
1123
1124 ir_constant *
1125 ir_call::constant_expression_value(struct hash_table *variable_context)
1126 {
1127 return this->callee->constant_expression_value(&this->actual_parameters, variable_context);
1128 }
1129
1130
1131 ir_constant *
1132 ir_function_signature::constant_expression_value(exec_list *actual_parameters, struct hash_table *variable_context)
1133 {
1134 const glsl_type *type = this->return_type;
1135 if (type == glsl_type::void_type)
1136 return NULL;
1137
1138 /* From the GLSL 1.20 spec, page 23:
1139 * "Function calls to user-defined functions (non-built-in functions)
1140 * cannot be used to form constant expressions."
1141 */
1142 if (!this->is_builtin)
1143 return NULL;
1144
1145 unsigned num_parameters = 0;
1146
1147 /* Check if all parameters are constant */
1148 ir_constant *op[3];
1149 foreach_list(n, actual_parameters) {
1150 ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value(variable_context);
1151 if (constant == NULL)
1152 return NULL;
1153
1154 op[num_parameters] = constant;
1155
1156 assert(num_parameters < 3);
1157 num_parameters++;
1158 }
1159
1160 /* Individual cases below can either:
1161 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
1162 * - Fill "data" with appopriate constant data
1163 * - Return an ir_constant directly.
1164 */
1165 void *mem_ctx = ralloc_parent(this);
1166 ir_expression *expr = NULL;
1167
1168 ir_constant_data data;
1169 memset(&data, 0, sizeof(data));
1170
1171 const char *callee = this->function_name();
1172 if (strcmp(callee, "abs") == 0) {
1173 expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL);
1174 } else if (strcmp(callee, "all") == 0) {
1175 assert(op[0]->type->is_boolean());
1176 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1177 if (!op[0]->value.b[c])
1178 return new(mem_ctx) ir_constant(false);
1179 }
1180 return new(mem_ctx) ir_constant(true);
1181 } else if (strcmp(callee, "any") == 0) {
1182 assert(op[0]->type->is_boolean());
1183 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1184 if (op[0]->value.b[c])
1185 return new(mem_ctx) ir_constant(true);
1186 }
1187 return new(mem_ctx) ir_constant(false);
1188 } else if (strcmp(callee, "acos") == 0) {
1189 assert(op[0]->type->is_float());
1190 for (unsigned c = 0; c < op[0]->type->components(); c++)
1191 data.f[c] = acosf(op[0]->value.f[c]);
1192 } else if (strcmp(callee, "acosh") == 0) {
1193 assert(op[0]->type->is_float());
1194 for (unsigned c = 0; c < op[0]->type->components(); c++)
1195 data.f[c] = acoshf(op[0]->value.f[c]);
1196 } else if (strcmp(callee, "asin") == 0) {
1197 assert(op[0]->type->is_float());
1198 for (unsigned c = 0; c < op[0]->type->components(); c++)
1199 data.f[c] = asinf(op[0]->value.f[c]);
1200 } else if (strcmp(callee, "asinh") == 0) {
1201 assert(op[0]->type->is_float());
1202 for (unsigned c = 0; c < op[0]->type->components(); c++)
1203 data.f[c] = asinhf(op[0]->value.f[c]);
1204 } else if (strcmp(callee, "atan") == 0) {
1205 assert(op[0]->type->is_float());
1206 if (num_parameters == 2) {
1207 assert(op[1]->type->is_float());
1208 for (unsigned c = 0; c < op[0]->type->components(); c++)
1209 data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]);
1210 } else {
1211 for (unsigned c = 0; c < op[0]->type->components(); c++)
1212 data.f[c] = atanf(op[0]->value.f[c]);
1213 }
1214 } else if (strcmp(callee, "atanh") == 0) {
1215 assert(op[0]->type->is_float());
1216 for (unsigned c = 0; c < op[0]->type->components(); c++)
1217 data.f[c] = atanhf(op[0]->value.f[c]);
1218 } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) {
1219 return ir_constant::zero(mem_ctx, type);
1220 } else if (strcmp(callee, "ceil") == 0) {
1221 expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL);
1222 } else if (strcmp(callee, "clamp") == 0) {
1223 assert(num_parameters == 3);
1224 unsigned c1_inc = op[1]->type->is_scalar() ? 0 : 1;
1225 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
1226 for (unsigned c = 0, c1 = 0, c2 = 0;
1227 c < op[0]->type->components();
1228 c1 += c1_inc, c2 += c2_inc, c++) {
1229
1230 switch (op[0]->type->base_type) {
1231 case GLSL_TYPE_UINT:
1232 data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1],
1233 op[2]->value.u[c2]);
1234 break;
1235 case GLSL_TYPE_INT:
1236 data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1],
1237 op[2]->value.i[c2]);
1238 break;
1239 case GLSL_TYPE_FLOAT:
1240 data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1],
1241 op[2]->value.f[c2]);
1242 break;
1243 default:
1244 assert(!"Should not get here.");
1245 }
1246 }
1247 } else if (strcmp(callee, "cos") == 0) {
1248 expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL);
1249 } else if (strcmp(callee, "cosh") == 0) {
1250 assert(op[0]->type->is_float());
1251 for (unsigned c = 0; c < op[0]->type->components(); c++)
1252 data.f[c] = coshf(op[0]->value.f[c]);
1253 } else if (strcmp(callee, "cross") == 0) {
1254 assert(op[0]->type == glsl_type::vec3_type);
1255 assert(op[1]->type == glsl_type::vec3_type);
1256 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
1257 op[1]->value.f[1] * op[0]->value.f[2]);
1258 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
1259 op[1]->value.f[2] * op[0]->value.f[0]);
1260 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
1261 op[1]->value.f[0] * op[0]->value.f[1]);
1262 } else if (strcmp(callee, "degrees") == 0) {
1263 assert(op[0]->type->is_float());
1264 for (unsigned c = 0; c < op[0]->type->components(); c++)
1265 data.f[c] = 180.0F / M_PI * op[0]->value.f[c];
1266 } else if (strcmp(callee, "distance") == 0) {
1267 assert(op[0]->type->is_float() && op[1]->type->is_float());
1268 float length_squared = 0.0;
1269 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1270 float t = op[0]->value.f[c] - op[1]->value.f[c];
1271 length_squared += t * t;
1272 }
1273 return new(mem_ctx) ir_constant(sqrtf(length_squared));
1274 } else if (strcmp(callee, "dot") == 0) {
1275 return new(mem_ctx) ir_constant(dot(op[0], op[1]));
1276 } else if (strcmp(callee, "equal") == 0) {
1277 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1278 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1279 switch (op[0]->type->base_type) {
1280 case GLSL_TYPE_UINT:
1281 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
1282 break;
1283 case GLSL_TYPE_INT:
1284 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
1285 break;
1286 case GLSL_TYPE_FLOAT:
1287 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
1288 break;
1289 case GLSL_TYPE_BOOL:
1290 data.b[c] = op[0]->value.b[c] == op[1]->value.b[c];
1291 break;
1292 default:
1293 assert(!"Should not get here.");
1294 }
1295 }
1296 } else if (strcmp(callee, "exp") == 0) {
1297 expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL);
1298 } else if (strcmp(callee, "exp2") == 0) {
1299 expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL);
1300 } else if (strcmp(callee, "faceforward") == 0) {
1301 if (dot(op[2], op[1]) < 0)
1302 return op[0];
1303 for (unsigned c = 0; c < op[0]->type->components(); c++)
1304 data.f[c] = -op[0]->value.f[c];
1305 } else if (strcmp(callee, "floor") == 0) {
1306 expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL);
1307 } else if (strcmp(callee, "fract") == 0) {
1308 expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL);
1309 } else if (strcmp(callee, "fwidth") == 0) {
1310 return ir_constant::zero(mem_ctx, type);
1311 } else if (strcmp(callee, "greaterThan") == 0) {
1312 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1313 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1314 switch (op[0]->type->base_type) {
1315 case GLSL_TYPE_UINT:
1316 data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
1317 break;
1318 case GLSL_TYPE_INT:
1319 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
1320 break;
1321 case GLSL_TYPE_FLOAT:
1322 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
1323 break;
1324 default:
1325 assert(!"Should not get here.");
1326 }
1327 }
1328 } else if (strcmp(callee, "greaterThanEqual") == 0) {
1329 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1330 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1331 switch (op[0]->type->base_type) {
1332 case GLSL_TYPE_UINT:
1333 data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c];
1334 break;
1335 case GLSL_TYPE_INT:
1336 data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c];
1337 break;
1338 case GLSL_TYPE_FLOAT:
1339 data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c];
1340 break;
1341 default:
1342 assert(!"Should not get here.");
1343 }
1344 }
1345 } else if (strcmp(callee, "inversesqrt") == 0) {
1346 expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL);
1347 } else if (strcmp(callee, "length") == 0) {
1348 return new(mem_ctx) ir_constant(sqrtf(dot(op[0], op[0])));
1349 } else if (strcmp(callee, "lessThan") == 0) {
1350 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1351 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1352 switch (op[0]->type->base_type) {
1353 case GLSL_TYPE_UINT:
1354 data.b[c] = op[0]->value.u[c] < op[1]->value.u[c];
1355 break;
1356 case GLSL_TYPE_INT:
1357 data.b[c] = op[0]->value.i[c] < op[1]->value.i[c];
1358 break;
1359 case GLSL_TYPE_FLOAT:
1360 data.b[c] = op[0]->value.f[c] < op[1]->value.f[c];
1361 break;
1362 default:
1363 assert(!"Should not get here.");
1364 }
1365 }
1366 } else if (strcmp(callee, "lessThanEqual") == 0) {
1367 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1368 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1369 switch (op[0]->type->base_type) {
1370 case GLSL_TYPE_UINT:
1371 data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c];
1372 break;
1373 case GLSL_TYPE_INT:
1374 data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c];
1375 break;
1376 case GLSL_TYPE_FLOAT:
1377 data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c];
1378 break;
1379 default:
1380 assert(!"Should not get here.");
1381 }
1382 }
1383 } else if (strcmp(callee, "log") == 0) {
1384 expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL);
1385 } else if (strcmp(callee, "log2") == 0) {
1386 expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL);
1387 } else if (strcmp(callee, "matrixCompMult") == 0) {
1388 assert(op[0]->type->is_float() && op[1]->type->is_float());
1389 for (unsigned c = 0; c < op[0]->type->components(); c++)
1390 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
1391 } else if (strcmp(callee, "max") == 0) {
1392 expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]);
1393 } else if (strcmp(callee, "min") == 0) {
1394 expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]);
1395 } else if (strcmp(callee, "mix") == 0) {
1396 assert(op[0]->type->is_float() && op[1]->type->is_float());
1397 if (op[2]->type->is_float()) {
1398 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
1399 unsigned components = op[0]->type->components();
1400 for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) {
1401 data.f[c] = op[0]->value.f[c] * (1 - op[2]->value.f[c2]) +
1402 op[1]->value.f[c] * op[2]->value.f[c2];
1403 }
1404 } else {
1405 assert(op[2]->type->is_boolean());
1406 for (unsigned c = 0; c < op[0]->type->components(); c++)
1407 data.f[c] = op[op[2]->value.b[c] ? 1 : 0]->value.f[c];
1408 }
1409 } else if (strcmp(callee, "mod") == 0) {
1410 expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]);
1411 } else if (strcmp(callee, "normalize") == 0) {
1412 assert(op[0]->type->is_float());
1413 float length = sqrtf(dot(op[0], op[0]));
1414
1415 if (length == 0)
1416 return ir_constant::zero(mem_ctx, type);
1417
1418 for (unsigned c = 0; c < op[0]->type->components(); c++)
1419 data.f[c] = op[0]->value.f[c] / length;
1420 } else if (strcmp(callee, "not") == 0) {
1421 expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL);
1422 } else if (strcmp(callee, "notEqual") == 0) {
1423 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1424 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1425 switch (op[0]->type->base_type) {
1426 case GLSL_TYPE_UINT:
1427 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
1428 break;
1429 case GLSL_TYPE_INT:
1430 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
1431 break;
1432 case GLSL_TYPE_FLOAT:
1433 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
1434 break;
1435 case GLSL_TYPE_BOOL:
1436 data.b[c] = op[0]->value.b[c] != op[1]->value.b[c];
1437 break;
1438 default:
1439 assert(!"Should not get here.");
1440 }
1441 }
1442 } else if (strcmp(callee, "outerProduct") == 0) {
1443 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
1444 const unsigned m = op[0]->type->vector_elements;
1445 const unsigned n = op[1]->type->vector_elements;
1446 for (unsigned j = 0; j < n; j++) {
1447 for (unsigned i = 0; i < m; i++) {
1448 data.f[i+m*j] = op[0]->value.f[i] * op[1]->value.f[j];
1449 }
1450 }
1451 } else if (strcmp(callee, "pow") == 0) {
1452 expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]);
1453 } else if (strcmp(callee, "radians") == 0) {
1454 assert(op[0]->type->is_float());
1455 for (unsigned c = 0; c < op[0]->type->components(); c++)
1456 data.f[c] = M_PI / 180.0F * op[0]->value.f[c];
1457 } else if (strcmp(callee, "reflect") == 0) {
1458 assert(op[0]->type->is_float());
1459 float dot_NI = dot(op[1], op[0]);
1460 for (unsigned c = 0; c < op[0]->type->components(); c++)
1461 data.f[c] = op[0]->value.f[c] - 2 * dot_NI * op[1]->value.f[c];
1462 } else if (strcmp(callee, "refract") == 0) {
1463 const float eta = op[2]->value.f[0];
1464 const float dot_NI = dot(op[1], op[0]);
1465 const float k = 1.0F - eta * eta * (1.0F - dot_NI * dot_NI);
1466 if (k < 0.0) {
1467 return ir_constant::zero(mem_ctx, type);
1468 } else {
1469 for (unsigned c = 0; c < type->components(); c++) {
1470 data.f[c] = eta * op[0]->value.f[c] - (eta * dot_NI + sqrtf(k))
1471 * op[1]->value.f[c];
1472 }
1473 }
1474 } else if (strcmp(callee, "round") == 0 ||
1475 strcmp(callee, "roundEven") == 0) {
1476 expr = new(mem_ctx) ir_expression(ir_unop_round_even, op[0]);
1477 } else if (strcmp(callee, "sign") == 0) {
1478 expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
1479 } else if (strcmp(callee, "sin") == 0) {
1480 expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL);
1481 } else if (strcmp(callee, "sinh") == 0) {
1482 assert(op[0]->type->is_float());
1483 for (unsigned c = 0; c < op[0]->type->components(); c++)
1484 data.f[c] = sinhf(op[0]->value.f[c]);
1485 } else if (strcmp(callee, "smoothstep") == 0) {
1486 assert(num_parameters == 3);
1487 assert(op[1]->type == op[0]->type);
1488 unsigned edge_inc = op[0]->type->is_scalar() ? 0 : 1;
1489 for (unsigned c = 0, e = 0; c < type->components(); e += edge_inc, c++) {
1490 const float edge0 = op[0]->value.f[e];
1491 const float edge1 = op[1]->value.f[e];
1492 if (edge0 == edge1) {
1493 data.f[c] = 0.0; /* Avoid a crash - results are undefined anyway */
1494 } else {
1495 const float numerator = op[2]->value.f[c] - edge0;
1496 const float denominator = edge1 - edge0;
1497 const float t = CLAMP(numerator/denominator, 0, 1);
1498 data.f[c] = t * t * (3 - 2 * t);
1499 }
1500 }
1501 } else if (strcmp(callee, "sqrt") == 0) {
1502 expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL);
1503 } else if (strcmp(callee, "step") == 0) {
1504 assert(op[0]->type->is_float() && op[1]->type->is_float());
1505 /* op[0] (edge) may be either a scalar or a vector */
1506 const unsigned c0_inc = op[0]->type->is_scalar() ? 0 : 1;
1507 for (unsigned c = 0, c0 = 0; c < type->components(); c0 += c0_inc, c++)
1508 data.f[c] = (op[1]->value.f[c] < op[0]->value.f[c0]) ? 0.0F : 1.0F;
1509 } else if (strcmp(callee, "tan") == 0) {
1510 assert(op[0]->type->is_float());
1511 for (unsigned c = 0; c < op[0]->type->components(); c++)
1512 data.f[c] = tanf(op[0]->value.f[c]);
1513 } else if (strcmp(callee, "tanh") == 0) {
1514 assert(op[0]->type->is_float());
1515 for (unsigned c = 0; c < op[0]->type->components(); c++)
1516 data.f[c] = tanhf(op[0]->value.f[c]);
1517 } else if (strcmp(callee, "transpose") == 0) {
1518 assert(op[0]->type->is_matrix());
1519 const unsigned n = op[0]->type->vector_elements;
1520 const unsigned m = op[0]->type->matrix_columns;
1521 for (unsigned j = 0; j < m; j++) {
1522 for (unsigned i = 0; i < n; i++) {
1523 data.f[m*i+j] += op[0]->value.f[i+n*j];
1524 }
1525 }
1526 } else if (strcmp(callee, "trunc") == 0) {
1527 expr = new(mem_ctx) ir_expression(ir_unop_trunc, op[0]);
1528 } else {
1529 /* Unsupported builtin - some are not allowed in constant expressions. */
1530 return NULL;
1531 }
1532
1533 if (expr != NULL)
1534 return expr->constant_expression_value();
1535
1536 return new(mem_ctx) ir_constant(type, &data);
1537 }