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"
43 dot(ir_constant
*op0
, ir_constant
*op1
)
45 assert(op0
->type
->is_float() && op1
->type
->is_float());
48 for (unsigned c
= 0; c
< op0
->type
->components(); c
++)
49 result
+= op0
->value
.f
[c
] * op1
->value
.f
[c
];
55 ir_expression::constant_expression_value()
57 if (this->type
->is_error())
60 ir_constant
*op
[Elements(this->operands
)] = { NULL
, };
61 ir_constant_data data
;
63 memset(&data
, 0, sizeof(data
));
65 for (unsigned operand
= 0; operand
< this->get_num_operands(); operand
++) {
66 op
[operand
] = this->operands
[operand
]->constant_expression_value();
72 assert(op
[0]->type
->base_type
== op
[1]->type
->base_type
);
74 bool op0_scalar
= op
[0]->type
->is_scalar();
75 bool op1_scalar
= op
[1] != NULL
&& op
[1]->type
->is_scalar();
77 /* When iterating over a vector or matrix's components, we want to increase
78 * the loop counter. However, for scalars, we want to stay at 0.
80 unsigned c0_inc
= op0_scalar
? 0 : 1;
81 unsigned c1_inc
= op1_scalar
? 0 : 1;
83 if (op1_scalar
|| !op
[1]) {
84 components
= op
[0]->type
->components();
86 components
= op
[1]->type
->components();
89 void *ctx
= ralloc_parent(this);
91 /* Handle array operations here, rather than below. */
92 if (op
[0]->type
->is_array()) {
93 assert(op
[1] != NULL
&& op
[1]->type
->is_array());
94 switch (this->operation
) {
95 case ir_binop_all_equal
:
96 return new(ctx
) ir_constant(op
[0]->has_value(op
[1]));
97 case ir_binop_any_nequal
:
98 return new(ctx
) ir_constant(!op
[0]->has_value(op
[1]));
105 switch (this->operation
) {
106 case ir_unop_bit_not
:
107 switch (op
[0]->type
->base_type
) {
109 for (unsigned c
= 0; c
< components
; c
++)
110 data
.i
[c
] = ~ op
[0]->value
.i
[c
];
113 for (unsigned c
= 0; c
< components
; c
++)
114 data
.u
[c
] = ~ op
[0]->value
.u
[c
];
121 case ir_unop_logic_not
:
122 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
123 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
124 data
.b
[c
] = !op
[0]->value
.b
[c
];
128 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
129 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
130 data
.i
[c
] = (int) op
[0]->value
.f
[c
];
134 assert(op
[0]->type
->base_type
== GLSL_TYPE_INT
);
135 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
136 data
.f
[c
] = (float) op
[0]->value
.i
[c
];
140 assert(op
[0]->type
->base_type
== GLSL_TYPE_UINT
);
141 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
142 data
.f
[c
] = (float) op
[0]->value
.u
[c
];
146 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
147 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
148 data
.f
[c
] = op
[0]->value
.b
[c
] ? 1.0F
: 0.0F
;
152 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
153 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
154 data
.b
[c
] = op
[0]->value
.f
[c
] != 0.0F
? true : false;
158 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
159 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
160 data
.u
[c
] = op
[0]->value
.b
[c
] ? 1 : 0;
164 assert(op
[0]->type
->is_integer());
165 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
166 data
.b
[c
] = op
[0]->value
.u
[c
] ? true : false;
170 assert(op
[0]->type
->base_type
== GLSL_TYPE_UINT
);
171 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
172 data
.i
[c
] = op
[0]->value
.u
[c
];
176 assert(op
[0]->type
->base_type
== GLSL_TYPE_INT
);
177 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
178 data
.u
[c
] = op
[0]->value
.i
[c
];
182 assert(op
[0]->type
->is_boolean());
184 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
185 if (op
[0]->value
.b
[c
])
191 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
192 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
193 data
.f
[c
] = truncf(op
[0]->value
.f
[c
]);
198 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
199 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
200 data
.f
[c
] = ceilf(op
[0]->value
.f
[c
]);
205 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
206 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
207 data
.f
[c
] = floorf(op
[0]->value
.f
[c
]);
212 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
213 switch (this->type
->base_type
) {
220 case GLSL_TYPE_FLOAT
:
221 data
.f
[c
] = op
[0]->value
.f
[c
] - floor(op
[0]->value
.f
[c
]);
230 case ir_unop_sin_reduced
:
231 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
232 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
233 data
.f
[c
] = sinf(op
[0]->value
.f
[c
]);
238 case ir_unop_cos_reduced
:
239 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
240 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
241 data
.f
[c
] = cosf(op
[0]->value
.f
[c
]);
246 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
247 switch (this->type
->base_type
) {
249 data
.u
[c
] = -((int) op
[0]->value
.u
[c
]);
252 data
.i
[c
] = -op
[0]->value
.i
[c
];
254 case GLSL_TYPE_FLOAT
:
255 data
.f
[c
] = -op
[0]->value
.f
[c
];
264 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
265 switch (this->type
->base_type
) {
267 data
.u
[c
] = op
[0]->value
.u
[c
];
270 data
.i
[c
] = op
[0]->value
.i
[c
];
272 data
.i
[c
] = -data
.i
[c
];
274 case GLSL_TYPE_FLOAT
:
275 data
.f
[c
] = fabs(op
[0]->value
.f
[c
]);
284 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
285 switch (this->type
->base_type
) {
287 data
.u
[c
] = op
[0]->value
.i
[c
] > 0;
290 data
.i
[c
] = (op
[0]->value
.i
[c
] > 0) - (op
[0]->value
.i
[c
] < 0);
292 case GLSL_TYPE_FLOAT
:
293 data
.f
[c
] = float((op
[0]->value
.f
[c
] > 0)-(op
[0]->value
.f
[c
] < 0));
302 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
303 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
304 switch (this->type
->base_type
) {
306 if (op
[0]->value
.u
[c
] != 0.0)
307 data
.u
[c
] = 1 / op
[0]->value
.u
[c
];
310 if (op
[0]->value
.i
[c
] != 0.0)
311 data
.i
[c
] = 1 / op
[0]->value
.i
[c
];
313 case GLSL_TYPE_FLOAT
:
314 if (op
[0]->value
.f
[c
] != 0.0)
315 data
.f
[c
] = 1.0F
/ op
[0]->value
.f
[c
];
324 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
325 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
326 data
.f
[c
] = 1.0F
/ sqrtf(op
[0]->value
.f
[c
]);
331 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
332 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
333 data
.f
[c
] = sqrtf(op
[0]->value
.f
[c
]);
338 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
339 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
340 data
.f
[c
] = expf(op
[0]->value
.f
[c
]);
345 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
346 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
347 data
.f
[c
] = exp2f(op
[0]->value
.f
[c
]);
352 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
353 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
354 data
.f
[c
] = logf(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
] = log2f(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
++) {
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
] = powf(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
381 data
.f
[0] = dot(op
[0], op
[1]);
385 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
386 for (unsigned c
= 0, c0
= 0, c1
= 0;
388 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
390 switch (op
[0]->type
->base_type
) {
392 data
.u
[c
] = MIN2(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
395 data
.i
[c
] = MIN2(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
397 case GLSL_TYPE_FLOAT
:
398 data
.f
[c
] = MIN2(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
407 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
408 for (unsigned c
= 0, c0
= 0, c1
= 0;
410 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
412 switch (op
[0]->type
->base_type
) {
414 data
.u
[c
] = MAX2(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
417 data
.i
[c
] = MAX2(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
419 case GLSL_TYPE_FLOAT
:
420 data
.f
[c
] = MAX2(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
429 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
430 for (unsigned c
= 0, c0
= 0, c1
= 0;
432 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
434 switch (op
[0]->type
->base_type
) {
436 data
.u
[c
] = op
[0]->value
.u
[c0
] + op
[1]->value
.u
[c1
];
439 data
.i
[c
] = op
[0]->value
.i
[c0
] + op
[1]->value
.i
[c1
];
441 case GLSL_TYPE_FLOAT
:
442 data
.f
[c
] = op
[0]->value
.f
[c0
] + op
[1]->value
.f
[c1
];
451 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
452 for (unsigned c
= 0, c0
= 0, c1
= 0;
454 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
456 switch (op
[0]->type
->base_type
) {
458 data
.u
[c
] = op
[0]->value
.u
[c0
] - op
[1]->value
.u
[c1
];
461 data
.i
[c
] = op
[0]->value
.i
[c0
] - op
[1]->value
.i
[c1
];
463 case GLSL_TYPE_FLOAT
:
464 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
];
473 /* Check for equal types, or unequal types involving scalars */
474 if ((op
[0]->type
== op
[1]->type
&& !op
[0]->type
->is_matrix())
475 || op0_scalar
|| op1_scalar
) {
476 for (unsigned c
= 0, c0
= 0, c1
= 0;
478 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
480 switch (op
[0]->type
->base_type
) {
482 data
.u
[c
] = op
[0]->value
.u
[c0
] * op
[1]->value
.u
[c1
];
485 data
.i
[c
] = op
[0]->value
.i
[c0
] * op
[1]->value
.i
[c1
];
487 case GLSL_TYPE_FLOAT
:
488 data
.f
[c
] = op
[0]->value
.f
[c0
] * op
[1]->value
.f
[c1
];
495 assert(op
[0]->type
->is_matrix() || op
[1]->type
->is_matrix());
497 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
498 * matrix can be a GLSL vector, either N or P can be 1.
500 * For vec*mat, the vector is treated as a row vector. This
501 * means the vector is a 1-row x M-column matrix.
503 * For mat*vec, the vector is treated as a column vector. Since
504 * matrix_columns is 1 for vectors, this just works.
506 const unsigned n
= op
[0]->type
->is_vector()
507 ? 1 : op
[0]->type
->vector_elements
;
508 const unsigned m
= op
[1]->type
->vector_elements
;
509 const unsigned p
= op
[1]->type
->matrix_columns
;
510 for (unsigned j
= 0; j
< p
; j
++) {
511 for (unsigned i
= 0; i
< n
; i
++) {
512 for (unsigned k
= 0; k
< m
; k
++) {
513 data
.f
[i
+n
*j
] += op
[0]->value
.f
[i
+n
*k
]*op
[1]->value
.f
[k
+m
*j
];
521 /* FINISHME: Emit warning when division-by-zero is detected. */
522 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
523 for (unsigned c
= 0, c0
= 0, c1
= 0;
525 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
527 switch (op
[0]->type
->base_type
) {
529 if (op
[1]->value
.u
[c1
] == 0) {
532 data
.u
[c
] = op
[0]->value
.u
[c0
] / op
[1]->value
.u
[c1
];
536 if (op
[1]->value
.i
[c1
] == 0) {
539 data
.i
[c
] = op
[0]->value
.i
[c0
] / op
[1]->value
.i
[c1
];
542 case GLSL_TYPE_FLOAT
:
543 data
.f
[c
] = op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
];
552 /* FINISHME: Emit warning when division-by-zero is detected. */
553 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
554 for (unsigned c
= 0, c0
= 0, c1
= 0;
556 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
558 switch (op
[0]->type
->base_type
) {
560 if (op
[1]->value
.u
[c1
] == 0) {
563 data
.u
[c
] = op
[0]->value
.u
[c0
] % op
[1]->value
.u
[c1
];
567 if (op
[1]->value
.i
[c1
] == 0) {
570 data
.i
[c
] = op
[0]->value
.i
[c0
] % op
[1]->value
.i
[c1
];
573 case GLSL_TYPE_FLOAT
:
574 /* We don't use fmod because it rounds toward zero; GLSL specifies
577 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
]
578 * floorf(op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
]);
587 case ir_binop_logic_and
:
588 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
589 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
590 data
.b
[c
] = op
[0]->value
.b
[c
] && op
[1]->value
.b
[c
];
592 case ir_binop_logic_xor
:
593 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
594 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
595 data
.b
[c
] = op
[0]->value
.b
[c
] ^ op
[1]->value
.b
[c
];
597 case ir_binop_logic_or
:
598 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
599 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
600 data
.b
[c
] = op
[0]->value
.b
[c
] || op
[1]->value
.b
[c
];
604 assert(op
[0]->type
== op
[1]->type
);
605 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
606 switch (op
[0]->type
->base_type
) {
608 data
.b
[0] = op
[0]->value
.u
[0] < op
[1]->value
.u
[0];
611 data
.b
[0] = op
[0]->value
.i
[0] < op
[1]->value
.i
[0];
613 case GLSL_TYPE_FLOAT
:
614 data
.b
[0] = op
[0]->value
.f
[0] < op
[1]->value
.f
[0];
621 case ir_binop_greater
:
622 assert(op
[0]->type
== op
[1]->type
);
623 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
624 switch (op
[0]->type
->base_type
) {
626 data
.b
[c
] = op
[0]->value
.u
[c
] > op
[1]->value
.u
[c
];
629 data
.b
[c
] = op
[0]->value
.i
[c
] > op
[1]->value
.i
[c
];
631 case GLSL_TYPE_FLOAT
:
632 data
.b
[c
] = op
[0]->value
.f
[c
] > op
[1]->value
.f
[c
];
639 case ir_binop_lequal
:
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
[0] = op
[0]->value
.u
[0] <= op
[1]->value
.u
[0];
647 data
.b
[0] = op
[0]->value
.i
[0] <= op
[1]->value
.i
[0];
649 case GLSL_TYPE_FLOAT
:
650 data
.b
[0] = op
[0]->value
.f
[0] <= op
[1]->value
.f
[0];
657 case ir_binop_gequal
:
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
[0] = op
[0]->value
.u
[0] >= op
[1]->value
.u
[0];
665 data
.b
[0] = op
[0]->value
.i
[0] >= op
[1]->value
.i
[0];
667 case GLSL_TYPE_FLOAT
:
668 data
.b
[0] = op
[0]->value
.f
[0] >= op
[1]->value
.f
[0];
676 assert(op
[0]->type
== op
[1]->type
);
677 for (unsigned c
= 0; c
< 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_nequal
:
694 assert(op
[0]->type
!= op
[1]->type
);
695 for (unsigned c
= 0; c
< 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
];
711 case ir_binop_all_equal
:
712 data
.b
[0] = op
[0]->has_value(op
[1]);
714 case ir_binop_any_nequal
:
715 data
.b
[0] = !op
[0]->has_value(op
[1]);
718 case ir_binop_lshift
:
719 for (unsigned c
= 0, c0
= 0, c1
= 0;
721 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
723 if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
724 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
725 data
.i
[c
] = op
[0]->value
.i
[c0
] << op
[1]->value
.i
[c1
];
727 } else if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
728 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
729 data
.i
[c
] = op
[0]->value
.i
[c0
] << op
[1]->value
.u
[c1
];
731 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
732 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
733 data
.u
[c
] = op
[0]->value
.u
[c0
] << op
[1]->value
.i
[c1
];
735 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
736 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
737 data
.u
[c
] = op
[0]->value
.u
[c0
] << op
[1]->value
.u
[c1
];
742 case ir_binop_rshift
:
743 for (unsigned c
= 0, c0
= 0, c1
= 0;
745 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
747 if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
748 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
749 data
.i
[c
] = op
[0]->value
.i
[c0
] >> op
[1]->value
.i
[c1
];
751 } else if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
752 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
753 data
.i
[c
] = op
[0]->value
.i
[c0
] >> op
[1]->value
.u
[c1
];
755 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
756 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
757 data
.u
[c
] = op
[0]->value
.u
[c0
] >> op
[1]->value
.i
[c1
];
759 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
760 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
761 data
.u
[c
] = op
[0]->value
.u
[c0
] >> op
[1]->value
.u
[c1
];
766 case ir_binop_bit_and
:
767 for (unsigned c
= 0, c0
= 0, c1
= 0;
769 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
771 switch (op
[0]->type
->base_type
) {
773 data
.i
[c
] = op
[0]->value
.i
[c0
] & op
[1]->value
.i
[c1
];
776 data
.u
[c
] = op
[0]->value
.u
[c0
] & op
[1]->value
.u
[c1
];
784 case ir_binop_bit_or
:
785 for (unsigned c
= 0, c0
= 0, c1
= 0;
787 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
789 switch (op
[0]->type
->base_type
) {
791 data
.i
[c
] = op
[0]->value
.i
[c0
] | op
[1]->value
.i
[c1
];
794 data
.u
[c
] = op
[0]->value
.u
[c0
] | op
[1]->value
.u
[c1
];
802 case ir_binop_bit_xor
:
803 for (unsigned c
= 0, c0
= 0, c1
= 0;
805 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
807 switch (op
[0]->type
->base_type
) {
809 data
.i
[c
] = op
[0]->value
.i
[c0
] ^ op
[1]->value
.i
[c1
];
812 data
.u
[c
] = op
[0]->value
.u
[c0
] ^ op
[1]->value
.u
[c1
];
820 case ir_quadop_vector
:
821 for (unsigned c
= 0; c
< this->type
->vector_elements
; c
++) {
822 switch (this->type
->base_type
) {
824 data
.i
[c
] = op
[c
]->value
.i
[0];
827 data
.u
[c
] = op
[c
]->value
.u
[0];
829 case GLSL_TYPE_FLOAT
:
830 data
.f
[c
] = op
[c
]->value
.f
[0];
839 /* FINISHME: Should handle all expression types. */
843 return new(ctx
) ir_constant(this->type
, &data
);
848 ir_texture::constant_expression_value()
850 /* texture lookups aren't constant expressions */
856 ir_swizzle::constant_expression_value()
858 ir_constant
*v
= this->val
->constant_expression_value();
861 ir_constant_data data
= { { 0 } };
863 const unsigned swiz_idx
[4] = {
864 this->mask
.x
, this->mask
.y
, this->mask
.z
, this->mask
.w
867 for (unsigned i
= 0; i
< this->mask
.num_components
; i
++) {
868 switch (v
->type
->base_type
) {
870 case GLSL_TYPE_INT
: data
.u
[i
] = v
->value
.u
[swiz_idx
[i
]]; break;
871 case GLSL_TYPE_FLOAT
: data
.f
[i
] = v
->value
.f
[swiz_idx
[i
]]; break;
872 case GLSL_TYPE_BOOL
: data
.b
[i
] = v
->value
.b
[swiz_idx
[i
]]; break;
873 default: assert(!"Should not get here."); break;
877 void *ctx
= ralloc_parent(this);
878 return new(ctx
) ir_constant(this->type
, &data
);
885 ir_dereference_variable::constant_expression_value()
887 /* This may occur during compile and var->type is glsl_type::error_type */
891 /* The constant_value of a uniform variable is its initializer,
892 * not the lifetime constant value of the uniform.
894 if (var
->mode
== ir_var_uniform
)
897 if (!var
->constant_value
)
900 return var
->constant_value
->clone(ralloc_parent(var
), NULL
);
905 ir_dereference_array::constant_expression_value()
907 ir_constant
*array
= this->array
->constant_expression_value();
908 ir_constant
*idx
= this->array_index
->constant_expression_value();
910 if ((array
!= NULL
) && (idx
!= NULL
)) {
911 void *ctx
= ralloc_parent(this);
912 if (array
->type
->is_matrix()) {
913 /* Array access of a matrix results in a vector.
915 const unsigned column
= idx
->value
.u
[0];
917 const glsl_type
*const column_type
= array
->type
->column_type();
919 /* Offset in the constant matrix to the first element of the column
922 const unsigned mat_idx
= column
* column_type
->vector_elements
;
924 ir_constant_data data
= { { 0 } };
926 switch (column_type
->base_type
) {
929 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
930 data
.u
[i
] = array
->value
.u
[mat_idx
+ i
];
934 case GLSL_TYPE_FLOAT
:
935 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
936 data
.f
[i
] = array
->value
.f
[mat_idx
+ i
];
941 assert(!"Should not get here.");
945 return new(ctx
) ir_constant(column_type
, &data
);
946 } else if (array
->type
->is_vector()) {
947 const unsigned component
= idx
->value
.u
[0];
949 return new(ctx
) ir_constant(array
, component
);
951 const unsigned index
= idx
->value
.u
[0];
952 return array
->get_array_element(index
)->clone(ctx
, NULL
);
960 ir_dereference_record::constant_expression_value()
962 ir_constant
*v
= this->record
->constant_expression_value();
964 return (v
!= NULL
) ? v
->get_record_field(this->field
) : NULL
;
969 ir_assignment::constant_expression_value()
971 /* FINISHME: Handle CEs involving assignment (return RHS) */
977 ir_constant::constant_expression_value()
984 ir_call::constant_expression_value()
986 if (this->type
== glsl_type::error_type
)
989 /* From the GLSL 1.20 spec, page 23:
990 * "Function calls to user-defined functions (non-built-in functions)
991 * cannot be used to form constant expressions."
993 if (!this->callee
->is_builtin
)
996 unsigned num_parameters
= 0;
998 /* Check if all parameters are constant */
1000 foreach_list(n
, &this->actual_parameters
) {
1001 ir_constant
*constant
= ((ir_rvalue
*) n
)->constant_expression_value();
1002 if (constant
== NULL
)
1005 op
[num_parameters
] = constant
;
1007 assert(num_parameters
< 3);
1011 /* Individual cases below can either:
1012 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
1013 * - Fill "data" with appopriate constant data
1014 * - Return an ir_constant directly.
1016 void *mem_ctx
= ralloc_parent(this);
1017 ir_expression
*expr
= NULL
;
1019 ir_constant_data data
;
1020 memset(&data
, 0, sizeof(data
));
1022 const char *callee
= this->callee_name();
1023 if (strcmp(callee
, "abs") == 0) {
1024 expr
= new(mem_ctx
) ir_expression(ir_unop_abs
, type
, op
[0], NULL
);
1025 } else if (strcmp(callee
, "all") == 0) {
1026 assert(op
[0]->type
->is_boolean());
1027 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1028 if (!op
[0]->value
.b
[c
])
1029 return new(mem_ctx
) ir_constant(false);
1031 return new(mem_ctx
) ir_constant(true);
1032 } else if (strcmp(callee
, "any") == 0) {
1033 assert(op
[0]->type
->is_boolean());
1034 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1035 if (op
[0]->value
.b
[c
])
1036 return new(mem_ctx
) ir_constant(true);
1038 return new(mem_ctx
) ir_constant(false);
1039 } else if (strcmp(callee
, "acos") == 0) {
1040 assert(op
[0]->type
->is_float());
1041 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1042 data
.f
[c
] = acosf(op
[0]->value
.f
[c
]);
1043 } else if (strcmp(callee
, "acosh") == 0) {
1044 assert(op
[0]->type
->is_float());
1045 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1046 data
.f
[c
] = acoshf(op
[0]->value
.f
[c
]);
1047 } else if (strcmp(callee
, "asin") == 0) {
1048 assert(op
[0]->type
->is_float());
1049 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1050 data
.f
[c
] = asinf(op
[0]->value
.f
[c
]);
1051 } else if (strcmp(callee
, "asinh") == 0) {
1052 assert(op
[0]->type
->is_float());
1053 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1054 data
.f
[c
] = asinhf(op
[0]->value
.f
[c
]);
1055 } else if (strcmp(callee
, "atan") == 0) {
1056 assert(op
[0]->type
->is_float());
1057 if (num_parameters
== 2) {
1058 assert(op
[1]->type
->is_float());
1059 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1060 data
.f
[c
] = atan2f(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
1062 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1063 data
.f
[c
] = atanf(op
[0]->value
.f
[c
]);
1065 } else if (strcmp(callee
, "atanh") == 0) {
1066 assert(op
[0]->type
->is_float());
1067 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1068 data
.f
[c
] = atanhf(op
[0]->value
.f
[c
]);
1069 } else if (strcmp(callee
, "dFdx") == 0 || strcmp(callee
, "dFdy") == 0) {
1070 return ir_constant::zero(mem_ctx
, this->type
);
1071 } else if (strcmp(callee
, "ceil") == 0) {
1072 expr
= new(mem_ctx
) ir_expression(ir_unop_ceil
, type
, op
[0], NULL
);
1073 } else if (strcmp(callee
, "clamp") == 0) {
1074 assert(num_parameters
== 3);
1075 unsigned c1_inc
= op
[1]->type
->is_scalar() ? 0 : 1;
1076 unsigned c2_inc
= op
[2]->type
->is_scalar() ? 0 : 1;
1077 for (unsigned c
= 0, c1
= 0, c2
= 0;
1078 c
< op
[0]->type
->components();
1079 c1
+= c1_inc
, c2
+= c2_inc
, c
++) {
1081 switch (op
[0]->type
->base_type
) {
1082 case GLSL_TYPE_UINT
:
1083 data
.u
[c
] = CLAMP(op
[0]->value
.u
[c
], op
[1]->value
.u
[c1
],
1084 op
[2]->value
.u
[c2
]);
1087 data
.i
[c
] = CLAMP(op
[0]->value
.i
[c
], op
[1]->value
.i
[c1
],
1088 op
[2]->value
.i
[c2
]);
1090 case GLSL_TYPE_FLOAT
:
1091 data
.f
[c
] = CLAMP(op
[0]->value
.f
[c
], op
[1]->value
.f
[c1
],
1092 op
[2]->value
.f
[c2
]);
1095 assert(!"Should not get here.");
1098 } else if (strcmp(callee
, "cos") == 0) {
1099 expr
= new(mem_ctx
) ir_expression(ir_unop_cos
, type
, op
[0], NULL
);
1100 } else if (strcmp(callee
, "cosh") == 0) {
1101 assert(op
[0]->type
->is_float());
1102 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1103 data
.f
[c
] = coshf(op
[0]->value
.f
[c
]);
1104 } else if (strcmp(callee
, "cross") == 0) {
1105 assert(op
[0]->type
== glsl_type::vec3_type
);
1106 assert(op
[1]->type
== glsl_type::vec3_type
);
1107 data
.f
[0] = (op
[0]->value
.f
[1] * op
[1]->value
.f
[2] -
1108 op
[1]->value
.f
[1] * op
[0]->value
.f
[2]);
1109 data
.f
[1] = (op
[0]->value
.f
[2] * op
[1]->value
.f
[0] -
1110 op
[1]->value
.f
[2] * op
[0]->value
.f
[0]);
1111 data
.f
[2] = (op
[0]->value
.f
[0] * op
[1]->value
.f
[1] -
1112 op
[1]->value
.f
[0] * op
[0]->value
.f
[1]);
1113 } else if (strcmp(callee
, "degrees") == 0) {
1114 assert(op
[0]->type
->is_float());
1115 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1116 data
.f
[c
] = 180.0F
/ M_PI
* op
[0]->value
.f
[c
];
1117 } else if (strcmp(callee
, "distance") == 0) {
1118 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1119 float length_squared
= 0.0;
1120 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1121 float t
= op
[0]->value
.f
[c
] - op
[1]->value
.f
[c
];
1122 length_squared
+= t
* t
;
1124 return new(mem_ctx
) ir_constant(sqrtf(length_squared
));
1125 } else if (strcmp(callee
, "dot") == 0) {
1126 return new(mem_ctx
) ir_constant(dot(op
[0], op
[1]));
1127 } else if (strcmp(callee
, "equal") == 0) {
1128 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1129 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1130 switch (op
[0]->type
->base_type
) {
1131 case GLSL_TYPE_UINT
:
1132 data
.b
[c
] = op
[0]->value
.u
[c
] == op
[1]->value
.u
[c
];
1135 data
.b
[c
] = op
[0]->value
.i
[c
] == op
[1]->value
.i
[c
];
1137 case GLSL_TYPE_FLOAT
:
1138 data
.b
[c
] = op
[0]->value
.f
[c
] == op
[1]->value
.f
[c
];
1140 case GLSL_TYPE_BOOL
:
1141 data
.b
[c
] = op
[0]->value
.b
[c
] == op
[1]->value
.b
[c
];
1144 assert(!"Should not get here.");
1147 } else if (strcmp(callee
, "exp") == 0) {
1148 expr
= new(mem_ctx
) ir_expression(ir_unop_exp
, type
, op
[0], NULL
);
1149 } else if (strcmp(callee
, "exp2") == 0) {
1150 expr
= new(mem_ctx
) ir_expression(ir_unop_exp2
, type
, op
[0], NULL
);
1151 } else if (strcmp(callee
, "faceforward") == 0) {
1152 if (dot(op
[2], op
[1]) < 0)
1154 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1155 data
.f
[c
] = -op
[0]->value
.f
[c
];
1156 } else if (strcmp(callee
, "floor") == 0) {
1157 expr
= new(mem_ctx
) ir_expression(ir_unop_floor
, type
, op
[0], NULL
);
1158 } else if (strcmp(callee
, "fract") == 0) {
1159 expr
= new(mem_ctx
) ir_expression(ir_unop_fract
, type
, op
[0], NULL
);
1160 } else if (strcmp(callee
, "fwidth") == 0) {
1161 return ir_constant::zero(mem_ctx
, this->type
);
1162 } else if (strcmp(callee
, "greaterThan") == 0) {
1163 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1164 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1165 switch (op
[0]->type
->base_type
) {
1166 case GLSL_TYPE_UINT
:
1167 data
.b
[c
] = op
[0]->value
.u
[c
] > op
[1]->value
.u
[c
];
1170 data
.b
[c
] = op
[0]->value
.i
[c
] > op
[1]->value
.i
[c
];
1172 case GLSL_TYPE_FLOAT
:
1173 data
.b
[c
] = op
[0]->value
.f
[c
] > op
[1]->value
.f
[c
];
1176 assert(!"Should not get here.");
1179 } else if (strcmp(callee
, "greaterThanEqual") == 0) {
1180 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1181 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1182 switch (op
[0]->type
->base_type
) {
1183 case GLSL_TYPE_UINT
:
1184 data
.b
[c
] = op
[0]->value
.u
[c
] >= op
[1]->value
.u
[c
];
1187 data
.b
[c
] = op
[0]->value
.i
[c
] >= op
[1]->value
.i
[c
];
1189 case GLSL_TYPE_FLOAT
:
1190 data
.b
[c
] = op
[0]->value
.f
[c
] >= op
[1]->value
.f
[c
];
1193 assert(!"Should not get here.");
1196 } else if (strcmp(callee
, "inversesqrt") == 0) {
1197 expr
= new(mem_ctx
) ir_expression(ir_unop_rsq
, type
, op
[0], NULL
);
1198 } else if (strcmp(callee
, "length") == 0) {
1199 return new(mem_ctx
) ir_constant(sqrtf(dot(op
[0], op
[0])));
1200 } else if (strcmp(callee
, "lessThan") == 0) {
1201 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1202 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1203 switch (op
[0]->type
->base_type
) {
1204 case GLSL_TYPE_UINT
:
1205 data
.b
[c
] = op
[0]->value
.u
[c
] < op
[1]->value
.u
[c
];
1208 data
.b
[c
] = op
[0]->value
.i
[c
] < op
[1]->value
.i
[c
];
1210 case GLSL_TYPE_FLOAT
:
1211 data
.b
[c
] = op
[0]->value
.f
[c
] < op
[1]->value
.f
[c
];
1214 assert(!"Should not get here.");
1217 } else if (strcmp(callee
, "lessThanEqual") == 0) {
1218 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1219 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1220 switch (op
[0]->type
->base_type
) {
1221 case GLSL_TYPE_UINT
:
1222 data
.b
[c
] = op
[0]->value
.u
[c
] <= op
[1]->value
.u
[c
];
1225 data
.b
[c
] = op
[0]->value
.i
[c
] <= op
[1]->value
.i
[c
];
1227 case GLSL_TYPE_FLOAT
:
1228 data
.b
[c
] = op
[0]->value
.f
[c
] <= op
[1]->value
.f
[c
];
1231 assert(!"Should not get here.");
1234 } else if (strcmp(callee
, "log") == 0) {
1235 expr
= new(mem_ctx
) ir_expression(ir_unop_log
, type
, op
[0], NULL
);
1236 } else if (strcmp(callee
, "log2") == 0) {
1237 expr
= new(mem_ctx
) ir_expression(ir_unop_log2
, type
, op
[0], NULL
);
1238 } else if (strcmp(callee
, "matrixCompMult") == 0) {
1239 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1240 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1241 data
.f
[c
] = op
[0]->value
.f
[c
] * op
[1]->value
.f
[c
];
1242 } else if (strcmp(callee
, "max") == 0) {
1243 expr
= new(mem_ctx
) ir_expression(ir_binop_max
, type
, op
[0], op
[1]);
1244 } else if (strcmp(callee
, "min") == 0) {
1245 expr
= new(mem_ctx
) ir_expression(ir_binop_min
, type
, op
[0], op
[1]);
1246 } else if (strcmp(callee
, "mix") == 0) {
1247 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1248 if (op
[2]->type
->is_float()) {
1249 unsigned c2_inc
= op
[2]->type
->is_scalar() ? 0 : 1;
1250 unsigned components
= op
[0]->type
->components();
1251 for (unsigned c
= 0, c2
= 0; c
< components
; c2
+= c2_inc
, c
++) {
1252 data
.f
[c
] = op
[0]->value
.f
[c
] * (1 - op
[2]->value
.f
[c2
]) +
1253 op
[1]->value
.f
[c
] * op
[2]->value
.f
[c2
];
1256 assert(op
[2]->type
->is_boolean());
1257 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1258 data
.f
[c
] = op
[op
[2]->value
.b
[c
] ? 1 : 0]->value
.f
[c
];
1260 } else if (strcmp(callee
, "mod") == 0) {
1261 expr
= new(mem_ctx
) ir_expression(ir_binop_mod
, type
, op
[0], op
[1]);
1262 } else if (strcmp(callee
, "normalize") == 0) {
1263 assert(op
[0]->type
->is_float());
1264 float length
= sqrtf(dot(op
[0], op
[0]));
1267 return ir_constant::zero(mem_ctx
, this->type
);
1269 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1270 data
.f
[c
] = op
[0]->value
.f
[c
] / length
;
1271 } else if (strcmp(callee
, "not") == 0) {
1272 expr
= new(mem_ctx
) ir_expression(ir_unop_logic_not
, type
, op
[0], NULL
);
1273 } else if (strcmp(callee
, "notEqual") == 0) {
1274 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1275 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1276 switch (op
[0]->type
->base_type
) {
1277 case GLSL_TYPE_UINT
:
1278 data
.b
[c
] = op
[0]->value
.u
[c
] != op
[1]->value
.u
[c
];
1281 data
.b
[c
] = op
[0]->value
.i
[c
] != op
[1]->value
.i
[c
];
1283 case GLSL_TYPE_FLOAT
:
1284 data
.b
[c
] = op
[0]->value
.f
[c
] != op
[1]->value
.f
[c
];
1286 case GLSL_TYPE_BOOL
:
1287 data
.b
[c
] = op
[0]->value
.b
[c
] != op
[1]->value
.b
[c
];
1290 assert(!"Should not get here.");
1293 } else if (strcmp(callee
, "outerProduct") == 0) {
1294 assert(op
[0]->type
->is_vector() && op
[1]->type
->is_vector());
1295 const unsigned m
= op
[0]->type
->vector_elements
;
1296 const unsigned n
= op
[1]->type
->vector_elements
;
1297 for (unsigned j
= 0; j
< n
; j
++) {
1298 for (unsigned i
= 0; i
< m
; i
++) {
1299 data
.f
[i
+m
*j
] = op
[0]->value
.f
[i
] * op
[1]->value
.f
[j
];
1302 } else if (strcmp(callee
, "pow") == 0) {
1303 expr
= new(mem_ctx
) ir_expression(ir_binop_pow
, type
, op
[0], op
[1]);
1304 } else if (strcmp(callee
, "radians") == 0) {
1305 assert(op
[0]->type
->is_float());
1306 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1307 data
.f
[c
] = M_PI
/ 180.0F
* op
[0]->value
.f
[c
];
1308 } else if (strcmp(callee
, "reflect") == 0) {
1309 assert(op
[0]->type
->is_float());
1310 float dot_NI
= dot(op
[1], op
[0]);
1311 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1312 data
.f
[c
] = op
[0]->value
.f
[c
] - 2 * dot_NI
* op
[1]->value
.f
[c
];
1313 } else if (strcmp(callee
, "refract") == 0) {
1314 const float eta
= op
[2]->value
.f
[0];
1315 const float dot_NI
= dot(op
[1], op
[0]);
1316 const float k
= 1.0F
- eta
* eta
* (1.0F
- dot_NI
* dot_NI
);
1318 return ir_constant::zero(mem_ctx
, this->type
);
1320 for (unsigned c
= 0; c
< type
->components(); c
++) {
1321 data
.f
[c
] = eta
* op
[0]->value
.f
[c
] - (eta
* dot_NI
+ sqrtf(k
))
1322 * op
[1]->value
.f
[c
];
1325 } else if (strcmp(callee
, "sign") == 0) {
1326 expr
= new(mem_ctx
) ir_expression(ir_unop_sign
, type
, op
[0], NULL
);
1327 } else if (strcmp(callee
, "sin") == 0) {
1328 expr
= new(mem_ctx
) ir_expression(ir_unop_sin
, type
, op
[0], NULL
);
1329 } else if (strcmp(callee
, "sinh") == 0) {
1330 assert(op
[0]->type
->is_float());
1331 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1332 data
.f
[c
] = sinhf(op
[0]->value
.f
[c
]);
1333 } else if (strcmp(callee
, "smoothstep") == 0) {
1334 assert(num_parameters
== 3);
1335 assert(op
[1]->type
== op
[0]->type
);
1336 unsigned edge_inc
= op
[0]->type
->is_scalar() ? 0 : 1;
1337 for (unsigned c
= 0, e
= 0; c
< type
->components(); e
+= edge_inc
, c
++) {
1338 const float edge0
= op
[0]->value
.f
[e
];
1339 const float edge1
= op
[1]->value
.f
[e
];
1340 if (edge0
== edge1
) {
1341 data
.f
[c
] = 0.0; /* Avoid a crash - results are undefined anyway */
1343 const float numerator
= op
[2]->value
.f
[c
] - edge0
;
1344 const float denominator
= edge1
- edge0
;
1345 const float t
= CLAMP(numerator
/denominator
, 0, 1);
1346 data
.f
[c
] = t
* t
* (3 - 2 * t
);
1349 } else if (strcmp(callee
, "sqrt") == 0) {
1350 expr
= new(mem_ctx
) ir_expression(ir_unop_sqrt
, type
, op
[0], NULL
);
1351 } else if (strcmp(callee
, "step") == 0) {
1352 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1353 /* op[0] (edge) may be either a scalar or a vector */
1354 const unsigned c0_inc
= op
[0]->type
->is_scalar() ? 0 : 1;
1355 for (unsigned c
= 0, c0
= 0; c
< type
->components(); c0
+= c0_inc
, c
++)
1356 data
.f
[c
] = (op
[1]->value
.f
[c
] < op
[0]->value
.f
[c0
]) ? 0.0F
: 1.0F
;
1357 } else if (strcmp(callee
, "tan") == 0) {
1358 assert(op
[0]->type
->is_float());
1359 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1360 data
.f
[c
] = tanf(op
[0]->value
.f
[c
]);
1361 } else if (strcmp(callee
, "tanh") == 0) {
1362 assert(op
[0]->type
->is_float());
1363 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1364 data
.f
[c
] = tanhf(op
[0]->value
.f
[c
]);
1365 } else if (strcmp(callee
, "transpose") == 0) {
1366 assert(op
[0]->type
->is_matrix());
1367 const unsigned n
= op
[0]->type
->vector_elements
;
1368 const unsigned m
= op
[0]->type
->matrix_columns
;
1369 for (unsigned j
= 0; j
< m
; j
++) {
1370 for (unsigned i
= 0; i
< n
; i
++) {
1371 data
.f
[m
*i
+j
] += op
[0]->value
.f
[i
+n
*j
];
1375 /* Unsupported builtin - some are not allowed in constant expressions. */
1380 return expr
->constant_expression_value();
1382 return new(mem_ctx
) ir_constant(this->type
, &data
);