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
38 #include "ir_visitor.h"
39 #include "glsl_types.h"
42 * Visitor class for evaluating constant expressions
44 class ir_constant_visitor
: public ir_visitor
{
52 virtual ~ir_constant_visitor()
60 * As typical for the visitor pattern, there must be one \c visit method for
61 * each concrete subclass of \c ir_instruction. Virtual base classes within
62 * the hierarchy should not have \c visit methods.
65 virtual void visit(ir_variable
*);
66 virtual void visit(ir_function_signature
*);
67 virtual void visit(ir_function
*);
68 virtual void visit(ir_expression
*);
69 virtual void visit(ir_texture
*);
70 virtual void visit(ir_swizzle
*);
71 virtual void visit(ir_dereference_variable
*);
72 virtual void visit(ir_dereference_array
*);
73 virtual void visit(ir_dereference_record
*);
74 virtual void visit(ir_assignment
*);
75 virtual void visit(ir_constant
*);
76 virtual void visit(ir_call
*);
77 virtual void visit(ir_return
*);
78 virtual void visit(ir_discard
*);
79 virtual void visit(ir_if
*);
80 virtual void visit(ir_loop
*);
81 virtual void visit(ir_loop_jump
*);
85 * Value of the constant expression.
88 * This field will be \c NULL if the expression is not constant valued.
90 /* FINIHSME: This cannot hold values for constant arrays or structures. */
96 ir_instruction::constant_expression_value()
98 ir_constant_visitor visitor
;
100 this->accept(& visitor
);
101 return visitor
.value
;
106 ir_constant_visitor::visit(ir_variable
*ir
)
114 ir_constant_visitor::visit(ir_function_signature
*ir
)
122 ir_constant_visitor::visit(ir_function
*ir
)
129 ir_constant_visitor::visit(ir_expression
*ir
)
132 ir_constant
*op
[2] = { NULL
, NULL
};
133 ir_constant_data data
;
135 memset(&data
, 0, sizeof(data
));
137 for (unsigned operand
= 0; operand
< ir
->get_num_operands(); operand
++) {
138 op
[operand
] = ir
->operands
[operand
]->constant_expression_value();
144 assert(op
[0]->type
->base_type
== op
[1]->type
->base_type
);
146 bool op0_scalar
= op
[0]->type
->is_scalar();
147 bool op1_scalar
= op
[1] != NULL
&& op
[1]->type
->is_scalar();
149 /* When iterating over a vector or matrix's components, we want to increase
150 * the loop counter. However, for scalars, we want to stay at 0.
152 unsigned c0_inc
= op0_scalar
? 0 : 1;
153 unsigned c1_inc
= op1_scalar
? 0 : 1;
155 if (op1_scalar
|| !op
[1]) {
156 components
= op
[0]->type
->components();
158 components
= op
[1]->type
->components();
161 switch (ir
->operation
) {
162 case ir_unop_logic_not
:
163 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
164 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++)
165 data
.b
[c
] = !op
[0]->value
.b
[c
];
169 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
170 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
171 data
.i
[c
] = op
[0]->value
.f
[c
];
175 assert(op
[0]->type
->base_type
== GLSL_TYPE_UINT
||
176 op
[0]->type
->base_type
== GLSL_TYPE_INT
);
177 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
178 if (op
[0]->type
->base_type
== GLSL_TYPE_INT
)
179 data
.f
[c
] = op
[0]->value
.i
[c
];
181 data
.f
[c
] = op
[0]->value
.u
[c
];
185 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
186 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
187 data
.f
[c
] = op
[0]->value
.b
[c
] ? 1.0 : 0.0;
191 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
192 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
193 data
.b
[c
] = bool(op
[0]->value
.f
[c
]);
197 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
198 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
199 data
.u
[c
] = op
[0]->value
.b
[c
] ? 1 : 0;
203 assert(op
[0]->type
->is_integer());
204 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
205 data
.b
[c
] = bool(op
[0]->value
.u
[c
]);
210 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
211 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
212 data
.f
[c
] = truncf(op
[0]->value
.f
[c
]);
217 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
218 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
219 data
.f
[c
] = ceilf(op
[0]->value
.f
[c
]);
224 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
225 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
226 data
.f
[c
] = floorf(op
[0]->value
.f
[c
]);
231 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
232 switch (ir
->type
->base_type
) {
239 case GLSL_TYPE_FLOAT
:
240 data
.f
[c
] = op
[0]->value
.f
[c
] - floor(op
[0]->value
.f
[c
]);
249 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
250 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
251 data
.f
[c
] = sinf(op
[0]->value
.f
[c
]);
256 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
257 switch (ir
->type
->base_type
) {
259 data
.u
[c
] = -op
[0]->value
.u
[c
];
262 data
.i
[c
] = -op
[0]->value
.i
[c
];
264 case GLSL_TYPE_FLOAT
:
265 data
.f
[c
] = -op
[0]->value
.f
[c
];
274 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
275 switch (ir
->type
->base_type
) {
277 data
.u
[c
] = op
[0]->value
.u
[c
];
280 data
.i
[c
] = op
[0]->value
.i
[c
];
282 data
.i
[c
] = -data
.i
[c
];
284 case GLSL_TYPE_FLOAT
:
285 data
.f
[c
] = fabs(op
[0]->value
.f
[c
]);
294 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
295 switch (ir
->type
->base_type
) {
297 data
.u
[c
] = op
[0]->value
.i
[c
] > 0;
300 data
.i
[c
] = (op
[0]->value
.i
[c
] > 0) - (op
[0]->value
.i
[c
] < 0);
302 case GLSL_TYPE_FLOAT
:
303 data
.f
[c
] = float((op
[0]->value
.f
[c
] > 0)-(op
[0]->value
.f
[c
] < 0));
312 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
313 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
314 switch (ir
->type
->base_type
) {
316 if (op
[0]->value
.u
[c
] != 0.0)
317 data
.u
[c
] = 1 / op
[0]->value
.u
[c
];
320 if (op
[0]->value
.i
[c
] != 0.0)
321 data
.i
[c
] = 1 / op
[0]->value
.i
[c
];
323 case GLSL_TYPE_FLOAT
:
324 if (op
[0]->value
.f
[c
] != 0.0)
325 data
.f
[c
] = 1.0 / op
[0]->value
.f
[c
];
334 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
335 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
336 data
.f
[c
] = 1.0 / sqrtf(op
[0]->value
.f
[c
]);
341 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
342 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
343 data
.f
[c
] = sqrtf(op
[0]->value
.f
[c
]);
348 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
349 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
350 data
.f
[c
] = expf(op
[0]->value
.f
[c
]);
355 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
356 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
357 data
.f
[c
] = exp2f(op
[0]->value
.f
[c
]);
362 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
363 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
364 data
.f
[c
] = logf(op
[0]->value
.f
[c
]);
369 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
370 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
371 data
.f
[c
] = log2f(op
[0]->value
.f
[c
]);
377 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
378 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
384 assert(op
[0]->type
->is_vector() && op
[1]->type
->is_vector());
386 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
387 switch (ir
->operands
[0]->type
->base_type
) {
389 data
.u
[0] += op
[0]->value
.u
[c
] * op
[1]->value
.u
[c
];
392 data
.i
[0] += op
[0]->value
.i
[c
] * op
[1]->value
.i
[c
];
394 case GLSL_TYPE_FLOAT
:
395 data
.f
[0] += op
[0]->value
.f
[c
] * op
[1]->value
.f
[c
];
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 (ir
->operands
[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 (ir
->operands
[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 (ir
->operands
[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 (ir
->operands
[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
];
517 case ir_binop_logic_and
:
518 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
519 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++)
520 data
.b
[c
] = op
[0]->value
.b
[c
] && op
[1]->value
.b
[c
];
522 case ir_binop_logic_xor
:
523 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
524 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++)
525 data
.b
[c
] = op
[0]->value
.b
[c
] ^ op
[1]->value
.b
[c
];
527 case ir_binop_logic_or
:
528 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
529 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++)
530 data
.b
[c
] = op
[0]->value
.b
[c
] || op
[1]->value
.b
[c
];
534 switch (ir
->operands
[0]->type
->base_type
) {
536 data
.b
[0] = op
[0]->value
.u
[0] < op
[1]->value
.u
[0];
539 data
.b
[0] = op
[0]->value
.i
[0] < op
[1]->value
.i
[0];
541 case GLSL_TYPE_FLOAT
:
542 data
.b
[0] = op
[0]->value
.f
[0] < op
[1]->value
.f
[0];
548 case ir_binop_greater
:
549 switch (ir
->operands
[0]->type
->base_type
) {
551 data
.b
[0] = op
[0]->value
.u
[0] > op
[1]->value
.u
[0];
554 data
.b
[0] = op
[0]->value
.i
[0] > op
[1]->value
.i
[0];
556 case GLSL_TYPE_FLOAT
:
557 data
.b
[0] = op
[0]->value
.f
[0] > op
[1]->value
.f
[0];
563 case ir_binop_lequal
:
564 switch (ir
->operands
[0]->type
->base_type
) {
566 data
.b
[0] = op
[0]->value
.u
[0] <= op
[1]->value
.u
[0];
569 data
.b
[0] = op
[0]->value
.i
[0] <= op
[1]->value
.i
[0];
571 case GLSL_TYPE_FLOAT
:
572 data
.b
[0] = op
[0]->value
.f
[0] <= op
[1]->value
.f
[0];
578 case ir_binop_gequal
:
579 switch (ir
->operands
[0]->type
->base_type
) {
581 data
.b
[0] = op
[0]->value
.u
[0] >= op
[1]->value
.u
[0];
584 data
.b
[0] = op
[0]->value
.i
[0] >= op
[1]->value
.i
[0];
586 case GLSL_TYPE_FLOAT
:
587 data
.b
[0] = op
[0]->value
.f
[0] >= op
[1]->value
.f
[0];
596 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
597 switch (ir
->operands
[0]->type
->base_type
) {
599 data
.b
[0] = data
.b
[0] && op
[0]->value
.u
[c
] == op
[1]->value
.u
[c
];
602 data
.b
[0] = data
.b
[0] && op
[0]->value
.i
[c
] == op
[1]->value
.i
[c
];
604 case GLSL_TYPE_FLOAT
:
605 data
.b
[0] = data
.b
[0] && op
[0]->value
.f
[c
] == op
[1]->value
.f
[c
];
608 data
.b
[0] = data
.b
[0] && op
[0]->value
.b
[c
] == op
[1]->value
.b
[c
];
615 case ir_binop_nequal
:
617 for (unsigned c
= 0; c
< ir
->operands
[0]->type
->components(); c
++) {
618 switch (ir
->operands
[0]->type
->base_type
) {
620 data
.b
[0] = data
.b
[0] || op
[0]->value
.u
[c
] != op
[1]->value
.u
[c
];
623 data
.b
[0] = data
.b
[0] || op
[0]->value
.i
[c
] != op
[1]->value
.i
[c
];
625 case GLSL_TYPE_FLOAT
:
626 data
.b
[0] = data
.b
[0] || op
[0]->value
.f
[c
] != op
[1]->value
.f
[c
];
629 data
.b
[0] = data
.b
[0] || op
[0]->value
.b
[c
] != op
[1]->value
.b
[c
];
638 /* FINISHME: Should handle all expression types. */
642 void *ctx
= talloc_parent(ir
);
643 this->value
= new(ctx
) ir_constant(ir
->type
, &data
);
648 ir_constant_visitor::visit(ir_texture
*ir
)
650 // FINISHME: Do stuff with texture lookups
657 ir_constant_visitor::visit(ir_swizzle
*ir
)
659 ir_constant
*v
= ir
->val
->constant_expression_value();
664 ir_constant_data data
;
666 const unsigned swiz_idx
[4] = {
667 ir
->mask
.x
, ir
->mask
.y
, ir
->mask
.z
, ir
->mask
.w
670 for (unsigned i
= 0; i
< ir
->mask
.num_components
; i
++) {
671 switch (v
->type
->base_type
) {
673 case GLSL_TYPE_INT
: data
.u
[i
] = v
->value
.u
[swiz_idx
[i
]]; break;
674 case GLSL_TYPE_FLOAT
: data
.f
[i
] = v
->value
.f
[swiz_idx
[i
]]; break;
675 case GLSL_TYPE_BOOL
: data
.b
[i
] = v
->value
.b
[swiz_idx
[i
]]; break;
676 default: assert(!"Should not get here."); break;
680 void *ctx
= talloc_parent(ir
);
681 this->value
= new(ctx
) ir_constant(ir
->type
, &data
);
687 ir_constant_visitor::visit(ir_dereference_variable
*ir
)
691 ir_variable
*var
= ir
->variable_referenced();
692 if (var
&& var
->constant_value
)
693 value
= var
->constant_value
->clone(NULL
);
698 ir_constant_visitor::visit(ir_dereference_array
*ir
)
700 void *ctx
= talloc_parent(ir
);
701 ir_constant
*array
= ir
->array
->constant_expression_value();
702 ir_constant
*idx
= ir
->array_index
->constant_expression_value();
706 if ((array
!= NULL
) && (idx
!= NULL
)) {
707 if (array
->type
->is_matrix()) {
708 /* Array access of a matrix results in a vector.
710 const unsigned column
= idx
->value
.u
[0];
712 const glsl_type
*const column_type
= array
->type
->column_type();
714 /* Offset in the constant matrix to the first element of the column
717 const unsigned mat_idx
= column
* column_type
->vector_elements
;
719 ir_constant_data data
;
721 switch (column_type
->base_type
) {
724 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
725 data
.u
[i
] = array
->value
.u
[mat_idx
+ i
];
729 case GLSL_TYPE_FLOAT
:
730 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
731 data
.f
[i
] = array
->value
.f
[mat_idx
+ i
];
736 assert(!"Should not get here.");
740 this->value
= new(ctx
) ir_constant(column_type
, &data
);
741 } else if (array
->type
->is_vector()) {
742 const unsigned component
= idx
->value
.u
[0];
744 this->value
= new(ctx
) ir_constant(array
, component
);
746 /* FINISHME: Handle access of constant arrays. */
753 ir_constant_visitor::visit(ir_dereference_record
*ir
)
755 ir_constant
*v
= ir
->record
->constant_expression_value();
757 this->value
= (v
!= NULL
) ? v
->get_record_field(ir
->field
) : NULL
;
762 ir_constant_visitor::visit(ir_assignment
*ir
)
770 ir_constant_visitor::visit(ir_constant
*ir
)
777 ir_constant_visitor::visit(ir_call
*ir
)
785 ir_constant_visitor::visit(ir_return
*ir
)
793 ir_constant_visitor::visit(ir_discard
*ir
)
801 ir_constant_visitor::visit(ir_if
*ir
)
809 ir_constant_visitor::visit(ir_loop
*ir
)
817 ir_constant_visitor::visit(ir_loop_jump
*ir
)