2910b2e162beb1152ad0ddd214c94b437a13be25
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 if (this->type
== glsl_type::error_type
)
1030 /* From the GLSL 1.20 spec, page 23:
1031 * "Function calls to user-defined functions (non-built-in functions)
1032 * cannot be used to form constant expressions."
1034 if (!this->callee
->is_builtin
)
1037 unsigned num_parameters
= 0;
1039 /* Check if all parameters are constant */
1041 foreach_list(n
, &this->actual_parameters
) {
1042 ir_constant
*constant
= ((ir_rvalue
*) n
)->constant_expression_value();
1043 if (constant
== NULL
)
1046 op
[num_parameters
] = constant
;
1048 assert(num_parameters
< 3);
1052 /* Individual cases below can either:
1053 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
1054 * - Fill "data" with appopriate constant data
1055 * - Return an ir_constant directly.
1057 void *mem_ctx
= ralloc_parent(this);
1058 ir_expression
*expr
= NULL
;
1060 ir_constant_data data
;
1061 memset(&data
, 0, sizeof(data
));
1063 const char *callee
= this->callee_name();
1064 if (strcmp(callee
, "abs") == 0) {
1065 expr
= new(mem_ctx
) ir_expression(ir_unop_abs
, type
, op
[0], NULL
);
1066 } else if (strcmp(callee
, "all") == 0) {
1067 assert(op
[0]->type
->is_boolean());
1068 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1069 if (!op
[0]->value
.b
[c
])
1070 return new(mem_ctx
) ir_constant(false);
1072 return new(mem_ctx
) ir_constant(true);
1073 } else if (strcmp(callee
, "any") == 0) {
1074 assert(op
[0]->type
->is_boolean());
1075 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1076 if (op
[0]->value
.b
[c
])
1077 return new(mem_ctx
) ir_constant(true);
1079 return new(mem_ctx
) ir_constant(false);
1080 } else if (strcmp(callee
, "acos") == 0) {
1081 assert(op
[0]->type
->is_float());
1082 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1083 data
.f
[c
] = acosf(op
[0]->value
.f
[c
]);
1084 } else if (strcmp(callee
, "acosh") == 0) {
1085 assert(op
[0]->type
->is_float());
1086 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1087 data
.f
[c
] = acoshf(op
[0]->value
.f
[c
]);
1088 } else if (strcmp(callee
, "asin") == 0) {
1089 assert(op
[0]->type
->is_float());
1090 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1091 data
.f
[c
] = asinf(op
[0]->value
.f
[c
]);
1092 } else if (strcmp(callee
, "asinh") == 0) {
1093 assert(op
[0]->type
->is_float());
1094 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1095 data
.f
[c
] = asinhf(op
[0]->value
.f
[c
]);
1096 } else if (strcmp(callee
, "atan") == 0) {
1097 assert(op
[0]->type
->is_float());
1098 if (num_parameters
== 2) {
1099 assert(op
[1]->type
->is_float());
1100 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1101 data
.f
[c
] = atan2f(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
1103 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1104 data
.f
[c
] = atanf(op
[0]->value
.f
[c
]);
1106 } else if (strcmp(callee
, "atanh") == 0) {
1107 assert(op
[0]->type
->is_float());
1108 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1109 data
.f
[c
] = atanhf(op
[0]->value
.f
[c
]);
1110 } else if (strcmp(callee
, "dFdx") == 0 || strcmp(callee
, "dFdy") == 0) {
1111 return ir_constant::zero(mem_ctx
, this->type
);
1112 } else if (strcmp(callee
, "ceil") == 0) {
1113 expr
= new(mem_ctx
) ir_expression(ir_unop_ceil
, type
, op
[0], NULL
);
1114 } else if (strcmp(callee
, "clamp") == 0) {
1115 assert(num_parameters
== 3);
1116 unsigned c1_inc
= op
[1]->type
->is_scalar() ? 0 : 1;
1117 unsigned c2_inc
= op
[2]->type
->is_scalar() ? 0 : 1;
1118 for (unsigned c
= 0, c1
= 0, c2
= 0;
1119 c
< op
[0]->type
->components();
1120 c1
+= c1_inc
, c2
+= c2_inc
, c
++) {
1122 switch (op
[0]->type
->base_type
) {
1123 case GLSL_TYPE_UINT
:
1124 data
.u
[c
] = CLAMP(op
[0]->value
.u
[c
], op
[1]->value
.u
[c1
],
1125 op
[2]->value
.u
[c2
]);
1128 data
.i
[c
] = CLAMP(op
[0]->value
.i
[c
], op
[1]->value
.i
[c1
],
1129 op
[2]->value
.i
[c2
]);
1131 case GLSL_TYPE_FLOAT
:
1132 data
.f
[c
] = CLAMP(op
[0]->value
.f
[c
], op
[1]->value
.f
[c1
],
1133 op
[2]->value
.f
[c2
]);
1136 assert(!"Should not get here.");
1139 } else if (strcmp(callee
, "cos") == 0) {
1140 expr
= new(mem_ctx
) ir_expression(ir_unop_cos
, type
, op
[0], NULL
);
1141 } else if (strcmp(callee
, "cosh") == 0) {
1142 assert(op
[0]->type
->is_float());
1143 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1144 data
.f
[c
] = coshf(op
[0]->value
.f
[c
]);
1145 } else if (strcmp(callee
, "cross") == 0) {
1146 assert(op
[0]->type
== glsl_type::vec3_type
);
1147 assert(op
[1]->type
== glsl_type::vec3_type
);
1148 data
.f
[0] = (op
[0]->value
.f
[1] * op
[1]->value
.f
[2] -
1149 op
[1]->value
.f
[1] * op
[0]->value
.f
[2]);
1150 data
.f
[1] = (op
[0]->value
.f
[2] * op
[1]->value
.f
[0] -
1151 op
[1]->value
.f
[2] * op
[0]->value
.f
[0]);
1152 data
.f
[2] = (op
[0]->value
.f
[0] * op
[1]->value
.f
[1] -
1153 op
[1]->value
.f
[0] * op
[0]->value
.f
[1]);
1154 } else if (strcmp(callee
, "degrees") == 0) {
1155 assert(op
[0]->type
->is_float());
1156 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1157 data
.f
[c
] = 180.0F
/ M_PI
* op
[0]->value
.f
[c
];
1158 } else if (strcmp(callee
, "distance") == 0) {
1159 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1160 float length_squared
= 0.0;
1161 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1162 float t
= op
[0]->value
.f
[c
] - op
[1]->value
.f
[c
];
1163 length_squared
+= t
* t
;
1165 return new(mem_ctx
) ir_constant(sqrtf(length_squared
));
1166 } else if (strcmp(callee
, "dot") == 0) {
1167 return new(mem_ctx
) ir_constant(dot(op
[0], op
[1]));
1168 } else if (strcmp(callee
, "equal") == 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
];
1176 data
.b
[c
] = op
[0]->value
.i
[c
] == op
[1]->value
.i
[c
];
1178 case GLSL_TYPE_FLOAT
:
1179 data
.b
[c
] = op
[0]->value
.f
[c
] == op
[1]->value
.f
[c
];
1181 case GLSL_TYPE_BOOL
:
1182 data
.b
[c
] = op
[0]->value
.b
[c
] == op
[1]->value
.b
[c
];
1185 assert(!"Should not get here.");
1188 } else if (strcmp(callee
, "exp") == 0) {
1189 expr
= new(mem_ctx
) ir_expression(ir_unop_exp
, type
, op
[0], NULL
);
1190 } else if (strcmp(callee
, "exp2") == 0) {
1191 expr
= new(mem_ctx
) ir_expression(ir_unop_exp2
, type
, op
[0], NULL
);
1192 } else if (strcmp(callee
, "faceforward") == 0) {
1193 if (dot(op
[2], op
[1]) < 0)
1195 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1196 data
.f
[c
] = -op
[0]->value
.f
[c
];
1197 } else if (strcmp(callee
, "floor") == 0) {
1198 expr
= new(mem_ctx
) ir_expression(ir_unop_floor
, type
, op
[0], NULL
);
1199 } else if (strcmp(callee
, "fract") == 0) {
1200 expr
= new(mem_ctx
) ir_expression(ir_unop_fract
, type
, op
[0], NULL
);
1201 } else if (strcmp(callee
, "fwidth") == 0) {
1202 return ir_constant::zero(mem_ctx
, this->type
);
1203 } else if (strcmp(callee
, "greaterThan") == 0) {
1204 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1205 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1206 switch (op
[0]->type
->base_type
) {
1207 case GLSL_TYPE_UINT
:
1208 data
.b
[c
] = op
[0]->value
.u
[c
] > op
[1]->value
.u
[c
];
1211 data
.b
[c
] = op
[0]->value
.i
[c
] > op
[1]->value
.i
[c
];
1213 case GLSL_TYPE_FLOAT
:
1214 data
.b
[c
] = op
[0]->value
.f
[c
] > op
[1]->value
.f
[c
];
1217 assert(!"Should not get here.");
1220 } else if (strcmp(callee
, "greaterThanEqual") == 0) {
1221 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1222 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1223 switch (op
[0]->type
->base_type
) {
1224 case GLSL_TYPE_UINT
:
1225 data
.b
[c
] = op
[0]->value
.u
[c
] >= op
[1]->value
.u
[c
];
1228 data
.b
[c
] = op
[0]->value
.i
[c
] >= op
[1]->value
.i
[c
];
1230 case GLSL_TYPE_FLOAT
:
1231 data
.b
[c
] = op
[0]->value
.f
[c
] >= op
[1]->value
.f
[c
];
1234 assert(!"Should not get here.");
1237 } else if (strcmp(callee
, "inversesqrt") == 0) {
1238 expr
= new(mem_ctx
) ir_expression(ir_unop_rsq
, type
, op
[0], NULL
);
1239 } else if (strcmp(callee
, "length") == 0) {
1240 return new(mem_ctx
) ir_constant(sqrtf(dot(op
[0], op
[0])));
1241 } else if (strcmp(callee
, "lessThan") == 0) {
1242 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1243 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1244 switch (op
[0]->type
->base_type
) {
1245 case GLSL_TYPE_UINT
:
1246 data
.b
[c
] = op
[0]->value
.u
[c
] < op
[1]->value
.u
[c
];
1249 data
.b
[c
] = op
[0]->value
.i
[c
] < op
[1]->value
.i
[c
];
1251 case GLSL_TYPE_FLOAT
:
1252 data
.b
[c
] = op
[0]->value
.f
[c
] < op
[1]->value
.f
[c
];
1255 assert(!"Should not get here.");
1258 } else if (strcmp(callee
, "lessThanEqual") == 0) {
1259 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1260 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1261 switch (op
[0]->type
->base_type
) {
1262 case GLSL_TYPE_UINT
:
1263 data
.b
[c
] = op
[0]->value
.u
[c
] <= op
[1]->value
.u
[c
];
1266 data
.b
[c
] = op
[0]->value
.i
[c
] <= op
[1]->value
.i
[c
];
1268 case GLSL_TYPE_FLOAT
:
1269 data
.b
[c
] = op
[0]->value
.f
[c
] <= op
[1]->value
.f
[c
];
1272 assert(!"Should not get here.");
1275 } else if (strcmp(callee
, "log") == 0) {
1276 expr
= new(mem_ctx
) ir_expression(ir_unop_log
, type
, op
[0], NULL
);
1277 } else if (strcmp(callee
, "log2") == 0) {
1278 expr
= new(mem_ctx
) ir_expression(ir_unop_log2
, type
, op
[0], NULL
);
1279 } else if (strcmp(callee
, "matrixCompMult") == 0) {
1280 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1281 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1282 data
.f
[c
] = op
[0]->value
.f
[c
] * op
[1]->value
.f
[c
];
1283 } else if (strcmp(callee
, "max") == 0) {
1284 expr
= new(mem_ctx
) ir_expression(ir_binop_max
, type
, op
[0], op
[1]);
1285 } else if (strcmp(callee
, "min") == 0) {
1286 expr
= new(mem_ctx
) ir_expression(ir_binop_min
, type
, op
[0], op
[1]);
1287 } else if (strcmp(callee
, "mix") == 0) {
1288 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1289 if (op
[2]->type
->is_float()) {
1290 unsigned c2_inc
= op
[2]->type
->is_scalar() ? 0 : 1;
1291 unsigned components
= op
[0]->type
->components();
1292 for (unsigned c
= 0, c2
= 0; c
< components
; c2
+= c2_inc
, c
++) {
1293 data
.f
[c
] = op
[0]->value
.f
[c
] * (1 - op
[2]->value
.f
[c2
]) +
1294 op
[1]->value
.f
[c
] * op
[2]->value
.f
[c2
];
1297 assert(op
[2]->type
->is_boolean());
1298 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1299 data
.f
[c
] = op
[op
[2]->value
.b
[c
] ? 1 : 0]->value
.f
[c
];
1301 } else if (strcmp(callee
, "mod") == 0) {
1302 expr
= new(mem_ctx
) ir_expression(ir_binop_mod
, type
, op
[0], op
[1]);
1303 } else if (strcmp(callee
, "normalize") == 0) {
1304 assert(op
[0]->type
->is_float());
1305 float length
= sqrtf(dot(op
[0], op
[0]));
1308 return ir_constant::zero(mem_ctx
, this->type
);
1310 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1311 data
.f
[c
] = op
[0]->value
.f
[c
] / length
;
1312 } else if (strcmp(callee
, "not") == 0) {
1313 expr
= new(mem_ctx
) ir_expression(ir_unop_logic_not
, type
, op
[0], NULL
);
1314 } else if (strcmp(callee
, "notEqual") == 0) {
1315 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1316 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1317 switch (op
[0]->type
->base_type
) {
1318 case GLSL_TYPE_UINT
:
1319 data
.b
[c
] = op
[0]->value
.u
[c
] != op
[1]->value
.u
[c
];
1322 data
.b
[c
] = op
[0]->value
.i
[c
] != op
[1]->value
.i
[c
];
1324 case GLSL_TYPE_FLOAT
:
1325 data
.b
[c
] = op
[0]->value
.f
[c
] != op
[1]->value
.f
[c
];
1327 case GLSL_TYPE_BOOL
:
1328 data
.b
[c
] = op
[0]->value
.b
[c
] != op
[1]->value
.b
[c
];
1331 assert(!"Should not get here.");
1334 } else if (strcmp(callee
, "outerProduct") == 0) {
1335 assert(op
[0]->type
->is_vector() && op
[1]->type
->is_vector());
1336 const unsigned m
= op
[0]->type
->vector_elements
;
1337 const unsigned n
= op
[1]->type
->vector_elements
;
1338 for (unsigned j
= 0; j
< n
; j
++) {
1339 for (unsigned i
= 0; i
< m
; i
++) {
1340 data
.f
[i
+m
*j
] = op
[0]->value
.f
[i
] * op
[1]->value
.f
[j
];
1343 } else if (strcmp(callee
, "pow") == 0) {
1344 expr
= new(mem_ctx
) ir_expression(ir_binop_pow
, type
, op
[0], op
[1]);
1345 } else if (strcmp(callee
, "radians") == 0) {
1346 assert(op
[0]->type
->is_float());
1347 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1348 data
.f
[c
] = M_PI
/ 180.0F
* op
[0]->value
.f
[c
];
1349 } else if (strcmp(callee
, "reflect") == 0) {
1350 assert(op
[0]->type
->is_float());
1351 float dot_NI
= dot(op
[1], op
[0]);
1352 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1353 data
.f
[c
] = op
[0]->value
.f
[c
] - 2 * dot_NI
* op
[1]->value
.f
[c
];
1354 } else if (strcmp(callee
, "refract") == 0) {
1355 const float eta
= op
[2]->value
.f
[0];
1356 const float dot_NI
= dot(op
[1], op
[0]);
1357 const float k
= 1.0F
- eta
* eta
* (1.0F
- dot_NI
* dot_NI
);
1359 return ir_constant::zero(mem_ctx
, this->type
);
1361 for (unsigned c
= 0; c
< type
->components(); c
++) {
1362 data
.f
[c
] = eta
* op
[0]->value
.f
[c
] - (eta
* dot_NI
+ sqrtf(k
))
1363 * op
[1]->value
.f
[c
];
1366 } else if (strcmp(callee
, "round") == 0 ||
1367 strcmp(callee
, "roundEven") == 0) {
1368 expr
= new(mem_ctx
) ir_expression(ir_unop_round_even
, op
[0]);
1369 } else if (strcmp(callee
, "sign") == 0) {
1370 expr
= new(mem_ctx
) ir_expression(ir_unop_sign
, type
, op
[0], NULL
);
1371 } else if (strcmp(callee
, "sin") == 0) {
1372 expr
= new(mem_ctx
) ir_expression(ir_unop_sin
, type
, op
[0], NULL
);
1373 } else if (strcmp(callee
, "sinh") == 0) {
1374 assert(op
[0]->type
->is_float());
1375 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1376 data
.f
[c
] = sinhf(op
[0]->value
.f
[c
]);
1377 } else if (strcmp(callee
, "smoothstep") == 0) {
1378 assert(num_parameters
== 3);
1379 assert(op
[1]->type
== op
[0]->type
);
1380 unsigned edge_inc
= op
[0]->type
->is_scalar() ? 0 : 1;
1381 for (unsigned c
= 0, e
= 0; c
< type
->components(); e
+= edge_inc
, c
++) {
1382 const float edge0
= op
[0]->value
.f
[e
];
1383 const float edge1
= op
[1]->value
.f
[e
];
1384 if (edge0
== edge1
) {
1385 data
.f
[c
] = 0.0; /* Avoid a crash - results are undefined anyway */
1387 const float numerator
= op
[2]->value
.f
[c
] - edge0
;
1388 const float denominator
= edge1
- edge0
;
1389 const float t
= CLAMP(numerator
/denominator
, 0, 1);
1390 data
.f
[c
] = t
* t
* (3 - 2 * t
);
1393 } else if (strcmp(callee
, "sqrt") == 0) {
1394 expr
= new(mem_ctx
) ir_expression(ir_unop_sqrt
, type
, op
[0], NULL
);
1395 } else if (strcmp(callee
, "step") == 0) {
1396 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1397 /* op[0] (edge) may be either a scalar or a vector */
1398 const unsigned c0_inc
= op
[0]->type
->is_scalar() ? 0 : 1;
1399 for (unsigned c
= 0, c0
= 0; c
< type
->components(); c0
+= c0_inc
, c
++)
1400 data
.f
[c
] = (op
[1]->value
.f
[c
] < op
[0]->value
.f
[c0
]) ? 0.0F
: 1.0F
;
1401 } else if (strcmp(callee
, "tan") == 0) {
1402 assert(op
[0]->type
->is_float());
1403 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1404 data
.f
[c
] = tanf(op
[0]->value
.f
[c
]);
1405 } else if (strcmp(callee
, "tanh") == 0) {
1406 assert(op
[0]->type
->is_float());
1407 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1408 data
.f
[c
] = tanhf(op
[0]->value
.f
[c
]);
1409 } else if (strcmp(callee
, "transpose") == 0) {
1410 assert(op
[0]->type
->is_matrix());
1411 const unsigned n
= op
[0]->type
->vector_elements
;
1412 const unsigned m
= op
[0]->type
->matrix_columns
;
1413 for (unsigned j
= 0; j
< m
; j
++) {
1414 for (unsigned i
= 0; i
< n
; i
++) {
1415 data
.f
[m
*i
+j
] += op
[0]->value
.f
[i
+n
*j
];
1418 } else if (strcmp(callee
, "trunc") == 0) {
1419 expr
= new(mem_ctx
) ir_expression(ir_unop_trunc
, op
[0]);
1421 /* Unsupported builtin - some are not allowed in constant expressions. */
1426 return expr
->constant_expression_value();
1428 return new(mem_ctx
) ir_constant(this->type
, &data
);