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"
41 #include "program/hash_table.h"
43 /* Using C99 rounding functions for roundToEven() implementation is
44 * difficult, because round(), rint, and nearbyint() are affected by
45 * fesetenv(), which the application may have done for its own
46 * purposes. Mesa's IROUND macro is close to what we want, but it
47 * rounds away from 0 on n + 0.5.
50 round_to_even(float val
)
52 int rounded
= IROUND(val
);
54 if (val
- floor(val
) == 0.5) {
56 rounded
+= val
> 0 ? -1 : 1;
63 dot(ir_constant
*op0
, ir_constant
*op1
)
65 assert(op0
->type
->is_float() && op1
->type
->is_float());
68 for (unsigned c
= 0; c
< op0
->type
->components(); c
++)
69 result
+= op0
->value
.f
[c
] * op1
->value
.f
[c
];
75 ir_rvalue::constant_expression_value(struct hash_table
*variable_context
)
77 assert(this->type
->is_error());
82 ir_expression::constant_expression_value(struct hash_table
*variable_context
)
84 if (this->type
->is_error())
87 ir_constant
*op
[Elements(this->operands
)] = { NULL
, };
88 ir_constant_data data
;
90 memset(&data
, 0, sizeof(data
));
92 for (unsigned operand
= 0; operand
< this->get_num_operands(); operand
++) {
93 op
[operand
] = this->operands
[operand
]->constant_expression_value(variable_context
);
99 assert(op
[0]->type
->base_type
== op
[1]->type
->base_type
||
100 this->operation
== ir_binop_lshift
||
101 this->operation
== ir_binop_rshift
);
103 bool op0_scalar
= op
[0]->type
->is_scalar();
104 bool op1_scalar
= op
[1] != NULL
&& op
[1]->type
->is_scalar();
106 /* When iterating over a vector or matrix's components, we want to increase
107 * the loop counter. However, for scalars, we want to stay at 0.
109 unsigned c0_inc
= op0_scalar
? 0 : 1;
110 unsigned c1_inc
= op1_scalar
? 0 : 1;
112 if (op1_scalar
|| !op
[1]) {
113 components
= op
[0]->type
->components();
115 components
= op
[1]->type
->components();
118 void *ctx
= ralloc_parent(this);
120 /* Handle array operations here, rather than below. */
121 if (op
[0]->type
->is_array()) {
122 assert(op
[1] != NULL
&& op
[1]->type
->is_array());
123 switch (this->operation
) {
124 case ir_binop_all_equal
:
125 return new(ctx
) ir_constant(op
[0]->has_value(op
[1]));
126 case ir_binop_any_nequal
:
127 return new(ctx
) ir_constant(!op
[0]->has_value(op
[1]));
134 switch (this->operation
) {
135 case ir_unop_bit_not
:
136 switch (op
[0]->type
->base_type
) {
138 for (unsigned c
= 0; c
< components
; c
++)
139 data
.i
[c
] = ~ op
[0]->value
.i
[c
];
142 for (unsigned c
= 0; c
< components
; c
++)
143 data
.u
[c
] = ~ op
[0]->value
.u
[c
];
150 case ir_unop_logic_not
:
151 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
152 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
153 data
.b
[c
] = !op
[0]->value
.b
[c
];
157 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
158 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
159 data
.i
[c
] = (int) op
[0]->value
.f
[c
];
163 assert(op
[0]->type
->base_type
== GLSL_TYPE_INT
);
164 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
165 data
.f
[c
] = (float) op
[0]->value
.i
[c
];
169 assert(op
[0]->type
->base_type
== GLSL_TYPE_UINT
);
170 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
171 data
.f
[c
] = (float) op
[0]->value
.u
[c
];
175 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
176 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
177 data
.f
[c
] = op
[0]->value
.b
[c
] ? 1.0F
: 0.0F
;
181 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
182 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
183 data
.b
[c
] = op
[0]->value
.f
[c
] != 0.0F
? true : false;
187 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
188 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
189 data
.u
[c
] = op
[0]->value
.b
[c
] ? 1 : 0;
193 assert(op
[0]->type
->is_integer());
194 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
195 data
.b
[c
] = op
[0]->value
.u
[c
] ? true : false;
199 assert(op
[0]->type
->base_type
== GLSL_TYPE_UINT
);
200 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
201 data
.i
[c
] = op
[0]->value
.u
[c
];
205 assert(op
[0]->type
->base_type
== GLSL_TYPE_INT
);
206 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
207 data
.u
[c
] = op
[0]->value
.i
[c
];
211 assert(op
[0]->type
->is_boolean());
213 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
214 if (op
[0]->value
.b
[c
])
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
] = truncf(op
[0]->value
.f
[c
]);
226 case ir_unop_round_even
:
227 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
228 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
229 data
.f
[c
] = round_to_even(op
[0]->value
.f
[c
]);
234 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
235 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
236 data
.f
[c
] = ceilf(op
[0]->value
.f
[c
]);
241 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
242 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
243 data
.f
[c
] = floorf(op
[0]->value
.f
[c
]);
248 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
249 switch (this->type
->base_type
) {
256 case GLSL_TYPE_FLOAT
:
257 data
.f
[c
] = op
[0]->value
.f
[c
] - floor(op
[0]->value
.f
[c
]);
266 case ir_unop_sin_reduced
:
267 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
268 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
269 data
.f
[c
] = sinf(op
[0]->value
.f
[c
]);
274 case ir_unop_cos_reduced
:
275 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
276 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
277 data
.f
[c
] = cosf(op
[0]->value
.f
[c
]);
282 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
283 switch (this->type
->base_type
) {
285 data
.u
[c
] = -((int) op
[0]->value
.u
[c
]);
288 data
.i
[c
] = -op
[0]->value
.i
[c
];
290 case GLSL_TYPE_FLOAT
:
291 data
.f
[c
] = -op
[0]->value
.f
[c
];
300 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
301 switch (this->type
->base_type
) {
303 data
.u
[c
] = op
[0]->value
.u
[c
];
306 data
.i
[c
] = op
[0]->value
.i
[c
];
308 data
.i
[c
] = -data
.i
[c
];
310 case GLSL_TYPE_FLOAT
:
311 data
.f
[c
] = fabs(op
[0]->value
.f
[c
]);
320 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
321 switch (this->type
->base_type
) {
323 data
.u
[c
] = op
[0]->value
.i
[c
] > 0;
326 data
.i
[c
] = (op
[0]->value
.i
[c
] > 0) - (op
[0]->value
.i
[c
] < 0);
328 case GLSL_TYPE_FLOAT
:
329 data
.f
[c
] = float((op
[0]->value
.f
[c
] > 0)-(op
[0]->value
.f
[c
] < 0));
338 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
339 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
340 switch (this->type
->base_type
) {
342 if (op
[0]->value
.u
[c
] != 0.0)
343 data
.u
[c
] = 1 / op
[0]->value
.u
[c
];
346 if (op
[0]->value
.i
[c
] != 0.0)
347 data
.i
[c
] = 1 / op
[0]->value
.i
[c
];
349 case GLSL_TYPE_FLOAT
:
350 if (op
[0]->value
.f
[c
] != 0.0)
351 data
.f
[c
] = 1.0F
/ op
[0]->value
.f
[c
];
360 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
361 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
362 data
.f
[c
] = 1.0F
/ sqrtf(op
[0]->value
.f
[c
]);
367 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
368 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
369 data
.f
[c
] = sqrtf(op
[0]->value
.f
[c
]);
374 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
375 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
376 data
.f
[c
] = expf(op
[0]->value
.f
[c
]);
381 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
382 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
383 data
.f
[c
] = exp2f(op
[0]->value
.f
[c
]);
388 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
389 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
390 data
.f
[c
] = logf(op
[0]->value
.f
[c
]);
395 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
396 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
397 data
.f
[c
] = log2f(op
[0]->value
.f
[c
]);
403 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
404 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
410 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
411 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
412 data
.f
[c
] = powf(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
417 data
.f
[0] = dot(op
[0], op
[1]);
421 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
422 for (unsigned c
= 0, c0
= 0, c1
= 0;
424 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
426 switch (op
[0]->type
->base_type
) {
428 data
.u
[c
] = MIN2(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
431 data
.i
[c
] = MIN2(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
433 case GLSL_TYPE_FLOAT
:
434 data
.f
[c
] = MIN2(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
443 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
444 for (unsigned c
= 0, c0
= 0, c1
= 0;
446 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
448 switch (op
[0]->type
->base_type
) {
450 data
.u
[c
] = MAX2(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
453 data
.i
[c
] = MAX2(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
455 case GLSL_TYPE_FLOAT
:
456 data
.f
[c
] = MAX2(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
465 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
466 for (unsigned c
= 0, c0
= 0, c1
= 0;
468 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
470 switch (op
[0]->type
->base_type
) {
472 data
.u
[c
] = op
[0]->value
.u
[c0
] + op
[1]->value
.u
[c1
];
475 data
.i
[c
] = op
[0]->value
.i
[c0
] + op
[1]->value
.i
[c1
];
477 case GLSL_TYPE_FLOAT
:
478 data
.f
[c
] = op
[0]->value
.f
[c0
] + op
[1]->value
.f
[c1
];
487 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
488 for (unsigned c
= 0, c0
= 0, c1
= 0;
490 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
492 switch (op
[0]->type
->base_type
) {
494 data
.u
[c
] = op
[0]->value
.u
[c0
] - op
[1]->value
.u
[c1
];
497 data
.i
[c
] = op
[0]->value
.i
[c0
] - op
[1]->value
.i
[c1
];
499 case GLSL_TYPE_FLOAT
:
500 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
];
509 /* Check for equal types, or unequal types involving scalars */
510 if ((op
[0]->type
== op
[1]->type
&& !op
[0]->type
->is_matrix())
511 || op0_scalar
|| op1_scalar
) {
512 for (unsigned c
= 0, c0
= 0, c1
= 0;
514 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
516 switch (op
[0]->type
->base_type
) {
518 data
.u
[c
] = op
[0]->value
.u
[c0
] * op
[1]->value
.u
[c1
];
521 data
.i
[c
] = op
[0]->value
.i
[c0
] * op
[1]->value
.i
[c1
];
523 case GLSL_TYPE_FLOAT
:
524 data
.f
[c
] = op
[0]->value
.f
[c0
] * op
[1]->value
.f
[c1
];
531 assert(op
[0]->type
->is_matrix() || op
[1]->type
->is_matrix());
533 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
534 * matrix can be a GLSL vector, either N or P can be 1.
536 * For vec*mat, the vector is treated as a row vector. This
537 * means the vector is a 1-row x M-column matrix.
539 * For mat*vec, the vector is treated as a column vector. Since
540 * matrix_columns is 1 for vectors, this just works.
542 const unsigned n
= op
[0]->type
->is_vector()
543 ? 1 : op
[0]->type
->vector_elements
;
544 const unsigned m
= op
[1]->type
->vector_elements
;
545 const unsigned p
= op
[1]->type
->matrix_columns
;
546 for (unsigned j
= 0; j
< p
; j
++) {
547 for (unsigned i
= 0; i
< n
; i
++) {
548 for (unsigned k
= 0; k
< m
; k
++) {
549 data
.f
[i
+n
*j
] += op
[0]->value
.f
[i
+n
*k
]*op
[1]->value
.f
[k
+m
*j
];
557 /* FINISHME: Emit warning when division-by-zero is detected. */
558 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
559 for (unsigned c
= 0, c0
= 0, c1
= 0;
561 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
563 switch (op
[0]->type
->base_type
) {
565 if (op
[1]->value
.u
[c1
] == 0) {
568 data
.u
[c
] = op
[0]->value
.u
[c0
] / op
[1]->value
.u
[c1
];
572 if (op
[1]->value
.i
[c1
] == 0) {
575 data
.i
[c
] = op
[0]->value
.i
[c0
] / op
[1]->value
.i
[c1
];
578 case GLSL_TYPE_FLOAT
:
579 data
.f
[c
] = op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
];
588 /* FINISHME: Emit warning when division-by-zero is detected. */
589 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
590 for (unsigned c
= 0, c0
= 0, c1
= 0;
592 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
594 switch (op
[0]->type
->base_type
) {
596 if (op
[1]->value
.u
[c1
] == 0) {
599 data
.u
[c
] = op
[0]->value
.u
[c0
] % op
[1]->value
.u
[c1
];
603 if (op
[1]->value
.i
[c1
] == 0) {
606 data
.i
[c
] = op
[0]->value
.i
[c0
] % op
[1]->value
.i
[c1
];
609 case GLSL_TYPE_FLOAT
:
610 /* We don't use fmod because it rounds toward zero; GLSL specifies
613 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
]
614 * floorf(op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
]);
623 case ir_binop_logic_and
:
624 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
625 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
626 data
.b
[c
] = op
[0]->value
.b
[c
] && op
[1]->value
.b
[c
];
628 case ir_binop_logic_xor
:
629 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
630 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
631 data
.b
[c
] = op
[0]->value
.b
[c
] ^ op
[1]->value
.b
[c
];
633 case ir_binop_logic_or
:
634 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
635 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
636 data
.b
[c
] = op
[0]->value
.b
[c
] || op
[1]->value
.b
[c
];
640 assert(op
[0]->type
== op
[1]->type
);
641 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
642 switch (op
[0]->type
->base_type
) {
644 data
.b
[c
] = op
[0]->value
.u
[c
] < op
[1]->value
.u
[c
];
647 data
.b
[c
] = op
[0]->value
.i
[c
] < op
[1]->value
.i
[c
];
649 case GLSL_TYPE_FLOAT
:
650 data
.b
[c
] = op
[0]->value
.f
[c
] < op
[1]->value
.f
[c
];
657 case ir_binop_greater
:
658 assert(op
[0]->type
== op
[1]->type
);
659 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
660 switch (op
[0]->type
->base_type
) {
662 data
.b
[c
] = op
[0]->value
.u
[c
] > op
[1]->value
.u
[c
];
665 data
.b
[c
] = op
[0]->value
.i
[c
] > op
[1]->value
.i
[c
];
667 case GLSL_TYPE_FLOAT
:
668 data
.b
[c
] = op
[0]->value
.f
[c
] > op
[1]->value
.f
[c
];
675 case ir_binop_lequal
:
676 assert(op
[0]->type
== op
[1]->type
);
677 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
678 switch (op
[0]->type
->base_type
) {
680 data
.b
[c
] = op
[0]->value
.u
[c
] <= op
[1]->value
.u
[c
];
683 data
.b
[c
] = op
[0]->value
.i
[c
] <= op
[1]->value
.i
[c
];
685 case GLSL_TYPE_FLOAT
:
686 data
.b
[c
] = op
[0]->value
.f
[c
] <= op
[1]->value
.f
[c
];
693 case ir_binop_gequal
:
694 assert(op
[0]->type
== op
[1]->type
);
695 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
696 switch (op
[0]->type
->base_type
) {
698 data
.b
[c
] = op
[0]->value
.u
[c
] >= op
[1]->value
.u
[c
];
701 data
.b
[c
] = op
[0]->value
.i
[c
] >= op
[1]->value
.i
[c
];
703 case GLSL_TYPE_FLOAT
:
704 data
.b
[c
] = op
[0]->value
.f
[c
] >= op
[1]->value
.f
[c
];
712 assert(op
[0]->type
== op
[1]->type
);
713 for (unsigned c
= 0; c
< components
; c
++) {
714 switch (op
[0]->type
->base_type
) {
716 data
.b
[c
] = op
[0]->value
.u
[c
] == op
[1]->value
.u
[c
];
719 data
.b
[c
] = op
[0]->value
.i
[c
] == op
[1]->value
.i
[c
];
721 case GLSL_TYPE_FLOAT
:
722 data
.b
[c
] = op
[0]->value
.f
[c
] == op
[1]->value
.f
[c
];
725 data
.b
[c
] = op
[0]->value
.b
[c
] == op
[1]->value
.b
[c
];
732 case ir_binop_nequal
:
733 assert(op
[0]->type
== op
[1]->type
);
734 for (unsigned c
= 0; c
< components
; c
++) {
735 switch (op
[0]->type
->base_type
) {
737 data
.b
[c
] = op
[0]->value
.u
[c
] != op
[1]->value
.u
[c
];
740 data
.b
[c
] = op
[0]->value
.i
[c
] != op
[1]->value
.i
[c
];
742 case GLSL_TYPE_FLOAT
:
743 data
.b
[c
] = op
[0]->value
.f
[c
] != op
[1]->value
.f
[c
];
746 data
.b
[c
] = op
[0]->value
.b
[c
] != op
[1]->value
.b
[c
];
753 case ir_binop_all_equal
:
754 data
.b
[0] = op
[0]->has_value(op
[1]);
756 case ir_binop_any_nequal
:
757 data
.b
[0] = !op
[0]->has_value(op
[1]);
760 case ir_binop_lshift
:
761 for (unsigned c
= 0, c0
= 0, c1
= 0;
763 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
765 if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
766 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
767 data
.i
[c
] = op
[0]->value
.i
[c0
] << op
[1]->value
.i
[c1
];
769 } else if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
770 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
771 data
.i
[c
] = op
[0]->value
.i
[c0
] << op
[1]->value
.u
[c1
];
773 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
774 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
775 data
.u
[c
] = op
[0]->value
.u
[c0
] << op
[1]->value
.i
[c1
];
777 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
778 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
779 data
.u
[c
] = op
[0]->value
.u
[c0
] << op
[1]->value
.u
[c1
];
784 case ir_binop_rshift
:
785 for (unsigned c
= 0, c0
= 0, c1
= 0;
787 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
789 if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
790 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
791 data
.i
[c
] = op
[0]->value
.i
[c0
] >> op
[1]->value
.i
[c1
];
793 } else if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
794 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
795 data
.i
[c
] = op
[0]->value
.i
[c0
] >> op
[1]->value
.u
[c1
];
797 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
798 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
799 data
.u
[c
] = op
[0]->value
.u
[c0
] >> op
[1]->value
.i
[c1
];
801 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
802 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
803 data
.u
[c
] = op
[0]->value
.u
[c0
] >> op
[1]->value
.u
[c1
];
808 case ir_binop_bit_and
:
809 for (unsigned c
= 0, c0
= 0, c1
= 0;
811 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
813 switch (op
[0]->type
->base_type
) {
815 data
.i
[c
] = op
[0]->value
.i
[c0
] & op
[1]->value
.i
[c1
];
818 data
.u
[c
] = op
[0]->value
.u
[c0
] & op
[1]->value
.u
[c1
];
826 case ir_binop_bit_or
:
827 for (unsigned c
= 0, c0
= 0, c1
= 0;
829 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
831 switch (op
[0]->type
->base_type
) {
833 data
.i
[c
] = op
[0]->value
.i
[c0
] | op
[1]->value
.i
[c1
];
836 data
.u
[c
] = op
[0]->value
.u
[c0
] | op
[1]->value
.u
[c1
];
844 case ir_binop_bit_xor
:
845 for (unsigned c
= 0, c0
= 0, c1
= 0;
847 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
849 switch (op
[0]->type
->base_type
) {
851 data
.i
[c
] = op
[0]->value
.i
[c0
] ^ op
[1]->value
.i
[c1
];
854 data
.u
[c
] = op
[0]->value
.u
[c0
] ^ op
[1]->value
.u
[c1
];
862 case ir_quadop_vector
:
863 for (unsigned c
= 0; c
< this->type
->vector_elements
; c
++) {
864 switch (this->type
->base_type
) {
866 data
.i
[c
] = op
[c
]->value
.i
[0];
869 data
.u
[c
] = op
[c
]->value
.u
[0];
871 case GLSL_TYPE_FLOAT
:
872 data
.f
[c
] = op
[c
]->value
.f
[0];
881 /* FINISHME: Should handle all expression types. */
885 return new(ctx
) ir_constant(this->type
, &data
);
890 ir_texture::constant_expression_value(struct hash_table
*variable_context
)
892 /* texture lookups aren't constant expressions */
898 ir_swizzle::constant_expression_value(struct hash_table
*variable_context
)
900 ir_constant
*v
= this->val
->constant_expression_value(variable_context
);
903 ir_constant_data data
= { { 0 } };
905 const unsigned swiz_idx
[4] = {
906 this->mask
.x
, this->mask
.y
, this->mask
.z
, this->mask
.w
909 for (unsigned i
= 0; i
< this->mask
.num_components
; i
++) {
910 switch (v
->type
->base_type
) {
912 case GLSL_TYPE_INT
: data
.u
[i
] = v
->value
.u
[swiz_idx
[i
]]; break;
913 case GLSL_TYPE_FLOAT
: data
.f
[i
] = v
->value
.f
[swiz_idx
[i
]]; break;
914 case GLSL_TYPE_BOOL
: data
.b
[i
] = v
->value
.b
[swiz_idx
[i
]]; break;
915 default: assert(!"Should not get here."); break;
919 void *ctx
= ralloc_parent(this);
920 return new(ctx
) ir_constant(this->type
, &data
);
927 ir_dereference_variable::constant_referenced(struct hash_table
*variable_context
,
928 ir_constant
*&store
, int &offset
) const
930 if (variable_context
) {
931 store
= (ir_constant
*)hash_table_find(variable_context
, var
);
940 ir_dereference_variable::constant_expression_value(struct hash_table
*variable_context
)
942 /* This may occur during compile and var->type is glsl_type::error_type */
946 /* Give priority to the context hashtable, if it exists */
947 if (variable_context
) {
948 ir_constant
*value
= (ir_constant
*)hash_table_find(variable_context
, var
);
953 /* The constant_value of a uniform variable is its initializer,
954 * not the lifetime constant value of the uniform.
956 if (var
->mode
== ir_var_uniform
)
959 if (!var
->constant_value
)
962 return var
->constant_value
->clone(ralloc_parent(var
), NULL
);
967 ir_dereference_array::constant_referenced(struct hash_table
*variable_context
,
968 ir_constant
*&store
, int &offset
) const
970 ir_constant
*index_c
= array_index
->constant_expression_value(variable_context
);
972 if (!index_c
|| !index_c
->type
->is_scalar() || !index_c
->type
->is_integer()) {
978 int index
= index_c
->type
->base_type
== GLSL_TYPE_INT
?
979 index_c
->get_int_component(0) :
980 index_c
->get_uint_component(0);
982 ir_constant
*substore
;
984 const ir_dereference
*deref
= array
->as_dereference();
991 deref
->constant_referenced(variable_context
, substore
, suboffset
);
999 const glsl_type
*vt
= substore
->type
;
1000 if (vt
->is_array()) {
1001 store
= substore
->get_array_element(index
);
1005 if (vt
->is_matrix()) {
1007 offset
= index
* vt
->vector_elements
;
1010 if (vt
->is_vector()) {
1012 offset
= suboffset
+ index
;
1021 ir_dereference_array::constant_expression_value(struct hash_table
*variable_context
)
1023 ir_constant
*array
= this->array
->constant_expression_value(variable_context
);
1024 ir_constant
*idx
= this->array_index
->constant_expression_value(variable_context
);
1026 if ((array
!= NULL
) && (idx
!= NULL
)) {
1027 void *ctx
= ralloc_parent(this);
1028 if (array
->type
->is_matrix()) {
1029 /* Array access of a matrix results in a vector.
1031 const unsigned column
= idx
->value
.u
[0];
1033 const glsl_type
*const column_type
= array
->type
->column_type();
1035 /* Offset in the constant matrix to the first element of the column
1038 const unsigned mat_idx
= column
* column_type
->vector_elements
;
1040 ir_constant_data data
= { { 0 } };
1042 switch (column_type
->base_type
) {
1043 case GLSL_TYPE_UINT
:
1045 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
1046 data
.u
[i
] = array
->value
.u
[mat_idx
+ i
];
1050 case GLSL_TYPE_FLOAT
:
1051 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
1052 data
.f
[i
] = array
->value
.f
[mat_idx
+ i
];
1057 assert(!"Should not get here.");
1061 return new(ctx
) ir_constant(column_type
, &data
);
1062 } else if (array
->type
->is_vector()) {
1063 const unsigned component
= idx
->value
.u
[0];
1065 return new(ctx
) ir_constant(array
, component
);
1067 const unsigned index
= idx
->value
.u
[0];
1068 return array
->get_array_element(index
)->clone(ctx
, NULL
);
1076 ir_dereference_record::constant_referenced(struct hash_table
*variable_context
,
1077 ir_constant
*&store
, int &offset
) const
1079 ir_constant
*substore
;
1081 const ir_dereference
*deref
= record
->as_dereference();
1088 deref
->constant_referenced(variable_context
, substore
, suboffset
);
1096 store
= substore
->get_record_field(field
);
1101 ir_dereference_record::constant_expression_value(struct hash_table
*variable_context
)
1103 ir_constant
*v
= this->record
->constant_expression_value();
1105 return (v
!= NULL
) ? v
->get_record_field(this->field
) : NULL
;
1110 ir_assignment::constant_expression_value(struct hash_table
*variable_context
)
1112 /* FINISHME: Handle CEs involving assignment (return RHS) */
1118 ir_constant::constant_expression_value(struct hash_table
*variable_context
)
1125 ir_call::constant_expression_value(struct hash_table
*variable_context
)
1127 return this->callee
->constant_expression_value(&this->actual_parameters
, variable_context
);
1132 ir_function_signature::constant_expression_value(exec_list
*actual_parameters
, struct hash_table
*variable_context
)
1134 const glsl_type
*type
= this->return_type
;
1135 if (type
== glsl_type::void_type
)
1138 /* From the GLSL 1.20 spec, page 23:
1139 * "Function calls to user-defined functions (non-built-in functions)
1140 * cannot be used to form constant expressions."
1142 if (!this->is_builtin
)
1145 unsigned num_parameters
= 0;
1147 /* Check if all parameters are constant */
1149 foreach_list(n
, actual_parameters
) {
1150 ir_constant
*constant
= ((ir_rvalue
*) n
)->constant_expression_value(variable_context
);
1151 if (constant
== NULL
)
1154 op
[num_parameters
] = constant
;
1156 assert(num_parameters
< 3);
1160 /* Individual cases below can either:
1161 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
1162 * - Fill "data" with appopriate constant data
1163 * - Return an ir_constant directly.
1165 void *mem_ctx
= ralloc_parent(this);
1166 ir_expression
*expr
= NULL
;
1168 ir_constant_data data
;
1169 memset(&data
, 0, sizeof(data
));
1171 const char *callee
= this->function_name();
1172 if (strcmp(callee
, "abs") == 0) {
1173 expr
= new(mem_ctx
) ir_expression(ir_unop_abs
, type
, op
[0], NULL
);
1174 } else if (strcmp(callee
, "all") == 0) {
1175 assert(op
[0]->type
->is_boolean());
1176 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1177 if (!op
[0]->value
.b
[c
])
1178 return new(mem_ctx
) ir_constant(false);
1180 return new(mem_ctx
) ir_constant(true);
1181 } else if (strcmp(callee
, "any") == 0) {
1182 assert(op
[0]->type
->is_boolean());
1183 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1184 if (op
[0]->value
.b
[c
])
1185 return new(mem_ctx
) ir_constant(true);
1187 return new(mem_ctx
) ir_constant(false);
1188 } else if (strcmp(callee
, "acos") == 0) {
1189 assert(op
[0]->type
->is_float());
1190 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1191 data
.f
[c
] = acosf(op
[0]->value
.f
[c
]);
1192 } else if (strcmp(callee
, "acosh") == 0) {
1193 assert(op
[0]->type
->is_float());
1194 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1195 data
.f
[c
] = acoshf(op
[0]->value
.f
[c
]);
1196 } else if (strcmp(callee
, "asin") == 0) {
1197 assert(op
[0]->type
->is_float());
1198 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1199 data
.f
[c
] = asinf(op
[0]->value
.f
[c
]);
1200 } else if (strcmp(callee
, "asinh") == 0) {
1201 assert(op
[0]->type
->is_float());
1202 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1203 data
.f
[c
] = asinhf(op
[0]->value
.f
[c
]);
1204 } else if (strcmp(callee
, "atan") == 0) {
1205 assert(op
[0]->type
->is_float());
1206 if (num_parameters
== 2) {
1207 assert(op
[1]->type
->is_float());
1208 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1209 data
.f
[c
] = atan2f(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
1211 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1212 data
.f
[c
] = atanf(op
[0]->value
.f
[c
]);
1214 } else if (strcmp(callee
, "atanh") == 0) {
1215 assert(op
[0]->type
->is_float());
1216 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1217 data
.f
[c
] = atanhf(op
[0]->value
.f
[c
]);
1218 } else if (strcmp(callee
, "dFdx") == 0 || strcmp(callee
, "dFdy") == 0) {
1219 return ir_constant::zero(mem_ctx
, type
);
1220 } else if (strcmp(callee
, "ceil") == 0) {
1221 expr
= new(mem_ctx
) ir_expression(ir_unop_ceil
, type
, op
[0], NULL
);
1222 } else if (strcmp(callee
, "clamp") == 0) {
1223 assert(num_parameters
== 3);
1224 unsigned c1_inc
= op
[1]->type
->is_scalar() ? 0 : 1;
1225 unsigned c2_inc
= op
[2]->type
->is_scalar() ? 0 : 1;
1226 for (unsigned c
= 0, c1
= 0, c2
= 0;
1227 c
< op
[0]->type
->components();
1228 c1
+= c1_inc
, c2
+= c2_inc
, c
++) {
1230 switch (op
[0]->type
->base_type
) {
1231 case GLSL_TYPE_UINT
:
1232 data
.u
[c
] = CLAMP(op
[0]->value
.u
[c
], op
[1]->value
.u
[c1
],
1233 op
[2]->value
.u
[c2
]);
1236 data
.i
[c
] = CLAMP(op
[0]->value
.i
[c
], op
[1]->value
.i
[c1
],
1237 op
[2]->value
.i
[c2
]);
1239 case GLSL_TYPE_FLOAT
:
1240 data
.f
[c
] = CLAMP(op
[0]->value
.f
[c
], op
[1]->value
.f
[c1
],
1241 op
[2]->value
.f
[c2
]);
1244 assert(!"Should not get here.");
1247 } else if (strcmp(callee
, "cos") == 0) {
1248 expr
= new(mem_ctx
) ir_expression(ir_unop_cos
, type
, op
[0], NULL
);
1249 } else if (strcmp(callee
, "cosh") == 0) {
1250 assert(op
[0]->type
->is_float());
1251 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1252 data
.f
[c
] = coshf(op
[0]->value
.f
[c
]);
1253 } else if (strcmp(callee
, "cross") == 0) {
1254 assert(op
[0]->type
== glsl_type::vec3_type
);
1255 assert(op
[1]->type
== glsl_type::vec3_type
);
1256 data
.f
[0] = (op
[0]->value
.f
[1] * op
[1]->value
.f
[2] -
1257 op
[1]->value
.f
[1] * op
[0]->value
.f
[2]);
1258 data
.f
[1] = (op
[0]->value
.f
[2] * op
[1]->value
.f
[0] -
1259 op
[1]->value
.f
[2] * op
[0]->value
.f
[0]);
1260 data
.f
[2] = (op
[0]->value
.f
[0] * op
[1]->value
.f
[1] -
1261 op
[1]->value
.f
[0] * op
[0]->value
.f
[1]);
1262 } else if (strcmp(callee
, "degrees") == 0) {
1263 assert(op
[0]->type
->is_float());
1264 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1265 data
.f
[c
] = 180.0F
/ M_PI
* op
[0]->value
.f
[c
];
1266 } else if (strcmp(callee
, "distance") == 0) {
1267 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1268 float length_squared
= 0.0;
1269 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1270 float t
= op
[0]->value
.f
[c
] - op
[1]->value
.f
[c
];
1271 length_squared
+= t
* t
;
1273 return new(mem_ctx
) ir_constant(sqrtf(length_squared
));
1274 } else if (strcmp(callee
, "dot") == 0) {
1275 return new(mem_ctx
) ir_constant(dot(op
[0], op
[1]));
1276 } else if (strcmp(callee
, "equal") == 0) {
1277 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1278 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1279 switch (op
[0]->type
->base_type
) {
1280 case GLSL_TYPE_UINT
:
1281 data
.b
[c
] = op
[0]->value
.u
[c
] == op
[1]->value
.u
[c
];
1284 data
.b
[c
] = op
[0]->value
.i
[c
] == op
[1]->value
.i
[c
];
1286 case GLSL_TYPE_FLOAT
:
1287 data
.b
[c
] = op
[0]->value
.f
[c
] == op
[1]->value
.f
[c
];
1289 case GLSL_TYPE_BOOL
:
1290 data
.b
[c
] = op
[0]->value
.b
[c
] == op
[1]->value
.b
[c
];
1293 assert(!"Should not get here.");
1296 } else if (strcmp(callee
, "exp") == 0) {
1297 expr
= new(mem_ctx
) ir_expression(ir_unop_exp
, type
, op
[0], NULL
);
1298 } else if (strcmp(callee
, "exp2") == 0) {
1299 expr
= new(mem_ctx
) ir_expression(ir_unop_exp2
, type
, op
[0], NULL
);
1300 } else if (strcmp(callee
, "faceforward") == 0) {
1301 if (dot(op
[2], op
[1]) < 0)
1303 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1304 data
.f
[c
] = -op
[0]->value
.f
[c
];
1305 } else if (strcmp(callee
, "floor") == 0) {
1306 expr
= new(mem_ctx
) ir_expression(ir_unop_floor
, type
, op
[0], NULL
);
1307 } else if (strcmp(callee
, "fract") == 0) {
1308 expr
= new(mem_ctx
) ir_expression(ir_unop_fract
, type
, op
[0], NULL
);
1309 } else if (strcmp(callee
, "fwidth") == 0) {
1310 return ir_constant::zero(mem_ctx
, type
);
1311 } else if (strcmp(callee
, "greaterThan") == 0) {
1312 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1313 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1314 switch (op
[0]->type
->base_type
) {
1315 case GLSL_TYPE_UINT
:
1316 data
.b
[c
] = op
[0]->value
.u
[c
] > op
[1]->value
.u
[c
];
1319 data
.b
[c
] = op
[0]->value
.i
[c
] > op
[1]->value
.i
[c
];
1321 case GLSL_TYPE_FLOAT
:
1322 data
.b
[c
] = op
[0]->value
.f
[c
] > op
[1]->value
.f
[c
];
1325 assert(!"Should not get here.");
1328 } else if (strcmp(callee
, "greaterThanEqual") == 0) {
1329 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1330 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1331 switch (op
[0]->type
->base_type
) {
1332 case GLSL_TYPE_UINT
:
1333 data
.b
[c
] = op
[0]->value
.u
[c
] >= op
[1]->value
.u
[c
];
1336 data
.b
[c
] = op
[0]->value
.i
[c
] >= op
[1]->value
.i
[c
];
1338 case GLSL_TYPE_FLOAT
:
1339 data
.b
[c
] = op
[0]->value
.f
[c
] >= op
[1]->value
.f
[c
];
1342 assert(!"Should not get here.");
1345 } else if (strcmp(callee
, "inversesqrt") == 0) {
1346 expr
= new(mem_ctx
) ir_expression(ir_unop_rsq
, type
, op
[0], NULL
);
1347 } else if (strcmp(callee
, "length") == 0) {
1348 return new(mem_ctx
) ir_constant(sqrtf(dot(op
[0], op
[0])));
1349 } else if (strcmp(callee
, "lessThan") == 0) {
1350 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1351 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1352 switch (op
[0]->type
->base_type
) {
1353 case GLSL_TYPE_UINT
:
1354 data
.b
[c
] = op
[0]->value
.u
[c
] < op
[1]->value
.u
[c
];
1357 data
.b
[c
] = op
[0]->value
.i
[c
] < op
[1]->value
.i
[c
];
1359 case GLSL_TYPE_FLOAT
:
1360 data
.b
[c
] = op
[0]->value
.f
[c
] < op
[1]->value
.f
[c
];
1363 assert(!"Should not get here.");
1366 } else if (strcmp(callee
, "lessThanEqual") == 0) {
1367 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1368 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1369 switch (op
[0]->type
->base_type
) {
1370 case GLSL_TYPE_UINT
:
1371 data
.b
[c
] = op
[0]->value
.u
[c
] <= op
[1]->value
.u
[c
];
1374 data
.b
[c
] = op
[0]->value
.i
[c
] <= op
[1]->value
.i
[c
];
1376 case GLSL_TYPE_FLOAT
:
1377 data
.b
[c
] = op
[0]->value
.f
[c
] <= op
[1]->value
.f
[c
];
1380 assert(!"Should not get here.");
1383 } else if (strcmp(callee
, "log") == 0) {
1384 expr
= new(mem_ctx
) ir_expression(ir_unop_log
, type
, op
[0], NULL
);
1385 } else if (strcmp(callee
, "log2") == 0) {
1386 expr
= new(mem_ctx
) ir_expression(ir_unop_log2
, type
, op
[0], NULL
);
1387 } else if (strcmp(callee
, "matrixCompMult") == 0) {
1388 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1389 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1390 data
.f
[c
] = op
[0]->value
.f
[c
] * op
[1]->value
.f
[c
];
1391 } else if (strcmp(callee
, "max") == 0) {
1392 expr
= new(mem_ctx
) ir_expression(ir_binop_max
, type
, op
[0], op
[1]);
1393 } else if (strcmp(callee
, "min") == 0) {
1394 expr
= new(mem_ctx
) ir_expression(ir_binop_min
, type
, op
[0], op
[1]);
1395 } else if (strcmp(callee
, "mix") == 0) {
1396 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1397 if (op
[2]->type
->is_float()) {
1398 unsigned c2_inc
= op
[2]->type
->is_scalar() ? 0 : 1;
1399 unsigned components
= op
[0]->type
->components();
1400 for (unsigned c
= 0, c2
= 0; c
< components
; c2
+= c2_inc
, c
++) {
1401 data
.f
[c
] = op
[0]->value
.f
[c
] * (1 - op
[2]->value
.f
[c2
]) +
1402 op
[1]->value
.f
[c
] * op
[2]->value
.f
[c2
];
1405 assert(op
[2]->type
->is_boolean());
1406 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1407 data
.f
[c
] = op
[op
[2]->value
.b
[c
] ? 1 : 0]->value
.f
[c
];
1409 } else if (strcmp(callee
, "mod") == 0) {
1410 expr
= new(mem_ctx
) ir_expression(ir_binop_mod
, type
, op
[0], op
[1]);
1411 } else if (strcmp(callee
, "normalize") == 0) {
1412 assert(op
[0]->type
->is_float());
1413 float length
= sqrtf(dot(op
[0], op
[0]));
1416 return ir_constant::zero(mem_ctx
, type
);
1418 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1419 data
.f
[c
] = op
[0]->value
.f
[c
] / length
;
1420 } else if (strcmp(callee
, "not") == 0) {
1421 expr
= new(mem_ctx
) ir_expression(ir_unop_logic_not
, type
, op
[0], NULL
);
1422 } else if (strcmp(callee
, "notEqual") == 0) {
1423 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1424 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1425 switch (op
[0]->type
->base_type
) {
1426 case GLSL_TYPE_UINT
:
1427 data
.b
[c
] = op
[0]->value
.u
[c
] != op
[1]->value
.u
[c
];
1430 data
.b
[c
] = op
[0]->value
.i
[c
] != op
[1]->value
.i
[c
];
1432 case GLSL_TYPE_FLOAT
:
1433 data
.b
[c
] = op
[0]->value
.f
[c
] != op
[1]->value
.f
[c
];
1435 case GLSL_TYPE_BOOL
:
1436 data
.b
[c
] = op
[0]->value
.b
[c
] != op
[1]->value
.b
[c
];
1439 assert(!"Should not get here.");
1442 } else if (strcmp(callee
, "outerProduct") == 0) {
1443 assert(op
[0]->type
->is_vector() && op
[1]->type
->is_vector());
1444 const unsigned m
= op
[0]->type
->vector_elements
;
1445 const unsigned n
= op
[1]->type
->vector_elements
;
1446 for (unsigned j
= 0; j
< n
; j
++) {
1447 for (unsigned i
= 0; i
< m
; i
++) {
1448 data
.f
[i
+m
*j
] = op
[0]->value
.f
[i
] * op
[1]->value
.f
[j
];
1451 } else if (strcmp(callee
, "pow") == 0) {
1452 expr
= new(mem_ctx
) ir_expression(ir_binop_pow
, type
, op
[0], op
[1]);
1453 } else if (strcmp(callee
, "radians") == 0) {
1454 assert(op
[0]->type
->is_float());
1455 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1456 data
.f
[c
] = M_PI
/ 180.0F
* op
[0]->value
.f
[c
];
1457 } else if (strcmp(callee
, "reflect") == 0) {
1458 assert(op
[0]->type
->is_float());
1459 float dot_NI
= dot(op
[1], op
[0]);
1460 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1461 data
.f
[c
] = op
[0]->value
.f
[c
] - 2 * dot_NI
* op
[1]->value
.f
[c
];
1462 } else if (strcmp(callee
, "refract") == 0) {
1463 const float eta
= op
[2]->value
.f
[0];
1464 const float dot_NI
= dot(op
[1], op
[0]);
1465 const float k
= 1.0F
- eta
* eta
* (1.0F
- dot_NI
* dot_NI
);
1467 return ir_constant::zero(mem_ctx
, type
);
1469 for (unsigned c
= 0; c
< type
->components(); c
++) {
1470 data
.f
[c
] = eta
* op
[0]->value
.f
[c
] - (eta
* dot_NI
+ sqrtf(k
))
1471 * op
[1]->value
.f
[c
];
1474 } else if (strcmp(callee
, "round") == 0 ||
1475 strcmp(callee
, "roundEven") == 0) {
1476 expr
= new(mem_ctx
) ir_expression(ir_unop_round_even
, op
[0]);
1477 } else if (strcmp(callee
, "sign") == 0) {
1478 expr
= new(mem_ctx
) ir_expression(ir_unop_sign
, type
, op
[0], NULL
);
1479 } else if (strcmp(callee
, "sin") == 0) {
1480 expr
= new(mem_ctx
) ir_expression(ir_unop_sin
, type
, op
[0], NULL
);
1481 } else if (strcmp(callee
, "sinh") == 0) {
1482 assert(op
[0]->type
->is_float());
1483 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1484 data
.f
[c
] = sinhf(op
[0]->value
.f
[c
]);
1485 } else if (strcmp(callee
, "smoothstep") == 0) {
1486 assert(num_parameters
== 3);
1487 assert(op
[1]->type
== op
[0]->type
);
1488 unsigned edge_inc
= op
[0]->type
->is_scalar() ? 0 : 1;
1489 for (unsigned c
= 0, e
= 0; c
< type
->components(); e
+= edge_inc
, c
++) {
1490 const float edge0
= op
[0]->value
.f
[e
];
1491 const float edge1
= op
[1]->value
.f
[e
];
1492 if (edge0
== edge1
) {
1493 data
.f
[c
] = 0.0; /* Avoid a crash - results are undefined anyway */
1495 const float numerator
= op
[2]->value
.f
[c
] - edge0
;
1496 const float denominator
= edge1
- edge0
;
1497 const float t
= CLAMP(numerator
/denominator
, 0, 1);
1498 data
.f
[c
] = t
* t
* (3 - 2 * t
);
1501 } else if (strcmp(callee
, "sqrt") == 0) {
1502 expr
= new(mem_ctx
) ir_expression(ir_unop_sqrt
, type
, op
[0], NULL
);
1503 } else if (strcmp(callee
, "step") == 0) {
1504 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1505 /* op[0] (edge) may be either a scalar or a vector */
1506 const unsigned c0_inc
= op
[0]->type
->is_scalar() ? 0 : 1;
1507 for (unsigned c
= 0, c0
= 0; c
< type
->components(); c0
+= c0_inc
, c
++)
1508 data
.f
[c
] = (op
[1]->value
.f
[c
] < op
[0]->value
.f
[c0
]) ? 0.0F
: 1.0F
;
1509 } else if (strcmp(callee
, "tan") == 0) {
1510 assert(op
[0]->type
->is_float());
1511 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1512 data
.f
[c
] = tanf(op
[0]->value
.f
[c
]);
1513 } else if (strcmp(callee
, "tanh") == 0) {
1514 assert(op
[0]->type
->is_float());
1515 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1516 data
.f
[c
] = tanhf(op
[0]->value
.f
[c
]);
1517 } else if (strcmp(callee
, "transpose") == 0) {
1518 assert(op
[0]->type
->is_matrix());
1519 const unsigned n
= op
[0]->type
->vector_elements
;
1520 const unsigned m
= op
[0]->type
->matrix_columns
;
1521 for (unsigned j
= 0; j
< m
; j
++) {
1522 for (unsigned i
= 0; i
< n
; i
++) {
1523 data
.f
[m
*i
+j
] += op
[0]->value
.f
[i
+n
*j
];
1526 } else if (strcmp(callee
, "trunc") == 0) {
1527 expr
= new(mem_ctx
) ir_expression(ir_unop_trunc
, op
[0]);
1529 /* Unsupported builtin - some are not allowed in constant expressions. */
1534 return expr
->constant_expression_value();
1536 return new(mem_ctx
) ir_constant(type
, &data
);