grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / libs / mesa / src / glsl / ir_constant_expression.cpp
blob2a3084896569eaecb9ee734ad6698d53cc15661b
1 /*
2 * Copyright © 2010 Intel Corporation
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:
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.
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.
24 /**
25 * \file ir_constant_expression.cpp
26 * Evaluate and process constant valued expressions
28 * In GLSL, constant valued expressions are used in several places. These
29 * must be processed and evaluated very early in the compilation process.
31 * * Sizes of arrays
32 * * Initializers for uniforms
33 * * Initializers for \c const variables
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"
42 static float
43 dot(ir_constant *op0, ir_constant *op1)
45 assert(op0->type->is_float() && op1->type->is_float());
47 float result = 0;
48 for (unsigned c = 0; c < op0->type->components(); c++)
49 result += op0->value.f[c] * op1->value.f[c];
51 return result;
54 ir_constant *
55 ir_expression::constant_expression_value()
57 if (this->type->is_error())
58 return NULL;
60 ir_constant *op[Elements(this->operands)] = { NULL, };
61 ir_constant_data data;
63 memset(&data, 0, sizeof(data));
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;
71 if (op[1] != NULL)
72 assert(op[0]->type->base_type == op[1]->type->base_type);
74 bool op0_scalar = op[0]->type->is_scalar();
75 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
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.
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();
89 void *ctx = ralloc_parent(this);
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;
102 return NULL;
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);
119 break;
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;
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];
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];
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];
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;
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;
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;
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;
168 break;
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;
177 break;
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]);
184 break;
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]);
191 break;
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]);
198 break;
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);
216 break;
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]);
224 break;
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]);
232 break;
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);
250 break;
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);
270 break;
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);
288 break;
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);
310 break;
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]);
317 break;
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]);
324 break;
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]);
331 break;
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]);
338 break;
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]);
345 break;
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]);
352 break;
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;
360 break;
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]);
367 break;
369 case ir_binop_dot:
370 data.f[0] = dot(op[0], op[1]);
371 break;
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++) {
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);
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++) {
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);
415 break;
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++) {
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);
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++) {
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);
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++) {
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);
483 } else {
484 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
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.
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.
492 * For mat*vec, the vector is treated as a column vector. Since
493 * matrix_columns is 1 for vectors, this just works.
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];
508 break;
509 case ir_binop_div:
510 /* FINISHME: Emit warning when division-by-zero is detected. */
511 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
512 for (unsigned c = 0, c0 = 0, c1 = 0;
513 c < components;
514 c0 += c0_inc, c1 += c1_inc, c++) {
516 switch (op[0]->type->base_type) {
517 case GLSL_TYPE_UINT:
518 if (op[1]->value.u[c1] == 0) {
519 data.u[c] = 0;
520 } else {
521 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
523 break;
524 case GLSL_TYPE_INT:
525 if (op[1]->value.i[c1] == 0) {
526 data.i[c] = 0;
527 } else {
528 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);
539 break;
540 case ir_binop_mod:
541 /* FINISHME: Emit warning when division-by-zero is detected. */
542 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
543 for (unsigned c = 0, c0 = 0, c1 = 0;
544 c < components;
545 c0 += c0_inc, c1 += c1_inc, c++) {
547 switch (op[0]->type->base_type) {
548 case GLSL_TYPE_UINT:
549 if (op[1]->value.u[c1] == 0) {
550 data.u[c] = 0;
551 } else {
552 data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
554 break;
555 case GLSL_TYPE_INT:
556 if (op[1]->value.i[c1] == 0) {
557 data.i[c] = 0;
558 } else {
559 data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
561 break;
562 case GLSL_TYPE_FLOAT:
563 /* We don't use fmod because it rounds toward zero; GLSL specifies
564 * the use of floor.
566 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]
567 * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
568 break;
569 default:
570 assert(0);
574 break;
576 case ir_binop_logic_and:
577 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
578 for (unsigned c = 0; c < op[0]->type->components(); c++)
579 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
580 break;
581 case ir_binop_logic_xor:
582 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
583 for (unsigned c = 0; c < op[0]->type->components(); c++)
584 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
585 break;
586 case ir_binop_logic_or:
587 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
588 for (unsigned c = 0; c < op[0]->type->components(); c++)
589 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
590 break;
592 case ir_binop_less:
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[0] = op[0]->value.u[0] < op[1]->value.u[0];
598 break;
599 case GLSL_TYPE_INT:
600 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
601 break;
602 case GLSL_TYPE_FLOAT:
603 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
604 break;
605 default:
606 assert(0);
609 break;
610 case ir_binop_greater:
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[c] = op[0]->value.u[c] > op[1]->value.u[c];
616 break;
617 case GLSL_TYPE_INT:
618 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
619 break;
620 case GLSL_TYPE_FLOAT:
621 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
622 break;
623 default:
624 assert(0);
627 break;
628 case ir_binop_lequal:
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);
645 break;
646 case ir_binop_gequal:
647 assert(op[0]->type == op[1]->type);
648 for (unsigned c = 0; c < op[0]->type->components(); c++) {
649 switch (op[0]->type->base_type) {
650 case GLSL_TYPE_UINT:
651 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
652 break;
653 case GLSL_TYPE_INT:
654 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
655 break;
656 case GLSL_TYPE_FLOAT:
657 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
658 break;
659 default:
660 assert(0);
663 break;
664 case ir_binop_equal:
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);
681 break;
682 case ir_binop_nequal:
683 assert(op[0]->type != op[1]->type);
684 for (unsigned c = 0; c < components; c++) {
685 switch (op[0]->type->base_type) {
686 case GLSL_TYPE_UINT:
687 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
688 break;
689 case GLSL_TYPE_INT:
690 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
691 break;
692 case GLSL_TYPE_FLOAT:
693 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
694 break;
695 default:
696 assert(0);
699 break;
700 case ir_binop_all_equal:
701 data.b[0] = op[0]->has_value(op[1]);
702 break;
703 case ir_binop_any_nequal:
704 data.b[0] = !op[0]->has_value(op[1]);
705 break;
707 case ir_binop_lshift:
708 for (unsigned c = 0, c0 = 0, c1 = 0;
709 c < components;
710 c0 += c0_inc, c1 += c1_inc, c++) {
712 if (op[0]->type->base_type == GLSL_TYPE_INT &&
713 op[1]->type->base_type == GLSL_TYPE_INT) {
714 data.i[c] = op[0]->value.i[c0] << op[1]->value.i[c1];
716 } else if (op[0]->type->base_type == GLSL_TYPE_INT &&
717 op[1]->type->base_type == GLSL_TYPE_UINT) {
718 data.i[c] = op[0]->value.i[c0] << op[1]->value.u[c1];
720 } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
721 op[1]->type->base_type == GLSL_TYPE_INT) {
722 data.u[c] = op[0]->value.u[c0] << op[1]->value.i[c1];
724 } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
725 op[1]->type->base_type == GLSL_TYPE_UINT) {
726 data.u[c] = op[0]->value.u[c0] << op[1]->value.u[c1];
729 break;
731 case ir_binop_rshift:
732 for (unsigned c = 0, c0 = 0, c1 = 0;
733 c < components;
734 c0 += c0_inc, c1 += c1_inc, c++) {
736 if (op[0]->type->base_type == GLSL_TYPE_INT &&
737 op[1]->type->base_type == GLSL_TYPE_INT) {
738 data.i[c] = op[0]->value.i[c0] >> op[1]->value.i[c1];
740 } else if (op[0]->type->base_type == GLSL_TYPE_INT &&
741 op[1]->type->base_type == GLSL_TYPE_UINT) {
742 data.i[c] = op[0]->value.i[c0] >> op[1]->value.u[c1];
744 } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
745 op[1]->type->base_type == GLSL_TYPE_INT) {
746 data.u[c] = op[0]->value.u[c0] >> op[1]->value.i[c1];
748 } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
749 op[1]->type->base_type == GLSL_TYPE_UINT) {
750 data.u[c] = op[0]->value.u[c0] >> op[1]->value.u[c1];
753 break;
755 case ir_binop_bit_and:
756 for (unsigned c = 0, c0 = 0, c1 = 0;
757 c < components;
758 c0 += c0_inc, c1 += c1_inc, c++) {
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);
771 break;
773 case ir_binop_bit_or:
774 for (unsigned c = 0, c0 = 0, c1 = 0;
775 c < components;
776 c0 += c0_inc, c1 += c1_inc, c++) {
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);
789 break;
791 case ir_binop_bit_xor:
792 for (unsigned c = 0, c0 = 0, c1 = 0;
793 c < components;
794 c0 += c0_inc, c1 += c1_inc, c++) {
796 switch (op[0]->type->base_type) {
797 case GLSL_TYPE_INT:
798 data.i[c] = op[0]->value.i[c0] ^ op[1]->value.i[c1];
799 break;
800 case GLSL_TYPE_UINT:
801 data.u[c] = op[0]->value.u[c0] ^ op[1]->value.u[c1];
802 break;
803 default:
804 assert(0);
807 break;
809 case ir_quadop_vector:
810 for (unsigned c = 0; c < this->type->vector_elements; c++) {
811 switch (this->type->base_type) {
812 case GLSL_TYPE_INT:
813 data.i[c] = op[c]->value.i[0];
814 break;
815 case GLSL_TYPE_UINT:
816 data.u[c] = op[c]->value.u[0];
817 break;
818 case GLSL_TYPE_FLOAT:
819 data.f[c] = op[c]->value.f[0];
820 break;
821 default:
822 assert(0);
825 break;
827 default:
828 /* FINISHME: Should handle all expression types. */
829 return NULL;
832 return new(ctx) ir_constant(this->type, &data);
836 ir_constant *
837 ir_texture::constant_expression_value()
839 /* texture lookups aren't constant expressions */
840 return NULL;
844 ir_constant *
845 ir_swizzle::constant_expression_value()
847 ir_constant *v = this->val->constant_expression_value();
849 if (v != NULL) {
850 ir_constant_data data = { { 0 } };
852 const unsigned swiz_idx[4] = {
853 this->mask.x, this->mask.y, this->mask.z, this->mask.w
856 for (unsigned i = 0; i < this->mask.num_components; i++) {
857 switch (v->type->base_type) {
858 case GLSL_TYPE_UINT:
859 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
860 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
861 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
862 default: assert(!"Should not get here."); break;
866 void *ctx = ralloc_parent(this);
867 return new(ctx) ir_constant(this->type, &data);
869 return NULL;
873 ir_constant *
874 ir_dereference_variable::constant_expression_value()
876 /* This may occur during compile and var->type is glsl_type::error_type */
877 if (!var)
878 return NULL;
880 /* The constant_value of a uniform variable is its initializer,
881 * not the lifetime constant value of the uniform.
883 if (var->mode == ir_var_uniform)
884 return NULL;
886 if (!var->constant_value)
887 return NULL;
889 return var->constant_value->clone(ralloc_parent(var), NULL);
893 ir_constant *
894 ir_dereference_array::constant_expression_value()
896 ir_constant *array = this->array->constant_expression_value();
897 ir_constant *idx = this->array_index->constant_expression_value();
899 if ((array != NULL) && (idx != NULL)) {
900 void *ctx = ralloc_parent(this);
901 if (array->type->is_matrix()) {
902 /* Array access of a matrix results in a vector.
904 const unsigned column = idx->value.u[0];
906 const glsl_type *const column_type = array->type->column_type();
908 /* Offset in the constant matrix to the first element of the column
909 * to be extracted.
911 const unsigned mat_idx = column * column_type->vector_elements;
913 ir_constant_data data = { { 0 } };
915 switch (column_type->base_type) {
916 case GLSL_TYPE_UINT:
917 case GLSL_TYPE_INT:
918 for (unsigned i = 0; i < column_type->vector_elements; i++)
919 data.u[i] = array->value.u[mat_idx + i];
921 break;
923 case GLSL_TYPE_FLOAT:
924 for (unsigned i = 0; i < column_type->vector_elements; i++)
925 data.f[i] = array->value.f[mat_idx + i];
927 break;
929 default:
930 assert(!"Should not get here.");
931 break;
934 return new(ctx) ir_constant(column_type, &data);
935 } else if (array->type->is_vector()) {
936 const unsigned component = idx->value.u[0];
938 return new(ctx) ir_constant(array, component);
939 } else {
940 const unsigned index = idx->value.u[0];
941 return array->get_array_element(index)->clone(ctx, NULL);
944 return NULL;
948 ir_constant *
949 ir_dereference_record::constant_expression_value()
951 ir_constant *v = this->record->constant_expression_value();
953 return (v != NULL) ? v->get_record_field(this->field) : NULL;
957 ir_constant *
958 ir_assignment::constant_expression_value()
960 /* FINISHME: Handle CEs involving assignment (return RHS) */
961 return NULL;
965 ir_constant *
966 ir_constant::constant_expression_value()
968 return this;
972 ir_constant *
973 ir_call::constant_expression_value()
975 if (this->type == glsl_type::error_type)
976 return NULL;
978 /* From the GLSL 1.20 spec, page 23:
979 * "Function calls to user-defined functions (non-built-in functions)
980 * cannot be used to form constant expressions."
982 if (!this->callee->is_builtin)
983 return NULL;
985 unsigned num_parameters = 0;
987 /* Check if all parameters are constant */
988 ir_constant *op[3];
989 foreach_list(n, &this->actual_parameters) {
990 ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value();
991 if (constant == NULL)
992 return NULL;
994 op[num_parameters] = constant;
996 assert(num_parameters < 3);
997 num_parameters++;
1000 /* Individual cases below can either:
1001 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
1002 * - Fill "data" with appopriate constant data
1003 * - Return an ir_constant directly.
1005 void *mem_ctx = ralloc_parent(this);
1006 ir_expression *expr = NULL;
1008 ir_constant_data data;
1009 memset(&data, 0, sizeof(data));
1011 const char *callee = this->callee_name();
1012 if (strcmp(callee, "abs") == 0) {
1013 expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL);
1014 } else if (strcmp(callee, "all") == 0) {
1015 assert(op[0]->type->is_boolean());
1016 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1017 if (!op[0]->value.b[c])
1018 return new(mem_ctx) ir_constant(false);
1020 return new(mem_ctx) ir_constant(true);
1021 } else if (strcmp(callee, "any") == 0) {
1022 assert(op[0]->type->is_boolean());
1023 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1024 if (op[0]->value.b[c])
1025 return new(mem_ctx) ir_constant(true);
1027 return new(mem_ctx) ir_constant(false);
1028 } else if (strcmp(callee, "acos") == 0) {
1029 assert(op[0]->type->is_float());
1030 for (unsigned c = 0; c < op[0]->type->components(); c++)
1031 data.f[c] = acosf(op[0]->value.f[c]);
1032 } else if (strcmp(callee, "acosh") == 0) {
1033 assert(op[0]->type->is_float());
1034 for (unsigned c = 0; c < op[0]->type->components(); c++)
1035 data.f[c] = acoshf(op[0]->value.f[c]);
1036 } else if (strcmp(callee, "asin") == 0) {
1037 assert(op[0]->type->is_float());
1038 for (unsigned c = 0; c < op[0]->type->components(); c++)
1039 data.f[c] = asinf(op[0]->value.f[c]);
1040 } else if (strcmp(callee, "asinh") == 0) {
1041 assert(op[0]->type->is_float());
1042 for (unsigned c = 0; c < op[0]->type->components(); c++)
1043 data.f[c] = asinhf(op[0]->value.f[c]);
1044 } else if (strcmp(callee, "atan") == 0) {
1045 assert(op[0]->type->is_float());
1046 if (num_parameters == 2) {
1047 assert(op[1]->type->is_float());
1048 for (unsigned c = 0; c < op[0]->type->components(); c++)
1049 data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]);
1050 } else {
1051 for (unsigned c = 0; c < op[0]->type->components(); c++)
1052 data.f[c] = atanf(op[0]->value.f[c]);
1054 } else if (strcmp(callee, "atanh") == 0) {
1055 assert(op[0]->type->is_float());
1056 for (unsigned c = 0; c < op[0]->type->components(); c++)
1057 data.f[c] = atanhf(op[0]->value.f[c]);
1058 } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) {
1059 return ir_constant::zero(mem_ctx, this->type);
1060 } else if (strcmp(callee, "ceil") == 0) {
1061 expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL);
1062 } else if (strcmp(callee, "clamp") == 0) {
1063 assert(num_parameters == 3);
1064 unsigned c1_inc = op[1]->type->is_scalar() ? 0 : 1;
1065 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
1066 for (unsigned c = 0, c1 = 0, c2 = 0;
1067 c < op[0]->type->components();
1068 c1 += c1_inc, c2 += c2_inc, c++) {
1070 switch (op[0]->type->base_type) {
1071 case GLSL_TYPE_UINT:
1072 data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1],
1073 op[2]->value.u[c2]);
1074 break;
1075 case GLSL_TYPE_INT:
1076 data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1],
1077 op[2]->value.i[c2]);
1078 break;
1079 case GLSL_TYPE_FLOAT:
1080 data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1],
1081 op[2]->value.f[c2]);
1082 break;
1083 default:
1084 assert(!"Should not get here.");
1087 } else if (strcmp(callee, "cos") == 0) {
1088 expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL);
1089 } else if (strcmp(callee, "cosh") == 0) {
1090 assert(op[0]->type->is_float());
1091 for (unsigned c = 0; c < op[0]->type->components(); c++)
1092 data.f[c] = coshf(op[0]->value.f[c]);
1093 } else if (strcmp(callee, "cross") == 0) {
1094 assert(op[0]->type == glsl_type::vec3_type);
1095 assert(op[1]->type == glsl_type::vec3_type);
1096 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
1097 op[1]->value.f[1] * op[0]->value.f[2]);
1098 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
1099 op[1]->value.f[2] * op[0]->value.f[0]);
1100 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
1101 op[1]->value.f[0] * op[0]->value.f[1]);
1102 } else if (strcmp(callee, "degrees") == 0) {
1103 assert(op[0]->type->is_float());
1104 for (unsigned c = 0; c < op[0]->type->components(); c++)
1105 data.f[c] = 180.0F / M_PI * op[0]->value.f[c];
1106 } else if (strcmp(callee, "distance") == 0) {
1107 assert(op[0]->type->is_float() && op[1]->type->is_float());
1108 float length_squared = 0.0;
1109 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1110 float t = op[0]->value.f[c] - op[1]->value.f[c];
1111 length_squared += t * t;
1113 return new(mem_ctx) ir_constant(sqrtf(length_squared));
1114 } else if (strcmp(callee, "dot") == 0) {
1115 return new(mem_ctx) ir_constant(dot(op[0], op[1]));
1116 } else if (strcmp(callee, "equal") == 0) {
1117 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1118 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1119 switch (op[0]->type->base_type) {
1120 case GLSL_TYPE_UINT:
1121 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
1122 break;
1123 case GLSL_TYPE_INT:
1124 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
1125 break;
1126 case GLSL_TYPE_FLOAT:
1127 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
1128 break;
1129 case GLSL_TYPE_BOOL:
1130 data.b[c] = op[0]->value.b[c] == op[1]->value.b[c];
1131 break;
1132 default:
1133 assert(!"Should not get here.");
1136 } else if (strcmp(callee, "exp") == 0) {
1137 expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL);
1138 } else if (strcmp(callee, "exp2") == 0) {
1139 expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL);
1140 } else if (strcmp(callee, "faceforward") == 0) {
1141 if (dot(op[2], op[1]) < 0)
1142 return op[0];
1143 for (unsigned c = 0; c < op[0]->type->components(); c++)
1144 data.f[c] = -op[0]->value.f[c];
1145 } else if (strcmp(callee, "floor") == 0) {
1146 expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL);
1147 } else if (strcmp(callee, "fract") == 0) {
1148 expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL);
1149 } else if (strcmp(callee, "fwidth") == 0) {
1150 return ir_constant::zero(mem_ctx, this->type);
1151 } else if (strcmp(callee, "greaterThan") == 0) {
1152 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1153 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1154 switch (op[0]->type->base_type) {
1155 case GLSL_TYPE_UINT:
1156 data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
1157 break;
1158 case GLSL_TYPE_INT:
1159 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
1160 break;
1161 case GLSL_TYPE_FLOAT:
1162 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
1163 break;
1164 default:
1165 assert(!"Should not get here.");
1168 } else if (strcmp(callee, "greaterThanEqual") == 0) {
1169 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1170 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1171 switch (op[0]->type->base_type) {
1172 case GLSL_TYPE_UINT:
1173 data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c];
1174 break;
1175 case GLSL_TYPE_INT:
1176 data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c];
1177 break;
1178 case GLSL_TYPE_FLOAT:
1179 data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c];
1180 break;
1181 default:
1182 assert(!"Should not get here.");
1185 } else if (strcmp(callee, "inversesqrt") == 0) {
1186 expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL);
1187 } else if (strcmp(callee, "length") == 0) {
1188 return new(mem_ctx) ir_constant(sqrtf(dot(op[0], op[0])));
1189 } else if (strcmp(callee, "lessThan") == 0) {
1190 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1191 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1192 switch (op[0]->type->base_type) {
1193 case GLSL_TYPE_UINT:
1194 data.b[c] = op[0]->value.u[c] < op[1]->value.u[c];
1195 break;
1196 case GLSL_TYPE_INT:
1197 data.b[c] = op[0]->value.i[c] < op[1]->value.i[c];
1198 break;
1199 case GLSL_TYPE_FLOAT:
1200 data.b[c] = op[0]->value.f[c] < op[1]->value.f[c];
1201 break;
1202 default:
1203 assert(!"Should not get here.");
1206 } else if (strcmp(callee, "lessThanEqual") == 0) {
1207 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1208 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1209 switch (op[0]->type->base_type) {
1210 case GLSL_TYPE_UINT:
1211 data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c];
1212 break;
1213 case GLSL_TYPE_INT:
1214 data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c];
1215 break;
1216 case GLSL_TYPE_FLOAT:
1217 data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c];
1218 break;
1219 default:
1220 assert(!"Should not get here.");
1223 } else if (strcmp(callee, "log") == 0) {
1224 expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL);
1225 } else if (strcmp(callee, "log2") == 0) {
1226 expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL);
1227 } else if (strcmp(callee, "matrixCompMult") == 0) {
1228 assert(op[0]->type->is_float() && op[1]->type->is_float());
1229 for (unsigned c = 0; c < op[0]->type->components(); c++)
1230 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
1231 } else if (strcmp(callee, "max") == 0) {
1232 expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]);
1233 } else if (strcmp(callee, "min") == 0) {
1234 expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]);
1235 } else if (strcmp(callee, "mix") == 0) {
1236 assert(op[0]->type->is_float() && op[1]->type->is_float());
1237 if (op[2]->type->is_float()) {
1238 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
1239 unsigned components = op[0]->type->components();
1240 for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) {
1241 data.f[c] = op[0]->value.f[c] * (1 - op[2]->value.f[c2]) +
1242 op[1]->value.f[c] * op[2]->value.f[c2];
1244 } else {
1245 assert(op[2]->type->is_boolean());
1246 for (unsigned c = 0; c < op[0]->type->components(); c++)
1247 data.f[c] = op[op[2]->value.b[c] ? 1 : 0]->value.f[c];
1249 } else if (strcmp(callee, "mod") == 0) {
1250 expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]);
1251 } else if (strcmp(callee, "normalize") == 0) {
1252 assert(op[0]->type->is_float());
1253 float length = sqrtf(dot(op[0], op[0]));
1255 if (length == 0)
1256 return ir_constant::zero(mem_ctx, this->type);
1258 for (unsigned c = 0; c < op[0]->type->components(); c++)
1259 data.f[c] = op[0]->value.f[c] / length;
1260 } else if (strcmp(callee, "not") == 0) {
1261 expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL);
1262 } else if (strcmp(callee, "notEqual") == 0) {
1263 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1264 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1265 switch (op[0]->type->base_type) {
1266 case GLSL_TYPE_UINT:
1267 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
1268 break;
1269 case GLSL_TYPE_INT:
1270 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
1271 break;
1272 case GLSL_TYPE_FLOAT:
1273 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
1274 break;
1275 case GLSL_TYPE_BOOL:
1276 data.b[c] = op[0]->value.b[c] != op[1]->value.b[c];
1277 break;
1278 default:
1279 assert(!"Should not get here.");
1282 } else if (strcmp(callee, "outerProduct") == 0) {
1283 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
1284 const unsigned m = op[0]->type->vector_elements;
1285 const unsigned n = op[1]->type->vector_elements;
1286 for (unsigned j = 0; j < n; j++) {
1287 for (unsigned i = 0; i < m; i++) {
1288 data.f[i+m*j] = op[0]->value.f[i] * op[1]->value.f[j];
1291 } else if (strcmp(callee, "pow") == 0) {
1292 expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]);
1293 } else if (strcmp(callee, "radians") == 0) {
1294 assert(op[0]->type->is_float());
1295 for (unsigned c = 0; c < op[0]->type->components(); c++)
1296 data.f[c] = M_PI / 180.0F * op[0]->value.f[c];
1297 } else if (strcmp(callee, "reflect") == 0) {
1298 assert(op[0]->type->is_float());
1299 float dot_NI = dot(op[1], op[0]);
1300 for (unsigned c = 0; c < op[0]->type->components(); c++)
1301 data.f[c] = op[0]->value.f[c] - 2 * dot_NI * op[1]->value.f[c];
1302 } else if (strcmp(callee, "refract") == 0) {
1303 const float eta = op[2]->value.f[0];
1304 const float dot_NI = dot(op[1], op[0]);
1305 const float k = 1.0F - eta * eta * (1.0F - dot_NI * dot_NI);
1306 if (k < 0.0) {
1307 return ir_constant::zero(mem_ctx, this->type);
1308 } else {
1309 for (unsigned c = 0; c < type->components(); c++) {
1310 data.f[c] = eta * op[0]->value.f[c] - (eta * dot_NI + sqrtf(k))
1311 * op[1]->value.f[c];
1314 } else if (strcmp(callee, "sign") == 0) {
1315 expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
1316 } else if (strcmp(callee, "sin") == 0) {
1317 expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL);
1318 } else if (strcmp(callee, "sinh") == 0) {
1319 assert(op[0]->type->is_float());
1320 for (unsigned c = 0; c < op[0]->type->components(); c++)
1321 data.f[c] = sinhf(op[0]->value.f[c]);
1322 } else if (strcmp(callee, "smoothstep") == 0) {
1323 assert(num_parameters == 3);
1324 assert(op[1]->type == op[0]->type);
1325 unsigned edge_inc = op[0]->type->is_scalar() ? 0 : 1;
1326 for (unsigned c = 0, e = 0; c < type->components(); e += edge_inc, c++) {
1327 const float edge0 = op[0]->value.f[e];
1328 const float edge1 = op[1]->value.f[e];
1329 if (edge0 == edge1) {
1330 data.f[c] = 0.0; /* Avoid a crash - results are undefined anyway */
1331 } else {
1332 const float numerator = op[2]->value.f[c] - edge0;
1333 const float denominator = edge1 - edge0;
1334 const float t = CLAMP(numerator/denominator, 0, 1);
1335 data.f[c] = t * t * (3 - 2 * t);
1338 } else if (strcmp(callee, "sqrt") == 0) {
1339 expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL);
1340 } else if (strcmp(callee, "step") == 0) {
1341 assert(op[0]->type->is_float() && op[1]->type->is_float());
1342 /* op[0] (edge) may be either a scalar or a vector */
1343 const unsigned c0_inc = op[0]->type->is_scalar() ? 0 : 1;
1344 for (unsigned c = 0, c0 = 0; c < type->components(); c0 += c0_inc, c++)
1345 data.f[c] = (op[1]->value.f[c] < op[0]->value.f[c0]) ? 0.0F : 1.0F;
1346 } else if (strcmp(callee, "tan") == 0) {
1347 assert(op[0]->type->is_float());
1348 for (unsigned c = 0; c < op[0]->type->components(); c++)
1349 data.f[c] = tanf(op[0]->value.f[c]);
1350 } else if (strcmp(callee, "tanh") == 0) {
1351 assert(op[0]->type->is_float());
1352 for (unsigned c = 0; c < op[0]->type->components(); c++)
1353 data.f[c] = tanhf(op[0]->value.f[c]);
1354 } else if (strcmp(callee, "transpose") == 0) {
1355 assert(op[0]->type->is_matrix());
1356 const unsigned n = op[0]->type->vector_elements;
1357 const unsigned m = op[0]->type->matrix_columns;
1358 for (unsigned j = 0; j < m; j++) {
1359 for (unsigned i = 0; i < n; i++) {
1360 data.f[m*i+j] += op[0]->value.f[i+n*j];
1363 } else {
1364 /* Unsupported builtin - some are not allowed in constant expressions. */
1365 return NULL;
1368 if (expr != NULL)
1369 return expr->constant_expression_value();
1371 return new(mem_ctx) ir_constant(this->type, &data);