linker: Reject shaders that have unresolved function calls
[mesa/nouveau-pmpeg.git] / src / glsl / ir_constant_expression.cpp
blob61a708f6e2ddf436338637820fab2f36be377a2e
1 /*
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
13 * Software.
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.
24 /**
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.
31 * * Sizes of arrays
32 * * Initializers for uniforms
33 * * Initializers for \c const variables
36 #include <math.h>
37 #include "main/core.h" /* for MAX2, MIN2, CLAMP */
38 #include "ir.h"
39 #include "ir_visitor.h"
40 #include "glsl_types.h"
42 static float
43 dot(ir_constant *op0, ir_constant *op1)
45 assert(op0->type->is_float() && op1->type->is_float());
47 float result = 0;
48 for (unsigned c = 0; c < op0->type->components(); c++)
49 result += op0->value.f[c] * op1->value.f[c];
51 return result;
54 ir_constant *
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();
64 if (!op[operand])
65 return NULL;
68 if (op[1] != NULL)
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;
79 unsigned components;
80 if (op1_scalar || !op[1]) {
81 components = op[0]->type->components();
82 } else {
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]));
96 default:
97 break;
99 return NULL;
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];
107 break;
109 case ir_unop_f2i:
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];
114 break;
115 case ir_unop_i2f:
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];
120 break;
121 case ir_unop_u2f:
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];
126 break;
127 case ir_unop_b2f:
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;
132 break;
133 case ir_unop_f2b:
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]);
138 break;
139 case ir_unop_b2i:
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;
144 break;
145 case ir_unop_i2b:
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]);
150 break;
152 case ir_unop_any:
153 assert(op[0]->type->is_boolean());
154 data.b[0] = false;
155 for (unsigned c = 0; c < op[0]->type->components(); c++) {
156 if (op[0]->value.b[c])
157 data.b[0] = true;
159 break;
161 case ir_unop_trunc:
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]);
166 break;
168 case ir_unop_ceil:
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]);
173 break;
175 case ir_unop_floor:
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]);
180 break;
182 case ir_unop_fract:
183 for (unsigned c = 0; c < op[0]->type->components(); c++) {
184 switch (this->type->base_type) {
185 case GLSL_TYPE_UINT:
186 data.u[c] = 0;
187 break;
188 case GLSL_TYPE_INT:
189 data.i[c] = 0;
190 break;
191 case GLSL_TYPE_FLOAT:
192 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
193 break;
194 default:
195 assert(0);
198 break;
200 case ir_unop_sin:
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]);
205 break;
207 case ir_unop_cos:
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]);
212 break;
214 case ir_unop_neg:
215 for (unsigned c = 0; c < op[0]->type->components(); c++) {
216 switch (this->type->base_type) {
217 case GLSL_TYPE_UINT:
218 data.u[c] = -op[0]->value.u[c];
219 break;
220 case GLSL_TYPE_INT:
221 data.i[c] = -op[0]->value.i[c];
222 break;
223 case GLSL_TYPE_FLOAT:
224 data.f[c] = -op[0]->value.f[c];
225 break;
226 default:
227 assert(0);
230 break;
232 case ir_unop_abs:
233 for (unsigned c = 0; c < op[0]->type->components(); c++) {
234 switch (this->type->base_type) {
235 case GLSL_TYPE_UINT:
236 data.u[c] = op[0]->value.u[c];
237 break;
238 case GLSL_TYPE_INT:
239 data.i[c] = op[0]->value.i[c];
240 if (data.i[c] < 0)
241 data.i[c] = -data.i[c];
242 break;
243 case GLSL_TYPE_FLOAT:
244 data.f[c] = fabs(op[0]->value.f[c]);
245 break;
246 default:
247 assert(0);
250 break;
252 case ir_unop_sign:
253 for (unsigned c = 0; c < op[0]->type->components(); c++) {
254 switch (this->type->base_type) {
255 case GLSL_TYPE_UINT:
256 data.u[c] = op[0]->value.i[c] > 0;
257 break;
258 case GLSL_TYPE_INT:
259 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
260 break;
261 case GLSL_TYPE_FLOAT:
262 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
263 break;
264 default:
265 assert(0);
268 break;
270 case ir_unop_rcp:
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) {
274 case GLSL_TYPE_UINT:
275 if (op[0]->value.u[c] != 0.0)
276 data.u[c] = 1 / op[0]->value.u[c];
277 break;
278 case GLSL_TYPE_INT:
279 if (op[0]->value.i[c] != 0.0)
280 data.i[c] = 1 / op[0]->value.i[c];
281 break;
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];
285 break;
286 default:
287 assert(0);
290 break;
292 case ir_unop_rsq:
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]);
297 break;
299 case ir_unop_sqrt:
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]);
304 break;
306 case ir_unop_exp:
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]);
311 break;
313 case ir_unop_exp2:
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]);
318 break;
320 case ir_unop_log:
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]);
325 break;
327 case ir_unop_log2:
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]);
332 break;
334 case ir_unop_dFdx:
335 case ir_unop_dFdy:
336 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
337 for (unsigned c = 0; c < op[0]->type->components(); c++) {
338 data.f[c] = 0.0;
340 break;
342 case ir_binop_pow:
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]);
347 break;
349 case ir_binop_dot:
350 data.f[0] = dot(op[0], op[1]);
351 break;
353 case ir_binop_min:
354 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
355 for (unsigned c = 0, c0 = 0, c1 = 0;
356 c < components;
357 c0 += c0_inc, c1 += c1_inc, c++) {
359 switch (op[0]->type->base_type) {
360 case GLSL_TYPE_UINT:
361 data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]);
362 break;
363 case GLSL_TYPE_INT:
364 data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]);
365 break;
366 case GLSL_TYPE_FLOAT:
367 data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]);
368 break;
369 default:
370 assert(0);
374 break;
375 case ir_binop_max:
376 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
377 for (unsigned c = 0, c0 = 0, c1 = 0;
378 c < components;
379 c0 += c0_inc, c1 += c1_inc, c++) {
381 switch (op[0]->type->base_type) {
382 case GLSL_TYPE_UINT:
383 data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]);
384 break;
385 case GLSL_TYPE_INT:
386 data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]);
387 break;
388 case GLSL_TYPE_FLOAT:
389 data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]);
390 break;
391 default:
392 assert(0);
395 break;
397 case ir_binop_cross:
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]);
406 break;
408 case ir_binop_add:
409 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
410 for (unsigned c = 0, c0 = 0, c1 = 0;
411 c < components;
412 c0 += c0_inc, c1 += c1_inc, c++) {
414 switch (op[0]->type->base_type) {
415 case GLSL_TYPE_UINT:
416 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
417 break;
418 case GLSL_TYPE_INT:
419 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
420 break;
421 case GLSL_TYPE_FLOAT:
422 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
423 break;
424 default:
425 assert(0);
429 break;
430 case ir_binop_sub:
431 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
432 for (unsigned c = 0, c0 = 0, c1 = 0;
433 c < components;
434 c0 += c0_inc, c1 += c1_inc, c++) {
436 switch (op[0]->type->base_type) {
437 case GLSL_TYPE_UINT:
438 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
439 break;
440 case GLSL_TYPE_INT:
441 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
442 break;
443 case GLSL_TYPE_FLOAT:
444 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
445 break;
446 default:
447 assert(0);
451 break;
452 case ir_binop_mul:
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;
457 c < components;
458 c0 += c0_inc, c1 += c1_inc, c++) {
460 switch (op[0]->type->base_type) {
461 case GLSL_TYPE_UINT:
462 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
463 break;
464 case GLSL_TYPE_INT:
465 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
466 break;
467 case GLSL_TYPE_FLOAT:
468 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
469 break;
470 default:
471 assert(0);
474 } else {
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];
499 break;
500 case ir_binop_div:
501 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
502 for (unsigned c = 0, c0 = 0, c1 = 0;
503 c < components;
504 c0 += c0_inc, c1 += c1_inc, c++) {
506 switch (op[0]->type->base_type) {
507 case GLSL_TYPE_UINT:
508 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
509 break;
510 case GLSL_TYPE_INT:
511 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
512 break;
513 case GLSL_TYPE_FLOAT:
514 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
515 break;
516 default:
517 assert(0);
521 break;
522 case ir_binop_mod:
523 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
524 for (unsigned c = 0, c0 = 0, c1 = 0;
525 c < components;
526 c0 += c0_inc, c1 += c1_inc, c++) {
528 switch (op[0]->type->base_type) {
529 case GLSL_TYPE_UINT:
530 data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
531 break;
532 case GLSL_TYPE_INT:
533 data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
534 break;
535 case GLSL_TYPE_FLOAT:
536 /* We don't use fmod because it rounds toward zero; GLSL specifies
537 * the use of floor.
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]);
541 break;
542 default:
543 assert(0);
547 break;
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];
553 break;
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];
558 break;
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];
563 break;
565 case ir_binop_less:
566 switch (op[0]->type->base_type) {
567 case GLSL_TYPE_UINT:
568 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
569 break;
570 case GLSL_TYPE_INT:
571 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
572 break;
573 case GLSL_TYPE_FLOAT:
574 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
575 break;
576 default:
577 assert(0);
579 break;
580 case ir_binop_greater:
581 switch (op[0]->type->base_type) {
582 case GLSL_TYPE_UINT:
583 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
584 break;
585 case GLSL_TYPE_INT:
586 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
587 break;
588 case GLSL_TYPE_FLOAT:
589 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
590 break;
591 default:
592 assert(0);
594 break;
595 case ir_binop_lequal:
596 switch (op[0]->type->base_type) {
597 case GLSL_TYPE_UINT:
598 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
599 break;
600 case GLSL_TYPE_INT:
601 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
602 break;
603 case GLSL_TYPE_FLOAT:
604 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
605 break;
606 default:
607 assert(0);
609 break;
610 case ir_binop_gequal:
611 switch (op[0]->type->base_type) {
612 case GLSL_TYPE_UINT:
613 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
614 break;
615 case GLSL_TYPE_INT:
616 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
617 break;
618 case GLSL_TYPE_FLOAT:
619 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
620 break;
621 default:
622 assert(0);
624 break;
625 case ir_binop_equal:
626 assert(op[0]->type == op[1]->type);
627 for (unsigned c = 0; c < components; c++) {
628 switch (op[0]->type->base_type) {
629 case GLSL_TYPE_UINT:
630 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
631 break;
632 case GLSL_TYPE_INT:
633 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
634 break;
635 case GLSL_TYPE_FLOAT:
636 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
637 break;
638 default:
639 assert(0);
642 break;
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) {
647 case GLSL_TYPE_UINT:
648 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
649 break;
650 case GLSL_TYPE_INT:
651 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
652 break;
653 case GLSL_TYPE_FLOAT:
654 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
655 break;
656 default:
657 assert(0);
660 break;
661 case ir_binop_all_equal:
662 data.b[0] = op[0]->has_value(op[1]);
663 break;
664 case ir_binop_any_nequal:
665 data.b[0] = !op[0]->has_value(op[1]);
666 break;
668 default:
669 /* FINISHME: Should handle all expression types. */
670 return NULL;
673 return new(ctx) ir_constant(this->type, &data);
677 ir_constant *
678 ir_texture::constant_expression_value()
680 /* texture lookups aren't constant expressions */
681 return NULL;
685 ir_constant *
686 ir_swizzle::constant_expression_value()
688 ir_constant *v = this->val->constant_expression_value();
690 if (v != NULL) {
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) {
699 case GLSL_TYPE_UINT:
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);
710 return NULL;
714 ir_constant *
715 ir_dereference_variable::constant_expression_value()
717 /* This may occur during compile and var->type is glsl_type::error_type */
718 if (!var)
719 return NULL;
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)
725 return NULL;
727 if (!var->constant_value)
728 return NULL;
730 return var->constant_value->clone(talloc_parent(var), NULL);
734 ir_constant *
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
750 * to be extracted.
752 const unsigned mat_idx = column * column_type->vector_elements;
754 ir_constant_data data;
756 switch (column_type->base_type) {
757 case GLSL_TYPE_UINT:
758 case GLSL_TYPE_INT:
759 for (unsigned i = 0; i < column_type->vector_elements; i++)
760 data.u[i] = array->value.u[mat_idx + i];
762 break;
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];
768 break;
770 default:
771 assert(!"Should not get here.");
772 break;
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);
780 } else {
781 const unsigned index = idx->value.u[0];
782 return array->get_array_element(index)->clone(ctx, NULL);
785 return NULL;
789 ir_constant *
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;
798 ir_constant *
799 ir_assignment::constant_expression_value()
801 /* FINISHME: Handle CEs involving assignment (return RHS) */
802 return NULL;
806 ir_constant *
807 ir_constant::constant_expression_value()
809 return this;
813 ir_constant *
814 ir_call::constant_expression_value()
816 if (this->type == glsl_type::error_type)
817 return NULL;
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)
824 return NULL;
826 unsigned num_parameters = 0;
828 /* Check if all parameters are constant */
829 ir_constant *op[3];
830 foreach_list(n, &this->actual_parameters) {
831 ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value();
832 if (constant == NULL)
833 return NULL;
835 op[num_parameters] = constant;
837 assert(num_parameters < 3);
838 num_parameters++;
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]);
883 } else {
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) {
900 case GLSL_TYPE_UINT:
901 data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1],
902 op[2]->value.u[c2]);
903 break;
904 case GLSL_TYPE_INT:
905 data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1],
906 op[2]->value.i[c2]);
907 break;
908 case GLSL_TYPE_FLOAT:
909 data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1],
910 op[2]->value.f[c2]);
911 break;
912 default:
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) {
942 case GLSL_TYPE_UINT:
943 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
944 break;
945 case GLSL_TYPE_INT:
946 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
947 break;
948 case GLSL_TYPE_FLOAT:
949 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
950 break;
951 case GLSL_TYPE_BOOL:
952 data.b[c] = op[0]->value.b[c] == op[1]->value.b[c];
953 break;
954 default:
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)
964 return op[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) {
977 case GLSL_TYPE_UINT:
978 data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
979 break;
980 case GLSL_TYPE_INT:
981 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
982 break;
983 case GLSL_TYPE_FLOAT:
984 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
985 break;
986 default:
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) {
994 case GLSL_TYPE_UINT:
995 data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c];
996 break;
997 case GLSL_TYPE_INT:
998 data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c];
999 break;
1000 case GLSL_TYPE_FLOAT:
1001 data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c];
1002 break;
1003 default:
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];
1017 break;
1018 case GLSL_TYPE_INT:
1019 data.b[c] = op[0]->value.i[c] < op[1]->value.i[c];
1020 break;
1021 case GLSL_TYPE_FLOAT:
1022 data.b[c] = op[0]->value.f[c] < op[1]->value.f[c];
1023 break;
1024 default:
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];
1034 break;
1035 case GLSL_TYPE_INT:
1036 data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c];
1037 break;
1038 case GLSL_TYPE_FLOAT:
1039 data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c];
1040 break;
1041 default:
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];
1066 } else {
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]));
1077 if (length == 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];
1090 break;
1091 case GLSL_TYPE_INT:
1092 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
1093 break;
1094 case GLSL_TYPE_FLOAT:
1095 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
1096 break;
1097 case GLSL_TYPE_BOOL:
1098 data.b[c] = op[0]->value.b[c] != op[1]->value.b[c];
1099 break;
1100 default:
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);
1128 if (k < 0.0) {
1129 return ir_constant::zero(mem_ctx, this->type);
1130 } else {
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 */
1153 } else {
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];
1185 } else {
1186 /* Unsupported builtin - some are not allowed in constant expressions. */
1187 return NULL;
1190 if (expr != NULL)
1191 return expr->constant_expression_value();
1193 return new(mem_ctx) ir_constant(this->type, &data);