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
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.
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.
32 * * Initializers for uniforms
33 * * Initializers for \c const variables
37 #include "main/core.h" /* for MAX2, MIN2, CLAMP */
39 #include "ir_visitor.h"
40 #include "glsl_types.h"
42 /* Using C99 rounding functions for roundToEven() implementation is
43 * difficult, because round(), rint, and nearbyint() are affected by
44 * fesetenv(), which the application may have done for its own
45 * purposes. Mesa's IROUND macro is close to what we want, but it
46 * rounds away from 0 on n + 0.5.
49 round_to_even(float val
)
51 int rounded
= IROUND(val
);
53 if (val
- floor(val
) == 0.5) {
55 rounded
+= val
> 0 ? -1 : 1;
62 dot(ir_constant
*op0
, ir_constant
*op1
)
64 assert(op0
->type
->is_float() && op1
->type
->is_float());
67 for (unsigned c
= 0; c
< op0
->type
->components(); c
++)
68 result
+= op0
->value
.f
[c
] * op1
->value
.f
[c
];
74 ir_rvalue::constant_expression_value()
76 assert(this->type
->is_error());
81 ir_expression::constant_expression_value()
83 if (this->type
->is_error())
86 ir_constant
*op
[Elements(this->operands
)] = { NULL
, };
87 ir_constant_data data
;
89 memset(&data
, 0, sizeof(data
));
91 for (unsigned operand
= 0; operand
< this->get_num_operands(); operand
++) {
92 op
[operand
] = this->operands
[operand
]->constant_expression_value();
98 assert(op
[0]->type
->base_type
== op
[1]->type
->base_type
||
99 this->operation
== ir_binop_lshift
||
100 this->operation
== ir_binop_rshift
);
102 bool op0_scalar
= op
[0]->type
->is_scalar();
103 bool op1_scalar
= op
[1] != NULL
&& op
[1]->type
->is_scalar();
105 /* When iterating over a vector or matrix's components, we want to increase
106 * the loop counter. However, for scalars, we want to stay at 0.
108 unsigned c0_inc
= op0_scalar
? 0 : 1;
109 unsigned c1_inc
= op1_scalar
? 0 : 1;
111 if (op1_scalar
|| !op
[1]) {
112 components
= op
[0]->type
->components();
114 components
= op
[1]->type
->components();
117 void *ctx
= ralloc_parent(this);
119 /* Handle array operations here, rather than below. */
120 if (op
[0]->type
->is_array()) {
121 assert(op
[1] != NULL
&& op
[1]->type
->is_array());
122 switch (this->operation
) {
123 case ir_binop_all_equal
:
124 return new(ctx
) ir_constant(op
[0]->has_value(op
[1]));
125 case ir_binop_any_nequal
:
126 return new(ctx
) ir_constant(!op
[0]->has_value(op
[1]));
133 switch (this->operation
) {
134 case ir_unop_bit_not
:
135 switch (op
[0]->type
->base_type
) {
137 for (unsigned c
= 0; c
< components
; c
++)
138 data
.i
[c
] = ~ op
[0]->value
.i
[c
];
141 for (unsigned c
= 0; c
< components
; c
++)
142 data
.u
[c
] = ~ op
[0]->value
.u
[c
];
149 case ir_unop_logic_not
:
150 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
151 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
152 data
.b
[c
] = !op
[0]->value
.b
[c
];
156 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
157 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
158 data
.i
[c
] = (int) op
[0]->value
.f
[c
];
162 assert(op
[0]->type
->base_type
== GLSL_TYPE_INT
);
163 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
164 data
.f
[c
] = (float) op
[0]->value
.i
[c
];
168 assert(op
[0]->type
->base_type
== GLSL_TYPE_UINT
);
169 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
170 data
.f
[c
] = (float) op
[0]->value
.u
[c
];
174 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
175 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
176 data
.f
[c
] = op
[0]->value
.b
[c
] ? 1.0F
: 0.0F
;
180 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
181 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
182 data
.b
[c
] = op
[0]->value
.f
[c
] != 0.0F
? true : false;
186 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
187 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
188 data
.u
[c
] = op
[0]->value
.b
[c
] ? 1 : 0;
192 assert(op
[0]->type
->is_integer());
193 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
194 data
.b
[c
] = op
[0]->value
.u
[c
] ? true : false;
198 assert(op
[0]->type
->base_type
== GLSL_TYPE_UINT
);
199 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
200 data
.i
[c
] = op
[0]->value
.u
[c
];
204 assert(op
[0]->type
->base_type
== GLSL_TYPE_INT
);
205 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
206 data
.u
[c
] = op
[0]->value
.i
[c
];
210 assert(op
[0]->type
->is_boolean());
212 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
213 if (op
[0]->value
.b
[c
])
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
] = truncf(op
[0]->value
.f
[c
]);
225 case ir_unop_round_even
:
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
] = round_to_even(op
[0]->value
.f
[c
]);
233 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
234 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
235 data
.f
[c
] = ceilf(op
[0]->value
.f
[c
]);
240 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
241 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
242 data
.f
[c
] = floorf(op
[0]->value
.f
[c
]);
247 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
248 switch (this->type
->base_type
) {
255 case GLSL_TYPE_FLOAT
:
256 data
.f
[c
] = op
[0]->value
.f
[c
] - floor(op
[0]->value
.f
[c
]);
265 case ir_unop_sin_reduced
:
266 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
267 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
268 data
.f
[c
] = sinf(op
[0]->value
.f
[c
]);
273 case ir_unop_cos_reduced
:
274 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
275 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
276 data
.f
[c
] = cosf(op
[0]->value
.f
[c
]);
281 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
282 switch (this->type
->base_type
) {
284 data
.u
[c
] = -((int) op
[0]->value
.u
[c
]);
287 data
.i
[c
] = -op
[0]->value
.i
[c
];
289 case GLSL_TYPE_FLOAT
:
290 data
.f
[c
] = -op
[0]->value
.f
[c
];
299 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
300 switch (this->type
->base_type
) {
302 data
.u
[c
] = op
[0]->value
.u
[c
];
305 data
.i
[c
] = op
[0]->value
.i
[c
];
307 data
.i
[c
] = -data
.i
[c
];
309 case GLSL_TYPE_FLOAT
:
310 data
.f
[c
] = fabs(op
[0]->value
.f
[c
]);
319 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
320 switch (this->type
->base_type
) {
322 data
.u
[c
] = op
[0]->value
.i
[c
] > 0;
325 data
.i
[c
] = (op
[0]->value
.i
[c
] > 0) - (op
[0]->value
.i
[c
] < 0);
327 case GLSL_TYPE_FLOAT
:
328 data
.f
[c
] = float((op
[0]->value
.f
[c
] > 0)-(op
[0]->value
.f
[c
] < 0));
337 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
338 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
339 switch (this->type
->base_type
) {
341 if (op
[0]->value
.u
[c
] != 0.0)
342 data
.u
[c
] = 1 / op
[0]->value
.u
[c
];
345 if (op
[0]->value
.i
[c
] != 0.0)
346 data
.i
[c
] = 1 / op
[0]->value
.i
[c
];
348 case GLSL_TYPE_FLOAT
:
349 if (op
[0]->value
.f
[c
] != 0.0)
350 data
.f
[c
] = 1.0F
/ op
[0]->value
.f
[c
];
359 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
360 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
361 data
.f
[c
] = 1.0F
/ sqrtf(op
[0]->value
.f
[c
]);
366 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
367 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
368 data
.f
[c
] = sqrtf(op
[0]->value
.f
[c
]);
373 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
374 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
375 data
.f
[c
] = expf(op
[0]->value
.f
[c
]);
380 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
381 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
382 data
.f
[c
] = exp2f(op
[0]->value
.f
[c
]);
387 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
388 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
389 data
.f
[c
] = logf(op
[0]->value
.f
[c
]);
394 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
395 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
396 data
.f
[c
] = log2f(op
[0]->value
.f
[c
]);
402 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
403 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
409 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
410 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
411 data
.f
[c
] = powf(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
416 data
.f
[0] = dot(op
[0], op
[1]);
420 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
421 for (unsigned c
= 0, c0
= 0, c1
= 0;
423 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
425 switch (op
[0]->type
->base_type
) {
427 data
.u
[c
] = MIN2(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
430 data
.i
[c
] = MIN2(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
432 case GLSL_TYPE_FLOAT
:
433 data
.f
[c
] = MIN2(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
442 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
443 for (unsigned c
= 0, c0
= 0, c1
= 0;
445 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
447 switch (op
[0]->type
->base_type
) {
449 data
.u
[c
] = MAX2(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
452 data
.i
[c
] = MAX2(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
454 case GLSL_TYPE_FLOAT
:
455 data
.f
[c
] = MAX2(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
464 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
465 for (unsigned c
= 0, c0
= 0, c1
= 0;
467 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
469 switch (op
[0]->type
->base_type
) {
471 data
.u
[c
] = op
[0]->value
.u
[c0
] + op
[1]->value
.u
[c1
];
474 data
.i
[c
] = op
[0]->value
.i
[c0
] + op
[1]->value
.i
[c1
];
476 case GLSL_TYPE_FLOAT
:
477 data
.f
[c
] = op
[0]->value
.f
[c0
] + op
[1]->value
.f
[c1
];
486 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
487 for (unsigned c
= 0, c0
= 0, c1
= 0;
489 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
491 switch (op
[0]->type
->base_type
) {
493 data
.u
[c
] = op
[0]->value
.u
[c0
] - op
[1]->value
.u
[c1
];
496 data
.i
[c
] = op
[0]->value
.i
[c0
] - op
[1]->value
.i
[c1
];
498 case GLSL_TYPE_FLOAT
:
499 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
];
508 /* Check for equal types, or unequal types involving scalars */
509 if ((op
[0]->type
== op
[1]->type
&& !op
[0]->type
->is_matrix())
510 || op0_scalar
|| op1_scalar
) {
511 for (unsigned c
= 0, c0
= 0, c1
= 0;
513 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
515 switch (op
[0]->type
->base_type
) {
517 data
.u
[c
] = op
[0]->value
.u
[c0
] * op
[1]->value
.u
[c1
];
520 data
.i
[c
] = op
[0]->value
.i
[c0
] * op
[1]->value
.i
[c1
];
522 case GLSL_TYPE_FLOAT
:
523 data
.f
[c
] = op
[0]->value
.f
[c0
] * op
[1]->value
.f
[c1
];
530 assert(op
[0]->type
->is_matrix() || op
[1]->type
->is_matrix());
532 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
533 * matrix can be a GLSL vector, either N or P can be 1.
535 * For vec*mat, the vector is treated as a row vector. This
536 * means the vector is a 1-row x M-column matrix.
538 * For mat*vec, the vector is treated as a column vector. Since
539 * matrix_columns is 1 for vectors, this just works.
541 const unsigned n
= op
[0]->type
->is_vector()
542 ? 1 : op
[0]->type
->vector_elements
;
543 const unsigned m
= op
[1]->type
->vector_elements
;
544 const unsigned p
= op
[1]->type
->matrix_columns
;
545 for (unsigned j
= 0; j
< p
; j
++) {
546 for (unsigned i
= 0; i
< n
; i
++) {
547 for (unsigned k
= 0; k
< m
; k
++) {
548 data
.f
[i
+n
*j
] += op
[0]->value
.f
[i
+n
*k
]*op
[1]->value
.f
[k
+m
*j
];
556 /* FINISHME: Emit warning when division-by-zero is detected. */
557 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
558 for (unsigned c
= 0, c0
= 0, c1
= 0;
560 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
562 switch (op
[0]->type
->base_type
) {
564 if (op
[1]->value
.u
[c1
] == 0) {
567 data
.u
[c
] = op
[0]->value
.u
[c0
] / op
[1]->value
.u
[c1
];
571 if (op
[1]->value
.i
[c1
] == 0) {
574 data
.i
[c
] = op
[0]->value
.i
[c0
] / op
[1]->value
.i
[c1
];
577 case GLSL_TYPE_FLOAT
:
578 data
.f
[c
] = op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
];
587 /* FINISHME: Emit warning when division-by-zero is detected. */
588 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
589 for (unsigned c
= 0, c0
= 0, c1
= 0;
591 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
593 switch (op
[0]->type
->base_type
) {
595 if (op
[1]->value
.u
[c1
] == 0) {
598 data
.u
[c
] = op
[0]->value
.u
[c0
] % op
[1]->value
.u
[c1
];
602 if (op
[1]->value
.i
[c1
] == 0) {
605 data
.i
[c
] = op
[0]->value
.i
[c0
] % op
[1]->value
.i
[c1
];
608 case GLSL_TYPE_FLOAT
:
609 /* We don't use fmod because it rounds toward zero; GLSL specifies
612 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
]
613 * floorf(op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
]);
622 case ir_binop_logic_and
:
623 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
624 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
625 data
.b
[c
] = op
[0]->value
.b
[c
] && op
[1]->value
.b
[c
];
627 case ir_binop_logic_xor
:
628 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
629 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
630 data
.b
[c
] = op
[0]->value
.b
[c
] ^ op
[1]->value
.b
[c
];
632 case ir_binop_logic_or
:
633 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
634 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
635 data
.b
[c
] = op
[0]->value
.b
[c
] || op
[1]->value
.b
[c
];
639 assert(op
[0]->type
== op
[1]->type
);
640 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
641 switch (op
[0]->type
->base_type
) {
643 data
.b
[0] = op
[0]->value
.u
[0] < op
[1]->value
.u
[0];
646 data
.b
[0] = op
[0]->value
.i
[0] < op
[1]->value
.i
[0];
648 case GLSL_TYPE_FLOAT
:
649 data
.b
[0] = op
[0]->value
.f
[0] < op
[1]->value
.f
[0];
656 case ir_binop_greater
:
657 assert(op
[0]->type
== op
[1]->type
);
658 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
659 switch (op
[0]->type
->base_type
) {
661 data
.b
[c
] = op
[0]->value
.u
[c
] > op
[1]->value
.u
[c
];
664 data
.b
[c
] = op
[0]->value
.i
[c
] > op
[1]->value
.i
[c
];
666 case GLSL_TYPE_FLOAT
:
667 data
.b
[c
] = op
[0]->value
.f
[c
] > op
[1]->value
.f
[c
];
674 case ir_binop_lequal
:
675 assert(op
[0]->type
== op
[1]->type
);
676 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
677 switch (op
[0]->type
->base_type
) {
679 data
.b
[0] = op
[0]->value
.u
[0] <= op
[1]->value
.u
[0];
682 data
.b
[0] = op
[0]->value
.i
[0] <= op
[1]->value
.i
[0];
684 case GLSL_TYPE_FLOAT
:
685 data
.b
[0] = op
[0]->value
.f
[0] <= op
[1]->value
.f
[0];
692 case ir_binop_gequal
:
693 assert(op
[0]->type
== op
[1]->type
);
694 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
695 switch (op
[0]->type
->base_type
) {
697 data
.b
[0] = op
[0]->value
.u
[0] >= op
[1]->value
.u
[0];
700 data
.b
[0] = op
[0]->value
.i
[0] >= op
[1]->value
.i
[0];
702 case GLSL_TYPE_FLOAT
:
703 data
.b
[0] = op
[0]->value
.f
[0] >= op
[1]->value
.f
[0];
711 assert(op
[0]->type
== op
[1]->type
);
712 for (unsigned c
= 0; c
< components
; c
++) {
713 switch (op
[0]->type
->base_type
) {
715 data
.b
[c
] = op
[0]->value
.u
[c
] == op
[1]->value
.u
[c
];
718 data
.b
[c
] = op
[0]->value
.i
[c
] == op
[1]->value
.i
[c
];
720 case GLSL_TYPE_FLOAT
:
721 data
.b
[c
] = op
[0]->value
.f
[c
] == op
[1]->value
.f
[c
];
724 data
.b
[c
] = op
[0]->value
.b
[c
] == op
[1]->value
.b
[c
];
731 case ir_binop_nequal
:
732 assert(op
[0]->type
== op
[1]->type
);
733 for (unsigned c
= 0; c
< components
; c
++) {
734 switch (op
[0]->type
->base_type
) {
736 data
.b
[c
] = op
[0]->value
.u
[c
] != op
[1]->value
.u
[c
];
739 data
.b
[c
] = op
[0]->value
.i
[c
] != op
[1]->value
.i
[c
];
741 case GLSL_TYPE_FLOAT
:
742 data
.b
[c
] = op
[0]->value
.f
[c
] != op
[1]->value
.f
[c
];
745 data
.b
[c
] = op
[0]->value
.b
[c
] != op
[1]->value
.b
[c
];
752 case ir_binop_all_equal
:
753 data
.b
[0] = op
[0]->has_value(op
[1]);
755 case ir_binop_any_nequal
:
756 data
.b
[0] = !op
[0]->has_value(op
[1]);
759 case ir_binop_lshift
:
760 for (unsigned c
= 0, c0
= 0, c1
= 0;
762 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
764 if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
765 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
766 data
.i
[c
] = op
[0]->value
.i
[c0
] << op
[1]->value
.i
[c1
];
768 } else if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
769 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
770 data
.i
[c
] = op
[0]->value
.i
[c0
] << op
[1]->value
.u
[c1
];
772 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
773 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
774 data
.u
[c
] = op
[0]->value
.u
[c0
] << op
[1]->value
.i
[c1
];
776 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
777 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
778 data
.u
[c
] = op
[0]->value
.u
[c0
] << op
[1]->value
.u
[c1
];
783 case ir_binop_rshift
:
784 for (unsigned c
= 0, c0
= 0, c1
= 0;
786 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
788 if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
789 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
790 data
.i
[c
] = op
[0]->value
.i
[c0
] >> op
[1]->value
.i
[c1
];
792 } else if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
793 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
794 data
.i
[c
] = op
[0]->value
.i
[c0
] >> op
[1]->value
.u
[c1
];
796 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
797 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
798 data
.u
[c
] = op
[0]->value
.u
[c0
] >> op
[1]->value
.i
[c1
];
800 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
801 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
802 data
.u
[c
] = op
[0]->value
.u
[c0
] >> op
[1]->value
.u
[c1
];
807 case ir_binop_bit_and
:
808 for (unsigned c
= 0, c0
= 0, c1
= 0;
810 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
812 switch (op
[0]->type
->base_type
) {
814 data
.i
[c
] = op
[0]->value
.i
[c0
] & op
[1]->value
.i
[c1
];
817 data
.u
[c
] = op
[0]->value
.u
[c0
] & op
[1]->value
.u
[c1
];
825 case ir_binop_bit_or
:
826 for (unsigned c
= 0, c0
= 0, c1
= 0;
828 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
830 switch (op
[0]->type
->base_type
) {
832 data
.i
[c
] = op
[0]->value
.i
[c0
] | op
[1]->value
.i
[c1
];
835 data
.u
[c
] = op
[0]->value
.u
[c0
] | op
[1]->value
.u
[c1
];
843 case ir_binop_bit_xor
:
844 for (unsigned c
= 0, c0
= 0, c1
= 0;
846 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
848 switch (op
[0]->type
->base_type
) {
850 data
.i
[c
] = op
[0]->value
.i
[c0
] ^ op
[1]->value
.i
[c1
];
853 data
.u
[c
] = op
[0]->value
.u
[c0
] ^ op
[1]->value
.u
[c1
];
861 case ir_quadop_vector
:
862 for (unsigned c
= 0; c
< this->type
->vector_elements
; c
++) {
863 switch (this->type
->base_type
) {
865 data
.i
[c
] = op
[c
]->value
.i
[0];
868 data
.u
[c
] = op
[c
]->value
.u
[0];
870 case GLSL_TYPE_FLOAT
:
871 data
.f
[c
] = op
[c
]->value
.f
[0];
880 /* FINISHME: Should handle all expression types. */
884 return new(ctx
) ir_constant(this->type
, &data
);
889 ir_texture::constant_expression_value()
891 /* texture lookups aren't constant expressions */
897 ir_swizzle::constant_expression_value()
899 ir_constant
*v
= this->val
->constant_expression_value();
902 ir_constant_data data
= { { 0 } };
904 const unsigned swiz_idx
[4] = {
905 this->mask
.x
, this->mask
.y
, this->mask
.z
, this->mask
.w
908 for (unsigned i
= 0; i
< this->mask
.num_components
; i
++) {
909 switch (v
->type
->base_type
) {
911 case GLSL_TYPE_INT
: data
.u
[i
] = v
->value
.u
[swiz_idx
[i
]]; break;
912 case GLSL_TYPE_FLOAT
: data
.f
[i
] = v
->value
.f
[swiz_idx
[i
]]; break;
913 case GLSL_TYPE_BOOL
: data
.b
[i
] = v
->value
.b
[swiz_idx
[i
]]; break;
914 default: assert(!"Should not get here."); break;
918 void *ctx
= ralloc_parent(this);
919 return new(ctx
) ir_constant(this->type
, &data
);
926 ir_dereference_variable::constant_expression_value()
928 /* This may occur during compile and var->type is glsl_type::error_type */
932 /* The constant_value of a uniform variable is its initializer,
933 * not the lifetime constant value of the uniform.
935 if (var
->mode
== ir_var_uniform
)
938 if (!var
->constant_value
)
941 return var
->constant_value
->clone(ralloc_parent(var
), NULL
);
946 ir_dereference_array::constant_expression_value()
948 ir_constant
*array
= this->array
->constant_expression_value();
949 ir_constant
*idx
= this->array_index
->constant_expression_value();
951 if ((array
!= NULL
) && (idx
!= NULL
)) {
952 void *ctx
= ralloc_parent(this);
953 if (array
->type
->is_matrix()) {
954 /* Array access of a matrix results in a vector.
956 const unsigned column
= idx
->value
.u
[0];
958 const glsl_type
*const column_type
= array
->type
->column_type();
960 /* Offset in the constant matrix to the first element of the column
963 const unsigned mat_idx
= column
* column_type
->vector_elements
;
965 ir_constant_data data
= { { 0 } };
967 switch (column_type
->base_type
) {
970 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
971 data
.u
[i
] = array
->value
.u
[mat_idx
+ i
];
975 case GLSL_TYPE_FLOAT
:
976 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
977 data
.f
[i
] = array
->value
.f
[mat_idx
+ i
];
982 assert(!"Should not get here.");
986 return new(ctx
) ir_constant(column_type
, &data
);
987 } else if (array
->type
->is_vector()) {
988 const unsigned component
= idx
->value
.u
[0];
990 return new(ctx
) ir_constant(array
, component
);
992 const unsigned index
= idx
->value
.u
[0];
993 return array
->get_array_element(index
)->clone(ctx
, NULL
);
1001 ir_dereference_record::constant_expression_value()
1003 ir_constant
*v
= this->record
->constant_expression_value();
1005 return (v
!= NULL
) ? v
->get_record_field(this->field
) : NULL
;
1010 ir_assignment::constant_expression_value()
1012 /* FINISHME: Handle CEs involving assignment (return RHS) */
1018 ir_constant::constant_expression_value()
1025 ir_call::constant_expression_value()
1027 return this->callee
->constant_expression_value(&this->actual_parameters
);
1032 ir_function_signature::constant_expression_value(exec_list
*actual_parameters
)
1034 const glsl_type
*type
= this->return_type
;
1035 if (type
== glsl_type::void_type
)
1038 /* From the GLSL 1.20 spec, page 23:
1039 * "Function calls to user-defined functions (non-built-in functions)
1040 * cannot be used to form constant expressions."
1042 if (!this->is_builtin
)
1045 unsigned num_parameters
= 0;
1047 /* Check if all parameters are constant */
1049 foreach_list(n
, actual_parameters
) {
1050 ir_constant
*constant
= ((ir_rvalue
*) n
)->constant_expression_value();
1051 if (constant
== NULL
)
1054 op
[num_parameters
] = constant
;
1056 assert(num_parameters
< 3);
1060 /* Individual cases below can either:
1061 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
1062 * - Fill "data" with appopriate constant data
1063 * - Return an ir_constant directly.
1065 void *mem_ctx
= ralloc_parent(this);
1066 ir_expression
*expr
= NULL
;
1068 ir_constant_data data
;
1069 memset(&data
, 0, sizeof(data
));
1071 const char *callee
= this->function_name();
1072 if (strcmp(callee
, "abs") == 0) {
1073 expr
= new(mem_ctx
) ir_expression(ir_unop_abs
, type
, op
[0], NULL
);
1074 } else if (strcmp(callee
, "all") == 0) {
1075 assert(op
[0]->type
->is_boolean());
1076 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1077 if (!op
[0]->value
.b
[c
])
1078 return new(mem_ctx
) ir_constant(false);
1080 return new(mem_ctx
) ir_constant(true);
1081 } else if (strcmp(callee
, "any") == 0) {
1082 assert(op
[0]->type
->is_boolean());
1083 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1084 if (op
[0]->value
.b
[c
])
1085 return new(mem_ctx
) ir_constant(true);
1087 return new(mem_ctx
) ir_constant(false);
1088 } else if (strcmp(callee
, "acos") == 0) {
1089 assert(op
[0]->type
->is_float());
1090 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1091 data
.f
[c
] = acosf(op
[0]->value
.f
[c
]);
1092 } else if (strcmp(callee
, "acosh") == 0) {
1093 assert(op
[0]->type
->is_float());
1094 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1095 data
.f
[c
] = acoshf(op
[0]->value
.f
[c
]);
1096 } else if (strcmp(callee
, "asin") == 0) {
1097 assert(op
[0]->type
->is_float());
1098 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1099 data
.f
[c
] = asinf(op
[0]->value
.f
[c
]);
1100 } else if (strcmp(callee
, "asinh") == 0) {
1101 assert(op
[0]->type
->is_float());
1102 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1103 data
.f
[c
] = asinhf(op
[0]->value
.f
[c
]);
1104 } else if (strcmp(callee
, "atan") == 0) {
1105 assert(op
[0]->type
->is_float());
1106 if (num_parameters
== 2) {
1107 assert(op
[1]->type
->is_float());
1108 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1109 data
.f
[c
] = atan2f(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
1111 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1112 data
.f
[c
] = atanf(op
[0]->value
.f
[c
]);
1114 } else if (strcmp(callee
, "atanh") == 0) {
1115 assert(op
[0]->type
->is_float());
1116 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1117 data
.f
[c
] = atanhf(op
[0]->value
.f
[c
]);
1118 } else if (strcmp(callee
, "dFdx") == 0 || strcmp(callee
, "dFdy") == 0) {
1119 return ir_constant::zero(mem_ctx
, type
);
1120 } else if (strcmp(callee
, "ceil") == 0) {
1121 expr
= new(mem_ctx
) ir_expression(ir_unop_ceil
, type
, op
[0], NULL
);
1122 } else if (strcmp(callee
, "clamp") == 0) {
1123 assert(num_parameters
== 3);
1124 unsigned c1_inc
= op
[1]->type
->is_scalar() ? 0 : 1;
1125 unsigned c2_inc
= op
[2]->type
->is_scalar() ? 0 : 1;
1126 for (unsigned c
= 0, c1
= 0, c2
= 0;
1127 c
< op
[0]->type
->components();
1128 c1
+= c1_inc
, c2
+= c2_inc
, c
++) {
1130 switch (op
[0]->type
->base_type
) {
1131 case GLSL_TYPE_UINT
:
1132 data
.u
[c
] = CLAMP(op
[0]->value
.u
[c
], op
[1]->value
.u
[c1
],
1133 op
[2]->value
.u
[c2
]);
1136 data
.i
[c
] = CLAMP(op
[0]->value
.i
[c
], op
[1]->value
.i
[c1
],
1137 op
[2]->value
.i
[c2
]);
1139 case GLSL_TYPE_FLOAT
:
1140 data
.f
[c
] = CLAMP(op
[0]->value
.f
[c
], op
[1]->value
.f
[c1
],
1141 op
[2]->value
.f
[c2
]);
1144 assert(!"Should not get here.");
1147 } else if (strcmp(callee
, "cos") == 0) {
1148 expr
= new(mem_ctx
) ir_expression(ir_unop_cos
, type
, op
[0], NULL
);
1149 } else if (strcmp(callee
, "cosh") == 0) {
1150 assert(op
[0]->type
->is_float());
1151 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1152 data
.f
[c
] = coshf(op
[0]->value
.f
[c
]);
1153 } else if (strcmp(callee
, "cross") == 0) {
1154 assert(op
[0]->type
== glsl_type::vec3_type
);
1155 assert(op
[1]->type
== glsl_type::vec3_type
);
1156 data
.f
[0] = (op
[0]->value
.f
[1] * op
[1]->value
.f
[2] -
1157 op
[1]->value
.f
[1] * op
[0]->value
.f
[2]);
1158 data
.f
[1] = (op
[0]->value
.f
[2] * op
[1]->value
.f
[0] -
1159 op
[1]->value
.f
[2] * op
[0]->value
.f
[0]);
1160 data
.f
[2] = (op
[0]->value
.f
[0] * op
[1]->value
.f
[1] -
1161 op
[1]->value
.f
[0] * op
[0]->value
.f
[1]);
1162 } else if (strcmp(callee
, "degrees") == 0) {
1163 assert(op
[0]->type
->is_float());
1164 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1165 data
.f
[c
] = 180.0F
/ M_PI
* op
[0]->value
.f
[c
];
1166 } else if (strcmp(callee
, "distance") == 0) {
1167 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1168 float length_squared
= 0.0;
1169 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1170 float t
= op
[0]->value
.f
[c
] - op
[1]->value
.f
[c
];
1171 length_squared
+= t
* t
;
1173 return new(mem_ctx
) ir_constant(sqrtf(length_squared
));
1174 } else if (strcmp(callee
, "dot") == 0) {
1175 return new(mem_ctx
) ir_constant(dot(op
[0], op
[1]));
1176 } else if (strcmp(callee
, "equal") == 0) {
1177 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1178 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1179 switch (op
[0]->type
->base_type
) {
1180 case GLSL_TYPE_UINT
:
1181 data
.b
[c
] = op
[0]->value
.u
[c
] == op
[1]->value
.u
[c
];
1184 data
.b
[c
] = op
[0]->value
.i
[c
] == op
[1]->value
.i
[c
];
1186 case GLSL_TYPE_FLOAT
:
1187 data
.b
[c
] = op
[0]->value
.f
[c
] == op
[1]->value
.f
[c
];
1189 case GLSL_TYPE_BOOL
:
1190 data
.b
[c
] = op
[0]->value
.b
[c
] == op
[1]->value
.b
[c
];
1193 assert(!"Should not get here.");
1196 } else if (strcmp(callee
, "exp") == 0) {
1197 expr
= new(mem_ctx
) ir_expression(ir_unop_exp
, type
, op
[0], NULL
);
1198 } else if (strcmp(callee
, "exp2") == 0) {
1199 expr
= new(mem_ctx
) ir_expression(ir_unop_exp2
, type
, op
[0], NULL
);
1200 } else if (strcmp(callee
, "faceforward") == 0) {
1201 if (dot(op
[2], op
[1]) < 0)
1203 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1204 data
.f
[c
] = -op
[0]->value
.f
[c
];
1205 } else if (strcmp(callee
, "floor") == 0) {
1206 expr
= new(mem_ctx
) ir_expression(ir_unop_floor
, type
, op
[0], NULL
);
1207 } else if (strcmp(callee
, "fract") == 0) {
1208 expr
= new(mem_ctx
) ir_expression(ir_unop_fract
, type
, op
[0], NULL
);
1209 } else if (strcmp(callee
, "fwidth") == 0) {
1210 return ir_constant::zero(mem_ctx
, type
);
1211 } else if (strcmp(callee
, "greaterThan") == 0) {
1212 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1213 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1214 switch (op
[0]->type
->base_type
) {
1215 case GLSL_TYPE_UINT
:
1216 data
.b
[c
] = op
[0]->value
.u
[c
] > op
[1]->value
.u
[c
];
1219 data
.b
[c
] = op
[0]->value
.i
[c
] > op
[1]->value
.i
[c
];
1221 case GLSL_TYPE_FLOAT
:
1222 data
.b
[c
] = op
[0]->value
.f
[c
] > op
[1]->value
.f
[c
];
1225 assert(!"Should not get here.");
1228 } else if (strcmp(callee
, "greaterThanEqual") == 0) {
1229 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1230 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1231 switch (op
[0]->type
->base_type
) {
1232 case GLSL_TYPE_UINT
:
1233 data
.b
[c
] = op
[0]->value
.u
[c
] >= op
[1]->value
.u
[c
];
1236 data
.b
[c
] = op
[0]->value
.i
[c
] >= op
[1]->value
.i
[c
];
1238 case GLSL_TYPE_FLOAT
:
1239 data
.b
[c
] = op
[0]->value
.f
[c
] >= op
[1]->value
.f
[c
];
1242 assert(!"Should not get here.");
1245 } else if (strcmp(callee
, "inversesqrt") == 0) {
1246 expr
= new(mem_ctx
) ir_expression(ir_unop_rsq
, type
, op
[0], NULL
);
1247 } else if (strcmp(callee
, "length") == 0) {
1248 return new(mem_ctx
) ir_constant(sqrtf(dot(op
[0], op
[0])));
1249 } else if (strcmp(callee
, "lessThan") == 0) {
1250 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1251 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1252 switch (op
[0]->type
->base_type
) {
1253 case GLSL_TYPE_UINT
:
1254 data
.b
[c
] = op
[0]->value
.u
[c
] < op
[1]->value
.u
[c
];
1257 data
.b
[c
] = op
[0]->value
.i
[c
] < op
[1]->value
.i
[c
];
1259 case GLSL_TYPE_FLOAT
:
1260 data
.b
[c
] = op
[0]->value
.f
[c
] < op
[1]->value
.f
[c
];
1263 assert(!"Should not get here.");
1266 } else if (strcmp(callee
, "lessThanEqual") == 0) {
1267 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1268 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1269 switch (op
[0]->type
->base_type
) {
1270 case GLSL_TYPE_UINT
:
1271 data
.b
[c
] = op
[0]->value
.u
[c
] <= op
[1]->value
.u
[c
];
1274 data
.b
[c
] = op
[0]->value
.i
[c
] <= op
[1]->value
.i
[c
];
1276 case GLSL_TYPE_FLOAT
:
1277 data
.b
[c
] = op
[0]->value
.f
[c
] <= op
[1]->value
.f
[c
];
1280 assert(!"Should not get here.");
1283 } else if (strcmp(callee
, "log") == 0) {
1284 expr
= new(mem_ctx
) ir_expression(ir_unop_log
, type
, op
[0], NULL
);
1285 } else if (strcmp(callee
, "log2") == 0) {
1286 expr
= new(mem_ctx
) ir_expression(ir_unop_log2
, type
, op
[0], NULL
);
1287 } else if (strcmp(callee
, "matrixCompMult") == 0) {
1288 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1289 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1290 data
.f
[c
] = op
[0]->value
.f
[c
] * op
[1]->value
.f
[c
];
1291 } else if (strcmp(callee
, "max") == 0) {
1292 expr
= new(mem_ctx
) ir_expression(ir_binop_max
, type
, op
[0], op
[1]);
1293 } else if (strcmp(callee
, "min") == 0) {
1294 expr
= new(mem_ctx
) ir_expression(ir_binop_min
, type
, op
[0], op
[1]);
1295 } else if (strcmp(callee
, "mix") == 0) {
1296 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1297 if (op
[2]->type
->is_float()) {
1298 unsigned c2_inc
= op
[2]->type
->is_scalar() ? 0 : 1;
1299 unsigned components
= op
[0]->type
->components();
1300 for (unsigned c
= 0, c2
= 0; c
< components
; c2
+= c2_inc
, c
++) {
1301 data
.f
[c
] = op
[0]->value
.f
[c
] * (1 - op
[2]->value
.f
[c2
]) +
1302 op
[1]->value
.f
[c
] * op
[2]->value
.f
[c2
];
1305 assert(op
[2]->type
->is_boolean());
1306 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1307 data
.f
[c
] = op
[op
[2]->value
.b
[c
] ? 1 : 0]->value
.f
[c
];
1309 } else if (strcmp(callee
, "mod") == 0) {
1310 expr
= new(mem_ctx
) ir_expression(ir_binop_mod
, type
, op
[0], op
[1]);
1311 } else if (strcmp(callee
, "normalize") == 0) {
1312 assert(op
[0]->type
->is_float());
1313 float length
= sqrtf(dot(op
[0], op
[0]));
1316 return ir_constant::zero(mem_ctx
, type
);
1318 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1319 data
.f
[c
] = op
[0]->value
.f
[c
] / length
;
1320 } else if (strcmp(callee
, "not") == 0) {
1321 expr
= new(mem_ctx
) ir_expression(ir_unop_logic_not
, type
, op
[0], NULL
);
1322 } else if (strcmp(callee
, "notEqual") == 0) {
1323 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1324 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1325 switch (op
[0]->type
->base_type
) {
1326 case GLSL_TYPE_UINT
:
1327 data
.b
[c
] = op
[0]->value
.u
[c
] != op
[1]->value
.u
[c
];
1330 data
.b
[c
] = op
[0]->value
.i
[c
] != op
[1]->value
.i
[c
];
1332 case GLSL_TYPE_FLOAT
:
1333 data
.b
[c
] = op
[0]->value
.f
[c
] != op
[1]->value
.f
[c
];
1335 case GLSL_TYPE_BOOL
:
1336 data
.b
[c
] = op
[0]->value
.b
[c
] != op
[1]->value
.b
[c
];
1339 assert(!"Should not get here.");
1342 } else if (strcmp(callee
, "outerProduct") == 0) {
1343 assert(op
[0]->type
->is_vector() && op
[1]->type
->is_vector());
1344 const unsigned m
= op
[0]->type
->vector_elements
;
1345 const unsigned n
= op
[1]->type
->vector_elements
;
1346 for (unsigned j
= 0; j
< n
; j
++) {
1347 for (unsigned i
= 0; i
< m
; i
++) {
1348 data
.f
[i
+m
*j
] = op
[0]->value
.f
[i
] * op
[1]->value
.f
[j
];
1351 } else if (strcmp(callee
, "pow") == 0) {
1352 expr
= new(mem_ctx
) ir_expression(ir_binop_pow
, type
, op
[0], op
[1]);
1353 } else if (strcmp(callee
, "radians") == 0) {
1354 assert(op
[0]->type
->is_float());
1355 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1356 data
.f
[c
] = M_PI
/ 180.0F
* op
[0]->value
.f
[c
];
1357 } else if (strcmp(callee
, "reflect") == 0) {
1358 assert(op
[0]->type
->is_float());
1359 float dot_NI
= dot(op
[1], op
[0]);
1360 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1361 data
.f
[c
] = op
[0]->value
.f
[c
] - 2 * dot_NI
* op
[1]->value
.f
[c
];
1362 } else if (strcmp(callee
, "refract") == 0) {
1363 const float eta
= op
[2]->value
.f
[0];
1364 const float dot_NI
= dot(op
[1], op
[0]);
1365 const float k
= 1.0F
- eta
* eta
* (1.0F
- dot_NI
* dot_NI
);
1367 return ir_constant::zero(mem_ctx
, type
);
1369 for (unsigned c
= 0; c
< type
->components(); c
++) {
1370 data
.f
[c
] = eta
* op
[0]->value
.f
[c
] - (eta
* dot_NI
+ sqrtf(k
))
1371 * op
[1]->value
.f
[c
];
1374 } else if (strcmp(callee
, "round") == 0 ||
1375 strcmp(callee
, "roundEven") == 0) {
1376 expr
= new(mem_ctx
) ir_expression(ir_unop_round_even
, op
[0]);
1377 } else if (strcmp(callee
, "sign") == 0) {
1378 expr
= new(mem_ctx
) ir_expression(ir_unop_sign
, type
, op
[0], NULL
);
1379 } else if (strcmp(callee
, "sin") == 0) {
1380 expr
= new(mem_ctx
) ir_expression(ir_unop_sin
, type
, op
[0], NULL
);
1381 } else if (strcmp(callee
, "sinh") == 0) {
1382 assert(op
[0]->type
->is_float());
1383 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1384 data
.f
[c
] = sinhf(op
[0]->value
.f
[c
]);
1385 } else if (strcmp(callee
, "smoothstep") == 0) {
1386 assert(num_parameters
== 3);
1387 assert(op
[1]->type
== op
[0]->type
);
1388 unsigned edge_inc
= op
[0]->type
->is_scalar() ? 0 : 1;
1389 for (unsigned c
= 0, e
= 0; c
< type
->components(); e
+= edge_inc
, c
++) {
1390 const float edge0
= op
[0]->value
.f
[e
];
1391 const float edge1
= op
[1]->value
.f
[e
];
1392 if (edge0
== edge1
) {
1393 data
.f
[c
] = 0.0; /* Avoid a crash - results are undefined anyway */
1395 const float numerator
= op
[2]->value
.f
[c
] - edge0
;
1396 const float denominator
= edge1
- edge0
;
1397 const float t
= CLAMP(numerator
/denominator
, 0, 1);
1398 data
.f
[c
] = t
* t
* (3 - 2 * t
);
1401 } else if (strcmp(callee
, "sqrt") == 0) {
1402 expr
= new(mem_ctx
) ir_expression(ir_unop_sqrt
, type
, op
[0], NULL
);
1403 } else if (strcmp(callee
, "step") == 0) {
1404 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1405 /* op[0] (edge) may be either a scalar or a vector */
1406 const unsigned c0_inc
= op
[0]->type
->is_scalar() ? 0 : 1;
1407 for (unsigned c
= 0, c0
= 0; c
< type
->components(); c0
+= c0_inc
, c
++)
1408 data
.f
[c
] = (op
[1]->value
.f
[c
] < op
[0]->value
.f
[c0
]) ? 0.0F
: 1.0F
;
1409 } else if (strcmp(callee
, "tan") == 0) {
1410 assert(op
[0]->type
->is_float());
1411 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1412 data
.f
[c
] = tanf(op
[0]->value
.f
[c
]);
1413 } else if (strcmp(callee
, "tanh") == 0) {
1414 assert(op
[0]->type
->is_float());
1415 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1416 data
.f
[c
] = tanhf(op
[0]->value
.f
[c
]);
1417 } else if (strcmp(callee
, "transpose") == 0) {
1418 assert(op
[0]->type
->is_matrix());
1419 const unsigned n
= op
[0]->type
->vector_elements
;
1420 const unsigned m
= op
[0]->type
->matrix_columns
;
1421 for (unsigned j
= 0; j
< m
; j
++) {
1422 for (unsigned i
= 0; i
< n
; i
++) {
1423 data
.f
[m
*i
+j
] += op
[0]->value
.f
[i
+n
*j
];
1426 } else if (strcmp(callee
, "trunc") == 0) {
1427 expr
= new(mem_ctx
) ir_expression(ir_unop_trunc
, op
[0]);
1429 /* Unsupported builtin - some are not allowed in constant expressions. */
1434 return expr
->constant_expression_value();
1436 return new(mem_ctx
) ir_constant(type
, &data
);