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