glsl: Fix constant-folding for reciprocal expressions
[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[Elements(this->operands)] = { 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 = ralloc_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 /* FINISHME: Emit warning when division-by-zero is detected. */
292 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
293 for (unsigned c = 0; c < op[0]->type->components(); c++) {
294 switch (this->type->base_type) {
295 case GLSL_TYPE_UINT:
296 if (op[0]->value.u[c] == 0.0)
297 return NULL;
298 data.u[c] = 1 / op[0]->value.u[c];
299 break;
300 case GLSL_TYPE_INT:
301 if (op[0]->value.i[c] == 0.0)
302 return NULL;
303 data.i[c] = 1 / op[0]->value.i[c];
304 break;
305 case GLSL_TYPE_FLOAT:
306 if (op[0]->value.f[c] == 0.0)
307 return NULL;
308 data.f[c] = 1.0F / op[0]->value.f[c];
309 break;
310 default:
311 assert(0);
312 }
313 }
314 break;
315
316 case ir_unop_rsq:
317 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
318 for (unsigned c = 0; c < op[0]->type->components(); c++) {
319 data.f[c] = 1.0F / sqrtf(op[0]->value.f[c]);
320 }
321 break;
322
323 case ir_unop_sqrt:
324 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
325 for (unsigned c = 0; c < op[0]->type->components(); c++) {
326 data.f[c] = sqrtf(op[0]->value.f[c]);
327 }
328 break;
329
330 case ir_unop_exp:
331 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
332 for (unsigned c = 0; c < op[0]->type->components(); c++) {
333 data.f[c] = expf(op[0]->value.f[c]);
334 }
335 break;
336
337 case ir_unop_exp2:
338 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
339 for (unsigned c = 0; c < op[0]->type->components(); c++) {
340 data.f[c] = exp2f(op[0]->value.f[c]);
341 }
342 break;
343
344 case ir_unop_log:
345 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
346 for (unsigned c = 0; c < op[0]->type->components(); c++) {
347 data.f[c] = logf(op[0]->value.f[c]);
348 }
349 break;
350
351 case ir_unop_log2:
352 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
353 for (unsigned c = 0; c < op[0]->type->components(); c++) {
354 data.f[c] = log2f(op[0]->value.f[c]);
355 }
356 break;
357
358 case ir_unop_dFdx:
359 case ir_unop_dFdy:
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] = 0.0;
363 }
364 break;
365
366 case ir_binop_pow:
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] = powf(op[0]->value.f[c], op[1]->value.f[c]);
370 }
371 break;
372
373 case ir_binop_dot:
374 data.f[0] = dot(op[0], op[1]);
375 break;
376
377 case ir_binop_min:
378 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
379 for (unsigned c = 0, c0 = 0, c1 = 0;
380 c < components;
381 c0 += c0_inc, c1 += c1_inc, c++) {
382
383 switch (op[0]->type->base_type) {
384 case GLSL_TYPE_UINT:
385 data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]);
386 break;
387 case GLSL_TYPE_INT:
388 data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]);
389 break;
390 case GLSL_TYPE_FLOAT:
391 data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]);
392 break;
393 default:
394 assert(0);
395 }
396 }
397
398 break;
399 case ir_binop_max:
400 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
401 for (unsigned c = 0, c0 = 0, c1 = 0;
402 c < components;
403 c0 += c0_inc, c1 += c1_inc, c++) {
404
405 switch (op[0]->type->base_type) {
406 case GLSL_TYPE_UINT:
407 data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]);
408 break;
409 case GLSL_TYPE_INT:
410 data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]);
411 break;
412 case GLSL_TYPE_FLOAT:
413 data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]);
414 break;
415 default:
416 assert(0);
417 }
418 }
419 break;
420
421 case ir_binop_add:
422 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
423 for (unsigned c = 0, c0 = 0, c1 = 0;
424 c < components;
425 c0 += c0_inc, c1 += c1_inc, c++) {
426
427 switch (op[0]->type->base_type) {
428 case GLSL_TYPE_UINT:
429 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
430 break;
431 case GLSL_TYPE_INT:
432 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
433 break;
434 case GLSL_TYPE_FLOAT:
435 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
436 break;
437 default:
438 assert(0);
439 }
440 }
441
442 break;
443 case ir_binop_sub:
444 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
445 for (unsigned c = 0, c0 = 0, c1 = 0;
446 c < components;
447 c0 += c0_inc, c1 += c1_inc, c++) {
448
449 switch (op[0]->type->base_type) {
450 case GLSL_TYPE_UINT:
451 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
452 break;
453 case GLSL_TYPE_INT:
454 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
455 break;
456 case GLSL_TYPE_FLOAT:
457 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
458 break;
459 default:
460 assert(0);
461 }
462 }
463
464 break;
465 case ir_binop_mul:
466 /* Check for equal types, or unequal types involving scalars */
467 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
468 || op0_scalar || op1_scalar) {
469 for (unsigned c = 0, c0 = 0, c1 = 0;
470 c < components;
471 c0 += c0_inc, c1 += c1_inc, c++) {
472
473 switch (op[0]->type->base_type) {
474 case GLSL_TYPE_UINT:
475 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
476 break;
477 case GLSL_TYPE_INT:
478 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
479 break;
480 case GLSL_TYPE_FLOAT:
481 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
482 break;
483 default:
484 assert(0);
485 }
486 }
487 } else {
488 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
489
490 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
491 * matrix can be a GLSL vector, either N or P can be 1.
492 *
493 * For vec*mat, the vector is treated as a row vector. This
494 * means the vector is a 1-row x M-column matrix.
495 *
496 * For mat*vec, the vector is treated as a column vector. Since
497 * matrix_columns is 1 for vectors, this just works.
498 */
499 const unsigned n = op[0]->type->is_vector()
500 ? 1 : op[0]->type->vector_elements;
501 const unsigned m = op[1]->type->vector_elements;
502 const unsigned p = op[1]->type->matrix_columns;
503 for (unsigned j = 0; j < p; j++) {
504 for (unsigned i = 0; i < n; i++) {
505 for (unsigned k = 0; k < m; k++) {
506 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
507 }
508 }
509 }
510 }
511
512 break;
513 case ir_binop_div:
514 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
515 for (unsigned c = 0, c0 = 0, c1 = 0;
516 c < components;
517 c0 += c0_inc, c1 += c1_inc, c++) {
518
519 switch (op[0]->type->base_type) {
520 case GLSL_TYPE_UINT:
521 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
522 break;
523 case GLSL_TYPE_INT:
524 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
525 break;
526 case GLSL_TYPE_FLOAT:
527 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
528 break;
529 default:
530 assert(0);
531 }
532 }
533
534 break;
535 case ir_binop_mod:
536 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
537 for (unsigned c = 0, c0 = 0, c1 = 0;
538 c < components;
539 c0 += c0_inc, c1 += c1_inc, c++) {
540
541 switch (op[0]->type->base_type) {
542 case GLSL_TYPE_UINT:
543 data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
544 break;
545 case GLSL_TYPE_INT:
546 data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
547 break;
548 case GLSL_TYPE_FLOAT:
549 /* We don't use fmod because it rounds toward zero; GLSL specifies
550 * the use of floor.
551 */
552 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]
553 * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
554 break;
555 default:
556 assert(0);
557 }
558 }
559
560 break;
561
562 case ir_binop_logic_and:
563 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
564 for (unsigned c = 0; c < op[0]->type->components(); c++)
565 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
566 break;
567 case ir_binop_logic_xor:
568 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
569 for (unsigned c = 0; c < op[0]->type->components(); c++)
570 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
571 break;
572 case ir_binop_logic_or:
573 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
574 for (unsigned c = 0; c < op[0]->type->components(); c++)
575 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
576 break;
577
578 case ir_binop_less:
579 assert(op[0]->type == op[1]->type);
580 for (unsigned c = 0; c < op[0]->type->components(); c++) {
581 switch (op[0]->type->base_type) {
582 case GLSL_TYPE_UINT:
583 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
584 break;
585 case GLSL_TYPE_INT:
586 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
587 break;
588 case GLSL_TYPE_FLOAT:
589 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
590 break;
591 default:
592 assert(0);
593 }
594 }
595 break;
596 case ir_binop_greater:
597 assert(op[0]->type == op[1]->type);
598 for (unsigned c = 0; c < op[0]->type->components(); c++) {
599 switch (op[0]->type->base_type) {
600 case GLSL_TYPE_UINT:
601 data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
602 break;
603 case GLSL_TYPE_INT:
604 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
605 break;
606 case GLSL_TYPE_FLOAT:
607 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
608 break;
609 default:
610 assert(0);
611 }
612 }
613 break;
614 case ir_binop_lequal:
615 assert(op[0]->type == op[1]->type);
616 for (unsigned c = 0; c < op[0]->type->components(); c++) {
617 switch (op[0]->type->base_type) {
618 case GLSL_TYPE_UINT:
619 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
620 break;
621 case GLSL_TYPE_INT:
622 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
623 break;
624 case GLSL_TYPE_FLOAT:
625 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
626 break;
627 default:
628 assert(0);
629 }
630 }
631 break;
632 case ir_binop_gequal:
633 assert(op[0]->type == op[1]->type);
634 for (unsigned c = 0; c < op[0]->type->components(); c++) {
635 switch (op[0]->type->base_type) {
636 case GLSL_TYPE_UINT:
637 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
638 break;
639 case GLSL_TYPE_INT:
640 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
641 break;
642 case GLSL_TYPE_FLOAT:
643 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
644 break;
645 default:
646 assert(0);
647 }
648 }
649 break;
650 case ir_binop_equal:
651 assert(op[0]->type == op[1]->type);
652 for (unsigned c = 0; c < components; c++) {
653 switch (op[0]->type->base_type) {
654 case GLSL_TYPE_UINT:
655 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
656 break;
657 case GLSL_TYPE_INT:
658 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
659 break;
660 case GLSL_TYPE_FLOAT:
661 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
662 break;
663 default:
664 assert(0);
665 }
666 }
667 break;
668 case ir_binop_nequal:
669 assert(op[0]->type != op[1]->type);
670 for (unsigned c = 0; c < components; c++) {
671 switch (op[0]->type->base_type) {
672 case GLSL_TYPE_UINT:
673 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
674 break;
675 case GLSL_TYPE_INT:
676 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
677 break;
678 case GLSL_TYPE_FLOAT:
679 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
680 break;
681 default:
682 assert(0);
683 }
684 }
685 break;
686 case ir_binop_all_equal:
687 data.b[0] = op[0]->has_value(op[1]);
688 break;
689 case ir_binop_any_nequal:
690 data.b[0] = !op[0]->has_value(op[1]);
691 break;
692
693 case ir_binop_lshift:
694 for (unsigned c = 0, c0 = 0, c1 = 0;
695 c < components;
696 c0 += c0_inc, c1 += c1_inc, c++) {
697
698 if (op[0]->type->base_type == GLSL_TYPE_INT &&
699 op[1]->type->base_type == GLSL_TYPE_INT) {
700 data.i[c] = op[0]->value.i[c0] << op[1]->value.i[c1];
701
702 } else if (op[0]->type->base_type == GLSL_TYPE_INT &&
703 op[1]->type->base_type == GLSL_TYPE_UINT) {
704 data.i[c] = op[0]->value.i[c0] << op[1]->value.u[c1];
705
706 } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
707 op[1]->type->base_type == GLSL_TYPE_INT) {
708 data.u[c] = op[0]->value.u[c0] << op[1]->value.i[c1];
709
710 } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
711 op[1]->type->base_type == GLSL_TYPE_UINT) {
712 data.u[c] = op[0]->value.u[c0] << op[1]->value.u[c1];
713 }
714 }
715 break;
716
717 case ir_binop_rshift:
718 for (unsigned c = 0, c0 = 0, c1 = 0;
719 c < components;
720 c0 += c0_inc, c1 += c1_inc, c++) {
721
722 if (op[0]->type->base_type == GLSL_TYPE_INT &&
723 op[1]->type->base_type == GLSL_TYPE_INT) {
724 data.i[c] = op[0]->value.i[c0] >> op[1]->value.i[c1];
725
726 } else if (op[0]->type->base_type == GLSL_TYPE_INT &&
727 op[1]->type->base_type == GLSL_TYPE_UINT) {
728 data.i[c] = op[0]->value.i[c0] >> op[1]->value.u[c1];
729
730 } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
731 op[1]->type->base_type == GLSL_TYPE_INT) {
732 data.u[c] = op[0]->value.u[c0] >> op[1]->value.i[c1];
733
734 } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
735 op[1]->type->base_type == GLSL_TYPE_UINT) {
736 data.u[c] = op[0]->value.u[c0] >> op[1]->value.u[c1];
737 }
738 }
739 break;
740
741 case ir_binop_bit_and:
742 for (unsigned c = 0, c0 = 0, c1 = 0;
743 c < components;
744 c0 += c0_inc, c1 += c1_inc, c++) {
745
746 switch (op[0]->type->base_type) {
747 case GLSL_TYPE_INT:
748 data.i[c] = op[0]->value.i[c0] & op[1]->value.i[c1];
749 break;
750 case GLSL_TYPE_UINT:
751 data.u[c] = op[0]->value.u[c0] & op[1]->value.u[c1];
752 break;
753 default:
754 assert(0);
755 }
756 }
757 break;
758
759 case ir_binop_bit_or:
760 for (unsigned c = 0, c0 = 0, c1 = 0;
761 c < components;
762 c0 += c0_inc, c1 += c1_inc, c++) {
763
764 switch (op[0]->type->base_type) {
765 case GLSL_TYPE_INT:
766 data.i[c] = op[0]->value.i[c0] | op[1]->value.i[c1];
767 break;
768 case GLSL_TYPE_UINT:
769 data.u[c] = op[0]->value.u[c0] | op[1]->value.u[c1];
770 break;
771 default:
772 assert(0);
773 }
774 }
775 break;
776
777 case ir_binop_bit_xor:
778 for (unsigned c = 0, c0 = 0, c1 = 0;
779 c < components;
780 c0 += c0_inc, c1 += c1_inc, c++) {
781
782 switch (op[0]->type->base_type) {
783 case GLSL_TYPE_INT:
784 data.i[c] = op[0]->value.i[c0] ^ op[1]->value.i[c1];
785 break;
786 case GLSL_TYPE_UINT:
787 data.u[c] = op[0]->value.u[c0] ^ op[1]->value.u[c1];
788 break;
789 default:
790 assert(0);
791 }
792 }
793 break;
794
795 case ir_quadop_vector:
796 for (unsigned c = 0; c < this->type->vector_elements; c++) {
797 switch (this->type->base_type) {
798 case GLSL_TYPE_INT:
799 data.i[c] = op[c]->value.i[0];
800 break;
801 case GLSL_TYPE_UINT:
802 data.u[c] = op[c]->value.u[0];
803 break;
804 case GLSL_TYPE_FLOAT:
805 data.f[c] = op[c]->value.f[0];
806 break;
807 default:
808 assert(0);
809 }
810 }
811 break;
812
813 default:
814 /* FINISHME: Should handle all expression types. */
815 return NULL;
816 }
817
818 return new(ctx) ir_constant(this->type, &data);
819 }
820
821
822 ir_constant *
823 ir_texture::constant_expression_value()
824 {
825 /* texture lookups aren't constant expressions */
826 return NULL;
827 }
828
829
830 ir_constant *
831 ir_swizzle::constant_expression_value()
832 {
833 ir_constant *v = this->val->constant_expression_value();
834
835 if (v != NULL) {
836 ir_constant_data data = { { 0 } };
837
838 const unsigned swiz_idx[4] = {
839 this->mask.x, this->mask.y, this->mask.z, this->mask.w
840 };
841
842 for (unsigned i = 0; i < this->mask.num_components; i++) {
843 switch (v->type->base_type) {
844 case GLSL_TYPE_UINT:
845 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
846 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
847 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
848 default: assert(!"Should not get here."); break;
849 }
850 }
851
852 void *ctx = ralloc_parent(this);
853 return new(ctx) ir_constant(this->type, &data);
854 }
855 return NULL;
856 }
857
858
859 ir_constant *
860 ir_dereference_variable::constant_expression_value()
861 {
862 /* This may occur during compile and var->type is glsl_type::error_type */
863 if (!var)
864 return NULL;
865
866 /* The constant_value of a uniform variable is its initializer,
867 * not the lifetime constant value of the uniform.
868 */
869 if (var->mode == ir_var_uniform)
870 return NULL;
871
872 if (!var->constant_value)
873 return NULL;
874
875 return var->constant_value->clone(ralloc_parent(var), NULL);
876 }
877
878
879 ir_constant *
880 ir_dereference_array::constant_expression_value()
881 {
882 ir_constant *array = this->array->constant_expression_value();
883 ir_constant *idx = this->array_index->constant_expression_value();
884
885 if ((array != NULL) && (idx != NULL)) {
886 void *ctx = ralloc_parent(this);
887 if (array->type->is_matrix()) {
888 /* Array access of a matrix results in a vector.
889 */
890 const unsigned column = idx->value.u[0];
891
892 const glsl_type *const column_type = array->type->column_type();
893
894 /* Offset in the constant matrix to the first element of the column
895 * to be extracted.
896 */
897 const unsigned mat_idx = column * column_type->vector_elements;
898
899 ir_constant_data data = { { 0 } };
900
901 switch (column_type->base_type) {
902 case GLSL_TYPE_UINT:
903 case GLSL_TYPE_INT:
904 for (unsigned i = 0; i < column_type->vector_elements; i++)
905 data.u[i] = array->value.u[mat_idx + i];
906
907 break;
908
909 case GLSL_TYPE_FLOAT:
910 for (unsigned i = 0; i < column_type->vector_elements; i++)
911 data.f[i] = array->value.f[mat_idx + i];
912
913 break;
914
915 default:
916 assert(!"Should not get here.");
917 break;
918 }
919
920 return new(ctx) ir_constant(column_type, &data);
921 } else if (array->type->is_vector()) {
922 const unsigned component = idx->value.u[0];
923
924 return new(ctx) ir_constant(array, component);
925 } else {
926 const unsigned index = idx->value.u[0];
927 return array->get_array_element(index)->clone(ctx, NULL);
928 }
929 }
930 return NULL;
931 }
932
933
934 ir_constant *
935 ir_dereference_record::constant_expression_value()
936 {
937 ir_constant *v = this->record->constant_expression_value();
938
939 return (v != NULL) ? v->get_record_field(this->field) : NULL;
940 }
941
942
943 ir_constant *
944 ir_assignment::constant_expression_value()
945 {
946 /* FINISHME: Handle CEs involving assignment (return RHS) */
947 return NULL;
948 }
949
950
951 ir_constant *
952 ir_constant::constant_expression_value()
953 {
954 return this;
955 }
956
957
958 ir_constant *
959 ir_call::constant_expression_value()
960 {
961 if (this->type == glsl_type::error_type)
962 return NULL;
963
964 /* From the GLSL 1.20 spec, page 23:
965 * "Function calls to user-defined functions (non-built-in functions)
966 * cannot be used to form constant expressions."
967 */
968 if (!this->callee->is_builtin)
969 return NULL;
970
971 unsigned num_parameters = 0;
972
973 /* Check if all parameters are constant */
974 ir_constant *op[3];
975 foreach_list(n, &this->actual_parameters) {
976 ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value();
977 if (constant == NULL)
978 return NULL;
979
980 op[num_parameters] = constant;
981
982 assert(num_parameters < 3);
983 num_parameters++;
984 }
985
986 /* Individual cases below can either:
987 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
988 * - Fill "data" with appopriate constant data
989 * - Return an ir_constant directly.
990 */
991 void *mem_ctx = ralloc_parent(this);
992 ir_expression *expr = NULL;
993
994 ir_constant_data data;
995 memset(&data, 0, sizeof(data));
996
997 const char *callee = this->callee_name();
998 if (strcmp(callee, "abs") == 0) {
999 expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL);
1000 } else if (strcmp(callee, "all") == 0) {
1001 assert(op[0]->type->is_boolean());
1002 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1003 if (!op[0]->value.b[c])
1004 return new(mem_ctx) ir_constant(false);
1005 }
1006 return new(mem_ctx) ir_constant(true);
1007 } else if (strcmp(callee, "any") == 0) {
1008 assert(op[0]->type->is_boolean());
1009 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1010 if (op[0]->value.b[c])
1011 return new(mem_ctx) ir_constant(true);
1012 }
1013 return new(mem_ctx) ir_constant(false);
1014 } else if (strcmp(callee, "acos") == 0) {
1015 assert(op[0]->type->is_float());
1016 for (unsigned c = 0; c < op[0]->type->components(); c++)
1017 data.f[c] = acosf(op[0]->value.f[c]);
1018 } else if (strcmp(callee, "acosh") == 0) {
1019 assert(op[0]->type->is_float());
1020 for (unsigned c = 0; c < op[0]->type->components(); c++)
1021 data.f[c] = acoshf(op[0]->value.f[c]);
1022 } else if (strcmp(callee, "asin") == 0) {
1023 assert(op[0]->type->is_float());
1024 for (unsigned c = 0; c < op[0]->type->components(); c++)
1025 data.f[c] = asinf(op[0]->value.f[c]);
1026 } else if (strcmp(callee, "asinh") == 0) {
1027 assert(op[0]->type->is_float());
1028 for (unsigned c = 0; c < op[0]->type->components(); c++)
1029 data.f[c] = asinhf(op[0]->value.f[c]);
1030 } else if (strcmp(callee, "atan") == 0) {
1031 assert(op[0]->type->is_float());
1032 if (num_parameters == 2) {
1033 assert(op[1]->type->is_float());
1034 for (unsigned c = 0; c < op[0]->type->components(); c++)
1035 data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]);
1036 } else {
1037 for (unsigned c = 0; c < op[0]->type->components(); c++)
1038 data.f[c] = atanf(op[0]->value.f[c]);
1039 }
1040 } else if (strcmp(callee, "atanh") == 0) {
1041 assert(op[0]->type->is_float());
1042 for (unsigned c = 0; c < op[0]->type->components(); c++)
1043 data.f[c] = atanhf(op[0]->value.f[c]);
1044 } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) {
1045 return ir_constant::zero(mem_ctx, this->type);
1046 } else if (strcmp(callee, "ceil") == 0) {
1047 expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL);
1048 } else if (strcmp(callee, "clamp") == 0) {
1049 assert(num_parameters == 3);
1050 unsigned c1_inc = op[1]->type->is_scalar() ? 0 : 1;
1051 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
1052 for (unsigned c = 0, c1 = 0, c2 = 0;
1053 c < op[0]->type->components();
1054 c1 += c1_inc, c2 += c2_inc, c++) {
1055
1056 switch (op[0]->type->base_type) {
1057 case GLSL_TYPE_UINT:
1058 data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1],
1059 op[2]->value.u[c2]);
1060 break;
1061 case GLSL_TYPE_INT:
1062 data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1],
1063 op[2]->value.i[c2]);
1064 break;
1065 case GLSL_TYPE_FLOAT:
1066 data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1],
1067 op[2]->value.f[c2]);
1068 break;
1069 default:
1070 assert(!"Should not get here.");
1071 }
1072 }
1073 } else if (strcmp(callee, "cos") == 0) {
1074 expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL);
1075 } else if (strcmp(callee, "cosh") == 0) {
1076 assert(op[0]->type->is_float());
1077 for (unsigned c = 0; c < op[0]->type->components(); c++)
1078 data.f[c] = coshf(op[0]->value.f[c]);
1079 } else if (strcmp(callee, "cross") == 0) {
1080 assert(op[0]->type == glsl_type::vec3_type);
1081 assert(op[1]->type == glsl_type::vec3_type);
1082 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
1083 op[1]->value.f[1] * op[0]->value.f[2]);
1084 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
1085 op[1]->value.f[2] * op[0]->value.f[0]);
1086 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
1087 op[1]->value.f[0] * op[0]->value.f[1]);
1088 } else if (strcmp(callee, "degrees") == 0) {
1089 assert(op[0]->type->is_float());
1090 for (unsigned c = 0; c < op[0]->type->components(); c++)
1091 data.f[c] = 180.0F / M_PI * op[0]->value.f[c];
1092 } else if (strcmp(callee, "distance") == 0) {
1093 assert(op[0]->type->is_float() && op[1]->type->is_float());
1094 float length_squared = 0.0;
1095 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1096 float t = op[0]->value.f[c] - op[1]->value.f[c];
1097 length_squared += t * t;
1098 }
1099 return new(mem_ctx) ir_constant(sqrtf(length_squared));
1100 } else if (strcmp(callee, "dot") == 0) {
1101 return new(mem_ctx) ir_constant(dot(op[0], op[1]));
1102 } else if (strcmp(callee, "equal") == 0) {
1103 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1104 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1105 switch (op[0]->type->base_type) {
1106 case GLSL_TYPE_UINT:
1107 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
1108 break;
1109 case GLSL_TYPE_INT:
1110 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
1111 break;
1112 case GLSL_TYPE_FLOAT:
1113 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
1114 break;
1115 case GLSL_TYPE_BOOL:
1116 data.b[c] = op[0]->value.b[c] == op[1]->value.b[c];
1117 break;
1118 default:
1119 assert(!"Should not get here.");
1120 }
1121 }
1122 } else if (strcmp(callee, "exp") == 0) {
1123 expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL);
1124 } else if (strcmp(callee, "exp2") == 0) {
1125 expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL);
1126 } else if (strcmp(callee, "faceforward") == 0) {
1127 if (dot(op[2], op[1]) < 0)
1128 return op[0];
1129 for (unsigned c = 0; c < op[0]->type->components(); c++)
1130 data.f[c] = -op[0]->value.f[c];
1131 } else if (strcmp(callee, "floor") == 0) {
1132 expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL);
1133 } else if (strcmp(callee, "fract") == 0) {
1134 expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL);
1135 } else if (strcmp(callee, "fwidth") == 0) {
1136 return ir_constant::zero(mem_ctx, this->type);
1137 } else if (strcmp(callee, "greaterThan") == 0) {
1138 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1139 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1140 switch (op[0]->type->base_type) {
1141 case GLSL_TYPE_UINT:
1142 data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
1143 break;
1144 case GLSL_TYPE_INT:
1145 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
1146 break;
1147 case GLSL_TYPE_FLOAT:
1148 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
1149 break;
1150 default:
1151 assert(!"Should not get here.");
1152 }
1153 }
1154 } else if (strcmp(callee, "greaterThanEqual") == 0) {
1155 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1156 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1157 switch (op[0]->type->base_type) {
1158 case GLSL_TYPE_UINT:
1159 data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c];
1160 break;
1161 case GLSL_TYPE_INT:
1162 data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c];
1163 break;
1164 case GLSL_TYPE_FLOAT:
1165 data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c];
1166 break;
1167 default:
1168 assert(!"Should not get here.");
1169 }
1170 }
1171 } else if (strcmp(callee, "inversesqrt") == 0) {
1172 expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL);
1173 } else if (strcmp(callee, "length") == 0) {
1174 return new(mem_ctx) ir_constant(sqrtf(dot(op[0], op[0])));
1175 } else if (strcmp(callee, "lessThan") == 0) {
1176 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1177 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1178 switch (op[0]->type->base_type) {
1179 case GLSL_TYPE_UINT:
1180 data.b[c] = op[0]->value.u[c] < op[1]->value.u[c];
1181 break;
1182 case GLSL_TYPE_INT:
1183 data.b[c] = op[0]->value.i[c] < op[1]->value.i[c];
1184 break;
1185 case GLSL_TYPE_FLOAT:
1186 data.b[c] = op[0]->value.f[c] < op[1]->value.f[c];
1187 break;
1188 default:
1189 assert(!"Should not get here.");
1190 }
1191 }
1192 } else if (strcmp(callee, "lessThanEqual") == 0) {
1193 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1194 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1195 switch (op[0]->type->base_type) {
1196 case GLSL_TYPE_UINT:
1197 data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c];
1198 break;
1199 case GLSL_TYPE_INT:
1200 data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c];
1201 break;
1202 case GLSL_TYPE_FLOAT:
1203 data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c];
1204 break;
1205 default:
1206 assert(!"Should not get here.");
1207 }
1208 }
1209 } else if (strcmp(callee, "log") == 0) {
1210 expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL);
1211 } else if (strcmp(callee, "log2") == 0) {
1212 expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL);
1213 } else if (strcmp(callee, "matrixCompMult") == 0) {
1214 assert(op[0]->type->is_float() && op[1]->type->is_float());
1215 for (unsigned c = 0; c < op[0]->type->components(); c++)
1216 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
1217 } else if (strcmp(callee, "max") == 0) {
1218 expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]);
1219 } else if (strcmp(callee, "min") == 0) {
1220 expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]);
1221 } else if (strcmp(callee, "mix") == 0) {
1222 assert(op[0]->type->is_float() && op[1]->type->is_float());
1223 if (op[2]->type->is_float()) {
1224 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
1225 unsigned components = op[0]->type->components();
1226 for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) {
1227 data.f[c] = op[0]->value.f[c] * (1 - op[2]->value.f[c2]) +
1228 op[1]->value.f[c] * op[2]->value.f[c2];
1229 }
1230 } else {
1231 assert(op[2]->type->is_boolean());
1232 for (unsigned c = 0; c < op[0]->type->components(); c++)
1233 data.f[c] = op[op[2]->value.b[c] ? 1 : 0]->value.f[c];
1234 }
1235 } else if (strcmp(callee, "mod") == 0) {
1236 expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]);
1237 } else if (strcmp(callee, "normalize") == 0) {
1238 assert(op[0]->type->is_float());
1239 float length = sqrtf(dot(op[0], op[0]));
1240
1241 if (length == 0)
1242 return ir_constant::zero(mem_ctx, this->type);
1243
1244 for (unsigned c = 0; c < op[0]->type->components(); c++)
1245 data.f[c] = op[0]->value.f[c] / length;
1246 } else if (strcmp(callee, "not") == 0) {
1247 expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL);
1248 } else if (strcmp(callee, "notEqual") == 0) {
1249 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1250 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1251 switch (op[0]->type->base_type) {
1252 case GLSL_TYPE_UINT:
1253 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
1254 break;
1255 case GLSL_TYPE_INT:
1256 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
1257 break;
1258 case GLSL_TYPE_FLOAT:
1259 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
1260 break;
1261 case GLSL_TYPE_BOOL:
1262 data.b[c] = op[0]->value.b[c] != op[1]->value.b[c];
1263 break;
1264 default:
1265 assert(!"Should not get here.");
1266 }
1267 }
1268 } else if (strcmp(callee, "outerProduct") == 0) {
1269 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
1270 const unsigned m = op[0]->type->vector_elements;
1271 const unsigned n = op[1]->type->vector_elements;
1272 for (unsigned j = 0; j < n; j++) {
1273 for (unsigned i = 0; i < m; i++) {
1274 data.f[i+m*j] = op[0]->value.f[i] * op[1]->value.f[j];
1275 }
1276 }
1277 } else if (strcmp(callee, "pow") == 0) {
1278 expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]);
1279 } else if (strcmp(callee, "radians") == 0) {
1280 assert(op[0]->type->is_float());
1281 for (unsigned c = 0; c < op[0]->type->components(); c++)
1282 data.f[c] = M_PI / 180.0F * op[0]->value.f[c];
1283 } else if (strcmp(callee, "reflect") == 0) {
1284 assert(op[0]->type->is_float());
1285 float dot_NI = dot(op[1], op[0]);
1286 for (unsigned c = 0; c < op[0]->type->components(); c++)
1287 data.f[c] = op[0]->value.f[c] - 2 * dot_NI * op[1]->value.f[c];
1288 } else if (strcmp(callee, "refract") == 0) {
1289 const float eta = op[2]->value.f[0];
1290 const float dot_NI = dot(op[1], op[0]);
1291 const float k = 1.0F - eta * eta * (1.0F - dot_NI * dot_NI);
1292 if (k < 0.0) {
1293 return ir_constant::zero(mem_ctx, this->type);
1294 } else {
1295 for (unsigned c = 0; c < type->components(); c++) {
1296 data.f[c] = eta * op[0]->value.f[c] - (eta * dot_NI + sqrtf(k))
1297 * op[1]->value.f[c];
1298 }
1299 }
1300 } else if (strcmp(callee, "sign") == 0) {
1301 expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
1302 } else if (strcmp(callee, "sin") == 0) {
1303 expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL);
1304 } else if (strcmp(callee, "sinh") == 0) {
1305 assert(op[0]->type->is_float());
1306 for (unsigned c = 0; c < op[0]->type->components(); c++)
1307 data.f[c] = sinhf(op[0]->value.f[c]);
1308 } else if (strcmp(callee, "smoothstep") == 0) {
1309 assert(num_parameters == 3);
1310 assert(op[1]->type == op[0]->type);
1311 unsigned edge_inc = op[0]->type->is_scalar() ? 0 : 1;
1312 for (unsigned c = 0, e = 0; c < type->components(); e += edge_inc, c++) {
1313 const float edge0 = op[0]->value.f[e];
1314 const float edge1 = op[1]->value.f[e];
1315 if (edge0 == edge1) {
1316 data.f[c] = 0.0; /* Avoid a crash - results are undefined anyway */
1317 } else {
1318 const float numerator = op[2]->value.f[c] - edge0;
1319 const float denominator = edge1 - edge0;
1320 const float t = CLAMP(numerator/denominator, 0, 1);
1321 data.f[c] = t * t * (3 - 2 * t);
1322 }
1323 }
1324 } else if (strcmp(callee, "sqrt") == 0) {
1325 expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL);
1326 } else if (strcmp(callee, "step") == 0) {
1327 assert(op[0]->type->is_float() && op[1]->type->is_float());
1328 /* op[0] (edge) may be either a scalar or a vector */
1329 const unsigned c0_inc = op[0]->type->is_scalar() ? 0 : 1;
1330 for (unsigned c = 0, c0 = 0; c < type->components(); c0 += c0_inc, c++)
1331 data.f[c] = (op[1]->value.f[c] < op[0]->value.f[c0]) ? 0.0F : 1.0F;
1332 } else if (strcmp(callee, "tan") == 0) {
1333 assert(op[0]->type->is_float());
1334 for (unsigned c = 0; c < op[0]->type->components(); c++)
1335 data.f[c] = tanf(op[0]->value.f[c]);
1336 } else if (strcmp(callee, "tanh") == 0) {
1337 assert(op[0]->type->is_float());
1338 for (unsigned c = 0; c < op[0]->type->components(); c++)
1339 data.f[c] = tanhf(op[0]->value.f[c]);
1340 } else if (strcmp(callee, "transpose") == 0) {
1341 assert(op[0]->type->is_matrix());
1342 const unsigned n = op[0]->type->vector_elements;
1343 const unsigned m = op[0]->type->matrix_columns;
1344 for (unsigned j = 0; j < m; j++) {
1345 for (unsigned i = 0; i < n; i++) {
1346 data.f[m*i+j] += op[0]->value.f[i+n*j];
1347 }
1348 }
1349 } else {
1350 /* Unsupported builtin - some are not allowed in constant expressions. */
1351 return NULL;
1352 }
1353
1354 if (expr != NULL)
1355 return expr->constant_expression_value();
1356
1357 return new(mem_ctx) ir_constant(this->type, &data);
1358 }