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 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
) {
92 case ir_binop_all_equal
:
93 return new(ctx
) ir_constant(op
[0]->has_value(op
[1]));
94 case ir_binop_any_nequal
:
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
->is_boolean());
155 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
156 if (op
[0]->value
.b
[c
])
162 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
163 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
164 data
.f
[c
] = truncf(op
[0]->value
.f
[c
]);
169 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
170 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
171 data
.f
[c
] = ceilf(op
[0]->value
.f
[c
]);
176 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
177 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
178 data
.f
[c
] = floorf(op
[0]->value
.f
[c
]);
183 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
184 switch (this->type
->base_type
) {
191 case GLSL_TYPE_FLOAT
:
192 data
.f
[c
] = op
[0]->value
.f
[c
] - floor(op
[0]->value
.f
[c
]);
201 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
202 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
203 data
.f
[c
] = sinf(op
[0]->value
.f
[c
]);
208 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
209 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
210 data
.f
[c
] = cosf(op
[0]->value
.f
[c
]);
215 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
216 switch (this->type
->base_type
) {
218 data
.u
[c
] = -op
[0]->value
.u
[c
];
221 data
.i
[c
] = -op
[0]->value
.i
[c
];
223 case GLSL_TYPE_FLOAT
:
224 data
.f
[c
] = -op
[0]->value
.f
[c
];
233 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
234 switch (this->type
->base_type
) {
236 data
.u
[c
] = op
[0]->value
.u
[c
];
239 data
.i
[c
] = op
[0]->value
.i
[c
];
241 data
.i
[c
] = -data
.i
[c
];
243 case GLSL_TYPE_FLOAT
:
244 data
.f
[c
] = fabs(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
.i
[c
] > 0;
259 data
.i
[c
] = (op
[0]->value
.i
[c
] > 0) - (op
[0]->value
.i
[c
] < 0);
261 case GLSL_TYPE_FLOAT
:
262 data
.f
[c
] = float((op
[0]->value
.f
[c
] > 0)-(op
[0]->value
.f
[c
] < 0));
271 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
272 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
273 switch (this->type
->base_type
) {
275 if (op
[0]->value
.u
[c
] != 0.0)
276 data
.u
[c
] = 1 / op
[0]->value
.u
[c
];
279 if (op
[0]->value
.i
[c
] != 0.0)
280 data
.i
[c
] = 1 / op
[0]->value
.i
[c
];
282 case GLSL_TYPE_FLOAT
:
283 if (op
[0]->value
.f
[c
] != 0.0)
284 data
.f
[c
] = 1.0 / 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
] = 1.0 / sqrtf(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
] = sqrtf(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
] = expf(op
[0]->value
.f
[c
]);
314 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
315 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
316 data
.f
[c
] = exp2f(op
[0]->value
.f
[c
]);
321 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
322 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
323 data
.f
[c
] = logf(op
[0]->value
.f
[c
]);
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
] = log2f(op
[0]->value
.f
[c
]);
336 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
337 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
343 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
344 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
345 data
.f
[c
] = powf(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
350 data
.f
[0] = dot(op
[0], op
[1]);
354 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
355 for (unsigned c
= 0, c0
= 0, c1
= 0;
357 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
359 switch (op
[0]->type
->base_type
) {
361 data
.u
[c
] = MIN2(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
364 data
.i
[c
] = MIN2(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
366 case GLSL_TYPE_FLOAT
:
367 data
.f
[c
] = MIN2(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
376 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
377 for (unsigned c
= 0, c0
= 0, c1
= 0;
379 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
381 switch (op
[0]->type
->base_type
) {
383 data
.u
[c
] = MAX2(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
386 data
.i
[c
] = MAX2(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
388 case GLSL_TYPE_FLOAT
:
389 data
.f
[c
] = MAX2(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
398 assert(op
[0]->type
== glsl_type::vec3_type
);
399 assert(op
[1]->type
== glsl_type::vec3_type
);
400 data
.f
[0] = (op
[0]->value
.f
[1] * op
[1]->value
.f
[2] -
401 op
[1]->value
.f
[1] * op
[0]->value
.f
[2]);
402 data
.f
[1] = (op
[0]->value
.f
[2] * op
[1]->value
.f
[0] -
403 op
[1]->value
.f
[2] * op
[0]->value
.f
[0]);
404 data
.f
[2] = (op
[0]->value
.f
[0] * op
[1]->value
.f
[1] -
405 op
[1]->value
.f
[0] * op
[0]->value
.f
[1]);
409 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
410 for (unsigned c
= 0, c0
= 0, c1
= 0;
412 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
414 switch (op
[0]->type
->base_type
) {
416 data
.u
[c
] = op
[0]->value
.u
[c0
] + op
[1]->value
.u
[c1
];
419 data
.i
[c
] = op
[0]->value
.i
[c0
] + op
[1]->value
.i
[c1
];
421 case GLSL_TYPE_FLOAT
:
422 data
.f
[c
] = op
[0]->value
.f
[c0
] + op
[1]->value
.f
[c1
];
431 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
432 for (unsigned c
= 0, c0
= 0, c1
= 0;
434 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
436 switch (op
[0]->type
->base_type
) {
438 data
.u
[c
] = op
[0]->value
.u
[c0
] - op
[1]->value
.u
[c1
];
441 data
.i
[c
] = op
[0]->value
.i
[c0
] - op
[1]->value
.i
[c1
];
443 case GLSL_TYPE_FLOAT
:
444 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
];
453 /* Check for equal types, or unequal types involving scalars */
454 if ((op
[0]->type
== op
[1]->type
&& !op
[0]->type
->is_matrix())
455 || op0_scalar
|| op1_scalar
) {
456 for (unsigned c
= 0, c0
= 0, c1
= 0;
458 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
460 switch (op
[0]->type
->base_type
) {
462 data
.u
[c
] = op
[0]->value
.u
[c0
] * op
[1]->value
.u
[c1
];
465 data
.i
[c
] = op
[0]->value
.i
[c0
] * op
[1]->value
.i
[c1
];
467 case GLSL_TYPE_FLOAT
:
468 data
.f
[c
] = op
[0]->value
.f
[c0
] * op
[1]->value
.f
[c1
];
475 assert(op
[0]->type
->is_matrix() || op
[1]->type
->is_matrix());
477 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
478 * matrix can be a GLSL vector, either N or P can be 1.
480 * For vec*mat, the vector is treated as a row vector. This
481 * means the vector is a 1-row x M-column matrix.
483 * For mat*vec, the vector is treated as a column vector. Since
484 * matrix_columns is 1 for vectors, this just works.
486 const unsigned n
= op
[0]->type
->is_vector()
487 ? 1 : op
[0]->type
->vector_elements
;
488 const unsigned m
= op
[1]->type
->vector_elements
;
489 const unsigned p
= op
[1]->type
->matrix_columns
;
490 for (unsigned j
= 0; j
< p
; j
++) {
491 for (unsigned i
= 0; i
< n
; i
++) {
492 for (unsigned k
= 0; k
< m
; k
++) {
493 data
.f
[i
+n
*j
] += op
[0]->value
.f
[i
+n
*k
]*op
[1]->value
.f
[k
+m
*j
];
501 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
502 for (unsigned c
= 0, c0
= 0, c1
= 0;
504 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
506 switch (op
[0]->type
->base_type
) {
508 data
.u
[c
] = op
[0]->value
.u
[c0
] / op
[1]->value
.u
[c1
];
511 data
.i
[c
] = op
[0]->value
.i
[c0
] / op
[1]->value
.i
[c1
];
513 case GLSL_TYPE_FLOAT
:
514 data
.f
[c
] = op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
];
523 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
524 for (unsigned c
= 0, c0
= 0, c1
= 0;
526 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
528 switch (op
[0]->type
->base_type
) {
530 data
.u
[c
] = op
[0]->value
.u
[c0
] % op
[1]->value
.u
[c1
];
533 data
.i
[c
] = op
[0]->value
.i
[c0
] % op
[1]->value
.i
[c1
];
535 case GLSL_TYPE_FLOAT
:
536 /* We don't use fmod because it rounds toward zero; GLSL specifies
539 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
]
540 * floorf(op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
]);
549 case ir_binop_logic_and
:
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_xor
:
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
];
559 case ir_binop_logic_or
:
560 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
561 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
562 data
.b
[c
] = op
[0]->value
.b
[c
] || op
[1]->value
.b
[c
];
566 switch (op
[0]->type
->base_type
) {
568 data
.b
[0] = op
[0]->value
.u
[0] < op
[1]->value
.u
[0];
571 data
.b
[0] = op
[0]->value
.i
[0] < op
[1]->value
.i
[0];
573 case GLSL_TYPE_FLOAT
:
574 data
.b
[0] = op
[0]->value
.f
[0] < op
[1]->value
.f
[0];
580 case ir_binop_greater
:
581 switch (op
[0]->type
->base_type
) {
583 data
.b
[0] = op
[0]->value
.u
[0] > op
[1]->value
.u
[0];
586 data
.b
[0] = op
[0]->value
.i
[0] > op
[1]->value
.i
[0];
588 case GLSL_TYPE_FLOAT
:
589 data
.b
[0] = op
[0]->value
.f
[0] > op
[1]->value
.f
[0];
595 case ir_binop_lequal
:
596 switch (op
[0]->type
->base_type
) {
598 data
.b
[0] = op
[0]->value
.u
[0] <= op
[1]->value
.u
[0];
601 data
.b
[0] = op
[0]->value
.i
[0] <= op
[1]->value
.i
[0];
603 case GLSL_TYPE_FLOAT
:
604 data
.b
[0] = op
[0]->value
.f
[0] <= op
[1]->value
.f
[0];
610 case ir_binop_gequal
:
611 switch (op
[0]->type
->base_type
) {
613 data
.b
[0] = op
[0]->value
.u
[0] >= op
[1]->value
.u
[0];
616 data
.b
[0] = op
[0]->value
.i
[0] >= op
[1]->value
.i
[0];
618 case GLSL_TYPE_FLOAT
:
619 data
.b
[0] = op
[0]->value
.f
[0] >= op
[1]->value
.f
[0];
626 assert(op
[0]->type
== op
[1]->type
);
627 for (unsigned c
= 0; c
< components
; c
++) {
628 switch (op
[0]->type
->base_type
) {
630 data
.b
[c
] = op
[0]->value
.u
[c
] == op
[1]->value
.u
[c
];
633 data
.b
[c
] = op
[0]->value
.i
[c
] == op
[1]->value
.i
[c
];
635 case GLSL_TYPE_FLOAT
:
636 data
.b
[c
] = op
[0]->value
.f
[c
] == op
[1]->value
.f
[c
];
643 case ir_binop_nequal
:
644 assert(op
[0]->type
!= op
[1]->type
);
645 for (unsigned c
= 0; c
< components
; c
++) {
646 switch (op
[0]->type
->base_type
) {
648 data
.b
[c
] = op
[0]->value
.u
[c
] != op
[1]->value
.u
[c
];
651 data
.b
[c
] = op
[0]->value
.i
[c
] != op
[1]->value
.i
[c
];
653 case GLSL_TYPE_FLOAT
:
654 data
.b
[c
] = op
[0]->value
.f
[c
] != op
[1]->value
.f
[c
];
661 case ir_binop_all_equal
:
662 data
.b
[0] = op
[0]->has_value(op
[1]);
664 case ir_binop_any_nequal
:
665 data
.b
[0] = !op
[0]->has_value(op
[1]);
669 /* FINISHME: Should handle all expression types. */
673 return new(ctx
) ir_constant(this->type
, &data
);
678 ir_texture::constant_expression_value()
680 /* texture lookups aren't constant expressions */
686 ir_swizzle::constant_expression_value()
688 ir_constant
*v
= this->val
->constant_expression_value();
691 ir_constant_data data
= { { 0 } };
693 const unsigned swiz_idx
[4] = {
694 this->mask
.x
, this->mask
.y
, this->mask
.z
, this->mask
.w
697 for (unsigned i
= 0; i
< this->mask
.num_components
; i
++) {
698 switch (v
->type
->base_type
) {
700 case GLSL_TYPE_INT
: data
.u
[i
] = v
->value
.u
[swiz_idx
[i
]]; break;
701 case GLSL_TYPE_FLOAT
: data
.f
[i
] = v
->value
.f
[swiz_idx
[i
]]; break;
702 case GLSL_TYPE_BOOL
: data
.b
[i
] = v
->value
.b
[swiz_idx
[i
]]; break;
703 default: assert(!"Should not get here."); break;
707 void *ctx
= talloc_parent(this);
708 return new(ctx
) ir_constant(this->type
, &data
);
715 ir_dereference_variable::constant_expression_value()
717 /* This may occur during compile and var->type is glsl_type::error_type */
721 /* The constant_value of a uniform variable is its initializer,
722 * not the lifetime constant value of the uniform.
724 if (var
->mode
== ir_var_uniform
)
727 if (!var
->constant_value
)
730 return var
->constant_value
->clone(talloc_parent(var
), NULL
);
735 ir_dereference_array::constant_expression_value()
737 ir_constant
*array
= this->array
->constant_expression_value();
738 ir_constant
*idx
= this->array_index
->constant_expression_value();
740 if ((array
!= NULL
) && (idx
!= NULL
)) {
741 void *ctx
= talloc_parent(this);
742 if (array
->type
->is_matrix()) {
743 /* Array access of a matrix results in a vector.
745 const unsigned column
= idx
->value
.u
[0];
747 const glsl_type
*const column_type
= array
->type
->column_type();
749 /* Offset in the constant matrix to the first element of the column
752 const unsigned mat_idx
= column
* column_type
->vector_elements
;
754 ir_constant_data data
;
756 switch (column_type
->base_type
) {
759 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
760 data
.u
[i
] = array
->value
.u
[mat_idx
+ i
];
764 case GLSL_TYPE_FLOAT
:
765 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
766 data
.f
[i
] = array
->value
.f
[mat_idx
+ i
];
771 assert(!"Should not get here.");
775 return new(ctx
) ir_constant(column_type
, &data
);
776 } else if (array
->type
->is_vector()) {
777 const unsigned component
= idx
->value
.u
[0];
779 return new(ctx
) ir_constant(array
, component
);
781 const unsigned index
= idx
->value
.u
[0];
782 return array
->get_array_element(index
)->clone(ctx
, NULL
);
790 ir_dereference_record::constant_expression_value()
792 ir_constant
*v
= this->record
->constant_expression_value();
794 return (v
!= NULL
) ? v
->get_record_field(this->field
) : NULL
;
799 ir_assignment::constant_expression_value()
801 /* FINISHME: Handle CEs involving assignment (return RHS) */
807 ir_constant::constant_expression_value()
814 ir_call::constant_expression_value()
816 if (this->type
== glsl_type::error_type
)
819 /* From the GLSL 1.20 spec, page 23:
820 * "Function calls to user-defined functions (non-built-in functions)
821 * cannot be used to form constant expressions."
823 if (!this->callee
->is_builtin
)
826 unsigned num_parameters
= 0;
828 /* Check if all parameters are constant */
830 foreach_list(n
, &this->actual_parameters
) {
831 ir_constant
*constant
= ((ir_rvalue
*) n
)->constant_expression_value();
832 if (constant
== NULL
)
835 op
[num_parameters
] = constant
;
837 assert(num_parameters
< 3);
841 /* Individual cases below can either:
842 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
843 * - Fill "data" with appopriate constant data
844 * - Return an ir_constant directly.
846 void *mem_ctx
= talloc_parent(this);
847 ir_expression
*expr
= NULL
;
849 ir_constant_data data
;
850 memset(&data
, 0, sizeof(data
));
852 const char *callee
= this->callee_name();
853 if (strcmp(callee
, "abs") == 0) {
854 expr
= new(mem_ctx
) ir_expression(ir_unop_abs
, type
, op
[0], NULL
);
855 } else if (strcmp(callee
, "all") == 0) {
856 assert(op
[0]->type
->is_boolean());
857 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
858 if (!op
[0]->value
.b
[c
])
859 return new(mem_ctx
) ir_constant(false);
861 return new(mem_ctx
) ir_constant(true);
862 } else if (strcmp(callee
, "any") == 0) {
863 assert(op
[0]->type
->is_boolean());
864 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
865 if (op
[0]->value
.b
[c
])
866 return new(mem_ctx
) ir_constant(true);
868 return new(mem_ctx
) ir_constant(false);
869 } else if (strcmp(callee
, "acos") == 0) {
870 assert(op
[0]->type
->is_float());
871 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
872 data
.f
[c
] = acosf(op
[0]->value
.f
[c
]);
873 } else if (strcmp(callee
, "asin") == 0) {
874 assert(op
[0]->type
->is_float());
875 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
876 data
.f
[c
] = asinf(op
[0]->value
.f
[c
]);
877 } else if (strcmp(callee
, "atan") == 0) {
878 assert(op
[0]->type
->is_float());
879 if (num_parameters
== 2) {
880 assert(op
[1]->type
->is_float());
881 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
882 data
.f
[c
] = atan2f(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
884 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
885 data
.f
[c
] = atanf(op
[0]->value
.f
[c
]);
887 } else if (strcmp(callee
, "dFdx") == 0 || strcmp(callee
, "dFdy") == 0) {
888 return ir_constant::zero(mem_ctx
, this->type
);
889 } else if (strcmp(callee
, "ceil") == 0) {
890 expr
= new(mem_ctx
) ir_expression(ir_unop_ceil
, type
, op
[0], NULL
);
891 } else if (strcmp(callee
, "clamp") == 0) {
892 assert(num_parameters
== 3);
893 unsigned c1_inc
= op
[1]->type
->is_scalar() ? 0 : 1;
894 unsigned c2_inc
= op
[2]->type
->is_scalar() ? 0 : 1;
895 for (unsigned c
= 0, c1
= 0, c2
= 0;
896 c
< op
[0]->type
->components();
897 c1
+= c1_inc
, c2
+= c2_inc
, c
++) {
899 switch (op
[0]->type
->base_type
) {
901 data
.u
[c
] = CLAMP(op
[0]->value
.u
[c
], op
[1]->value
.u
[c1
],
905 data
.i
[c
] = CLAMP(op
[0]->value
.i
[c
], op
[1]->value
.i
[c1
],
908 case GLSL_TYPE_FLOAT
:
909 data
.f
[c
] = CLAMP(op
[0]->value
.f
[c
], op
[1]->value
.f
[c1
],
913 assert(!"Should not get here.");
916 } else if (strcmp(callee
, "cos") == 0) {
917 expr
= new(mem_ctx
) ir_expression(ir_unop_cos
, type
, op
[0], NULL
);
918 } else if (strcmp(callee
, "cosh") == 0) {
919 assert(op
[0]->type
->is_float());
920 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
921 data
.f
[c
] = coshf(op
[0]->value
.f
[c
]);
922 } else if (strcmp(callee
, "cross") == 0) {
923 expr
= new(mem_ctx
) ir_expression(ir_binop_cross
, type
, op
[0], op
[1]);
924 } else if (strcmp(callee
, "degrees") == 0) {
925 assert(op
[0]->type
->is_float());
926 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
927 data
.f
[c
] = 180.0/M_PI
* op
[0]->value
.f
[c
];
928 } else if (strcmp(callee
, "distance") == 0) {
929 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
930 float length_squared
= 0.0;
931 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
932 float t
= op
[0]->value
.f
[c
] - op
[1]->value
.f
[c
];
933 length_squared
+= t
* t
;
935 return new(mem_ctx
) ir_constant(sqrtf(length_squared
));
936 } else if (strcmp(callee
, "dot") == 0) {
937 return new(mem_ctx
) ir_constant(dot(op
[0], op
[1]));
938 } else if (strcmp(callee
, "equal") == 0) {
939 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
940 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
941 switch (op
[0]->type
->base_type
) {
943 data
.b
[c
] = op
[0]->value
.u
[c
] == op
[1]->value
.u
[c
];
946 data
.b
[c
] = op
[0]->value
.i
[c
] == op
[1]->value
.i
[c
];
948 case GLSL_TYPE_FLOAT
:
949 data
.b
[c
] = op
[0]->value
.f
[c
] == op
[1]->value
.f
[c
];
952 data
.b
[c
] = op
[0]->value
.b
[c
] == op
[1]->value
.b
[c
];
955 assert(!"Should not get here.");
958 } else if (strcmp(callee
, "exp") == 0) {
959 expr
= new(mem_ctx
) ir_expression(ir_unop_exp
, type
, op
[0], NULL
);
960 } else if (strcmp(callee
, "exp2") == 0) {
961 expr
= new(mem_ctx
) ir_expression(ir_unop_exp2
, type
, op
[0], NULL
);
962 } else if (strcmp(callee
, "faceforward") == 0) {
963 if (dot(op
[2], op
[1]) < 0)
965 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
966 data
.f
[c
] = -op
[0]->value
.f
[c
];
967 } else if (strcmp(callee
, "floor") == 0) {
968 expr
= new(mem_ctx
) ir_expression(ir_unop_floor
, type
, op
[0], NULL
);
969 } else if (strcmp(callee
, "fract") == 0) {
970 expr
= new(mem_ctx
) ir_expression(ir_unop_fract
, type
, op
[0], NULL
);
971 } else if (strcmp(callee
, "fwidth") == 0) {
972 return ir_constant::zero(mem_ctx
, this->type
);
973 } else if (strcmp(callee
, "greaterThan") == 0) {
974 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
975 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
976 switch (op
[0]->type
->base_type
) {
978 data
.b
[c
] = op
[0]->value
.u
[c
] > op
[1]->value
.u
[c
];
981 data
.b
[c
] = op
[0]->value
.i
[c
] > op
[1]->value
.i
[c
];
983 case GLSL_TYPE_FLOAT
:
984 data
.b
[c
] = op
[0]->value
.f
[c
] > op
[1]->value
.f
[c
];
987 assert(!"Should not get here.");
990 } else if (strcmp(callee
, "greaterThanEqual") == 0) {
991 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
992 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
993 switch (op
[0]->type
->base_type
) {
995 data
.b
[c
] = op
[0]->value
.u
[c
] >= op
[1]->value
.u
[c
];
998 data
.b
[c
] = op
[0]->value
.i
[c
] >= op
[1]->value
.i
[c
];
1000 case GLSL_TYPE_FLOAT
:
1001 data
.b
[c
] = op
[0]->value
.f
[c
] >= op
[1]->value
.f
[c
];
1004 assert(!"Should not get here.");
1007 } else if (strcmp(callee
, "inversesqrt") == 0) {
1008 expr
= new(mem_ctx
) ir_expression(ir_unop_rsq
, type
, op
[0], NULL
);
1009 } else if (strcmp(callee
, "length") == 0) {
1010 return new(mem_ctx
) ir_constant(sqrtf(dot(op
[0], op
[0])));
1011 } else if (strcmp(callee
, "lessThan") == 0) {
1012 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1013 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1014 switch (op
[0]->type
->base_type
) {
1015 case GLSL_TYPE_UINT
:
1016 data
.b
[c
] = op
[0]->value
.u
[c
] < op
[1]->value
.u
[c
];
1019 data
.b
[c
] = op
[0]->value
.i
[c
] < op
[1]->value
.i
[c
];
1021 case GLSL_TYPE_FLOAT
:
1022 data
.b
[c
] = op
[0]->value
.f
[c
] < op
[1]->value
.f
[c
];
1025 assert(!"Should not get here.");
1028 } else if (strcmp(callee
, "lessThanEqual") == 0) {
1029 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1030 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1031 switch (op
[0]->type
->base_type
) {
1032 case GLSL_TYPE_UINT
:
1033 data
.b
[c
] = op
[0]->value
.u
[c
] <= op
[1]->value
.u
[c
];
1036 data
.b
[c
] = op
[0]->value
.i
[c
] <= op
[1]->value
.i
[c
];
1038 case GLSL_TYPE_FLOAT
:
1039 data
.b
[c
] = op
[0]->value
.f
[c
] <= op
[1]->value
.f
[c
];
1042 assert(!"Should not get here.");
1045 } else if (strcmp(callee
, "log") == 0) {
1046 expr
= new(mem_ctx
) ir_expression(ir_unop_log
, type
, op
[0], NULL
);
1047 } else if (strcmp(callee
, "log2") == 0) {
1048 expr
= new(mem_ctx
) ir_expression(ir_unop_log2
, type
, op
[0], NULL
);
1049 } else if (strcmp(callee
, "matrixCompMult") == 0) {
1050 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1051 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1052 data
.f
[c
] = op
[0]->value
.f
[c
] * op
[1]->value
.f
[c
];
1053 } else if (strcmp(callee
, "max") == 0) {
1054 expr
= new(mem_ctx
) ir_expression(ir_binop_max
, type
, op
[0], op
[1]);
1055 } else if (strcmp(callee
, "min") == 0) {
1056 expr
= new(mem_ctx
) ir_expression(ir_binop_min
, type
, op
[0], op
[1]);
1057 } else if (strcmp(callee
, "mix") == 0) {
1058 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1059 if (op
[2]->type
->is_float()) {
1060 unsigned c2_inc
= op
[2]->type
->is_scalar() ? 0 : 1;
1061 unsigned components
= op
[0]->type
->components();
1062 for (unsigned c
= 0, c2
= 0; c
< components
; c2
+= c2_inc
, c
++) {
1063 data
.f
[c
] = op
[0]->value
.f
[c
] * (1 - op
[2]->value
.f
[c2
]) +
1064 op
[1]->value
.f
[c
] * op
[2]->value
.f
[c2
];
1067 assert(op
[2]->type
->is_boolean());
1068 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1069 data
.f
[c
] = op
[op
[2]->value
.b
[c
] ? 1 : 0]->value
.f
[c
];
1071 } else if (strcmp(callee
, "mod") == 0) {
1072 expr
= new(mem_ctx
) ir_expression(ir_binop_mod
, type
, op
[0], op
[1]);
1073 } else if (strcmp(callee
, "normalize") == 0) {
1074 assert(op
[0]->type
->is_float());
1075 float length
= sqrtf(dot(op
[0], op
[0]));
1078 return ir_constant::zero(mem_ctx
, this->type
);
1080 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1081 data
.f
[c
] = op
[0]->value
.f
[c
] / length
;
1082 } else if (strcmp(callee
, "not") == 0) {
1083 expr
= new(mem_ctx
) ir_expression(ir_unop_logic_not
, type
, op
[0], NULL
);
1084 } else if (strcmp(callee
, "notEqual") == 0) {
1085 assert(op
[0]->type
->is_vector() && op
[1] && op
[1]->type
->is_vector());
1086 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
1087 switch (op
[0]->type
->base_type
) {
1088 case GLSL_TYPE_UINT
:
1089 data
.b
[c
] = op
[0]->value
.u
[c
] != op
[1]->value
.u
[c
];
1092 data
.b
[c
] = op
[0]->value
.i
[c
] != op
[1]->value
.i
[c
];
1094 case GLSL_TYPE_FLOAT
:
1095 data
.b
[c
] = op
[0]->value
.f
[c
] != op
[1]->value
.f
[c
];
1097 case GLSL_TYPE_BOOL
:
1098 data
.b
[c
] = op
[0]->value
.b
[c
] != op
[1]->value
.b
[c
];
1101 assert(!"Should not get here.");
1104 } else if (strcmp(callee
, "outerProduct") == 0) {
1105 assert(op
[0]->type
->is_vector() && op
[1]->type
->is_vector());
1106 const unsigned m
= op
[0]->type
->vector_elements
;
1107 const unsigned n
= op
[1]->type
->vector_elements
;
1108 for (unsigned j
= 0; j
< n
; j
++) {
1109 for (unsigned i
= 0; i
< m
; i
++) {
1110 data
.f
[i
+m
*j
] = op
[0]->value
.f
[i
] * op
[1]->value
.f
[j
];
1113 } else if (strcmp(callee
, "pow") == 0) {
1114 expr
= new(mem_ctx
) ir_expression(ir_binop_pow
, type
, op
[0], op
[1]);
1115 } else if (strcmp(callee
, "radians") == 0) {
1116 assert(op
[0]->type
->is_float());
1117 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1118 data
.f
[c
] = M_PI
/180.0 * op
[0]->value
.f
[c
];
1119 } else if (strcmp(callee
, "reflect") == 0) {
1120 assert(op
[0]->type
->is_float());
1121 float dot_NI
= dot(op
[1], op
[0]);
1122 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1123 data
.f
[c
] = op
[0]->value
.f
[c
] - 2 * dot_NI
* op
[1]->value
.f
[c
];
1124 } else if (strcmp(callee
, "refract") == 0) {
1125 const float eta
= op
[2]->value
.f
[0];
1126 const float dot_NI
= dot(op
[1], op
[0]);
1127 const float k
= 1.0 - eta
* eta
* (1.0 - dot_NI
* dot_NI
);
1129 return ir_constant::zero(mem_ctx
, this->type
);
1131 for (unsigned c
= 0; c
< type
->components(); c
++) {
1132 data
.f
[c
] = eta
* op
[0]->value
.f
[c
] - (eta
* dot_NI
+ sqrtf(k
))
1133 * op
[1]->value
.f
[c
];
1136 } else if (strcmp(callee
, "sign") == 0) {
1137 expr
= new(mem_ctx
) ir_expression(ir_unop_sign
, type
, op
[0], NULL
);
1138 } else if (strcmp(callee
, "sin") == 0) {
1139 expr
= new(mem_ctx
) ir_expression(ir_unop_sin
, type
, op
[0], NULL
);
1140 } else if (strcmp(callee
, "sinh") == 0) {
1141 assert(op
[0]->type
->is_float());
1142 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1143 data
.f
[c
] = sinhf(op
[0]->value
.f
[c
]);
1144 } else if (strcmp(callee
, "smoothstep") == 0) {
1145 assert(num_parameters
== 3);
1146 assert(op
[1]->type
== op
[0]->type
);
1147 unsigned edge_inc
= op
[0]->type
->is_scalar() ? 0 : 1;
1148 for (unsigned c
= 0, e
= 0; c
< type
->components(); e
+= edge_inc
, c
++) {
1149 const float edge0
= op
[0]->value
.f
[e
];
1150 const float edge1
= op
[1]->value
.f
[e
];
1151 if (edge0
== edge1
) {
1152 data
.f
[c
] = 0.0; /* Avoid a crash - results are undefined anyway */
1154 const float numerator
= op
[2]->value
.f
[c
] - edge0
;
1155 const float denominator
= edge1
- edge0
;
1156 const float t
= CLAMP(numerator
/denominator
, 0, 1);
1157 data
.f
[c
] = t
* t
* (3 - 2 * t
);
1160 } else if (strcmp(callee
, "sqrt") == 0) {
1161 expr
= new(mem_ctx
) ir_expression(ir_unop_sqrt
, type
, op
[0], NULL
);
1162 } else if (strcmp(callee
, "step") == 0) {
1163 assert(op
[0]->type
->is_float() && op
[1]->type
->is_float());
1164 /* op[0] (edge) may be either a scalar or a vector */
1165 const unsigned c0_inc
= op
[0]->type
->is_scalar() ? 0 : 1;
1166 for (unsigned c
= 0, c0
= 0; c
< type
->components(); c0
+= c0_inc
, c
++)
1167 data
.f
[c
] = (op
[1]->value
.f
[c
] < op
[0]->value
.f
[c0
]) ? 0.0 : 1.0;
1168 } else if (strcmp(callee
, "tan") == 0) {
1169 assert(op
[0]->type
->is_float());
1170 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1171 data
.f
[c
] = tanf(op
[0]->value
.f
[c
]);
1172 } else if (strcmp(callee
, "tanh") == 0) {
1173 assert(op
[0]->type
->is_float());
1174 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
1175 data
.f
[c
] = tanhf(op
[0]->value
.f
[c
]);
1176 } else if (strcmp(callee
, "transpose") == 0) {
1177 assert(op
[0]->type
->is_matrix());
1178 const unsigned n
= op
[0]->type
->vector_elements
;
1179 const unsigned m
= op
[0]->type
->matrix_columns
;
1180 for (unsigned j
= 0; j
< m
; j
++) {
1181 for (unsigned i
= 0; i
< n
; i
++) {
1182 data
.f
[m
*i
+j
] += op
[0]->value
.f
[i
+n
*j
];
1186 /* Unsupported builtin - some are not allowed in constant expressions. */
1191 return expr
->constant_expression_value();
1193 return new(mem_ctx
) ir_constant(this->type
, &data
);