glsl: Initialize variable in ir_swizzle::constant_expression_value.
[mesa.git] / src / glsl / ir_constant_expression.cpp
1 /*
2 * Copyright © 2010 Intel Corporation
3 *
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:
10 *
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.
14 *
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.
22 */
23
24 /**
25 * \file ir_constant_expression.cpp
26 * Evaluate and process constant valued expressions
27 *
28 * In GLSL, constant valued expressions are used in several places. These
29 * must be processed and evaluated very early in the compilation process.
30 *
31 * * Sizes of arrays
32 * * Initializers for uniforms
33 * * Initializers for \c const variables
34 */
35
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"
41
42 static float
43 dot(ir_constant *op0, ir_constant *op1)
44 {
45 assert(op0->type->is_float() && op1->type->is_float());
46
47 float result = 0;
48 for (unsigned c = 0; c < op0->type->components(); c++)
49 result += op0->value.f[c] * op1->value.f[c];
50
51 return result;
52 }
53
54 ir_constant *
55 ir_expression::constant_expression_value()
56 {
57 ir_constant *op[2] = { NULL, NULL };
58 ir_constant_data data;
59
60 memset(&data, 0, sizeof(data));
61
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;
66 }
67
68 if (op[1] != NULL)
69 assert(op[0]->type->base_type == op[1]->type->base_type);
70
71 bool op0_scalar = op[0]->type->is_scalar();
72 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
73
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.
76 */
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();
84 }
85
86 void *ctx = talloc_parent(this);
87
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_equal:
93 return new(ctx) ir_constant(op[0]->has_value(op[1]));
94 case ir_binop_nequal:
95 return new(ctx) ir_constant(!op[0]->has_value(op[1]));
96 default:
97 break;
98 }
99 return NULL;
100 }
101
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;
108
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];
113 }
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];
119 }
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];
125 }
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;
131 }
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]);
137 }
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;
143 }
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]);
149 }
150 break;
151
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;
158 }
159 break;
160
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]);
165 }
166 break;
167
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]);
172 }
173 break;
174
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]);
179 }
180 break;
181
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);
196 }
197 }
198 break;
199
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]);
204 }
205 break;
206
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]);
211 }
212 break;
213
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);
228 }
229 }
230 break;
231
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);
248 }
249 }
250 break;
251
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);
266 }
267 }
268 break;
269
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);
288 }
289 }
290 break;
291
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]);
296 }
297 break;
298
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]);
303 }
304 break;
305
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]);
310 }
311 break;
312
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]);
317 }
318 break;
319
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]);
324 }
325 break;
326
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]);
331 }
332 break;
333
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;
339 }
340 break;
341
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]);
346 }
347 break;
348
349 case ir_binop_dot:
350 data.f[0] = dot(op[0], op[1]);
351 break;
352
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++) {
358
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);
371 }
372 }
373
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++) {
380
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);
393 }
394 }
395 break;
396
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;
407
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++) {
413
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);
426 }
427 }
428
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++) {
435
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);
448 }
449 }
450
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++) {
459
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);
472 }
473 }
474 } else {
475 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
476
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.
479 *
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.
482 *
483 * For mat*vec, the vector is treated as a column vector. Since
484 * matrix_columns is 1 for vectors, this just works.
485 */
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];
494 }
495 }
496 }
497 }
498
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++) {
505
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);
518 }
519 }
520
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++) {
527
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.
538 */
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);
544 }
545 }
546
547 break;
548
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;
564
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);
578 }
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);
593 }
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);
608 }
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);
623 }
624 break;
625
626 case ir_binop_equal:
627 data.b[0] = op[0]->has_value(op[1]);
628 break;
629 case ir_binop_nequal:
630 data.b[0] = !op[0]->has_value(op[1]);
631 break;
632
633 default:
634 /* FINISHME: Should handle all expression types. */
635 return NULL;
636 }
637
638 return new(ctx) ir_constant(this->type, &data);
639 }
640
641
642 ir_constant *
643 ir_texture::constant_expression_value()
644 {
645 /* texture lookups aren't constant expressions */
646 return NULL;
647 }
648
649
650 ir_constant *
651 ir_swizzle::constant_expression_value()
652 {
653 ir_constant *v = this->val->constant_expression_value();
654
655 if (v != NULL) {
656 ir_constant_data data = { { 0 } };
657
658 const unsigned swiz_idx[4] = {
659 this->mask.x, this->mask.y, this->mask.z, this->mask.w
660 };
661
662 for (unsigned i = 0; i < this->mask.num_components; i++) {
663 switch (v->type->base_type) {
664 case GLSL_TYPE_UINT:
665 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
666 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
667 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
668 default: assert(!"Should not get here."); break;
669 }
670 }
671
672 void *ctx = talloc_parent(this);
673 return new(ctx) ir_constant(this->type, &data);
674 }
675 return NULL;
676 }
677
678
679 ir_constant *
680 ir_dereference_variable::constant_expression_value()
681 {
682 /* This may occur during compile and var->type is glsl_type::error_type */
683 if (!var)
684 return NULL;
685
686 /* The constant_value of a uniform variable is its initializer,
687 * not the lifetime constant value of the uniform.
688 */
689 if (var->mode == ir_var_uniform)
690 return NULL;
691
692 if (!var->constant_value)
693 return NULL;
694
695 return var->constant_value->clone(talloc_parent(var), NULL);
696 }
697
698
699 ir_constant *
700 ir_dereference_array::constant_expression_value()
701 {
702 ir_constant *array = this->array->constant_expression_value();
703 ir_constant *idx = this->array_index->constant_expression_value();
704
705 if ((array != NULL) && (idx != NULL)) {
706 void *ctx = talloc_parent(this);
707 if (array->type->is_matrix()) {
708 /* Array access of a matrix results in a vector.
709 */
710 const unsigned column = idx->value.u[0];
711
712 const glsl_type *const column_type = array->type->column_type();
713
714 /* Offset in the constant matrix to the first element of the column
715 * to be extracted.
716 */
717 const unsigned mat_idx = column * column_type->vector_elements;
718
719 ir_constant_data data;
720
721 switch (column_type->base_type) {
722 case GLSL_TYPE_UINT:
723 case GLSL_TYPE_INT:
724 for (unsigned i = 0; i < column_type->vector_elements; i++)
725 data.u[i] = array->value.u[mat_idx + i];
726
727 break;
728
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];
732
733 break;
734
735 default:
736 assert(!"Should not get here.");
737 break;
738 }
739
740 return new(ctx) ir_constant(column_type, &data);
741 } else if (array->type->is_vector()) {
742 const unsigned component = idx->value.u[0];
743
744 return new(ctx) ir_constant(array, component);
745 } else {
746 const unsigned index = idx->value.u[0];
747 return array->get_array_element(index)->clone(ctx, NULL);
748 }
749 }
750 return NULL;
751 }
752
753
754 ir_constant *
755 ir_dereference_record::constant_expression_value()
756 {
757 ir_constant *v = this->record->constant_expression_value();
758
759 return (v != NULL) ? v->get_record_field(this->field) : NULL;
760 }
761
762
763 ir_constant *
764 ir_assignment::constant_expression_value()
765 {
766 /* FINISHME: Handle CEs involving assignment (return RHS) */
767 return NULL;
768 }
769
770
771 ir_constant *
772 ir_constant::constant_expression_value()
773 {
774 return this;
775 }
776
777
778 ir_constant *
779 ir_call::constant_expression_value()
780 {
781 if (this->type == glsl_type::error_type)
782 return NULL;
783
784 /* From the GLSL 1.20 spec, page 23:
785 * "Function calls to user-defined functions (non-built-in functions)
786 * cannot be used to form constant expressions."
787 */
788 if (!this->callee->function()->is_builtin)
789 return NULL;
790
791 unsigned num_parameters = 0;
792
793 /* Check if all parameters are constant */
794 ir_constant *op[3];
795 foreach_list(n, &this->actual_parameters) {
796 ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value();
797 if (constant == NULL)
798 return NULL;
799
800 op[num_parameters] = constant;
801
802 assert(num_parameters < 3);
803 num_parameters++;
804 }
805
806 /* Individual cases below can either:
807 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
808 * - Fill "data" with appopriate constant data
809 * - Return an ir_constant directly.
810 */
811 void *mem_ctx = talloc_parent(this);
812 ir_expression *expr = NULL;
813
814 ir_constant_data data;
815 memset(&data, 0, sizeof(data));
816
817 const char *callee = this->callee_name();
818 if (strcmp(callee, "abs") == 0) {
819 expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL);
820 } else if (strcmp(callee, "all") == 0) {
821 assert(op[0]->type->is_boolean());
822 for (unsigned c = 0; c < op[0]->type->components(); c++) {
823 if (!op[0]->value.b[c])
824 return new(mem_ctx) ir_constant(false);
825 }
826 return new(mem_ctx) ir_constant(true);
827 } else if (strcmp(callee, "any") == 0) {
828 assert(op[0]->type->is_boolean());
829 for (unsigned c = 0; c < op[0]->type->components(); c++) {
830 if (op[0]->value.b[c])
831 return new(mem_ctx) ir_constant(true);
832 }
833 return new(mem_ctx) ir_constant(false);
834 } else if (strcmp(callee, "acos") == 0) {
835 assert(op[0]->type->is_float());
836 for (unsigned c = 0; c < op[0]->type->components(); c++)
837 data.f[c] = acosf(op[0]->value.f[c]);
838 } else if (strcmp(callee, "asin") == 0) {
839 assert(op[0]->type->is_float());
840 for (unsigned c = 0; c < op[0]->type->components(); c++)
841 data.f[c] = asinf(op[0]->value.f[c]);
842 } else if (strcmp(callee, "atan") == 0) {
843 assert(op[0]->type->is_float());
844 if (num_parameters == 2) {
845 assert(op[1]->type->is_float());
846 for (unsigned c = 0; c < op[0]->type->components(); c++)
847 data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]);
848 } else {
849 for (unsigned c = 0; c < op[0]->type->components(); c++)
850 data.f[c] = atanf(op[0]->value.f[c]);
851 }
852 } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) {
853 return ir_constant::zero(mem_ctx, this->type);
854 } else if (strcmp(callee, "ceil") == 0) {
855 expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL);
856 } else if (strcmp(callee, "clamp") == 0) {
857 assert(num_parameters == 3);
858 unsigned c1_inc = op[1]->type->is_scalar() ? 0 : 1;
859 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
860 for (unsigned c = 0, c1 = 0, c2 = 0;
861 c < op[0]->type->components();
862 c1 += c1_inc, c2 += c2_inc, c++) {
863
864 switch (op[0]->type->base_type) {
865 case GLSL_TYPE_UINT:
866 data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1],
867 op[2]->value.u[c2]);
868 break;
869 case GLSL_TYPE_INT:
870 data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1],
871 op[2]->value.i[c2]);
872 break;
873 case GLSL_TYPE_FLOAT:
874 data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1],
875 op[2]->value.f[c2]);
876 break;
877 default:
878 assert(!"Should not get here.");
879 }
880 }
881 } else if (strcmp(callee, "cos") == 0) {
882 expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL);
883 } else if (strcmp(callee, "cosh") == 0) {
884 assert(op[0]->type->is_float());
885 for (unsigned c = 0; c < op[0]->type->components(); c++)
886 data.f[c] = coshf(op[0]->value.f[c]);
887 } else if (strcmp(callee, "cross") == 0) {
888 expr = new(mem_ctx) ir_expression(ir_binop_cross, type, op[0], op[1]);
889 } else if (strcmp(callee, "degrees") == 0) {
890 assert(op[0]->type->is_float());
891 for (unsigned c = 0; c < op[0]->type->components(); c++)
892 data.f[c] = 180.0/M_PI * op[0]->value.f[c];
893 } else if (strcmp(callee, "distance") == 0) {
894 assert(op[0]->type->is_float() && op[1]->type->is_float());
895 float length_squared = 0.0;
896 for (unsigned c = 0; c < op[0]->type->components(); c++) {
897 float t = op[0]->value.f[c] - op[1]->value.f[c];
898 length_squared += t * t;
899 }
900 return new(mem_ctx) ir_constant(sqrtf(length_squared));
901 } else if (strcmp(callee, "dot") == 0) {
902 return new(mem_ctx) ir_constant(dot(op[0], op[1]));
903 } else if (strcmp(callee, "equal") == 0) {
904 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
905 for (unsigned c = 0; c < op[0]->type->components(); c++) {
906 switch (op[0]->type->base_type) {
907 case GLSL_TYPE_UINT:
908 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
909 break;
910 case GLSL_TYPE_INT:
911 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
912 break;
913 case GLSL_TYPE_FLOAT:
914 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
915 break;
916 case GLSL_TYPE_BOOL:
917 data.b[c] = op[0]->value.b[c] == op[1]->value.b[c];
918 break;
919 default:
920 assert(!"Should not get here.");
921 }
922 }
923 } else if (strcmp(callee, "exp") == 0) {
924 expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL);
925 } else if (strcmp(callee, "exp2") == 0) {
926 expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL);
927 } else if (strcmp(callee, "faceforward") == 0) {
928 if (dot(op[2], op[1]) < 0)
929 return op[0];
930 for (unsigned c = 0; c < op[0]->type->components(); c++)
931 data.f[c] = -op[0]->value.f[c];
932 } else if (strcmp(callee, "floor") == 0) {
933 expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL);
934 } else if (strcmp(callee, "fract") == 0) {
935 expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL);
936 } else if (strcmp(callee, "fwidth") == 0) {
937 return ir_constant::zero(mem_ctx, this->type);
938 } else if (strcmp(callee, "greaterThan") == 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 default:
952 assert(!"Should not get here.");
953 }
954 }
955 } else if (strcmp(callee, "greaterThanEqual") == 0) {
956 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
957 for (unsigned c = 0; c < op[0]->type->components(); c++) {
958 switch (op[0]->type->base_type) {
959 case GLSL_TYPE_UINT:
960 data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c];
961 break;
962 case GLSL_TYPE_INT:
963 data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c];
964 break;
965 case GLSL_TYPE_FLOAT:
966 data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c];
967 break;
968 default:
969 assert(!"Should not get here.");
970 }
971 }
972 } else if (strcmp(callee, "inversesqrt") == 0) {
973 expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL);
974 } else if (strcmp(callee, "length") == 0) {
975 return new(mem_ctx) ir_constant(sqrtf(dot(op[0], op[0])));
976 } else if (strcmp(callee, "lessThan") == 0) {
977 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
978 for (unsigned c = 0; c < op[0]->type->components(); c++) {
979 switch (op[0]->type->base_type) {
980 case GLSL_TYPE_UINT:
981 data.b[c] = op[0]->value.u[c] < op[1]->value.u[c];
982 break;
983 case GLSL_TYPE_INT:
984 data.b[c] = op[0]->value.i[c] < op[1]->value.i[c];
985 break;
986 case GLSL_TYPE_FLOAT:
987 data.b[c] = op[0]->value.f[c] < op[1]->value.f[c];
988 break;
989 default:
990 assert(!"Should not get here.");
991 }
992 }
993 } else if (strcmp(callee, "lessThanEqual") == 0) {
994 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
995 for (unsigned c = 0; c < op[0]->type->components(); c++) {
996 switch (op[0]->type->base_type) {
997 case GLSL_TYPE_UINT:
998 data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c];
999 break;
1000 case GLSL_TYPE_INT:
1001 data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c];
1002 break;
1003 case GLSL_TYPE_FLOAT:
1004 data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c];
1005 break;
1006 default:
1007 assert(!"Should not get here.");
1008 }
1009 }
1010 } else if (strcmp(callee, "log") == 0) {
1011 expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL);
1012 } else if (strcmp(callee, "log2") == 0) {
1013 expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL);
1014 } else if (strcmp(callee, "matrixCompMult") == 0) {
1015 assert(op[0]->type->is_float() && op[1]->type->is_float());
1016 for (unsigned c = 0; c < op[0]->type->components(); c++)
1017 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
1018 } else if (strcmp(callee, "max") == 0) {
1019 expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]);
1020 } else if (strcmp(callee, "min") == 0) {
1021 expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]);
1022 } else if (strcmp(callee, "mix") == 0) {
1023 assert(op[0]->type->is_float() && op[1]->type->is_float());
1024 if (op[2]->type->is_float()) {
1025 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
1026 unsigned components = op[0]->type->components();
1027 for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) {
1028 data.f[c] = op[0]->value.f[c] * (1 - op[2]->value.f[c2]) +
1029 op[1]->value.f[c] * op[2]->value.f[c2];
1030 }
1031 } else {
1032 assert(op[2]->type->is_boolean());
1033 for (unsigned c = 0; c < op[0]->type->components(); c++)
1034 data.f[c] = op[op[2]->value.b[c] ? 1 : 0]->value.f[c];
1035 }
1036 } else if (strcmp(callee, "mod") == 0) {
1037 expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]);
1038 } else if (strcmp(callee, "normalize") == 0) {
1039 assert(op[0]->type->is_float());
1040 float length = sqrtf(dot(op[0], op[0]));
1041
1042 if (length == 0)
1043 return ir_constant::zero(mem_ctx, this->type);
1044
1045 for (unsigned c = 0; c < op[0]->type->components(); c++)
1046 data.f[c] = op[0]->value.f[c] / length;
1047 } else if (strcmp(callee, "not") == 0) {
1048 expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL);
1049 } else if (strcmp(callee, "notEqual") == 0) {
1050 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1051 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1052 switch (op[0]->type->base_type) {
1053 case GLSL_TYPE_UINT:
1054 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
1055 break;
1056 case GLSL_TYPE_INT:
1057 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
1058 break;
1059 case GLSL_TYPE_FLOAT:
1060 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
1061 break;
1062 case GLSL_TYPE_BOOL:
1063 data.b[c] = op[0]->value.b[c] != op[1]->value.b[c];
1064 break;
1065 default:
1066 assert(!"Should not get here.");
1067 }
1068 }
1069 } else if (strcmp(callee, "outerProduct") == 0) {
1070 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
1071 const unsigned m = op[0]->type->vector_elements;
1072 const unsigned n = op[1]->type->vector_elements;
1073 for (unsigned j = 0; j < n; j++) {
1074 for (unsigned i = 0; i < m; i++) {
1075 data.f[i+m*j] = op[0]->value.f[i] * op[1]->value.f[j];
1076 }
1077 }
1078 } else if (strcmp(callee, "pow") == 0) {
1079 expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]);
1080 } else if (strcmp(callee, "radians") == 0) {
1081 assert(op[0]->type->is_float());
1082 for (unsigned c = 0; c < op[0]->type->components(); c++)
1083 data.f[c] = M_PI/180.0 * op[0]->value.f[c];
1084 } else if (strcmp(callee, "reflect") == 0) {
1085 assert(op[0]->type->is_float());
1086 float dot_NI = dot(op[1], op[0]);
1087 for (unsigned c = 0; c < op[0]->type->components(); c++)
1088 data.f[c] = op[0]->value.f[c] - 2 * dot_NI * op[1]->value.f[c];
1089 } else if (strcmp(callee, "refract") == 0) {
1090 const float eta = op[2]->value.f[0];
1091 const float dot_NI = dot(op[1], op[0]);
1092 const float k = 1.0 - eta * eta * (1.0 - dot_NI * dot_NI);
1093 if (k < 0.0) {
1094 return ir_constant::zero(mem_ctx, this->type);
1095 } else {
1096 for (unsigned c = 0; c < type->components(); c++) {
1097 data.f[c] = eta * op[0]->value.f[c] - (eta * dot_NI + sqrtf(k))
1098 * op[1]->value.f[c];
1099 }
1100 }
1101 } else if (strcmp(callee, "sign") == 0) {
1102 expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
1103 } else if (strcmp(callee, "sin") == 0) {
1104 expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL);
1105 } else if (strcmp(callee, "sinh") == 0) {
1106 assert(op[0]->type->is_float());
1107 for (unsigned c = 0; c < op[0]->type->components(); c++)
1108 data.f[c] = sinhf(op[0]->value.f[c]);
1109 } else if (strcmp(callee, "smoothstep") == 0) {
1110 assert(num_parameters == 3);
1111 assert(op[1]->type == op[0]->type);
1112 unsigned edge_inc = op[0]->type->is_scalar() ? 0 : 1;
1113 for (unsigned c = 0, e = 0; c < type->components(); e += edge_inc, c++) {
1114 const float edge0 = op[0]->value.f[e];
1115 const float edge1 = op[1]->value.f[e];
1116 if (edge0 == edge1) {
1117 data.f[c] = 0.0; /* Avoid a crash - results are undefined anyway */
1118 } else {
1119 const float numerator = op[2]->value.f[c] - edge0;
1120 const float denominator = edge1 - edge0;
1121 const float t = CLAMP(numerator/denominator, 0, 1);
1122 data.f[c] = t * t * (3 - 2 * t);
1123 }
1124 }
1125 } else if (strcmp(callee, "sqrt") == 0) {
1126 expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL);
1127 } else if (strcmp(callee, "step") == 0) {
1128 assert(op[0]->type->is_float() && op[1]->type->is_float());
1129 /* op[0] (edge) may be either a scalar or a vector */
1130 const unsigned c0_inc = op[0]->type->is_scalar() ? 0 : 1;
1131 for (unsigned c = 0, c0 = 0; c < type->components(); c0 += c0_inc, c++)
1132 data.f[c] = (op[1]->value.f[c] < op[0]->value.f[c0]) ? 0.0 : 1.0;
1133 } else if (strcmp(callee, "tan") == 0) {
1134 assert(op[0]->type->is_float());
1135 for (unsigned c = 0; c < op[0]->type->components(); c++)
1136 data.f[c] = tanf(op[0]->value.f[c]);
1137 } else if (strcmp(callee, "tanh") == 0) {
1138 assert(op[0]->type->is_float());
1139 for (unsigned c = 0; c < op[0]->type->components(); c++)
1140 data.f[c] = tanhf(op[0]->value.f[c]);
1141 } else if (strcmp(callee, "transpose") == 0) {
1142 assert(op[0]->type->is_matrix());
1143 const unsigned n = op[0]->type->vector_elements;
1144 const unsigned m = op[0]->type->matrix_columns;
1145 for (unsigned j = 0; j < m; j++) {
1146 for (unsigned i = 0; i < n; i++) {
1147 data.f[m*i+j] += op[0]->value.f[i+n*j];
1148 }
1149 }
1150 } else {
1151 /* Unsupported builtin - some are not allowed in constant expressions. */
1152 return NULL;
1153 }
1154
1155 if (expr != NULL)
1156 return expr->constant_expression_value();
1157
1158 return new(mem_ctx) ir_constant(this->type, &data);
1159 }