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/macros.h"
39 #include "ir_visitor.h"
40 #include "glsl_types.h"
43 ir_expression::constant_expression_value()
45 ir_constant
*op
[2] = { NULL
, NULL
};
46 ir_constant_data data
;
48 memset(&data
, 0, sizeof(data
));
50 for (unsigned operand
= 0; operand
< this->get_num_operands(); operand
++) {
51 op
[operand
] = this->operands
[operand
]->constant_expression_value();
57 assert(op
[0]->type
->base_type
== op
[1]->type
->base_type
);
59 bool op0_scalar
= op
[0]->type
->is_scalar();
60 bool op1_scalar
= op
[1] != NULL
&& op
[1]->type
->is_scalar();
62 /* When iterating over a vector or matrix's components, we want to increase
63 * the loop counter. However, for scalars, we want to stay at 0.
65 unsigned c0_inc
= op0_scalar
? 0 : 1;
66 unsigned c1_inc
= op1_scalar
? 0 : 1;
68 if (op1_scalar
|| !op
[1]) {
69 components
= op
[0]->type
->components();
71 components
= op
[1]->type
->components();
74 void *ctx
= talloc_parent(this);
76 /* Handle array operations here, rather than below. */
77 if (op
[0]->type
->is_array()) {
78 assert(op
[1] != NULL
&& op
[1]->type
->is_array());
79 switch (this->operation
) {
81 return new(ctx
) ir_constant(op
[0]->has_value(op
[1]));
83 return new(ctx
) ir_constant(!op
[0]->has_value(op
[1]));
90 switch (this->operation
) {
91 case ir_unop_logic_not
:
92 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
93 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
94 data
.b
[c
] = !op
[0]->value
.b
[c
];
98 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
99 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
100 data
.i
[c
] = op
[0]->value
.f
[c
];
104 assert(op
[0]->type
->base_type
== GLSL_TYPE_INT
);
105 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
106 data
.f
[c
] = op
[0]->value
.i
[c
];
110 assert(op
[0]->type
->base_type
== GLSL_TYPE_UINT
);
111 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
112 data
.f
[c
] = op
[0]->value
.u
[c
];
116 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
117 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
118 data
.f
[c
] = op
[0]->value
.b
[c
] ? 1.0 : 0.0;
122 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
123 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
124 data
.b
[c
] = bool(op
[0]->value
.f
[c
]);
128 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
129 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
130 data
.u
[c
] = op
[0]->value
.b
[c
] ? 1 : 0;
134 assert(op
[0]->type
->is_integer());
135 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
136 data
.b
[c
] = bool(op
[0]->value
.u
[c
]);
141 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
142 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
143 data
.f
[c
] = truncf(op
[0]->value
.f
[c
]);
148 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
149 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
150 data
.f
[c
] = ceilf(op
[0]->value
.f
[c
]);
155 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
156 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
157 data
.f
[c
] = floorf(op
[0]->value
.f
[c
]);
162 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
163 switch (this->type
->base_type
) {
170 case GLSL_TYPE_FLOAT
:
171 data
.f
[c
] = op
[0]->value
.f
[c
] - floor(op
[0]->value
.f
[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
] = sinf(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
] = cosf(op
[0]->value
.f
[c
]);
194 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
195 switch (this->type
->base_type
) {
197 data
.u
[c
] = -op
[0]->value
.u
[c
];
200 data
.i
[c
] = -op
[0]->value
.i
[c
];
202 case GLSL_TYPE_FLOAT
:
203 data
.f
[c
] = -op
[0]->value
.f
[c
];
212 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
213 switch (this->type
->base_type
) {
215 data
.u
[c
] = op
[0]->value
.u
[c
];
218 data
.i
[c
] = op
[0]->value
.i
[c
];
220 data
.i
[c
] = -data
.i
[c
];
222 case GLSL_TYPE_FLOAT
:
223 data
.f
[c
] = fabs(op
[0]->value
.f
[c
]);
232 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
233 switch (this->type
->base_type
) {
235 data
.u
[c
] = op
[0]->value
.i
[c
] > 0;
238 data
.i
[c
] = (op
[0]->value
.i
[c
] > 0) - (op
[0]->value
.i
[c
] < 0);
240 case GLSL_TYPE_FLOAT
:
241 data
.f
[c
] = float((op
[0]->value
.f
[c
] > 0)-(op
[0]->value
.f
[c
] < 0));
250 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
251 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
252 switch (this->type
->base_type
) {
254 if (op
[0]->value
.u
[c
] != 0.0)
255 data
.u
[c
] = 1 / op
[0]->value
.u
[c
];
258 if (op
[0]->value
.i
[c
] != 0.0)
259 data
.i
[c
] = 1 / op
[0]->value
.i
[c
];
261 case GLSL_TYPE_FLOAT
:
262 if (op
[0]->value
.f
[c
] != 0.0)
263 data
.f
[c
] = 1.0 / op
[0]->value
.f
[c
];
272 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
273 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
274 data
.f
[c
] = 1.0 / sqrtf(op
[0]->value
.f
[c
]);
279 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
280 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
281 data
.f
[c
] = sqrtf(op
[0]->value
.f
[c
]);
286 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
287 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
288 data
.f
[c
] = expf(op
[0]->value
.f
[c
]);
293 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
294 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
295 data
.f
[c
] = exp2f(op
[0]->value
.f
[c
]);
300 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
301 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
302 data
.f
[c
] = logf(op
[0]->value
.f
[c
]);
307 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
308 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
309 data
.f
[c
] = log2f(op
[0]->value
.f
[c
]);
315 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
316 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
322 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
323 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
324 data
.f
[c
] = powf(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
329 assert(op
[0]->type
->is_vector() && op
[1]->type
->is_vector());
331 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
332 switch (op
[0]->type
->base_type
) {
334 data
.u
[0] += op
[0]->value
.u
[c
] * op
[1]->value
.u
[c
];
337 data
.i
[0] += op
[0]->value
.i
[c
] * op
[1]->value
.i
[c
];
339 case GLSL_TYPE_FLOAT
:
340 data
.f
[0] += op
[0]->value
.f
[c
] * op
[1]->value
.f
[c
];
349 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
350 for (unsigned c
= 0, c0
= 0, c1
= 0;
352 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
354 switch (op
[0]->type
->base_type
) {
356 data
.u
[c
] = MIN2(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
359 data
.i
[c
] = MIN2(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
361 case GLSL_TYPE_FLOAT
:
362 data
.f
[c
] = MIN2(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
371 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
372 for (unsigned c
= 0, c0
= 0, c1
= 0;
374 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
376 switch (op
[0]->type
->base_type
) {
378 data
.u
[c
] = MAX2(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
381 data
.i
[c
] = MAX2(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
383 case GLSL_TYPE_FLOAT
:
384 data
.f
[c
] = MAX2(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
393 assert(op
[0]->type
== glsl_type::vec3_type
);
394 assert(op
[1]->type
== glsl_type::vec3_type
);
395 data
.f
[0] = (op
[0]->value
.f
[1] * op
[1]->value
.f
[2] -
396 op
[1]->value
.f
[1] * op
[0]->value
.f
[2]);
397 data
.f
[1] = (op
[0]->value
.f
[2] * op
[1]->value
.f
[0] -
398 op
[1]->value
.f
[2] * op
[0]->value
.f
[0]);
399 data
.f
[2] = (op
[0]->value
.f
[0] * op
[1]->value
.f
[1] -
400 op
[1]->value
.f
[0] * op
[0]->value
.f
[1]);
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
] = op
[0]->value
.u
[c0
] + op
[1]->value
.u
[c1
];
414 data
.i
[c
] = op
[0]->value
.i
[c0
] + op
[1]->value
.i
[c1
];
416 case GLSL_TYPE_FLOAT
:
417 data
.f
[c
] = 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 /* Check for equal types, or unequal types involving scalars */
449 if ((op
[0]->type
== op
[1]->type
&& !op
[0]->type
->is_matrix())
450 || op0_scalar
|| op1_scalar
) {
451 for (unsigned c
= 0, c0
= 0, c1
= 0;
453 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
455 switch (op
[0]->type
->base_type
) {
457 data
.u
[c
] = op
[0]->value
.u
[c0
] * op
[1]->value
.u
[c1
];
460 data
.i
[c
] = op
[0]->value
.i
[c0
] * op
[1]->value
.i
[c1
];
462 case GLSL_TYPE_FLOAT
:
463 data
.f
[c
] = op
[0]->value
.f
[c0
] * op
[1]->value
.f
[c1
];
470 assert(op
[0]->type
->is_matrix() || op
[1]->type
->is_matrix());
472 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
473 * matrix can be a GLSL vector, either N or P can be 1.
475 * For vec*mat, the vector is treated as a row vector. This
476 * means the vector is a 1-row x M-column matrix.
478 * For mat*vec, the vector is treated as a column vector. Since
479 * matrix_columns is 1 for vectors, this just works.
481 const unsigned n
= op
[0]->type
->is_vector()
482 ? 1 : op
[0]->type
->vector_elements
;
483 const unsigned m
= op
[1]->type
->vector_elements
;
484 const unsigned p
= op
[1]->type
->matrix_columns
;
485 for (unsigned j
= 0; j
< p
; j
++) {
486 for (unsigned i
= 0; i
< n
; i
++) {
487 for (unsigned k
= 0; k
< m
; k
++) {
488 data
.f
[i
+n
*j
] += op
[0]->value
.f
[i
+n
*k
]*op
[1]->value
.f
[k
+m
*j
];
496 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
497 for (unsigned c
= 0, c0
= 0, c1
= 0;
499 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
501 switch (op
[0]->type
->base_type
) {
503 data
.u
[c
] = op
[0]->value
.u
[c0
] / op
[1]->value
.u
[c1
];
506 data
.i
[c
] = op
[0]->value
.i
[c0
] / op
[1]->value
.i
[c1
];
508 case GLSL_TYPE_FLOAT
:
509 data
.f
[c
] = op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
];
518 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
519 for (unsigned c
= 0, c0
= 0, c1
= 0;
521 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
523 switch (op
[0]->type
->base_type
) {
525 data
.u
[c
] = op
[0]->value
.u
[c0
] % op
[1]->value
.u
[c1
];
528 data
.i
[c
] = op
[0]->value
.i
[c0
] % op
[1]->value
.i
[c1
];
530 case GLSL_TYPE_FLOAT
:
531 /* We don't use fmod because it rounds toward zero; GLSL specifies
534 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
]
535 * floorf(op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
]);
544 case ir_binop_logic_and
:
545 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
546 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
547 data
.b
[c
] = op
[0]->value
.b
[c
] && op
[1]->value
.b
[c
];
549 case ir_binop_logic_xor
:
550 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
551 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
552 data
.b
[c
] = op
[0]->value
.b
[c
] ^ op
[1]->value
.b
[c
];
554 case ir_binop_logic_or
:
555 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
556 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
557 data
.b
[c
] = op
[0]->value
.b
[c
] || op
[1]->value
.b
[c
];
561 switch (op
[0]->type
->base_type
) {
563 data
.b
[0] = op
[0]->value
.u
[0] < op
[1]->value
.u
[0];
566 data
.b
[0] = op
[0]->value
.i
[0] < op
[1]->value
.i
[0];
568 case GLSL_TYPE_FLOAT
:
569 data
.b
[0] = op
[0]->value
.f
[0] < op
[1]->value
.f
[0];
575 case ir_binop_greater
:
576 switch (op
[0]->type
->base_type
) {
578 data
.b
[0] = op
[0]->value
.u
[0] > op
[1]->value
.u
[0];
581 data
.b
[0] = op
[0]->value
.i
[0] > op
[1]->value
.i
[0];
583 case GLSL_TYPE_FLOAT
:
584 data
.b
[0] = op
[0]->value
.f
[0] > op
[1]->value
.f
[0];
590 case ir_binop_lequal
:
591 switch (op
[0]->type
->base_type
) {
593 data
.b
[0] = op
[0]->value
.u
[0] <= op
[1]->value
.u
[0];
596 data
.b
[0] = op
[0]->value
.i
[0] <= op
[1]->value
.i
[0];
598 case GLSL_TYPE_FLOAT
:
599 data
.b
[0] = op
[0]->value
.f
[0] <= op
[1]->value
.f
[0];
605 case ir_binop_gequal
:
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];
622 data
.b
[0] = op
[0]->has_value(op
[1]);
624 case ir_binop_nequal
:
625 data
.b
[0] = !op
[0]->has_value(op
[1]);
629 /* FINISHME: Should handle all expression types. */
633 return new(ctx
) ir_constant(this->type
, &data
);
638 ir_texture::constant_expression_value()
640 /* texture lookups aren't constant expressions */
646 ir_swizzle::constant_expression_value()
648 ir_constant
*v
= this->val
->constant_expression_value();
651 ir_constant_data data
;
653 const unsigned swiz_idx
[4] = {
654 this->mask
.x
, this->mask
.y
, this->mask
.z
, this->mask
.w
657 for (unsigned i
= 0; i
< this->mask
.num_components
; i
++) {
658 switch (v
->type
->base_type
) {
660 case GLSL_TYPE_INT
: data
.u
[i
] = v
->value
.u
[swiz_idx
[i
]]; break;
661 case GLSL_TYPE_FLOAT
: data
.f
[i
] = v
->value
.f
[swiz_idx
[i
]]; break;
662 case GLSL_TYPE_BOOL
: data
.b
[i
] = v
->value
.b
[swiz_idx
[i
]]; break;
663 default: assert(!"Should not get here."); break;
667 void *ctx
= talloc_parent(this);
668 return new(ctx
) ir_constant(this->type
, &data
);
675 ir_dereference_variable::constant_expression_value()
677 /* This may occur during compile and var->type is glsl_type::error_type */
681 return var
->constant_value
? var
->constant_value
->clone(NULL
) : NULL
;
686 ir_dereference_array::constant_expression_value()
688 void *ctx
= talloc_parent(this);
689 ir_constant
*array
= this->array
->constant_expression_value();
690 ir_constant
*idx
= this->array_index
->constant_expression_value();
692 if ((array
!= NULL
) && (idx
!= NULL
)) {
693 if (array
->type
->is_matrix()) {
694 /* Array access of a matrix results in a vector.
696 const unsigned column
= idx
->value
.u
[0];
698 const glsl_type
*const column_type
= array
->type
->column_type();
700 /* Offset in the constant matrix to the first element of the column
703 const unsigned mat_idx
= column
* column_type
->vector_elements
;
705 ir_constant_data data
;
707 switch (column_type
->base_type
) {
710 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
711 data
.u
[i
] = array
->value
.u
[mat_idx
+ i
];
715 case GLSL_TYPE_FLOAT
:
716 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
717 data
.f
[i
] = array
->value
.f
[mat_idx
+ i
];
722 assert(!"Should not get here.");
726 return new(ctx
) ir_constant(column_type
, &data
);
727 } else if (array
->type
->is_vector()) {
728 const unsigned component
= idx
->value
.u
[0];
730 return new(ctx
) ir_constant(array
, component
);
732 const unsigned index
= idx
->value
.u
[0];
733 return array
->get_array_element(index
)->clone(NULL
);
741 ir_dereference_record::constant_expression_value()
743 ir_constant
*v
= this->record
->constant_expression_value();
745 return (v
!= NULL
) ? v
->get_record_field(this->field
) : NULL
;
750 ir_assignment::constant_expression_value()
752 /* FINISHME: Handle CEs involving assignment (return RHS) */
758 ir_constant::constant_expression_value()
765 ir_call::constant_expression_value()
767 if (this->type
== glsl_type::error_type
)
770 /* From the GLSL 1.20 spec, page 23:
771 * "Function calls to user-defined functions (non-built-in functions)
772 * cannot be used to form constant expressions."
774 if (!this->callee
->is_built_in
)
777 unsigned num_parameters
= 0;
779 /* Check if all parameters are constant */
781 foreach_list(n
, &this->actual_parameters
) {
782 ir_constant
*constant
= ((ir_rvalue
*) n
)->constant_expression_value();
783 if (constant
== NULL
)
786 op
[num_parameters
] = constant
;
788 assert(num_parameters
< 3);
792 /* Individual cases below can either:
793 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
794 * - Fill "data" with appopriate constant data
795 * - Return an ir_constant directly.
797 void *mem_ctx
= talloc_parent(this);
798 ir_expression
*expr
= NULL
;
800 ir_constant_data data
;
801 memset(&data
, 0, sizeof(data
));
803 const char *callee
= this->callee_name();
804 if (strcmp(callee
, "abs") == 0) {
805 expr
= new(mem_ctx
) ir_expression(ir_unop_abs
, type
, op
[0], NULL
);
806 } else if (strcmp(callee
, "all") == 0) {
807 assert(op
[0]->type
->is_boolean());
808 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
809 if (!op
[0]->value
.b
[c
])
810 return new(mem_ctx
) ir_constant(false);
812 return new(mem_ctx
) ir_constant(true);
813 } else if (strcmp(callee
, "any") == 0) {
814 return NULL
; /* FINISHME: implement this */
815 } else if (strcmp(callee
, "asin") == 0) {
816 return NULL
; /* FINISHME: implement this */
817 } else if (strcmp(callee
, "atan") == 0) {
818 return NULL
; /* FINISHME: implement this */
819 } else if (strcmp(callee
, "dFdx") == 0 || strcmp(callee
, "dFdy") == 0) {
820 return ir_constant::zero(mem_ctx
, this->type
);
821 } else if (strcmp(callee
, "ceil") == 0) {
822 expr
= new(mem_ctx
) ir_expression(ir_unop_ceil
, type
, op
[0], NULL
);
823 } else if (strcmp(callee
, "clamp") == 0) {
824 return NULL
; /* FINISHME: implement this */
825 } else if (strcmp(callee
, "cos") == 0) {
826 expr
= new(mem_ctx
) ir_expression(ir_unop_cos
, type
, op
[0], NULL
);
827 } else if (strcmp(callee
, "cosh") == 0) {
828 return NULL
; /* FINISHME: implement this */
829 } else if (strcmp(callee
, "cross") == 0) {
830 expr
= new(mem_ctx
) ir_expression(ir_binop_cross
, type
, op
[0], op
[1]);
831 } else if (strcmp(callee
, "degrees") == 0) {
832 return NULL
; /* FINISHME: implement this */
833 } else if (strcmp(callee
, "distance") == 0) {
834 return NULL
; /* FINISHME: implement this */
835 } else if (strcmp(callee
, "dot") == 0) {
836 expr
= new(mem_ctx
) ir_expression(ir_binop_dot
, type
, op
[0], op
[1]);
837 } else if (strcmp(callee
, "equal") == 0) {
838 return NULL
; /* FINISHME: implement this */
839 } else if (strcmp(callee
, "exp") == 0) {
840 expr
= new(mem_ctx
) ir_expression(ir_unop_exp
, type
, op
[0], NULL
);
841 } else if (strcmp(callee
, "exp2") == 0) {
842 expr
= new(mem_ctx
) ir_expression(ir_unop_exp2
, type
, op
[0], NULL
);
843 } else if (strcmp(callee
, "faceforward") == 0) {
844 return NULL
; /* FINISHME: implement this */
845 } else if (strcmp(callee
, "floor") == 0) {
846 expr
= new(mem_ctx
) ir_expression(ir_unop_floor
, type
, op
[0], NULL
);
847 } else if (strcmp(callee
, "fract") == 0) {
848 expr
= new(mem_ctx
) ir_expression(ir_unop_fract
, type
, op
[0], NULL
);
849 } else if (strcmp(callee
, "fwidth") == 0) {
850 return ir_constant::zero(mem_ctx
, this->type
);
851 } else if (strcmp(callee
, "greaterThan") == 0) {
852 return NULL
; /* FINISHME: implement this */
853 } else if (strcmp(callee
, "greaterThanEqual") == 0) {
854 return NULL
; /* FINISHME: implement this */
855 } else if (strcmp(callee
, "inversesqrt") == 0) {
856 expr
= new(mem_ctx
) ir_expression(ir_unop_rsq
, type
, op
[0], NULL
);
857 } else if (strcmp(callee
, "length") == 0) {
858 return NULL
; /* FINISHME: implement this */
859 } else if (strcmp(callee
, "lessThan") == 0) {
860 return NULL
; /* FINISHME: implement this */
861 } else if (strcmp(callee
, "lessThanEqual") == 0) {
862 return NULL
; /* FINISHME: implement this */
863 } else if (strcmp(callee
, "log") == 0) {
864 expr
= new(mem_ctx
) ir_expression(ir_unop_log
, type
, op
[0], NULL
);
865 } else if (strcmp(callee
, "log2") == 0) {
866 expr
= new(mem_ctx
) ir_expression(ir_unop_log2
, type
, op
[0], NULL
);
867 } else if (strcmp(callee
, "matrixCompMult") == 0) {
868 return NULL
; /* FINISHME: implement this */
869 } else if (strcmp(callee
, "max") == 0) {
870 expr
= new(mem_ctx
) ir_expression(ir_binop_max
, type
, op
[0], op
[1]);
871 } else if (strcmp(callee
, "min") == 0) {
872 expr
= new(mem_ctx
) ir_expression(ir_binop_min
, type
, op
[0], op
[1]);
873 } else if (strcmp(callee
, "mix") == 0) {
874 return NULL
; /* FINISHME: implement this */
875 } else if (strcmp(callee
, "mod") == 0) {
876 expr
= new(mem_ctx
) ir_expression(ir_binop_mod
, type
, op
[0], op
[1]);
877 } else if (strcmp(callee
, "normalize") == 0) {
878 return NULL
; /* FINISHME: implement this */
879 } else if (strcmp(callee
, "not") == 0) {
880 expr
= new(mem_ctx
) ir_expression(ir_unop_logic_not
, type
, op
[0], NULL
);
881 } else if (strcmp(callee
, "notEqual") == 0) {
882 return NULL
; /* FINISHME: implement this */
883 } else if (strcmp(callee
, "outerProduct") == 0) {
884 return NULL
; /* FINISHME: implement this */
885 } else if (strcmp(callee
, "pow") == 0) {
886 expr
= new(mem_ctx
) ir_expression(ir_binop_pow
, type
, op
[0], op
[1]);
887 } else if (strcmp(callee
, "radians") == 0) {
888 return NULL
; /* FINISHME: implement this */
889 } else if (strcmp(callee
, "reflect") == 0) {
890 return NULL
; /* FINISHME: implement this */
891 } else if (strcmp(callee
, "refract") == 0) {
892 return NULL
; /* FINISHME: implement this */
893 } else if (strcmp(callee
, "sign") == 0) {
894 expr
= new(mem_ctx
) ir_expression(ir_unop_sign
, type
, op
[0], NULL
);
895 } else if (strcmp(callee
, "sin") == 0) {
896 expr
= new(mem_ctx
) ir_expression(ir_unop_sin
, type
, op
[0], NULL
);
897 } else if (strcmp(callee
, "sinh") == 0) {
898 return NULL
; /* FINISHME: implement this */
899 } else if (strcmp(callee
, "smoothstep") == 0) {
900 return NULL
; /* FINISHME: implement this */
901 } else if (strcmp(callee
, "sqrt") == 0) {
902 expr
= new(mem_ctx
) ir_expression(ir_unop_sqrt
, type
, op
[0], NULL
);
903 } else if (strcmp(callee
, "step") == 0) {
904 return NULL
; /* FINISHME: implement this */
905 } else if (strcmp(callee
, "tan") == 0) {
906 return NULL
; /* FINISHME: implement this */
907 } else if (strcmp(callee
, "tanh") == 0) {
908 return NULL
; /* FINISHME: implement this */
909 } else if (strcmp(callee
, "transpose") == 0) {
910 return NULL
; /* FINISHME: implement this */
912 /* Unsupported builtin - some are not allowed in constant expressions. */
917 return expr
->constant_expression_value();
919 return new(mem_ctx
) ir_constant(this->type
, &data
);