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