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;
171 assert(op
[0]->type
->is_boolean());
173 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
174 if (op
[0]->value
.b
[c
])
180 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
181 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
182 data
.f
[c
] = truncf(op
[0]->value
.f
[c
]);
187 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
188 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
189 data
.f
[c
] = ceilf(op
[0]->value
.f
[c
]);
194 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
195 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
196 data
.f
[c
] = floorf(op
[0]->value
.f
[c
]);
201 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
202 switch (this->type
->base_type
) {
209 case GLSL_TYPE_FLOAT
:
210 data
.f
[c
] = op
[0]->value
.f
[c
] - floor(op
[0]->value
.f
[c
]);
219 case ir_unop_sin_reduced
:
220 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
221 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
222 data
.f
[c
] = sinf(op
[0]->value
.f
[c
]);
227 case ir_unop_cos_reduced
:
228 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
229 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
230 data
.f
[c
] = cosf(op
[0]->value
.f
[c
]);
235 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
236 switch (this->type
->base_type
) {
238 data
.u
[c
] = -((int) op
[0]->value
.u
[c
]);
241 data
.i
[c
] = -op
[0]->value
.i
[c
];
243 case GLSL_TYPE_FLOAT
:
244 data
.f
[c
] = -op
[0]->value
.f
[c
];
253 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
254 switch (this->type
->base_type
) {
256 data
.u
[c
] = op
[0]->value
.u
[c
];
259 data
.i
[c
] = op
[0]->value
.i
[c
];
261 data
.i
[c
] = -data
.i
[c
];
263 case GLSL_TYPE_FLOAT
:
264 data
.f
[c
] = fabs(op
[0]->value
.f
[c
]);
273 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
274 switch (this->type
->base_type
) {
276 data
.u
[c
] = op
[0]->value
.i
[c
] > 0;
279 data
.i
[c
] = (op
[0]->value
.i
[c
] > 0) - (op
[0]->value
.i
[c
] < 0);
281 case GLSL_TYPE_FLOAT
:
282 data
.f
[c
] = float((op
[0]->value
.f
[c
] > 0)-(op
[0]->value
.f
[c
] < 0));
291 /* FINISHME: Emit warning when division-by-zero is detected. */
292 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
293 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
294 switch (this->type
->base_type
) {
296 if (op
[0]->value
.u
[c
] == 0.0)
298 data
.u
[c
] = 1 / op
[0]->value
.u
[c
];
301 if (op
[0]->value
.i
[c
] == 0.0)
303 data
.i
[c
] = 1 / op
[0]->value
.i
[c
];
305 case GLSL_TYPE_FLOAT
:
306 if (op
[0]->value
.f
[c
] == 0.0)
308 data
.f
[c
] = 1.0F
/ op
[0]->value
.f
[c
];
317 /* FINISHME: Emit warning when division-by-zero is detected. */
318 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
319 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
320 float s
= sqrtf(op
[0]->value
.f
[c
]);
323 data
.f
[c
] = 1.0F
/ s
;
328 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
329 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
330 data
.f
[c
] = sqrtf(op
[0]->value
.f
[c
]);
335 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
336 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
337 data
.f
[c
] = expf(op
[0]->value
.f
[c
]);
342 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
343 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
344 data
.f
[c
] = exp2f(op
[0]->value
.f
[c
]);
349 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
350 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
351 data
.f
[c
] = logf(op
[0]->value
.f
[c
]);
356 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
357 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
358 data
.f
[c
] = log2f(op
[0]->value
.f
[c
]);
364 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
365 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
371 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
372 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
373 data
.f
[c
] = powf(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
378 data
.f
[0] = dot(op
[0], op
[1]);
382 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
383 for (unsigned c
= 0, c0
= 0, c1
= 0;
385 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
387 switch (op
[0]->type
->base_type
) {
389 data
.u
[c
] = MIN2(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
392 data
.i
[c
] = MIN2(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
394 case GLSL_TYPE_FLOAT
:
395 data
.f
[c
] = MIN2(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
404 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
405 for (unsigned c
= 0, c0
= 0, c1
= 0;
407 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
409 switch (op
[0]->type
->base_type
) {
411 data
.u
[c
] = MAX2(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
414 data
.i
[c
] = MAX2(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
416 case GLSL_TYPE_FLOAT
:
417 data
.f
[c
] = MAX2(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
426 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
427 for (unsigned c
= 0, c0
= 0, c1
= 0;
429 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
431 switch (op
[0]->type
->base_type
) {
433 data
.u
[c
] = op
[0]->value
.u
[c0
] + op
[1]->value
.u
[c1
];
436 data
.i
[c
] = op
[0]->value
.i
[c0
] + op
[1]->value
.i
[c1
];
438 case GLSL_TYPE_FLOAT
:
439 data
.f
[c
] = op
[0]->value
.f
[c0
] + op
[1]->value
.f
[c1
];
448 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
449 for (unsigned c
= 0, c0
= 0, c1
= 0;
451 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
453 switch (op
[0]->type
->base_type
) {
455 data
.u
[c
] = op
[0]->value
.u
[c0
] - op
[1]->value
.u
[c1
];
458 data
.i
[c
] = op
[0]->value
.i
[c0
] - op
[1]->value
.i
[c1
];
460 case GLSL_TYPE_FLOAT
:
461 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
];
470 /* Check for equal types, or unequal types involving scalars */
471 if ((op
[0]->type
== op
[1]->type
&& !op
[0]->type
->is_matrix())
472 || op0_scalar
|| op1_scalar
) {
473 for (unsigned c
= 0, c0
= 0, c1
= 0;
475 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
477 switch (op
[0]->type
->base_type
) {
479 data
.u
[c
] = op
[0]->value
.u
[c0
] * op
[1]->value
.u
[c1
];
482 data
.i
[c
] = op
[0]->value
.i
[c0
] * op
[1]->value
.i
[c1
];
484 case GLSL_TYPE_FLOAT
:
485 data
.f
[c
] = op
[0]->value
.f
[c0
] * op
[1]->value
.f
[c1
];
492 assert(op
[0]->type
->is_matrix() || op
[1]->type
->is_matrix());
494 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
495 * matrix can be a GLSL vector, either N or P can be 1.
497 * For vec*mat, the vector is treated as a row vector. This
498 * means the vector is a 1-row x M-column matrix.
500 * For mat*vec, the vector is treated as a column vector. Since
501 * matrix_columns is 1 for vectors, this just works.
503 const unsigned n
= op
[0]->type
->is_vector()
504 ? 1 : op
[0]->type
->vector_elements
;
505 const unsigned m
= op
[1]->type
->vector_elements
;
506 const unsigned p
= op
[1]->type
->matrix_columns
;
507 for (unsigned j
= 0; j
< p
; j
++) {
508 for (unsigned i
= 0; i
< n
; i
++) {
509 for (unsigned k
= 0; k
< m
; k
++) {
510 data
.f
[i
+n
*j
] += op
[0]->value
.f
[i
+n
*k
]*op
[1]->value
.f
[k
+m
*j
];
518 /* FINISHME: Emit warning when division-by-zero is detected. */
519 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
520 for (unsigned c
= 0, c0
= 0, c1
= 0;
522 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
524 switch (op
[0]->type
->base_type
) {
526 if (op
[1]->value
.u
[c1
] == 0)
528 data
.u
[c
] = op
[0]->value
.u
[c0
] / op
[1]->value
.u
[c1
];
531 if (op
[1]->value
.i
[c1
] == 0)
533 data
.i
[c
] = op
[0]->value
.i
[c0
] / op
[1]->value
.i
[c1
];
535 case GLSL_TYPE_FLOAT
:
536 if (op
[1]->value
.f
[c1
] == 0)
538 data
.f
[c
] = op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
];
547 /* FINISHME: Emit warning when division-by-zero is detected. */
548 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
549 for (unsigned c
= 0, c0
= 0, c1
= 0;
551 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
553 switch (op
[0]->type
->base_type
) {
555 if (op
[1]->value
.u
[c1
] == 0)
557 data
.u
[c
] = op
[0]->value
.u
[c0
] % op
[1]->value
.u
[c1
];
560 if (op
[1]->value
.i
[c1
] == 0)
562 data
.i
[c
] = op
[0]->value
.i
[c0
] % op
[1]->value
.i
[c1
];
564 case GLSL_TYPE_FLOAT
:
565 if (op
[1]->value
.f
[c1
] == 0)
567 /* We don't use fmod because it rounds toward zero; GLSL specifies
570 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
]
571 * floorf(op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
]);
580 case ir_binop_logic_and
:
581 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
582 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
583 data
.b
[c
] = op
[0]->value
.b
[c
] && op
[1]->value
.b
[c
];
585 case ir_binop_logic_xor
:
586 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
587 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
588 data
.b
[c
] = op
[0]->value
.b
[c
] ^ op
[1]->value
.b
[c
];
590 case ir_binop_logic_or
:
591 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
592 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
593 data
.b
[c
] = op
[0]->value
.b
[c
] || op
[1]->value
.b
[c
];
597 assert(op
[0]->type
== op
[1]->type
);
598 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
599 switch (op
[0]->type
->base_type
) {
601 data
.b
[0] = op
[0]->value
.u
[0] < op
[1]->value
.u
[0];
604 data
.b
[0] = op
[0]->value
.i
[0] < op
[1]->value
.i
[0];
606 case GLSL_TYPE_FLOAT
:
607 data
.b
[0] = op
[0]->value
.f
[0] < op
[1]->value
.f
[0];
614 case ir_binop_greater
:
615 assert(op
[0]->type
== op
[1]->type
);
616 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
617 switch (op
[0]->type
->base_type
) {
619 data
.b
[c
] = op
[0]->value
.u
[c
] > op
[1]->value
.u
[c
];
622 data
.b
[c
] = op
[0]->value
.i
[c
] > op
[1]->value
.i
[c
];
624 case GLSL_TYPE_FLOAT
:
625 data
.b
[c
] = op
[0]->value
.f
[c
] > op
[1]->value
.f
[c
];
632 case ir_binop_lequal
:
633 assert(op
[0]->type
== op
[1]->type
);
634 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
635 switch (op
[0]->type
->base_type
) {
637 data
.b
[0] = op
[0]->value
.u
[0] <= op
[1]->value
.u
[0];
640 data
.b
[0] = op
[0]->value
.i
[0] <= op
[1]->value
.i
[0];
642 case GLSL_TYPE_FLOAT
:
643 data
.b
[0] = op
[0]->value
.f
[0] <= op
[1]->value
.f
[0];
650 case ir_binop_gequal
:
651 assert(op
[0]->type
== op
[1]->type
);
652 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
653 switch (op
[0]->type
->base_type
) {
655 data
.b
[0] = op
[0]->value
.u
[0] >= op
[1]->value
.u
[0];
658 data
.b
[0] = op
[0]->value
.i
[0] >= op
[1]->value
.i
[0];
660 case GLSL_TYPE_FLOAT
:
661 data
.b
[0] = op
[0]->value
.f
[0] >= op
[1]->value
.f
[0];
669 assert(op
[0]->type
== op
[1]->type
);
670 for (unsigned c
= 0; c
< components
; c
++) {
671 switch (op
[0]->type
->base_type
) {
673 data
.b
[c
] = op
[0]->value
.u
[c
] == op
[1]->value
.u
[c
];
676 data
.b
[c
] = op
[0]->value
.i
[c
] == op
[1]->value
.i
[c
];
678 case GLSL_TYPE_FLOAT
:
679 data
.b
[c
] = op
[0]->value
.f
[c
] == op
[1]->value
.f
[c
];
686 case ir_binop_nequal
:
687 assert(op
[0]->type
!= op
[1]->type
);
688 for (unsigned c
= 0; c
< components
; c
++) {
689 switch (op
[0]->type
->base_type
) {
691 data
.b
[c
] = op
[0]->value
.u
[c
] != op
[1]->value
.u
[c
];
694 data
.b
[c
] = op
[0]->value
.i
[c
] != op
[1]->value
.i
[c
];
696 case GLSL_TYPE_FLOAT
:
697 data
.b
[c
] = op
[0]->value
.f
[c
] != op
[1]->value
.f
[c
];
704 case ir_binop_all_equal
:
705 data
.b
[0] = op
[0]->has_value(op
[1]);
707 case ir_binop_any_nequal
:
708 data
.b
[0] = !op
[0]->has_value(op
[1]);
711 case ir_binop_lshift
:
712 for (unsigned c
= 0, c0
= 0, c1
= 0;
714 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
716 if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
717 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
718 data
.i
[c
] = op
[0]->value
.i
[c0
] << op
[1]->value
.i
[c1
];
720 } else if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
721 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
722 data
.i
[c
] = op
[0]->value
.i
[c0
] << op
[1]->value
.u
[c1
];
724 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
725 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
726 data
.u
[c
] = op
[0]->value
.u
[c0
] << op
[1]->value
.i
[c1
];
728 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
729 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
730 data
.u
[c
] = op
[0]->value
.u
[c0
] << op
[1]->value
.u
[c1
];
735 case ir_binop_rshift
:
736 for (unsigned c
= 0, c0
= 0, c1
= 0;
738 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
740 if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
741 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
742 data
.i
[c
] = op
[0]->value
.i
[c0
] >> op
[1]->value
.i
[c1
];
744 } else if (op
[0]->type
->base_type
== GLSL_TYPE_INT
&&
745 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
746 data
.i
[c
] = op
[0]->value
.i
[c0
] >> op
[1]->value
.u
[c1
];
748 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
749 op
[1]->type
->base_type
== GLSL_TYPE_INT
) {
750 data
.u
[c
] = op
[0]->value
.u
[c0
] >> op
[1]->value
.i
[c1
];
752 } else if (op
[0]->type
->base_type
== GLSL_TYPE_UINT
&&
753 op
[1]->type
->base_type
== GLSL_TYPE_UINT
) {
754 data
.u
[c
] = op
[0]->value
.u
[c0
] >> op
[1]->value
.u
[c1
];
759 case ir_binop_bit_and
:
760 for (unsigned c
= 0, c0
= 0, c1
= 0;
762 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
764 switch (op
[0]->type
->base_type
) {
766 data
.i
[c
] = op
[0]->value
.i
[c0
] & op
[1]->value
.i
[c1
];
769 data
.u
[c
] = op
[0]->value
.u
[c0
] & op
[1]->value
.u
[c1
];
777 case ir_binop_bit_or
:
778 for (unsigned c
= 0, c0
= 0, c1
= 0;
780 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
782 switch (op
[0]->type
->base_type
) {
784 data
.i
[c
] = op
[0]->value
.i
[c0
] | op
[1]->value
.i
[c1
];
787 data
.u
[c
] = op
[0]->value
.u
[c0
] | op
[1]->value
.u
[c1
];
795 case ir_binop_bit_xor
:
796 for (unsigned c
= 0, c0
= 0, c1
= 0;
798 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
800 switch (op
[0]->type
->base_type
) {
802 data
.i
[c
] = op
[0]->value
.i
[c0
] ^ op
[1]->value
.i
[c1
];
805 data
.u
[c
] = op
[0]->value
.u
[c0
] ^ op
[1]->value
.u
[c1
];
813 case ir_quadop_vector
:
814 for (unsigned c
= 0; c
< this->type
->vector_elements
; c
++) {
815 switch (this->type
->base_type
) {
817 data
.i
[c
] = op
[c
]->value
.i
[0];
820 data
.u
[c
] = op
[c
]->value
.u
[0];
822 case GLSL_TYPE_FLOAT
:
823 data
.f
[c
] = op
[c
]->value
.f
[0];
832 /* FINISHME: Should handle all expression types. */
836 return new(ctx
) ir_constant(this->type
, &data
);
841 ir_texture::constant_expression_value()
843 /* texture lookups aren't constant expressions */
849 ir_swizzle::constant_expression_value()
851 ir_constant
*v
= this->val
->constant_expression_value();
854 ir_constant_data data
= { { 0 } };
856 const unsigned swiz_idx
[4] = {
857 this->mask
.x
, this->mask
.y
, this->mask
.z
, this->mask
.w
860 for (unsigned i
= 0; i
< this->mask
.num_components
; i
++) {
861 switch (v
->type
->base_type
) {
863 case GLSL_TYPE_INT
: data
.u
[i
] = v
->value
.u
[swiz_idx
[i
]]; break;
864 case GLSL_TYPE_FLOAT
: data
.f
[i
] = v
->value
.f
[swiz_idx
[i
]]; break;
865 case GLSL_TYPE_BOOL
: data
.b
[i
] = v
->value
.b
[swiz_idx
[i
]]; break;
866 default: assert(!"Should not get here."); break;
870 void *ctx
= ralloc_parent(this);
871 return new(ctx
) ir_constant(this->type
, &data
);
878 ir_dereference_variable::constant_expression_value()
880 /* This may occur during compile and var->type is glsl_type::error_type */
884 /* The constant_value of a uniform variable is its initializer,
885 * not the lifetime constant value of the uniform.
887 if (var
->mode
== ir_var_uniform
)
890 if (!var
->constant_value
)
893 return var
->constant_value
->clone(ralloc_parent(var
), NULL
);
898 ir_dereference_array::constant_expression_value()
900 ir_constant
*array
= this->array
->constant_expression_value();
901 ir_constant
*idx
= this->array_index
->constant_expression_value();
903 if ((array
!= NULL
) && (idx
!= NULL
)) {
904 void *ctx
= ralloc_parent(this);
905 if (array
->type
->is_matrix()) {
906 /* Array access of a matrix results in a vector.
908 const unsigned column
= idx
->value
.u
[0];
910 const glsl_type
*const column_type
= array
->type
->column_type();
912 /* Offset in the constant matrix to the first element of the column
915 const unsigned mat_idx
= column
* column_type
->vector_elements
;
917 ir_constant_data data
= { { 0 } };
919 switch (column_type
->base_type
) {
922 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
923 data
.u
[i
] = array
->value
.u
[mat_idx
+ i
];
927 case GLSL_TYPE_FLOAT
:
928 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
929 data
.f
[i
] = array
->value
.f
[mat_idx
+ i
];
934 assert(!"Should not get here.");
938 return new(ctx
) ir_constant(column_type
, &data
);
939 } else if (array
->type
->is_vector()) {
940 const unsigned component
= idx
->value
.u
[0];
942 return new(ctx
) ir_constant(array
, component
);
944 const unsigned index
= idx
->value
.u
[0];
945 return array
->get_array_element(index
)->clone(ctx
, NULL
);
953 ir_dereference_record::constant_expression_value()
955 ir_constant
*v
= this->record
->constant_expression_value();
957 return (v
!= NULL
) ? v
->get_record_field(this->field
) : NULL
;
962 ir_assignment::constant_expression_value()
964 /* FINISHME: Handle CEs involving assignment (return RHS) */
970 ir_constant::constant_expression_value()
977 ir_call::constant_expression_value()
979 if (this->type
== glsl_type::error_type
)
982 /* From the GLSL 1.20 spec, page 23:
983 * "Function calls to user-defined functions (non-built-in functions)
984 * cannot be used to form constant expressions."
986 if (!this->callee
->is_builtin
)
989 unsigned num_parameters
= 0;
991 /* Check if all parameters are constant */
993 foreach_list(n
, &this->actual_parameters
) {
994 ir_constant
*constant
= ((ir_rvalue
*) n
)->constant_expression_value();
995 if (constant
== NULL
)
998 op
[num_parameters
] = constant
;
1000 assert(num_parameters
< 3);
1004 /* Individual cases below can either:
1005 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
1006 * - Fill "data" with appopriate constant data
1007 * - Return an ir_constant directly.
1009 void *mem_ctx
= ralloc_parent(this);
1010 ir_expression
*expr
= NULL
;
1012 ir_constant_data data
;
1013 memset(&data
, 0, sizeof(data
));
1015 const char *callee
= this->callee_name();
1016 if (strcmp(callee
, "abs") == 0) {
1017 expr
= new(mem_ctx
) ir_expression(ir_unop_abs
, type
, op
[0], NULL
);
1018 } else if (strcmp(callee
, "all") == 0) {
1019 assert(op
[0]->type
->is_boolean());
1020 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1021 if (!op
[0]->value
.b
[c
])
1022 return new(mem_ctx
) ir_constant(false);
1024 return new(mem_ctx
) ir_constant(true);
1025 } else if (strcmp(callee
, "any") == 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(true);
1031 return new(mem_ctx
) ir_constant(false);
1032 } else if (strcmp(callee
, "acos") == 0) {
1033 assert(op
[0]->type
->is_float());
1034 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1035 data
.f
[c
] = acosf(op
[0]->value
.f
[c
]);
1036 } else if (strcmp(callee
, "acosh") == 0) {
1037 assert(op
[0]->type
->is_float());
1038 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1039 data
.f
[c
] = acoshf(op
[0]->value
.f
[c
]);
1040 } else if (strcmp(callee
, "asin") == 0) {
1041 assert(op
[0]->type
->is_float());
1042 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1043 data
.f
[c
] = asinf(op
[0]->value
.f
[c
]);
1044 } else if (strcmp(callee
, "asinh") == 0) {
1045 assert(op
[0]->type
->is_float());
1046 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1047 data
.f
[c
] = asinhf(op
[0]->value
.f
[c
]);
1048 } else if (strcmp(callee
, "atan") == 0) {
1049 assert(op
[0]->type
->is_float());
1050 if (num_parameters
== 2) {
1051 assert(op
[1]->type
->is_float());
1052 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1053 data
.f
[c
] = atan2f(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
1055 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1056 data
.f
[c
] = atanf(op
[0]->value
.f
[c
]);
1058 } else if (strcmp(callee
, "atanh") == 0) {
1059 assert(op
[0]->type
->is_float());
1060 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1061 data
.f
[c
] = atanhf(op
[0]->value
.f
[c
]);
1062 } else if (strcmp(callee
, "dFdx") == 0 || strcmp(callee
, "dFdy") == 0) {
1063 return ir_constant::zero(mem_ctx
, this->type
);
1064 } else if (strcmp(callee
, "ceil") == 0) {
1065 expr
= new(mem_ctx
) ir_expression(ir_unop_ceil
, type
, op
[0], NULL
);
1066 } else if (strcmp(callee
, "clamp") == 0) {
1067 assert(num_parameters
== 3);
1068 unsigned c1_inc
= op
[1]->type
->is_scalar() ? 0 : 1;
1069 unsigned c2_inc
= op
[2]->type
->is_scalar() ? 0 : 1;
1070 for (unsigned c
= 0, c1
= 0, c2
= 0;
1071 c
< op
[0]->type
->components();
1072 c1
+= c1_inc
, c2
+= c2_inc
, c
++) {
1074 switch (op
[0]->type
->base_type
) {
1075 case GLSL_TYPE_UINT
:
1076 data
.u
[c
] = CLAMP(op
[0]->value
.u
[c
], op
[1]->value
.u
[c1
],
1077 op
[2]->value
.u
[c2
]);
1080 data
.i
[c
] = CLAMP(op
[0]->value
.i
[c
], op
[1]->value
.i
[c1
],
1081 op
[2]->value
.i
[c2
]);
1083 case GLSL_TYPE_FLOAT
:
1084 data
.f
[c
] = CLAMP(op
[0]->value
.f
[c
], op
[1]->value
.f
[c1
],
1085 op
[2]->value
.f
[c2
]);
1088 assert(!"Should not get here.");
1091 } else if (strcmp(callee
, "cos") == 0) {
1092 expr
= new(mem_ctx
) ir_expression(ir_unop_cos
, type
, op
[0], NULL
);
1093 } else if (strcmp(callee
, "cosh") == 0) {
1094 assert(op
[0]->type
->is_float());
1095 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1096 data
.f
[c
] = coshf(op
[0]->value
.f
[c
]);
1097 } else if (strcmp(callee
, "cross") == 0) {
1098 assert(op
[0]->type
== glsl_type::vec3_type
);
1099 assert(op
[1]->type
== glsl_type::vec3_type
);
1100 data
.f
[0] = (op
[0]->value
.f
[1] * op
[1]->value
.f
[2] -
1101 op
[1]->value
.f
[1] * op
[0]->value
.f
[2]);
1102 data
.f
[1] = (op
[0]->value
.f
[2] * op
[1]->value
.f
[0] -
1103 op
[1]->value
.f
[2] * op
[0]->value
.f
[0]);
1104 data
.f
[2] = (op
[0]->value
.f
[0] * op
[1]->value
.f
[1] -
1105 op
[1]->value
.f
[0] * op
[0]->value
.f
[1]);
1106 } else if (strcmp(callee
, "degrees") == 0) {
1107 assert(op
[0]->type
->is_float());
1108 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1109 data
.f
[c
] = 180.0F
/ M_PI
* op
[0]->value
.f
[c
];
1110 } else if (strcmp(callee
, "distance") == 0) {
1111 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1112 float length_squared
= 0.0;
1113 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1114 float t
= op
[0]->value
.f
[c
] - op
[1]->value
.f
[c
];
1115 length_squared
+= t
* t
;
1117 return new(mem_ctx
) ir_constant(sqrtf(length_squared
));
1118 } else if (strcmp(callee
, "dot") == 0) {
1119 return new(mem_ctx
) ir_constant(dot(op
[0], op
[1]));
1120 } else if (strcmp(callee
, "equal") == 0) {
1121 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1122 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1123 switch (op
[0]->type
->base_type
) {
1124 case GLSL_TYPE_UINT
:
1125 data
.b
[c
] = op
[0]->value
.u
[c
] == op
[1]->value
.u
[c
];
1128 data
.b
[c
] = op
[0]->value
.i
[c
] == op
[1]->value
.i
[c
];
1130 case GLSL_TYPE_FLOAT
:
1131 data
.b
[c
] = op
[0]->value
.f
[c
] == op
[1]->value
.f
[c
];
1133 case GLSL_TYPE_BOOL
:
1134 data
.b
[c
] = op
[0]->value
.b
[c
] == op
[1]->value
.b
[c
];
1137 assert(!"Should not get here.");
1140 } else if (strcmp(callee
, "exp") == 0) {
1141 expr
= new(mem_ctx
) ir_expression(ir_unop_exp
, type
, op
[0], NULL
);
1142 } else if (strcmp(callee
, "exp2") == 0) {
1143 expr
= new(mem_ctx
) ir_expression(ir_unop_exp2
, type
, op
[0], NULL
);
1144 } else if (strcmp(callee
, "faceforward") == 0) {
1145 if (dot(op
[2], op
[1]) < 0)
1147 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1148 data
.f
[c
] = -op
[0]->value
.f
[c
];
1149 } else if (strcmp(callee
, "floor") == 0) {
1150 expr
= new(mem_ctx
) ir_expression(ir_unop_floor
, type
, op
[0], NULL
);
1151 } else if (strcmp(callee
, "fract") == 0) {
1152 expr
= new(mem_ctx
) ir_expression(ir_unop_fract
, type
, op
[0], NULL
);
1153 } else if (strcmp(callee
, "fwidth") == 0) {
1154 return ir_constant::zero(mem_ctx
, this->type
);
1155 } else if (strcmp(callee
, "greaterThan") == 0) {
1156 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1157 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1158 switch (op
[0]->type
->base_type
) {
1159 case GLSL_TYPE_UINT
:
1160 data
.b
[c
] = op
[0]->value
.u
[c
] > op
[1]->value
.u
[c
];
1163 data
.b
[c
] = op
[0]->value
.i
[c
] > op
[1]->value
.i
[c
];
1165 case GLSL_TYPE_FLOAT
:
1166 data
.b
[c
] = op
[0]->value
.f
[c
] > op
[1]->value
.f
[c
];
1169 assert(!"Should not get here.");
1172 } else if (strcmp(callee
, "greaterThanEqual") == 0) {
1173 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1174 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1175 switch (op
[0]->type
->base_type
) {
1176 case GLSL_TYPE_UINT
:
1177 data
.b
[c
] = op
[0]->value
.u
[c
] >= op
[1]->value
.u
[c
];
1180 data
.b
[c
] = op
[0]->value
.i
[c
] >= op
[1]->value
.i
[c
];
1182 case GLSL_TYPE_FLOAT
:
1183 data
.b
[c
] = op
[0]->value
.f
[c
] >= op
[1]->value
.f
[c
];
1186 assert(!"Should not get here.");
1189 } else if (strcmp(callee
, "inversesqrt") == 0) {
1190 expr
= new(mem_ctx
) ir_expression(ir_unop_rsq
, type
, op
[0], NULL
);
1191 } else if (strcmp(callee
, "length") == 0) {
1192 return new(mem_ctx
) ir_constant(sqrtf(dot(op
[0], op
[0])));
1193 } else if (strcmp(callee
, "lessThan") == 0) {
1194 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1195 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1196 switch (op
[0]->type
->base_type
) {
1197 case GLSL_TYPE_UINT
:
1198 data
.b
[c
] = op
[0]->value
.u
[c
] < op
[1]->value
.u
[c
];
1201 data
.b
[c
] = op
[0]->value
.i
[c
] < op
[1]->value
.i
[c
];
1203 case GLSL_TYPE_FLOAT
:
1204 data
.b
[c
] = op
[0]->value
.f
[c
] < op
[1]->value
.f
[c
];
1207 assert(!"Should not get here.");
1210 } else if (strcmp(callee
, "lessThanEqual") == 0) {
1211 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1212 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1213 switch (op
[0]->type
->base_type
) {
1214 case GLSL_TYPE_UINT
:
1215 data
.b
[c
] = op
[0]->value
.u
[c
] <= op
[1]->value
.u
[c
];
1218 data
.b
[c
] = op
[0]->value
.i
[c
] <= op
[1]->value
.i
[c
];
1220 case GLSL_TYPE_FLOAT
:
1221 data
.b
[c
] = op
[0]->value
.f
[c
] <= op
[1]->value
.f
[c
];
1224 assert(!"Should not get here.");
1227 } else if (strcmp(callee
, "log") == 0) {
1228 expr
= new(mem_ctx
) ir_expression(ir_unop_log
, type
, op
[0], NULL
);
1229 } else if (strcmp(callee
, "log2") == 0) {
1230 expr
= new(mem_ctx
) ir_expression(ir_unop_log2
, type
, op
[0], NULL
);
1231 } else if (strcmp(callee
, "matrixCompMult") == 0) {
1232 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1233 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1234 data
.f
[c
] = op
[0]->value
.f
[c
] * op
[1]->value
.f
[c
];
1235 } else if (strcmp(callee
, "max") == 0) {
1236 expr
= new(mem_ctx
) ir_expression(ir_binop_max
, type
, op
[0], op
[1]);
1237 } else if (strcmp(callee
, "min") == 0) {
1238 expr
= new(mem_ctx
) ir_expression(ir_binop_min
, type
, op
[0], op
[1]);
1239 } else if (strcmp(callee
, "mix") == 0) {
1240 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1241 if (op
[2]->type
->is_float()) {
1242 unsigned c2_inc
= op
[2]->type
->is_scalar() ? 0 : 1;
1243 unsigned components
= op
[0]->type
->components();
1244 for (unsigned c
= 0, c2
= 0; c
< components
; c2
+= c2_inc
, c
++) {
1245 data
.f
[c
] = op
[0]->value
.f
[c
] * (1 - op
[2]->value
.f
[c2
]) +
1246 op
[1]->value
.f
[c
] * op
[2]->value
.f
[c2
];
1249 assert(op
[2]->type
->is_boolean());
1250 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1251 data
.f
[c
] = op
[op
[2]->value
.b
[c
] ? 1 : 0]->value
.f
[c
];
1253 } else if (strcmp(callee
, "mod") == 0) {
1254 expr
= new(mem_ctx
) ir_expression(ir_binop_mod
, type
, op
[0], op
[1]);
1255 } else if (strcmp(callee
, "normalize") == 0) {
1256 assert(op
[0]->type
->is_float());
1257 float length
= sqrtf(dot(op
[0], op
[0]));
1260 return ir_constant::zero(mem_ctx
, this->type
);
1262 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1263 data
.f
[c
] = op
[0]->value
.f
[c
] / length
;
1264 } else if (strcmp(callee
, "not") == 0) {
1265 expr
= new(mem_ctx
) ir_expression(ir_unop_logic_not
, type
, op
[0], NULL
);
1266 } else if (strcmp(callee
, "notEqual") == 0) {
1267 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1268 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1269 switch (op
[0]->type
->base_type
) {
1270 case GLSL_TYPE_UINT
:
1271 data
.b
[c
] = op
[0]->value
.u
[c
] != op
[1]->value
.u
[c
];
1274 data
.b
[c
] = op
[0]->value
.i
[c
] != op
[1]->value
.i
[c
];
1276 case GLSL_TYPE_FLOAT
:
1277 data
.b
[c
] = op
[0]->value
.f
[c
] != op
[1]->value
.f
[c
];
1279 case GLSL_TYPE_BOOL
:
1280 data
.b
[c
] = op
[0]->value
.b
[c
] != op
[1]->value
.b
[c
];
1283 assert(!"Should not get here.");
1286 } else if (strcmp(callee
, "outerProduct") == 0) {
1287 assert(op
[0]->type
->is_vector() && op
[1]->type
->is_vector());
1288 const unsigned m
= op
[0]->type
->vector_elements
;
1289 const unsigned n
= op
[1]->type
->vector_elements
;
1290 for (unsigned j
= 0; j
< n
; j
++) {
1291 for (unsigned i
= 0; i
< m
; i
++) {
1292 data
.f
[i
+m
*j
] = op
[0]->value
.f
[i
] * op
[1]->value
.f
[j
];
1295 } else if (strcmp(callee
, "pow") == 0) {
1296 expr
= new(mem_ctx
) ir_expression(ir_binop_pow
, type
, op
[0], op
[1]);
1297 } else if (strcmp(callee
, "radians") == 0) {
1298 assert(op
[0]->type
->is_float());
1299 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1300 data
.f
[c
] = M_PI
/ 180.0F
* op
[0]->value
.f
[c
];
1301 } else if (strcmp(callee
, "reflect") == 0) {
1302 assert(op
[0]->type
->is_float());
1303 float dot_NI
= dot(op
[1], op
[0]);
1304 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1305 data
.f
[c
] = op
[0]->value
.f
[c
] - 2 * dot_NI
* op
[1]->value
.f
[c
];
1306 } else if (strcmp(callee
, "refract") == 0) {
1307 const float eta
= op
[2]->value
.f
[0];
1308 const float dot_NI
= dot(op
[1], op
[0]);
1309 const float k
= 1.0F
- eta
* eta
* (1.0F
- dot_NI
* dot_NI
);
1311 return ir_constant::zero(mem_ctx
, this->type
);
1313 for (unsigned c
= 0; c
< type
->components(); c
++) {
1314 data
.f
[c
] = eta
* op
[0]->value
.f
[c
] - (eta
* dot_NI
+ sqrtf(k
))
1315 * op
[1]->value
.f
[c
];
1318 } else if (strcmp(callee
, "sign") == 0) {
1319 expr
= new(mem_ctx
) ir_expression(ir_unop_sign
, type
, op
[0], NULL
);
1320 } else if (strcmp(callee
, "sin") == 0) {
1321 expr
= new(mem_ctx
) ir_expression(ir_unop_sin
, type
, op
[0], NULL
);
1322 } else if (strcmp(callee
, "sinh") == 0) {
1323 assert(op
[0]->type
->is_float());
1324 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1325 data
.f
[c
] = sinhf(op
[0]->value
.f
[c
]);
1326 } else if (strcmp(callee
, "smoothstep") == 0) {
1327 assert(num_parameters
== 3);
1328 assert(op
[1]->type
== op
[0]->type
);
1329 unsigned edge_inc
= op
[0]->type
->is_scalar() ? 0 : 1;
1330 for (unsigned c
= 0, e
= 0; c
< type
->components(); e
+= edge_inc
, c
++) {
1331 const float edge0
= op
[0]->value
.f
[e
];
1332 const float edge1
= op
[1]->value
.f
[e
];
1333 if (edge0
== edge1
) {
1334 data
.f
[c
] = 0.0; /* Avoid a crash - results are undefined anyway */
1336 const float numerator
= op
[2]->value
.f
[c
] - edge0
;
1337 const float denominator
= edge1
- edge0
;
1338 const float t
= CLAMP(numerator
/denominator
, 0, 1);
1339 data
.f
[c
] = t
* t
* (3 - 2 * t
);
1342 } else if (strcmp(callee
, "sqrt") == 0) {
1343 expr
= new(mem_ctx
) ir_expression(ir_unop_sqrt
, type
, op
[0], NULL
);
1344 } else if (strcmp(callee
, "step") == 0) {
1345 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1346 /* op[0] (edge) may be either a scalar or a vector */
1347 const unsigned c0_inc
= op
[0]->type
->is_scalar() ? 0 : 1;
1348 for (unsigned c
= 0, c0
= 0; c
< type
->components(); c0
+= c0_inc
, c
++)
1349 data
.f
[c
] = (op
[1]->value
.f
[c
] < op
[0]->value
.f
[c0
]) ? 0.0F
: 1.0F
;
1350 } else if (strcmp(callee
, "tan") == 0) {
1351 assert(op
[0]->type
->is_float());
1352 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1353 data
.f
[c
] = tanf(op
[0]->value
.f
[c
]);
1354 } else if (strcmp(callee
, "tanh") == 0) {
1355 assert(op
[0]->type
->is_float());
1356 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1357 data
.f
[c
] = tanhf(op
[0]->value
.f
[c
]);
1358 } else if (strcmp(callee
, "transpose") == 0) {
1359 assert(op
[0]->type
->is_matrix());
1360 const unsigned n
= op
[0]->type
->vector_elements
;
1361 const unsigned m
= op
[0]->type
->matrix_columns
;
1362 for (unsigned j
= 0; j
< m
; j
++) {
1363 for (unsigned i
= 0; i
< n
; i
++) {
1364 data
.f
[m
*i
+j
] += op
[0]->value
.f
[i
+n
*j
];
1368 /* Unsupported builtin - some are not allowed in constant expressions. */
1373 return expr
->constant_expression_value();
1375 return new(mem_ctx
) ir_constant(this->type
, &data
);