4fd6d09a3afbf6dc7191a4bc106c984481d8d69e
[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 = 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 case ir_quadop_vector:
792 for (unsigned c = 0; c < this->type->vector_elements; c++) {
793 switch (this->type->base_type) {
794 case GLSL_TYPE_INT:
795 data.i[c] = op[c]->value.i[0];
796 break;
797 case GLSL_TYPE_UINT:
798 data.u[c] = op[c]->value.u[0];
799 break;
800 case GLSL_TYPE_FLOAT:
801 data.f[c] = op[c]->value.f[0];
802 break;
803 default:
804 assert(0);
805 }
806 }
807 break;
808
809 default:
810 /* FINISHME: Should handle all expression types. */
811 return NULL;
812 }
813
814 return new(ctx) ir_constant(this->type, &data);
815 }
816
817
818 ir_constant *
819 ir_texture::constant_expression_value()
820 {
821 /* texture lookups aren't constant expressions */
822 return NULL;
823 }
824
825
826 ir_constant *
827 ir_swizzle::constant_expression_value()
828 {
829 ir_constant *v = this->val->constant_expression_value();
830
831 if (v != NULL) {
832 ir_constant_data data = { { 0 } };
833
834 const unsigned swiz_idx[4] = {
835 this->mask.x, this->mask.y, this->mask.z, this->mask.w
836 };
837
838 for (unsigned i = 0; i < this->mask.num_components; i++) {
839 switch (v->type->base_type) {
840 case GLSL_TYPE_UINT:
841 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
842 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
843 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
844 default: assert(!"Should not get here."); break;
845 }
846 }
847
848 void *ctx = talloc_parent(this);
849 return new(ctx) ir_constant(this->type, &data);
850 }
851 return NULL;
852 }
853
854
855 ir_constant *
856 ir_dereference_variable::constant_expression_value()
857 {
858 /* This may occur during compile and var->type is glsl_type::error_type */
859 if (!var)
860 return NULL;
861
862 /* The constant_value of a uniform variable is its initializer,
863 * not the lifetime constant value of the uniform.
864 */
865 if (var->mode == ir_var_uniform)
866 return NULL;
867
868 if (!var->constant_value)
869 return NULL;
870
871 return var->constant_value->clone(talloc_parent(var), NULL);
872 }
873
874
875 ir_constant *
876 ir_dereference_array::constant_expression_value()
877 {
878 ir_constant *array = this->array->constant_expression_value();
879 ir_constant *idx = this->array_index->constant_expression_value();
880
881 if ((array != NULL) && (idx != NULL)) {
882 void *ctx = talloc_parent(this);
883 if (array->type->is_matrix()) {
884 /* Array access of a matrix results in a vector.
885 */
886 const unsigned column = idx->value.u[0];
887
888 const glsl_type *const column_type = array->type->column_type();
889
890 /* Offset in the constant matrix to the first element of the column
891 * to be extracted.
892 */
893 const unsigned mat_idx = column * column_type->vector_elements;
894
895 ir_constant_data data = { { 0 } };
896
897 switch (column_type->base_type) {
898 case GLSL_TYPE_UINT:
899 case GLSL_TYPE_INT:
900 for (unsigned i = 0; i < column_type->vector_elements; i++)
901 data.u[i] = array->value.u[mat_idx + i];
902
903 break;
904
905 case GLSL_TYPE_FLOAT:
906 for (unsigned i = 0; i < column_type->vector_elements; i++)
907 data.f[i] = array->value.f[mat_idx + i];
908
909 break;
910
911 default:
912 assert(!"Should not get here.");
913 break;
914 }
915
916 return new(ctx) ir_constant(column_type, &data);
917 } else if (array->type->is_vector()) {
918 const unsigned component = idx->value.u[0];
919
920 return new(ctx) ir_constant(array, component);
921 } else {
922 const unsigned index = idx->value.u[0];
923 return array->get_array_element(index)->clone(ctx, NULL);
924 }
925 }
926 return NULL;
927 }
928
929
930 ir_constant *
931 ir_dereference_record::constant_expression_value()
932 {
933 ir_constant *v = this->record->constant_expression_value();
934
935 return (v != NULL) ? v->get_record_field(this->field) : NULL;
936 }
937
938
939 ir_constant *
940 ir_assignment::constant_expression_value()
941 {
942 /* FINISHME: Handle CEs involving assignment (return RHS) */
943 return NULL;
944 }
945
946
947 ir_constant *
948 ir_constant::constant_expression_value()
949 {
950 return this;
951 }
952
953
954 ir_constant *
955 ir_call::constant_expression_value()
956 {
957 if (this->type == glsl_type::error_type)
958 return NULL;
959
960 /* From the GLSL 1.20 spec, page 23:
961 * "Function calls to user-defined functions (non-built-in functions)
962 * cannot be used to form constant expressions."
963 */
964 if (!this->callee->is_builtin)
965 return NULL;
966
967 unsigned num_parameters = 0;
968
969 /* Check if all parameters are constant */
970 ir_constant *op[3];
971 foreach_list(n, &this->actual_parameters) {
972 ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value();
973 if (constant == NULL)
974 return NULL;
975
976 op[num_parameters] = constant;
977
978 assert(num_parameters < 3);
979 num_parameters++;
980 }
981
982 /* Individual cases below can either:
983 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
984 * - Fill "data" with appopriate constant data
985 * - Return an ir_constant directly.
986 */
987 void *mem_ctx = talloc_parent(this);
988 ir_expression *expr = NULL;
989
990 ir_constant_data data;
991 memset(&data, 0, sizeof(data));
992
993 const char *callee = this->callee_name();
994 if (strcmp(callee, "abs") == 0) {
995 expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL);
996 } else if (strcmp(callee, "all") == 0) {
997 assert(op[0]->type->is_boolean());
998 for (unsigned c = 0; c < op[0]->type->components(); c++) {
999 if (!op[0]->value.b[c])
1000 return new(mem_ctx) ir_constant(false);
1001 }
1002 return new(mem_ctx) ir_constant(true);
1003 } else if (strcmp(callee, "any") == 0) {
1004 assert(op[0]->type->is_boolean());
1005 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1006 if (op[0]->value.b[c])
1007 return new(mem_ctx) ir_constant(true);
1008 }
1009 return new(mem_ctx) ir_constant(false);
1010 } else if (strcmp(callee, "acos") == 0) {
1011 assert(op[0]->type->is_float());
1012 for (unsigned c = 0; c < op[0]->type->components(); c++)
1013 data.f[c] = acosf(op[0]->value.f[c]);
1014 } else if (strcmp(callee, "acosh") == 0) {
1015 assert(op[0]->type->is_float());
1016 for (unsigned c = 0; c < op[0]->type->components(); c++)
1017 data.f[c] = acoshf(op[0]->value.f[c]);
1018 } else if (strcmp(callee, "asin") == 0) {
1019 assert(op[0]->type->is_float());
1020 for (unsigned c = 0; c < op[0]->type->components(); c++)
1021 data.f[c] = asinf(op[0]->value.f[c]);
1022 } else if (strcmp(callee, "asinh") == 0) {
1023 assert(op[0]->type->is_float());
1024 for (unsigned c = 0; c < op[0]->type->components(); c++)
1025 data.f[c] = asinhf(op[0]->value.f[c]);
1026 } else if (strcmp(callee, "atan") == 0) {
1027 assert(op[0]->type->is_float());
1028 if (num_parameters == 2) {
1029 assert(op[1]->type->is_float());
1030 for (unsigned c = 0; c < op[0]->type->components(); c++)
1031 data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]);
1032 } else {
1033 for (unsigned c = 0; c < op[0]->type->components(); c++)
1034 data.f[c] = atanf(op[0]->value.f[c]);
1035 }
1036 } else if (strcmp(callee, "atanh") == 0) {
1037 assert(op[0]->type->is_float());
1038 for (unsigned c = 0; c < op[0]->type->components(); c++)
1039 data.f[c] = atanhf(op[0]->value.f[c]);
1040 } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) {
1041 return ir_constant::zero(mem_ctx, this->type);
1042 } else if (strcmp(callee, "ceil") == 0) {
1043 expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL);
1044 } else if (strcmp(callee, "clamp") == 0) {
1045 assert(num_parameters == 3);
1046 unsigned c1_inc = op[1]->type->is_scalar() ? 0 : 1;
1047 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
1048 for (unsigned c = 0, c1 = 0, c2 = 0;
1049 c < op[0]->type->components();
1050 c1 += c1_inc, c2 += c2_inc, c++) {
1051
1052 switch (op[0]->type->base_type) {
1053 case GLSL_TYPE_UINT:
1054 data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1],
1055 op[2]->value.u[c2]);
1056 break;
1057 case GLSL_TYPE_INT:
1058 data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1],
1059 op[2]->value.i[c2]);
1060 break;
1061 case GLSL_TYPE_FLOAT:
1062 data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1],
1063 op[2]->value.f[c2]);
1064 break;
1065 default:
1066 assert(!"Should not get here.");
1067 }
1068 }
1069 } else if (strcmp(callee, "cos") == 0) {
1070 expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL);
1071 } else if (strcmp(callee, "cosh") == 0) {
1072 assert(op[0]->type->is_float());
1073 for (unsigned c = 0; c < op[0]->type->components(); c++)
1074 data.f[c] = coshf(op[0]->value.f[c]);
1075 } else if (strcmp(callee, "cross") == 0) {
1076 assert(op[0]->type == glsl_type::vec3_type);
1077 assert(op[1]->type == glsl_type::vec3_type);
1078 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
1079 op[1]->value.f[1] * op[0]->value.f[2]);
1080 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
1081 op[1]->value.f[2] * op[0]->value.f[0]);
1082 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
1083 op[1]->value.f[0] * op[0]->value.f[1]);
1084 } else if (strcmp(callee, "degrees") == 0) {
1085 assert(op[0]->type->is_float());
1086 for (unsigned c = 0; c < op[0]->type->components(); c++)
1087 data.f[c] = 180.0F / M_PI * op[0]->value.f[c];
1088 } else if (strcmp(callee, "distance") == 0) {
1089 assert(op[0]->type->is_float() && op[1]->type->is_float());
1090 float length_squared = 0.0;
1091 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1092 float t = op[0]->value.f[c] - op[1]->value.f[c];
1093 length_squared += t * t;
1094 }
1095 return new(mem_ctx) ir_constant(sqrtf(length_squared));
1096 } else if (strcmp(callee, "dot") == 0) {
1097 return new(mem_ctx) ir_constant(dot(op[0], op[1]));
1098 } else if (strcmp(callee, "equal") == 0) {
1099 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1100 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1101 switch (op[0]->type->base_type) {
1102 case GLSL_TYPE_UINT:
1103 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
1104 break;
1105 case GLSL_TYPE_INT:
1106 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
1107 break;
1108 case GLSL_TYPE_FLOAT:
1109 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
1110 break;
1111 case GLSL_TYPE_BOOL:
1112 data.b[c] = op[0]->value.b[c] == op[1]->value.b[c];
1113 break;
1114 default:
1115 assert(!"Should not get here.");
1116 }
1117 }
1118 } else if (strcmp(callee, "exp") == 0) {
1119 expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL);
1120 } else if (strcmp(callee, "exp2") == 0) {
1121 expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL);
1122 } else if (strcmp(callee, "faceforward") == 0) {
1123 if (dot(op[2], op[1]) < 0)
1124 return op[0];
1125 for (unsigned c = 0; c < op[0]->type->components(); c++)
1126 data.f[c] = -op[0]->value.f[c];
1127 } else if (strcmp(callee, "floor") == 0) {
1128 expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL);
1129 } else if (strcmp(callee, "fract") == 0) {
1130 expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL);
1131 } else if (strcmp(callee, "fwidth") == 0) {
1132 return ir_constant::zero(mem_ctx, this->type);
1133 } else if (strcmp(callee, "greaterThan") == 0) {
1134 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1135 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1136 switch (op[0]->type->base_type) {
1137 case GLSL_TYPE_UINT:
1138 data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
1139 break;
1140 case GLSL_TYPE_INT:
1141 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
1142 break;
1143 case GLSL_TYPE_FLOAT:
1144 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
1145 break;
1146 default:
1147 assert(!"Should not get here.");
1148 }
1149 }
1150 } else if (strcmp(callee, "greaterThanEqual") == 0) {
1151 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1152 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1153 switch (op[0]->type->base_type) {
1154 case GLSL_TYPE_UINT:
1155 data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c];
1156 break;
1157 case GLSL_TYPE_INT:
1158 data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c];
1159 break;
1160 case GLSL_TYPE_FLOAT:
1161 data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c];
1162 break;
1163 default:
1164 assert(!"Should not get here.");
1165 }
1166 }
1167 } else if (strcmp(callee, "inversesqrt") == 0) {
1168 expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL);
1169 } else if (strcmp(callee, "length") == 0) {
1170 return new(mem_ctx) ir_constant(sqrtf(dot(op[0], op[0])));
1171 } else if (strcmp(callee, "lessThan") == 0) {
1172 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1173 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1174 switch (op[0]->type->base_type) {
1175 case GLSL_TYPE_UINT:
1176 data.b[c] = op[0]->value.u[c] < op[1]->value.u[c];
1177 break;
1178 case GLSL_TYPE_INT:
1179 data.b[c] = op[0]->value.i[c] < op[1]->value.i[c];
1180 break;
1181 case GLSL_TYPE_FLOAT:
1182 data.b[c] = op[0]->value.f[c] < op[1]->value.f[c];
1183 break;
1184 default:
1185 assert(!"Should not get here.");
1186 }
1187 }
1188 } else if (strcmp(callee, "lessThanEqual") == 0) {
1189 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1190 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1191 switch (op[0]->type->base_type) {
1192 case GLSL_TYPE_UINT:
1193 data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c];
1194 break;
1195 case GLSL_TYPE_INT:
1196 data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c];
1197 break;
1198 case GLSL_TYPE_FLOAT:
1199 data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c];
1200 break;
1201 default:
1202 assert(!"Should not get here.");
1203 }
1204 }
1205 } else if (strcmp(callee, "log") == 0) {
1206 expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL);
1207 } else if (strcmp(callee, "log2") == 0) {
1208 expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL);
1209 } else if (strcmp(callee, "matrixCompMult") == 0) {
1210 assert(op[0]->type->is_float() && op[1]->type->is_float());
1211 for (unsigned c = 0; c < op[0]->type->components(); c++)
1212 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
1213 } else if (strcmp(callee, "max") == 0) {
1214 expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]);
1215 } else if (strcmp(callee, "min") == 0) {
1216 expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]);
1217 } else if (strcmp(callee, "mix") == 0) {
1218 assert(op[0]->type->is_float() && op[1]->type->is_float());
1219 if (op[2]->type->is_float()) {
1220 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
1221 unsigned components = op[0]->type->components();
1222 for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) {
1223 data.f[c] = op[0]->value.f[c] * (1 - op[2]->value.f[c2]) +
1224 op[1]->value.f[c] * op[2]->value.f[c2];
1225 }
1226 } else {
1227 assert(op[2]->type->is_boolean());
1228 for (unsigned c = 0; c < op[0]->type->components(); c++)
1229 data.f[c] = op[op[2]->value.b[c] ? 1 : 0]->value.f[c];
1230 }
1231 } else if (strcmp(callee, "mod") == 0) {
1232 expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]);
1233 } else if (strcmp(callee, "normalize") == 0) {
1234 assert(op[0]->type->is_float());
1235 float length = sqrtf(dot(op[0], op[0]));
1236
1237 if (length == 0)
1238 return ir_constant::zero(mem_ctx, this->type);
1239
1240 for (unsigned c = 0; c < op[0]->type->components(); c++)
1241 data.f[c] = op[0]->value.f[c] / length;
1242 } else if (strcmp(callee, "not") == 0) {
1243 expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL);
1244 } else if (strcmp(callee, "notEqual") == 0) {
1245 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1246 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1247 switch (op[0]->type->base_type) {
1248 case GLSL_TYPE_UINT:
1249 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
1250 break;
1251 case GLSL_TYPE_INT:
1252 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
1253 break;
1254 case GLSL_TYPE_FLOAT:
1255 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
1256 break;
1257 case GLSL_TYPE_BOOL:
1258 data.b[c] = op[0]->value.b[c] != op[1]->value.b[c];
1259 break;
1260 default:
1261 assert(!"Should not get here.");
1262 }
1263 }
1264 } else if (strcmp(callee, "outerProduct") == 0) {
1265 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
1266 const unsigned m = op[0]->type->vector_elements;
1267 const unsigned n = op[1]->type->vector_elements;
1268 for (unsigned j = 0; j < n; j++) {
1269 for (unsigned i = 0; i < m; i++) {
1270 data.f[i+m*j] = op[0]->value.f[i] * op[1]->value.f[j];
1271 }
1272 }
1273 } else if (strcmp(callee, "pow") == 0) {
1274 expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]);
1275 } else if (strcmp(callee, "radians") == 0) {
1276 assert(op[0]->type->is_float());
1277 for (unsigned c = 0; c < op[0]->type->components(); c++)
1278 data.f[c] = M_PI / 180.0F * op[0]->value.f[c];
1279 } else if (strcmp(callee, "reflect") == 0) {
1280 assert(op[0]->type->is_float());
1281 float dot_NI = dot(op[1], op[0]);
1282 for (unsigned c = 0; c < op[0]->type->components(); c++)
1283 data.f[c] = op[0]->value.f[c] - 2 * dot_NI * op[1]->value.f[c];
1284 } else if (strcmp(callee, "refract") == 0) {
1285 const float eta = op[2]->value.f[0];
1286 const float dot_NI = dot(op[1], op[0]);
1287 const float k = 1.0F - eta * eta * (1.0F - dot_NI * dot_NI);
1288 if (k < 0.0) {
1289 return ir_constant::zero(mem_ctx, this->type);
1290 } else {
1291 for (unsigned c = 0; c < type->components(); c++) {
1292 data.f[c] = eta * op[0]->value.f[c] - (eta * dot_NI + sqrtf(k))
1293 * op[1]->value.f[c];
1294 }
1295 }
1296 } else if (strcmp(callee, "sign") == 0) {
1297 expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
1298 } else if (strcmp(callee, "sin") == 0) {
1299 expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL);
1300 } else if (strcmp(callee, "sinh") == 0) {
1301 assert(op[0]->type->is_float());
1302 for (unsigned c = 0; c < op[0]->type->components(); c++)
1303 data.f[c] = sinhf(op[0]->value.f[c]);
1304 } else if (strcmp(callee, "smoothstep") == 0) {
1305 assert(num_parameters == 3);
1306 assert(op[1]->type == op[0]->type);
1307 unsigned edge_inc = op[0]->type->is_scalar() ? 0 : 1;
1308 for (unsigned c = 0, e = 0; c < type->components(); e += edge_inc, c++) {
1309 const float edge0 = op[0]->value.f[e];
1310 const float edge1 = op[1]->value.f[e];
1311 if (edge0 == edge1) {
1312 data.f[c] = 0.0; /* Avoid a crash - results are undefined anyway */
1313 } else {
1314 const float numerator = op[2]->value.f[c] - edge0;
1315 const float denominator = edge1 - edge0;
1316 const float t = CLAMP(numerator/denominator, 0, 1);
1317 data.f[c] = t * t * (3 - 2 * t);
1318 }
1319 }
1320 } else if (strcmp(callee, "sqrt") == 0) {
1321 expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL);
1322 } else if (strcmp(callee, "step") == 0) {
1323 assert(op[0]->type->is_float() && op[1]->type->is_float());
1324 /* op[0] (edge) may be either a scalar or a vector */
1325 const unsigned c0_inc = op[0]->type->is_scalar() ? 0 : 1;
1326 for (unsigned c = 0, c0 = 0; c < type->components(); c0 += c0_inc, c++)
1327 data.f[c] = (op[1]->value.f[c] < op[0]->value.f[c0]) ? 0.0F : 1.0F;
1328 } else if (strcmp(callee, "tan") == 0) {
1329 assert(op[0]->type->is_float());
1330 for (unsigned c = 0; c < op[0]->type->components(); c++)
1331 data.f[c] = tanf(op[0]->value.f[c]);
1332 } else if (strcmp(callee, "tanh") == 0) {
1333 assert(op[0]->type->is_float());
1334 for (unsigned c = 0; c < op[0]->type->components(); c++)
1335 data.f[c] = tanhf(op[0]->value.f[c]);
1336 } else if (strcmp(callee, "transpose") == 0) {
1337 assert(op[0]->type->is_matrix());
1338 const unsigned n = op[0]->type->vector_elements;
1339 const unsigned m = op[0]->type->matrix_columns;
1340 for (unsigned j = 0; j < m; j++) {
1341 for (unsigned i = 0; i < n; i++) {
1342 data.f[m*i+j] += op[0]->value.f[i+n*j];
1343 }
1344 }
1345 } else {
1346 /* Unsupported builtin - some are not allowed in constant expressions. */
1347 return NULL;
1348 }
1349
1350 if (expr != NULL)
1351 return expr->constant_expression_value();
1352
1353 return new(mem_ctx) ir_constant(this->type, &data);
1354 }