06bea2bef6e95724275cbdf35c0e5ed0e49b99e1
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 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 ir_constant
*op
[2] = { NULL
, NULL
};
58 ir_constant_data data
;
60 memset(&data
, 0, sizeof(data
));
62 for (unsigned operand
= 0; operand
< this->get_num_operands(); operand
++) {
63 op
[operand
] = this->operands
[operand
]->constant_expression_value();
69 assert(op
[0]->type
->base_type
== op
[1]->type
->base_type
);
71 bool op0_scalar
= op
[0]->type
->is_scalar();
72 bool op1_scalar
= op
[1] != NULL
&& op
[1]->type
->is_scalar();
74 /* When iterating over a vector or matrix's components, we want to increase
75 * the loop counter. However, for scalars, we want to stay at 0.
77 unsigned c0_inc
= op0_scalar
? 0 : 1;
78 unsigned c1_inc
= op1_scalar
? 0 : 1;
80 if (op1_scalar
|| !op
[1]) {
81 components
= op
[0]->type
->components();
83 components
= op
[1]->type
->components();
86 void *ctx
= talloc_parent(this);
88 /* Handle array operations here, rather than below. */
89 if (op
[0]->type
->is_array()) {
90 assert(op
[1] != NULL
&& op
[1]->type
->is_array());
91 switch (this->operation
) {
93 return new(ctx
) ir_constant(op
[0]->has_value(op
[1]));
95 return new(ctx
) ir_constant(!op
[0]->has_value(op
[1]));
102 switch (this->operation
) {
103 case ir_unop_logic_not
:
104 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
105 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
106 data
.b
[c
] = !op
[0]->value
.b
[c
];
110 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
111 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
112 data
.i
[c
] = op
[0]->value
.f
[c
];
116 assert(op
[0]->type
->base_type
== GLSL_TYPE_INT
);
117 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
118 data
.f
[c
] = op
[0]->value
.i
[c
];
122 assert(op
[0]->type
->base_type
== GLSL_TYPE_UINT
);
123 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
124 data
.f
[c
] = op
[0]->value
.u
[c
];
128 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
129 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
130 data
.f
[c
] = op
[0]->value
.b
[c
] ? 1.0 : 0.0;
134 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
135 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
136 data
.b
[c
] = bool(op
[0]->value
.f
[c
]);
140 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
141 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
142 data
.u
[c
] = op
[0]->value
.b
[c
] ? 1 : 0;
146 assert(op
[0]->type
->is_integer());
147 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
148 data
.b
[c
] = bool(op
[0]->value
.u
[c
]);
153 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
154 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
155 data
.f
[c
] = truncf(op
[0]->value
.f
[c
]);
160 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
161 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
162 data
.f
[c
] = ceilf(op
[0]->value
.f
[c
]);
167 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
168 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
169 data
.f
[c
] = floorf(op
[0]->value
.f
[c
]);
174 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
175 switch (this->type
->base_type
) {
182 case GLSL_TYPE_FLOAT
:
183 data
.f
[c
] = op
[0]->value
.f
[c
] - floor(op
[0]->value
.f
[c
]);
192 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
193 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
194 data
.f
[c
] = sinf(op
[0]->value
.f
[c
]);
199 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
200 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
201 data
.f
[c
] = cosf(op
[0]->value
.f
[c
]);
206 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
207 switch (this->type
->base_type
) {
209 data
.u
[c
] = -op
[0]->value
.u
[c
];
212 data
.i
[c
] = -op
[0]->value
.i
[c
];
214 case GLSL_TYPE_FLOAT
:
215 data
.f
[c
] = -op
[0]->value
.f
[c
];
224 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
225 switch (this->type
->base_type
) {
227 data
.u
[c
] = op
[0]->value
.u
[c
];
230 data
.i
[c
] = op
[0]->value
.i
[c
];
232 data
.i
[c
] = -data
.i
[c
];
234 case GLSL_TYPE_FLOAT
:
235 data
.f
[c
] = fabs(op
[0]->value
.f
[c
]);
244 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
245 switch (this->type
->base_type
) {
247 data
.u
[c
] = op
[0]->value
.i
[c
] > 0;
250 data
.i
[c
] = (op
[0]->value
.i
[c
] > 0) - (op
[0]->value
.i
[c
] < 0);
252 case GLSL_TYPE_FLOAT
:
253 data
.f
[c
] = float((op
[0]->value
.f
[c
] > 0)-(op
[0]->value
.f
[c
] < 0));
262 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
263 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
264 switch (this->type
->base_type
) {
266 if (op
[0]->value
.u
[c
] != 0.0)
267 data
.u
[c
] = 1 / op
[0]->value
.u
[c
];
270 if (op
[0]->value
.i
[c
] != 0.0)
271 data
.i
[c
] = 1 / op
[0]->value
.i
[c
];
273 case GLSL_TYPE_FLOAT
:
274 if (op
[0]->value
.f
[c
] != 0.0)
275 data
.f
[c
] = 1.0 / op
[0]->value
.f
[c
];
284 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
285 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
286 data
.f
[c
] = 1.0 / sqrtf(op
[0]->value
.f
[c
]);
291 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
292 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
293 data
.f
[c
] = sqrtf(op
[0]->value
.f
[c
]);
298 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
299 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
300 data
.f
[c
] = expf(op
[0]->value
.f
[c
]);
305 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
306 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
307 data
.f
[c
] = exp2f(op
[0]->value
.f
[c
]);
312 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
313 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
314 data
.f
[c
] = logf(op
[0]->value
.f
[c
]);
319 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
320 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
321 data
.f
[c
] = log2f(op
[0]->value
.f
[c
]);
327 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
328 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
334 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
335 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
336 data
.f
[c
] = powf(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
341 data
.f
[0] = dot(op
[0], op
[1]);
345 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
346 for (unsigned c
= 0, c0
= 0, c1
= 0;
348 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
350 switch (op
[0]->type
->base_type
) {
352 data
.u
[c
] = MIN2(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
355 data
.i
[c
] = MIN2(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
357 case GLSL_TYPE_FLOAT
:
358 data
.f
[c
] = MIN2(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
367 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
368 for (unsigned c
= 0, c0
= 0, c1
= 0;
370 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
372 switch (op
[0]->type
->base_type
) {
374 data
.u
[c
] = MAX2(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
377 data
.i
[c
] = MAX2(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
379 case GLSL_TYPE_FLOAT
:
380 data
.f
[c
] = MAX2(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
389 assert(op
[0]->type
== glsl_type::vec3_type
);
390 assert(op
[1]->type
== glsl_type::vec3_type
);
391 data
.f
[0] = (op
[0]->value
.f
[1] * op
[1]->value
.f
[2] -
392 op
[1]->value
.f
[1] * op
[0]->value
.f
[2]);
393 data
.f
[1] = (op
[0]->value
.f
[2] * op
[1]->value
.f
[0] -
394 op
[1]->value
.f
[2] * op
[0]->value
.f
[0]);
395 data
.f
[2] = (op
[0]->value
.f
[0] * op
[1]->value
.f
[1] -
396 op
[1]->value
.f
[0] * op
[0]->value
.f
[1]);
400 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
401 for (unsigned c
= 0, c0
= 0, c1
= 0;
403 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
405 switch (op
[0]->type
->base_type
) {
407 data
.u
[c
] = op
[0]->value
.u
[c0
] + op
[1]->value
.u
[c1
];
410 data
.i
[c
] = op
[0]->value
.i
[c0
] + op
[1]->value
.i
[c1
];
412 case GLSL_TYPE_FLOAT
:
413 data
.f
[c
] = op
[0]->value
.f
[c0
] + op
[1]->value
.f
[c1
];
422 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
423 for (unsigned c
= 0, c0
= 0, c1
= 0;
425 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
427 switch (op
[0]->type
->base_type
) {
429 data
.u
[c
] = op
[0]->value
.u
[c0
] - op
[1]->value
.u
[c1
];
432 data
.i
[c
] = op
[0]->value
.i
[c0
] - op
[1]->value
.i
[c1
];
434 case GLSL_TYPE_FLOAT
:
435 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
];
444 /* Check for equal types, or unequal types involving scalars */
445 if ((op
[0]->type
== op
[1]->type
&& !op
[0]->type
->is_matrix())
446 || op0_scalar
|| op1_scalar
) {
447 for (unsigned c
= 0, c0
= 0, c1
= 0;
449 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
451 switch (op
[0]->type
->base_type
) {
453 data
.u
[c
] = op
[0]->value
.u
[c0
] * op
[1]->value
.u
[c1
];
456 data
.i
[c
] = op
[0]->value
.i
[c0
] * op
[1]->value
.i
[c1
];
458 case GLSL_TYPE_FLOAT
:
459 data
.f
[c
] = op
[0]->value
.f
[c0
] * op
[1]->value
.f
[c1
];
466 assert(op
[0]->type
->is_matrix() || op
[1]->type
->is_matrix());
468 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
469 * matrix can be a GLSL vector, either N or P can be 1.
471 * For vec*mat, the vector is treated as a row vector. This
472 * means the vector is a 1-row x M-column matrix.
474 * For mat*vec, the vector is treated as a column vector. Since
475 * matrix_columns is 1 for vectors, this just works.
477 const unsigned n
= op
[0]->type
->is_vector()
478 ? 1 : op
[0]->type
->vector_elements
;
479 const unsigned m
= op
[1]->type
->vector_elements
;
480 const unsigned p
= op
[1]->type
->matrix_columns
;
481 for (unsigned j
= 0; j
< p
; j
++) {
482 for (unsigned i
= 0; i
< n
; i
++) {
483 for (unsigned k
= 0; k
< m
; k
++) {
484 data
.f
[i
+n
*j
] += op
[0]->value
.f
[i
+n
*k
]*op
[1]->value
.f
[k
+m
*j
];
492 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
493 for (unsigned c
= 0, c0
= 0, c1
= 0;
495 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
497 switch (op
[0]->type
->base_type
) {
499 data
.u
[c
] = op
[0]->value
.u
[c0
] / op
[1]->value
.u
[c1
];
502 data
.i
[c
] = op
[0]->value
.i
[c0
] / op
[1]->value
.i
[c1
];
504 case GLSL_TYPE_FLOAT
:
505 data
.f
[c
] = op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
];
514 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
515 for (unsigned c
= 0, c0
= 0, c1
= 0;
517 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
519 switch (op
[0]->type
->base_type
) {
521 data
.u
[c
] = op
[0]->value
.u
[c0
] % op
[1]->value
.u
[c1
];
524 data
.i
[c
] = op
[0]->value
.i
[c0
] % op
[1]->value
.i
[c1
];
526 case GLSL_TYPE_FLOAT
:
527 /* We don't use fmod because it rounds toward zero; GLSL specifies
530 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
]
531 * floorf(op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
]);
540 case ir_binop_logic_and
:
541 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
542 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
543 data
.b
[c
] = op
[0]->value
.b
[c
] && op
[1]->value
.b
[c
];
545 case ir_binop_logic_xor
:
546 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
547 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
548 data
.b
[c
] = op
[0]->value
.b
[c
] ^ op
[1]->value
.b
[c
];
550 case ir_binop_logic_or
:
551 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
552 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
553 data
.b
[c
] = op
[0]->value
.b
[c
] || op
[1]->value
.b
[c
];
557 switch (op
[0]->type
->base_type
) {
559 data
.b
[0] = op
[0]->value
.u
[0] < op
[1]->value
.u
[0];
562 data
.b
[0] = op
[0]->value
.i
[0] < op
[1]->value
.i
[0];
564 case GLSL_TYPE_FLOAT
:
565 data
.b
[0] = op
[0]->value
.f
[0] < op
[1]->value
.f
[0];
571 case ir_binop_greater
:
572 switch (op
[0]->type
->base_type
) {
574 data
.b
[0] = op
[0]->value
.u
[0] > op
[1]->value
.u
[0];
577 data
.b
[0] = op
[0]->value
.i
[0] > op
[1]->value
.i
[0];
579 case GLSL_TYPE_FLOAT
:
580 data
.b
[0] = op
[0]->value
.f
[0] > op
[1]->value
.f
[0];
586 case ir_binop_lequal
:
587 switch (op
[0]->type
->base_type
) {
589 data
.b
[0] = op
[0]->value
.u
[0] <= op
[1]->value
.u
[0];
592 data
.b
[0] = op
[0]->value
.i
[0] <= op
[1]->value
.i
[0];
594 case GLSL_TYPE_FLOAT
:
595 data
.b
[0] = op
[0]->value
.f
[0] <= op
[1]->value
.f
[0];
601 case ir_binop_gequal
:
602 switch (op
[0]->type
->base_type
) {
604 data
.b
[0] = op
[0]->value
.u
[0] >= op
[1]->value
.u
[0];
607 data
.b
[0] = op
[0]->value
.i
[0] >= op
[1]->value
.i
[0];
609 case GLSL_TYPE_FLOAT
:
610 data
.b
[0] = op
[0]->value
.f
[0] >= op
[1]->value
.f
[0];
618 data
.b
[0] = op
[0]->has_value(op
[1]);
620 case ir_binop_nequal
:
621 data
.b
[0] = !op
[0]->has_value(op
[1]);
625 /* FINISHME: Should handle all expression types. */
629 return new(ctx
) ir_constant(this->type
, &data
);
634 ir_texture::constant_expression_value()
636 /* texture lookups aren't constant expressions */
642 ir_swizzle::constant_expression_value()
644 ir_constant
*v
= this->val
->constant_expression_value();
647 ir_constant_data data
;
649 const unsigned swiz_idx
[4] = {
650 this->mask
.x
, this->mask
.y
, this->mask
.z
, this->mask
.w
653 for (unsigned i
= 0; i
< this->mask
.num_components
; i
++) {
654 switch (v
->type
->base_type
) {
656 case GLSL_TYPE_INT
: data
.u
[i
] = v
->value
.u
[swiz_idx
[i
]]; break;
657 case GLSL_TYPE_FLOAT
: data
.f
[i
] = v
->value
.f
[swiz_idx
[i
]]; break;
658 case GLSL_TYPE_BOOL
: data
.b
[i
] = v
->value
.b
[swiz_idx
[i
]]; break;
659 default: assert(!"Should not get here."); break;
663 void *ctx
= talloc_parent(this);
664 return new(ctx
) ir_constant(this->type
, &data
);
671 ir_dereference_variable::constant_expression_value()
673 /* This may occur during compile and var->type is glsl_type::error_type */
677 /* The constant_value of a uniform variable is its initializer,
678 * not the lifetime constant value of the uniform.
680 if (var
->mode
== ir_var_uniform
)
683 return var
->constant_value
? var
->constant_value
->clone(NULL
) : NULL
;
688 ir_dereference_array::constant_expression_value()
690 void *ctx
= talloc_parent(this);
691 ir_constant
*array
= this->array
->constant_expression_value();
692 ir_constant
*idx
= this->array_index
->constant_expression_value();
694 if ((array
!= NULL
) && (idx
!= NULL
)) {
695 if (array
->type
->is_matrix()) {
696 /* Array access of a matrix results in a vector.
698 const unsigned column
= idx
->value
.u
[0];
700 const glsl_type
*const column_type
= array
->type
->column_type();
702 /* Offset in the constant matrix to the first element of the column
705 const unsigned mat_idx
= column
* column_type
->vector_elements
;
707 ir_constant_data data
;
709 switch (column_type
->base_type
) {
712 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
713 data
.u
[i
] = array
->value
.u
[mat_idx
+ i
];
717 case GLSL_TYPE_FLOAT
:
718 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
719 data
.f
[i
] = array
->value
.f
[mat_idx
+ i
];
724 assert(!"Should not get here.");
728 return new(ctx
) ir_constant(column_type
, &data
);
729 } else if (array
->type
->is_vector()) {
730 const unsigned component
= idx
->value
.u
[0];
732 return new(ctx
) ir_constant(array
, component
);
734 const unsigned index
= idx
->value
.u
[0];
735 return array
->get_array_element(index
)->clone(NULL
);
743 ir_dereference_record::constant_expression_value()
745 ir_constant
*v
= this->record
->constant_expression_value();
747 return (v
!= NULL
) ? v
->get_record_field(this->field
) : NULL
;
752 ir_assignment::constant_expression_value()
754 /* FINISHME: Handle CEs involving assignment (return RHS) */
760 ir_constant::constant_expression_value()
767 ir_call::constant_expression_value()
769 if (this->type
== glsl_type::error_type
)
772 /* From the GLSL 1.20 spec, page 23:
773 * "Function calls to user-defined functions (non-built-in functions)
774 * cannot be used to form constant expressions."
776 if (!this->callee
->is_built_in
)
779 unsigned num_parameters
= 0;
781 /* Check if all parameters are constant */
783 foreach_list(n
, &this->actual_parameters
) {
784 ir_constant
*constant
= ((ir_rvalue
*) n
)->constant_expression_value();
785 if (constant
== NULL
)
788 op
[num_parameters
] = constant
;
790 assert(num_parameters
< 3);
794 /* Individual cases below can either:
795 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
796 * - Fill "data" with appopriate constant data
797 * - Return an ir_constant directly.
799 void *mem_ctx
= talloc_parent(this);
800 ir_expression
*expr
= NULL
;
802 ir_constant_data data
;
803 memset(&data
, 0, sizeof(data
));
805 const char *callee
= this->callee_name();
806 if (strcmp(callee
, "abs") == 0) {
807 expr
= new(mem_ctx
) ir_expression(ir_unop_abs
, type
, op
[0], NULL
);
808 } else if (strcmp(callee
, "all") == 0) {
809 assert(op
[0]->type
->is_boolean());
810 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
811 if (!op
[0]->value
.b
[c
])
812 return new(mem_ctx
) ir_constant(false);
814 return new(mem_ctx
) ir_constant(true);
815 } else if (strcmp(callee
, "any") == 0) {
816 assert(op
[0]->type
->is_boolean());
817 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
818 if (op
[0]->value
.b
[c
])
819 return new(mem_ctx
) ir_constant(true);
821 return new(mem_ctx
) ir_constant(false);
822 } else if (strcmp(callee
, "acos") == 0) {
823 assert(op
[0]->type
->is_float());
824 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
825 data
.f
[c
] = acosf(op
[0]->value
.f
[c
]);
826 } else if (strcmp(callee
, "asin") == 0) {
827 assert(op
[0]->type
->is_float());
828 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
829 data
.f
[c
] = asinf(op
[0]->value
.f
[c
]);
830 } else if (strcmp(callee
, "atan") == 0) {
831 assert(op
[0]->type
->is_float());
832 if (num_parameters
== 2) {
833 assert(op
[1]->type
->is_float());
834 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
835 data
.f
[c
] = atan2f(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
837 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
838 data
.f
[c
] = atanf(op
[0]->value
.f
[c
]);
840 } else if (strcmp(callee
, "dFdx") == 0 || strcmp(callee
, "dFdy") == 0) {
841 return ir_constant::zero(mem_ctx
, this->type
);
842 } else if (strcmp(callee
, "ceil") == 0) {
843 expr
= new(mem_ctx
) ir_expression(ir_unop_ceil
, type
, op
[0], NULL
);
844 } else if (strcmp(callee
, "clamp") == 0) {
845 assert(num_parameters
== 3);
846 unsigned c1_inc
= op
[1]->type
->is_scalar() ? 0 : 1;
847 unsigned c2_inc
= op
[2]->type
->is_scalar() ? 0 : 1;
848 for (unsigned c
= 0, c1
= 0, c2
= 0;
849 c
< op
[0]->type
->components();
850 c1
+= c1_inc
, c2
+= c2_inc
, c
++) {
852 switch (op
[0]->type
->base_type
) {
854 data
.u
[c
] = CLAMP(op
[0]->value
.u
[c
], op
[1]->value
.u
[c1
],
858 data
.i
[c
] = CLAMP(op
[0]->value
.i
[c
], op
[1]->value
.i
[c1
],
861 case GLSL_TYPE_FLOAT
:
862 data
.f
[c
] = CLAMP(op
[0]->value
.f
[c
], op
[1]->value
.f
[c1
],
866 assert(!"Should not get here.");
869 } else if (strcmp(callee
, "cos") == 0) {
870 expr
= new(mem_ctx
) ir_expression(ir_unop_cos
, type
, op
[0], NULL
);
871 } else if (strcmp(callee
, "cosh") == 0) {
872 assert(op
[0]->type
->is_float());
873 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
874 data
.f
[c
] = coshf(op
[0]->value
.f
[c
]);
875 } else if (strcmp(callee
, "cross") == 0) {
876 expr
= new(mem_ctx
) ir_expression(ir_binop_cross
, type
, op
[0], op
[1]);
877 } else if (strcmp(callee
, "degrees") == 0) {
878 assert(op
[0]->type
->is_float());
879 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
880 data
.f
[c
] = 180.0/M_PI
* op
[0]->value
.f
[c
];
881 } else if (strcmp(callee
, "distance") == 0) {
882 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
883 float length_squared
= 0.0;
884 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
885 float t
= op
[0]->value
.f
[c
] - op
[1]->value
.f
[c
];
886 length_squared
+= t
* t
;
888 return new(mem_ctx
) ir_constant(sqrtf(length_squared
));
889 } else if (strcmp(callee
, "dot") == 0) {
890 return new(mem_ctx
) ir_constant(dot(op
[0], op
[1]));
891 } else if (strcmp(callee
, "equal") == 0) {
892 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
893 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
894 switch (op
[0]->type
->base_type
) {
896 data
.b
[c
] = op
[0]->value
.u
[c
] == op
[1]->value
.u
[c
];
899 data
.b
[c
] = op
[0]->value
.i
[c
] == op
[1]->value
.i
[c
];
901 case GLSL_TYPE_FLOAT
:
902 data
.b
[c
] = op
[0]->value
.f
[c
] == op
[1]->value
.f
[c
];
905 assert(!"Should not get here.");
908 } else if (strcmp(callee
, "exp") == 0) {
909 expr
= new(mem_ctx
) ir_expression(ir_unop_exp
, type
, op
[0], NULL
);
910 } else if (strcmp(callee
, "exp2") == 0) {
911 expr
= new(mem_ctx
) ir_expression(ir_unop_exp2
, type
, op
[0], NULL
);
912 } else if (strcmp(callee
, "faceforward") == 0) {
913 if (dot(op
[2], op
[1]) < 0)
915 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
916 data
.f
[c
] = -op
[0]->value
.f
[c
];
917 } else if (strcmp(callee
, "floor") == 0) {
918 expr
= new(mem_ctx
) ir_expression(ir_unop_floor
, type
, op
[0], NULL
);
919 } else if (strcmp(callee
, "fract") == 0) {
920 expr
= new(mem_ctx
) ir_expression(ir_unop_fract
, type
, op
[0], NULL
);
921 } else if (strcmp(callee
, "fwidth") == 0) {
922 return ir_constant::zero(mem_ctx
, this->type
);
923 } else if (strcmp(callee
, "greaterThan") == 0) {
924 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
925 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
926 switch (op
[0]->type
->base_type
) {
928 data
.b
[c
] = op
[0]->value
.u
[c
] > op
[1]->value
.u
[c
];
931 data
.b
[c
] = op
[0]->value
.i
[c
] > op
[1]->value
.i
[c
];
933 case GLSL_TYPE_FLOAT
:
934 data
.b
[c
] = op
[0]->value
.f
[c
] > op
[1]->value
.f
[c
];
937 assert(!"Should not get here.");
940 } else if (strcmp(callee
, "greaterThanEqual") == 0) {
941 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
942 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
943 switch (op
[0]->type
->base_type
) {
945 data
.b
[c
] = op
[0]->value
.u
[c
] >= op
[1]->value
.u
[c
];
948 data
.b
[c
] = op
[0]->value
.i
[c
] >= op
[1]->value
.i
[c
];
950 case GLSL_TYPE_FLOAT
:
951 data
.b
[c
] = op
[0]->value
.f
[c
] >= op
[1]->value
.f
[c
];
954 assert(!"Should not get here.");
957 } else if (strcmp(callee
, "inversesqrt") == 0) {
958 expr
= new(mem_ctx
) ir_expression(ir_unop_rsq
, type
, op
[0], NULL
);
959 } else if (strcmp(callee
, "length") == 0) {
960 return new(mem_ctx
) ir_constant(sqrtf(dot(op
[0], op
[0])));
961 } else if (strcmp(callee
, "lessThan") == 0) {
962 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
963 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
964 switch (op
[0]->type
->base_type
) {
966 data
.b
[c
] = op
[0]->value
.u
[c
] < op
[1]->value
.u
[c
];
969 data
.b
[c
] = op
[0]->value
.i
[c
] < op
[1]->value
.i
[c
];
971 case GLSL_TYPE_FLOAT
:
972 data
.b
[c
] = op
[0]->value
.f
[c
] < op
[1]->value
.f
[c
];
975 assert(!"Should not get here.");
978 } else if (strcmp(callee
, "lessThanEqual") == 0) {
979 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
980 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
981 switch (op
[0]->type
->base_type
) {
983 data
.b
[c
] = op
[0]->value
.u
[c
] <= op
[1]->value
.u
[c
];
986 data
.b
[c
] = op
[0]->value
.i
[c
] <= op
[1]->value
.i
[c
];
988 case GLSL_TYPE_FLOAT
:
989 data
.b
[c
] = op
[0]->value
.f
[c
] <= op
[1]->value
.f
[c
];
992 assert(!"Should not get here.");
995 } else if (strcmp(callee
, "log") == 0) {
996 expr
= new(mem_ctx
) ir_expression(ir_unop_log
, type
, op
[0], NULL
);
997 } else if (strcmp(callee
, "log2") == 0) {
998 expr
= new(mem_ctx
) ir_expression(ir_unop_log2
, type
, op
[0], NULL
);
999 } else if (strcmp(callee
, "matrixCompMult") == 0) {
1000 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1001 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1002 data
.f
[c
] = op
[0]->value
.f
[c
] * op
[1]->value
.f
[c
];
1003 } else if (strcmp(callee
, "max") == 0) {
1004 expr
= new(mem_ctx
) ir_expression(ir_binop_max
, type
, op
[0], op
[1]);
1005 } else if (strcmp(callee
, "min") == 0) {
1006 expr
= new(mem_ctx
) ir_expression(ir_binop_min
, type
, op
[0], op
[1]);
1007 } else if (strcmp(callee
, "mix") == 0) {
1008 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1009 if (op
[2]->type
->is_float()) {
1010 unsigned c2_inc
= op
[2]->type
->is_scalar() ? 0 : 1;
1011 unsigned components
= op
[0]->type
->components();
1012 for (unsigned c
= 0, c2
= 0; c
< components
; c2
+= c2_inc
, c
++) {
1013 data
.f
[c
] = op
[0]->value
.f
[c
] * (1 - op
[2]->value
.f
[c2
]) +
1014 op
[1]->value
.f
[c
] * op
[2]->value
.f
[c2
];
1017 assert(op
[2]->type
->is_boolean());
1018 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1019 data
.f
[c
] = op
[op
[2]->value
.b
[c
] ? 1 : 0]->value
.f
[c
];
1021 } else if (strcmp(callee
, "mod") == 0) {
1022 expr
= new(mem_ctx
) ir_expression(ir_binop_mod
, type
, op
[0], op
[1]);
1023 } else if (strcmp(callee
, "normalize") == 0) {
1024 assert(op
[0]->type
->is_float());
1025 float length
= sqrtf(dot(op
[0], op
[0]));
1028 return ir_constant::zero(mem_ctx
, this->type
);
1030 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1031 data
.f
[c
] = op
[0]->value
.f
[c
] / length
;
1032 } else if (strcmp(callee
, "not") == 0) {
1033 expr
= new(mem_ctx
) ir_expression(ir_unop_logic_not
, type
, op
[0], NULL
);
1034 } else if (strcmp(callee
, "notEqual") == 0) {
1035 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1036 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1037 switch (op
[0]->type
->base_type
) {
1038 case GLSL_TYPE_UINT
:
1039 data
.b
[c
] = op
[0]->value
.u
[c
] != op
[1]->value
.u
[c
];
1042 data
.b
[c
] = op
[0]->value
.i
[c
] != op
[1]->value
.i
[c
];
1044 case GLSL_TYPE_FLOAT
:
1045 data
.b
[c
] = op
[0]->value
.f
[c
] != op
[1]->value
.f
[c
];
1048 assert(!"Should not get here.");
1051 } else if (strcmp(callee
, "outerProduct") == 0) {
1052 assert(op
[0]->type
->is_vector() && op
[1]->type
->is_vector());
1053 const unsigned m
= op
[0]->type
->vector_elements
;
1054 const unsigned n
= op
[1]->type
->vector_elements
;
1055 for (unsigned j
= 0; j
< n
; j
++) {
1056 for (unsigned i
= 0; i
< m
; i
++) {
1057 data
.f
[i
+m
*j
] = op
[0]->value
.f
[i
] * op
[1]->value
.f
[j
];
1060 } else if (strcmp(callee
, "pow") == 0) {
1061 expr
= new(mem_ctx
) ir_expression(ir_binop_pow
, type
, op
[0], op
[1]);
1062 } else if (strcmp(callee
, "radians") == 0) {
1063 assert(op
[0]->type
->is_float());
1064 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1065 data
.f
[c
] = M_PI
/180.0 * op
[0]->value
.f
[c
];
1066 } else if (strcmp(callee
, "reflect") == 0) {
1067 assert(op
[0]->type
->is_float());
1068 float dot_NI
= dot(op
[1], op
[0]);
1069 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1070 data
.f
[c
] = op
[0]->value
.f
[c
] - 2 * dot_NI
* op
[1]->value
.f
[c
];
1071 } else if (strcmp(callee
, "refract") == 0) {
1072 const float eta
= op
[2]->value
.f
[0];
1073 const float dot_NI
= dot(op
[1], op
[0]);
1074 const float k
= 1.0 - eta
* eta
* (1.0 - dot_NI
* dot_NI
);
1076 return ir_constant::zero(mem_ctx
, this->type
);
1078 for (unsigned c
= 0; c
< type
->components(); c
++) {
1079 data
.f
[c
] = eta
* op
[0]->value
.f
[c
] - (eta
* dot_NI
+ sqrtf(k
))
1080 * op
[1]->value
.f
[c
];
1083 } else if (strcmp(callee
, "sign") == 0) {
1084 expr
= new(mem_ctx
) ir_expression(ir_unop_sign
, type
, op
[0], NULL
);
1085 } else if (strcmp(callee
, "sin") == 0) {
1086 expr
= new(mem_ctx
) ir_expression(ir_unop_sin
, type
, op
[0], NULL
);
1087 } else if (strcmp(callee
, "sinh") == 0) {
1088 assert(op
[0]->type
->is_float());
1089 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1090 data
.f
[c
] = sinhf(op
[0]->value
.f
[c
]);
1091 } else if (strcmp(callee
, "smoothstep") == 0) {
1092 assert(num_parameters
== 3);
1093 assert(op
[1]->type
== op
[0]->type
);
1094 unsigned edge_inc
= op
[0]->type
->is_scalar() ? 0 : 1;
1095 for (unsigned c
= 0, e
= 0; c
< type
->components(); e
+= edge_inc
, c
++) {
1096 const float edge0
= op
[0]->value
.f
[e
];
1097 const float edge1
= op
[1]->value
.f
[e
];
1098 if (edge0
== edge1
) {
1099 data
.f
[c
] = 0.0; /* Avoid a crash - results are undefined anyway */
1101 const float numerator
= op
[2]->value
.f
[c
] - edge0
;
1102 const float denominator
= edge1
- edge0
;
1103 const float t
= CLAMP(numerator
/denominator
, 0, 1);
1104 data
.f
[c
] = t
* t
* (3 - 2 * t
);
1107 } else if (strcmp(callee
, "sqrt") == 0) {
1108 expr
= new(mem_ctx
) ir_expression(ir_unop_sqrt
, type
, op
[0], NULL
);
1109 } else if (strcmp(callee
, "step") == 0) {
1110 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1111 /* op[0] (edge) may be either a scalar or a vector */
1112 const unsigned c0_inc
= op
[0]->type
->is_scalar() ? 0 : 1;
1113 for (unsigned c
= 0, c0
= 0; c
< type
->components(); c0
+= c0_inc
, c
++)
1114 data
.f
[c
] = (op
[1]->value
.f
[c
] < op
[0]->value
.f
[c0
]) ? 0.0 : 1.0;
1115 } else if (strcmp(callee
, "tan") == 0) {
1116 assert(op
[0]->type
->is_float());
1117 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1118 data
.f
[c
] = tanf(op
[0]->value
.f
[c
]);
1119 } else if (strcmp(callee
, "tanh") == 0) {
1120 assert(op
[0]->type
->is_float());
1121 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1122 data
.f
[c
] = tanhf(op
[0]->value
.f
[c
]);
1123 } else if (strcmp(callee
, "transpose") == 0) {
1124 assert(op
[0]->type
->is_matrix());
1125 const unsigned n
= op
[0]->type
->vector_elements
;
1126 const unsigned m
= op
[0]->type
->matrix_columns
;
1127 for (unsigned j
= 0; j
< m
; j
++) {
1128 for (unsigned i
= 0; i
< n
; i
++) {
1129 data
.f
[m
*i
+j
] += op
[0]->value
.f
[i
+n
*j
];
1133 /* Unsupported builtin - some are not allowed in constant expressions. */
1138 return expr
->constant_expression_value();
1140 return new(mem_ctx
) ir_constant(this->type
, &data
);