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"
41 #define min(x,y) (x) < (y) ? (x) : (y)
42 #define max(x,y) (x) > (y) ? (x) : (y)
45 ir_expression::constant_expression_value()
47 ir_constant
*op
[2] = { NULL
, NULL
};
48 ir_constant_data data
;
50 memset(&data
, 0, sizeof(data
));
52 for (unsigned operand
= 0; operand
< this->get_num_operands(); operand
++) {
53 op
[operand
] = this->operands
[operand
]->constant_expression_value();
59 assert(op
[0]->type
->base_type
== op
[1]->type
->base_type
);
61 bool op0_scalar
= op
[0]->type
->is_scalar();
62 bool op1_scalar
= op
[1] != NULL
&& op
[1]->type
->is_scalar();
64 /* When iterating over a vector or matrix's components, we want to increase
65 * the loop counter. However, for scalars, we want to stay at 0.
67 unsigned c0_inc
= op0_scalar
? 0 : 1;
68 unsigned c1_inc
= op1_scalar
? 0 : 1;
70 if (op1_scalar
|| !op
[1]) {
71 components
= op
[0]->type
->components();
73 components
= op
[1]->type
->components();
76 void *ctx
= talloc_parent(this);
78 /* Handle array operations here, rather than below. */
79 if (op
[0]->type
->is_array()) {
80 assert(op
[1] != NULL
&& op
[1]->type
->is_array());
81 switch (this->operation
) {
83 return new(ctx
) ir_constant(op
[0]->has_value(op
[1]));
85 return new(ctx
) ir_constant(!op
[0]->has_value(op
[1]));
92 switch (this->operation
) {
93 case ir_unop_logic_not
:
94 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
95 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
96 data
.b
[c
] = !op
[0]->value
.b
[c
];
100 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
101 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
102 data
.i
[c
] = op
[0]->value
.f
[c
];
106 assert(op
[0]->type
->base_type
== GLSL_TYPE_INT
);
107 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
108 data
.f
[c
] = op
[0]->value
.i
[c
];
112 assert(op
[0]->type
->base_type
== GLSL_TYPE_UINT
);
113 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
114 data
.f
[c
] = op
[0]->value
.u
[c
];
118 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
119 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
120 data
.f
[c
] = op
[0]->value
.b
[c
] ? 1.0 : 0.0;
124 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
125 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
126 data
.b
[c
] = bool(op
[0]->value
.f
[c
]);
130 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
131 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
132 data
.u
[c
] = op
[0]->value
.b
[c
] ? 1 : 0;
136 assert(op
[0]->type
->is_integer());
137 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
138 data
.b
[c
] = bool(op
[0]->value
.u
[c
]);
143 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
144 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
145 data
.f
[c
] = truncf(op
[0]->value
.f
[c
]);
150 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
151 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
152 data
.f
[c
] = ceilf(op
[0]->value
.f
[c
]);
157 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
158 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
159 data
.f
[c
] = floorf(op
[0]->value
.f
[c
]);
164 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
165 switch (this->type
->base_type
) {
172 case GLSL_TYPE_FLOAT
:
173 data
.f
[c
] = op
[0]->value
.f
[c
] - floor(op
[0]->value
.f
[c
]);
182 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
183 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
184 data
.f
[c
] = sinf(op
[0]->value
.f
[c
]);
189 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
190 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
191 data
.f
[c
] = cosf(op
[0]->value
.f
[c
]);
196 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
197 switch (this->type
->base_type
) {
199 data
.u
[c
] = -op
[0]->value
.u
[c
];
202 data
.i
[c
] = -op
[0]->value
.i
[c
];
204 case GLSL_TYPE_FLOAT
:
205 data
.f
[c
] = -op
[0]->value
.f
[c
];
214 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
215 switch (this->type
->base_type
) {
217 data
.u
[c
] = op
[0]->value
.u
[c
];
220 data
.i
[c
] = op
[0]->value
.i
[c
];
222 data
.i
[c
] = -data
.i
[c
];
224 case GLSL_TYPE_FLOAT
:
225 data
.f
[c
] = fabs(op
[0]->value
.f
[c
]);
234 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
235 switch (this->type
->base_type
) {
237 data
.u
[c
] = op
[0]->value
.i
[c
] > 0;
240 data
.i
[c
] = (op
[0]->value
.i
[c
] > 0) - (op
[0]->value
.i
[c
] < 0);
242 case GLSL_TYPE_FLOAT
:
243 data
.f
[c
] = float((op
[0]->value
.f
[c
] > 0)-(op
[0]->value
.f
[c
] < 0));
252 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
253 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
254 switch (this->type
->base_type
) {
256 if (op
[0]->value
.u
[c
] != 0.0)
257 data
.u
[c
] = 1 / op
[0]->value
.u
[c
];
260 if (op
[0]->value
.i
[c
] != 0.0)
261 data
.i
[c
] = 1 / op
[0]->value
.i
[c
];
263 case GLSL_TYPE_FLOAT
:
264 if (op
[0]->value
.f
[c
] != 0.0)
265 data
.f
[c
] = 1.0 / op
[0]->value
.f
[c
];
274 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
275 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
276 data
.f
[c
] = 1.0 / sqrtf(op
[0]->value
.f
[c
]);
281 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
282 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
283 data
.f
[c
] = sqrtf(op
[0]->value
.f
[c
]);
288 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
289 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
290 data
.f
[c
] = expf(op
[0]->value
.f
[c
]);
295 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
296 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
297 data
.f
[c
] = exp2f(op
[0]->value
.f
[c
]);
302 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
303 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
304 data
.f
[c
] = logf(op
[0]->value
.f
[c
]);
309 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
310 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
311 data
.f
[c
] = log2f(op
[0]->value
.f
[c
]);
317 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
318 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
324 assert(op
[0]->type
->base_type
== GLSL_TYPE_FLOAT
);
325 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
326 data
.f
[c
] = powf(op
[0]->value
.f
[c
], op
[1]->value
.f
[c
]);
331 assert(op
[0]->type
->is_vector() && op
[1]->type
->is_vector());
333 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++) {
334 switch (op
[0]->type
->base_type
) {
336 data
.u
[0] += op
[0]->value
.u
[c
] * op
[1]->value
.u
[c
];
339 data
.i
[0] += op
[0]->value
.i
[c
] * op
[1]->value
.i
[c
];
341 case GLSL_TYPE_FLOAT
:
342 data
.f
[0] += op
[0]->value
.f
[c
] * op
[1]->value
.f
[c
];
351 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
352 for (unsigned c
= 0, c0
= 0, c1
= 0;
354 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
356 switch (op
[0]->type
->base_type
) {
358 data
.u
[c
] = min(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
361 data
.i
[c
] = min(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
363 case GLSL_TYPE_FLOAT
:
364 data
.f
[c
] = min(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
373 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
374 for (unsigned c
= 0, c0
= 0, c1
= 0;
376 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
378 switch (op
[0]->type
->base_type
) {
380 data
.u
[c
] = max(op
[0]->value
.u
[c0
], op
[1]->value
.u
[c1
]);
383 data
.i
[c
] = max(op
[0]->value
.i
[c0
], op
[1]->value
.i
[c1
]);
385 case GLSL_TYPE_FLOAT
:
386 data
.f
[c
] = max(op
[0]->value
.f
[c0
], op
[1]->value
.f
[c1
]);
395 assert(op
[0]->type
== glsl_type::vec3_type
);
396 assert(op
[1]->type
== glsl_type::vec3_type
);
397 data
.f
[0] = (op
[0]->value
.f
[1] * op
[1]->value
.f
[2] -
398 op
[1]->value
.f
[1] * op
[0]->value
.f
[2]);
399 data
.f
[1] = (op
[0]->value
.f
[2] * op
[1]->value
.f
[0] -
400 op
[1]->value
.f
[2] * op
[0]->value
.f
[0]);
401 data
.f
[2] = (op
[0]->value
.f
[0] * op
[1]->value
.f
[1] -
402 op
[1]->value
.f
[0] * op
[0]->value
.f
[1]);
406 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
407 for (unsigned c
= 0, c0
= 0, c1
= 0;
409 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
411 switch (op
[0]->type
->base_type
) {
413 data
.u
[c
] = op
[0]->value
.u
[c0
] + op
[1]->value
.u
[c1
];
416 data
.i
[c
] = op
[0]->value
.i
[c0
] + op
[1]->value
.i
[c1
];
418 case GLSL_TYPE_FLOAT
:
419 data
.f
[c
] = op
[0]->value
.f
[c0
] + op
[1]->value
.f
[c1
];
428 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
429 for (unsigned c
= 0, c0
= 0, c1
= 0;
431 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
433 switch (op
[0]->type
->base_type
) {
435 data
.u
[c
] = op
[0]->value
.u
[c0
] - op
[1]->value
.u
[c1
];
438 data
.i
[c
] = op
[0]->value
.i
[c0
] - op
[1]->value
.i
[c1
];
440 case GLSL_TYPE_FLOAT
:
441 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
];
450 /* Check for equal types, or unequal types involving scalars */
451 if ((op
[0]->type
== op
[1]->type
&& !op
[0]->type
->is_matrix())
452 || op0_scalar
|| op1_scalar
) {
453 for (unsigned c
= 0, c0
= 0, c1
= 0;
455 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
457 switch (op
[0]->type
->base_type
) {
459 data
.u
[c
] = op
[0]->value
.u
[c0
] * op
[1]->value
.u
[c1
];
462 data
.i
[c
] = op
[0]->value
.i
[c0
] * op
[1]->value
.i
[c1
];
464 case GLSL_TYPE_FLOAT
:
465 data
.f
[c
] = op
[0]->value
.f
[c0
] * op
[1]->value
.f
[c1
];
472 assert(op
[0]->type
->is_matrix() || op
[1]->type
->is_matrix());
474 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
475 * matrix can be a GLSL vector, either N or P can be 1.
477 * For vec*mat, the vector is treated as a row vector. This
478 * means the vector is a 1-row x M-column matrix.
480 * For mat*vec, the vector is treated as a column vector. Since
481 * matrix_columns is 1 for vectors, this just works.
483 const unsigned n
= op
[0]->type
->is_vector()
484 ? 1 : op
[0]->type
->vector_elements
;
485 const unsigned m
= op
[1]->type
->vector_elements
;
486 const unsigned p
= op
[1]->type
->matrix_columns
;
487 for (unsigned j
= 0; j
< p
; j
++) {
488 for (unsigned i
= 0; i
< n
; i
++) {
489 for (unsigned k
= 0; k
< m
; k
++) {
490 data
.f
[i
+n
*j
] += op
[0]->value
.f
[i
+n
*k
]*op
[1]->value
.f
[k
+m
*j
];
498 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
499 for (unsigned c
= 0, c0
= 0, c1
= 0;
501 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
503 switch (op
[0]->type
->base_type
) {
505 data
.u
[c
] = op
[0]->value
.u
[c0
] / op
[1]->value
.u
[c1
];
508 data
.i
[c
] = op
[0]->value
.i
[c0
] / op
[1]->value
.i
[c1
];
510 case GLSL_TYPE_FLOAT
:
511 data
.f
[c
] = op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
];
520 assert(op
[0]->type
== op
[1]->type
|| op0_scalar
|| op1_scalar
);
521 for (unsigned c
= 0, c0
= 0, c1
= 0;
523 c0
+= c0_inc
, c1
+= c1_inc
, c
++) {
525 switch (op
[0]->type
->base_type
) {
527 data
.u
[c
] = op
[0]->value
.u
[c0
] % op
[1]->value
.u
[c1
];
530 data
.i
[c
] = op
[0]->value
.i
[c0
] % op
[1]->value
.i
[c1
];
532 case GLSL_TYPE_FLOAT
:
533 /* We don't use fmod because it rounds toward zero; GLSL specifies
536 data
.f
[c
] = op
[0]->value
.f
[c0
] - op
[1]->value
.f
[c1
]
537 * floorf(op
[0]->value
.f
[c0
] / op
[1]->value
.f
[c1
]);
546 case ir_binop_logic_and
:
547 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
548 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
549 data
.b
[c
] = op
[0]->value
.b
[c
] && op
[1]->value
.b
[c
];
551 case ir_binop_logic_xor
:
552 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
553 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
554 data
.b
[c
] = op
[0]->value
.b
[c
] ^ op
[1]->value
.b
[c
];
556 case ir_binop_logic_or
:
557 assert(op
[0]->type
->base_type
== GLSL_TYPE_BOOL
);
558 for (unsigned c
= 0; c
< op
[0]->type
->components(); c
++)
559 data
.b
[c
] = op
[0]->value
.b
[c
] || op
[1]->value
.b
[c
];
563 switch (op
[0]->type
->base_type
) {
565 data
.b
[0] = op
[0]->value
.u
[0] < op
[1]->value
.u
[0];
568 data
.b
[0] = op
[0]->value
.i
[0] < op
[1]->value
.i
[0];
570 case GLSL_TYPE_FLOAT
:
571 data
.b
[0] = op
[0]->value
.f
[0] < op
[1]->value
.f
[0];
577 case ir_binop_greater
:
578 switch (op
[0]->type
->base_type
) {
580 data
.b
[0] = op
[0]->value
.u
[0] > op
[1]->value
.u
[0];
583 data
.b
[0] = op
[0]->value
.i
[0] > op
[1]->value
.i
[0];
585 case GLSL_TYPE_FLOAT
:
586 data
.b
[0] = op
[0]->value
.f
[0] > op
[1]->value
.f
[0];
592 case ir_binop_lequal
:
593 switch (op
[0]->type
->base_type
) {
595 data
.b
[0] = op
[0]->value
.u
[0] <= op
[1]->value
.u
[0];
598 data
.b
[0] = op
[0]->value
.i
[0] <= op
[1]->value
.i
[0];
600 case GLSL_TYPE_FLOAT
:
601 data
.b
[0] = op
[0]->value
.f
[0] <= op
[1]->value
.f
[0];
607 case ir_binop_gequal
:
608 switch (op
[0]->type
->base_type
) {
610 data
.b
[0] = op
[0]->value
.u
[0] >= op
[1]->value
.u
[0];
613 data
.b
[0] = op
[0]->value
.i
[0] >= op
[1]->value
.i
[0];
615 case GLSL_TYPE_FLOAT
:
616 data
.b
[0] = op
[0]->value
.f
[0] >= op
[1]->value
.f
[0];
624 data
.b
[0] = op
[0]->has_value(op
[1]);
626 case ir_binop_nequal
:
627 data
.b
[0] = !op
[0]->has_value(op
[1]);
631 /* FINISHME: Should handle all expression types. */
635 return new(ctx
) ir_constant(this->type
, &data
);
640 ir_texture::constant_expression_value()
642 /* texture lookups aren't constant expressions */
648 ir_swizzle::constant_expression_value()
650 ir_constant
*v
= this->val
->constant_expression_value();
653 ir_constant_data data
;
655 const unsigned swiz_idx
[4] = {
656 this->mask
.x
, this->mask
.y
, this->mask
.z
, this->mask
.w
659 for (unsigned i
= 0; i
< this->mask
.num_components
; i
++) {
660 switch (v
->type
->base_type
) {
662 case GLSL_TYPE_INT
: data
.u
[i
] = v
->value
.u
[swiz_idx
[i
]]; break;
663 case GLSL_TYPE_FLOAT
: data
.f
[i
] = v
->value
.f
[swiz_idx
[i
]]; break;
664 case GLSL_TYPE_BOOL
: data
.b
[i
] = v
->value
.b
[swiz_idx
[i
]]; break;
665 default: assert(!"Should not get here."); break;
669 void *ctx
= talloc_parent(this);
670 return new(ctx
) ir_constant(this->type
, &data
);
677 ir_dereference_variable::constant_expression_value()
679 return var
->constant_value
? var
->constant_value
->clone(NULL
) : NULL
;
684 ir_dereference_array::constant_expression_value()
686 void *ctx
= talloc_parent(this);
687 ir_constant
*array
= this->array
->constant_expression_value();
688 ir_constant
*idx
= this->array_index
->constant_expression_value();
690 if ((array
!= NULL
) && (idx
!= NULL
)) {
691 if (array
->type
->is_matrix()) {
692 /* Array access of a matrix results in a vector.
694 const unsigned column
= idx
->value
.u
[0];
696 const glsl_type
*const column_type
= array
->type
->column_type();
698 /* Offset in the constant matrix to the first element of the column
701 const unsigned mat_idx
= column
* column_type
->vector_elements
;
703 ir_constant_data data
;
705 switch (column_type
->base_type
) {
708 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
709 data
.u
[i
] = array
->value
.u
[mat_idx
+ i
];
713 case GLSL_TYPE_FLOAT
:
714 for (unsigned i
= 0; i
< column_type
->vector_elements
; i
++)
715 data
.f
[i
] = array
->value
.f
[mat_idx
+ i
];
720 assert(!"Should not get here.");
724 return new(ctx
) ir_constant(column_type
, &data
);
725 } else if (array
->type
->is_vector()) {
726 const unsigned component
= idx
->value
.u
[0];
728 return new(ctx
) ir_constant(array
, component
);
730 const unsigned index
= idx
->value
.u
[0];
731 return array
->get_array_element(index
)->clone(NULL
);
739 ir_dereference_record::constant_expression_value()
741 ir_constant
*v
= this->record
->constant_expression_value();
743 return (v
!= NULL
) ? v
->get_record_field(this->field
) : NULL
;
748 ir_assignment::constant_expression_value()
750 /* FINISHME: Handle CEs involving assignment (return RHS) */
756 ir_constant::constant_expression_value()
763 ir_call::constant_expression_value()
765 /* FINISHME: Handle CEs involving builtin function calls. */