cce13139b77361a72db9f49c250c69f2016a465a
[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/macros.h"
38 #include "ir.h"
39 #include "ir_visitor.h"
40 #include "glsl_types.h"
41
42 ir_constant *
43 ir_expression::constant_expression_value()
44 {
45 ir_constant *op[2] = { NULL, NULL };
46 ir_constant_data data;
47
48 memset(&data, 0, sizeof(data));
49
50 for (unsigned operand = 0; operand < this->get_num_operands(); operand++) {
51 op[operand] = this->operands[operand]->constant_expression_value();
52 if (!op[operand])
53 return NULL;
54 }
55
56 if (op[1] != NULL)
57 assert(op[0]->type->base_type == op[1]->type->base_type);
58
59 bool op0_scalar = op[0]->type->is_scalar();
60 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
61
62 /* When iterating over a vector or matrix's components, we want to increase
63 * the loop counter. However, for scalars, we want to stay at 0.
64 */
65 unsigned c0_inc = op0_scalar ? 0 : 1;
66 unsigned c1_inc = op1_scalar ? 0 : 1;
67 unsigned components;
68 if (op1_scalar || !op[1]) {
69 components = op[0]->type->components();
70 } else {
71 components = op[1]->type->components();
72 }
73
74 void *ctx = talloc_parent(this);
75
76 /* Handle array operations here, rather than below. */
77 if (op[0]->type->is_array()) {
78 assert(op[1] != NULL && op[1]->type->is_array());
79 switch (this->operation) {
80 case ir_binop_equal:
81 return new(ctx) ir_constant(op[0]->has_value(op[1]));
82 case ir_binop_nequal:
83 return new(ctx) ir_constant(!op[0]->has_value(op[1]));
84 default:
85 break;
86 }
87 return NULL;
88 }
89
90 switch (this->operation) {
91 case ir_unop_logic_not:
92 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
93 for (unsigned c = 0; c < op[0]->type->components(); c++)
94 data.b[c] = !op[0]->value.b[c];
95 break;
96
97 case ir_unop_f2i:
98 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
99 for (unsigned c = 0; c < op[0]->type->components(); c++) {
100 data.i[c] = op[0]->value.f[c];
101 }
102 break;
103 case ir_unop_i2f:
104 assert(op[0]->type->base_type == GLSL_TYPE_INT);
105 for (unsigned c = 0; c < op[0]->type->components(); c++) {
106 data.f[c] = op[0]->value.i[c];
107 }
108 break;
109 case ir_unop_u2f:
110 assert(op[0]->type->base_type == GLSL_TYPE_UINT);
111 for (unsigned c = 0; c < op[0]->type->components(); c++) {
112 data.f[c] = op[0]->value.u[c];
113 }
114 break;
115 case ir_unop_b2f:
116 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
117 for (unsigned c = 0; c < op[0]->type->components(); c++) {
118 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
119 }
120 break;
121 case ir_unop_f2b:
122 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
123 for (unsigned c = 0; c < op[0]->type->components(); c++) {
124 data.b[c] = bool(op[0]->value.f[c]);
125 }
126 break;
127 case ir_unop_b2i:
128 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
129 for (unsigned c = 0; c < op[0]->type->components(); c++) {
130 data.u[c] = op[0]->value.b[c] ? 1 : 0;
131 }
132 break;
133 case ir_unop_i2b:
134 assert(op[0]->type->is_integer());
135 for (unsigned c = 0; c < op[0]->type->components(); c++) {
136 data.b[c] = bool(op[0]->value.u[c]);
137 }
138 break;
139
140 case ir_unop_trunc:
141 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
142 for (unsigned c = 0; c < op[0]->type->components(); c++) {
143 data.f[c] = truncf(op[0]->value.f[c]);
144 }
145 break;
146
147 case ir_unop_ceil:
148 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
149 for (unsigned c = 0; c < op[0]->type->components(); c++) {
150 data.f[c] = ceilf(op[0]->value.f[c]);
151 }
152 break;
153
154 case ir_unop_floor:
155 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
156 for (unsigned c = 0; c < op[0]->type->components(); c++) {
157 data.f[c] = floorf(op[0]->value.f[c]);
158 }
159 break;
160
161 case ir_unop_fract:
162 for (unsigned c = 0; c < op[0]->type->components(); c++) {
163 switch (this->type->base_type) {
164 case GLSL_TYPE_UINT:
165 data.u[c] = 0;
166 break;
167 case GLSL_TYPE_INT:
168 data.i[c] = 0;
169 break;
170 case GLSL_TYPE_FLOAT:
171 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
172 break;
173 default:
174 assert(0);
175 }
176 }
177 break;
178
179 case ir_unop_sin:
180 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
181 for (unsigned c = 0; c < op[0]->type->components(); c++) {
182 data.f[c] = sinf(op[0]->value.f[c]);
183 }
184 break;
185
186 case ir_unop_cos:
187 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
188 for (unsigned c = 0; c < op[0]->type->components(); c++) {
189 data.f[c] = cosf(op[0]->value.f[c]);
190 }
191 break;
192
193 case ir_unop_neg:
194 for (unsigned c = 0; c < op[0]->type->components(); c++) {
195 switch (this->type->base_type) {
196 case GLSL_TYPE_UINT:
197 data.u[c] = -op[0]->value.u[c];
198 break;
199 case GLSL_TYPE_INT:
200 data.i[c] = -op[0]->value.i[c];
201 break;
202 case GLSL_TYPE_FLOAT:
203 data.f[c] = -op[0]->value.f[c];
204 break;
205 default:
206 assert(0);
207 }
208 }
209 break;
210
211 case ir_unop_abs:
212 for (unsigned c = 0; c < op[0]->type->components(); c++) {
213 switch (this->type->base_type) {
214 case GLSL_TYPE_UINT:
215 data.u[c] = op[0]->value.u[c];
216 break;
217 case GLSL_TYPE_INT:
218 data.i[c] = op[0]->value.i[c];
219 if (data.i[c] < 0)
220 data.i[c] = -data.i[c];
221 break;
222 case GLSL_TYPE_FLOAT:
223 data.f[c] = fabs(op[0]->value.f[c]);
224 break;
225 default:
226 assert(0);
227 }
228 }
229 break;
230
231 case ir_unop_sign:
232 for (unsigned c = 0; c < op[0]->type->components(); c++) {
233 switch (this->type->base_type) {
234 case GLSL_TYPE_UINT:
235 data.u[c] = op[0]->value.i[c] > 0;
236 break;
237 case GLSL_TYPE_INT:
238 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
239 break;
240 case GLSL_TYPE_FLOAT:
241 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
242 break;
243 default:
244 assert(0);
245 }
246 }
247 break;
248
249 case ir_unop_rcp:
250 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
251 for (unsigned c = 0; c < op[0]->type->components(); c++) {
252 switch (this->type->base_type) {
253 case GLSL_TYPE_UINT:
254 if (op[0]->value.u[c] != 0.0)
255 data.u[c] = 1 / op[0]->value.u[c];
256 break;
257 case GLSL_TYPE_INT:
258 if (op[0]->value.i[c] != 0.0)
259 data.i[c] = 1 / op[0]->value.i[c];
260 break;
261 case GLSL_TYPE_FLOAT:
262 if (op[0]->value.f[c] != 0.0)
263 data.f[c] = 1.0 / op[0]->value.f[c];
264 break;
265 default:
266 assert(0);
267 }
268 }
269 break;
270
271 case ir_unop_rsq:
272 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
273 for (unsigned c = 0; c < op[0]->type->components(); c++) {
274 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
275 }
276 break;
277
278 case ir_unop_sqrt:
279 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
280 for (unsigned c = 0; c < op[0]->type->components(); c++) {
281 data.f[c] = sqrtf(op[0]->value.f[c]);
282 }
283 break;
284
285 case ir_unop_exp:
286 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
287 for (unsigned c = 0; c < op[0]->type->components(); c++) {
288 data.f[c] = expf(op[0]->value.f[c]);
289 }
290 break;
291
292 case ir_unop_exp2:
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] = exp2f(op[0]->value.f[c]);
296 }
297 break;
298
299 case ir_unop_log:
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] = logf(op[0]->value.f[c]);
303 }
304 break;
305
306 case ir_unop_log2:
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] = log2f(op[0]->value.f[c]);
310 }
311 break;
312
313 case ir_unop_dFdx:
314 case ir_unop_dFdy:
315 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
316 for (unsigned c = 0; c < op[0]->type->components(); c++) {
317 data.f[c] = 0.0;
318 }
319 break;
320
321 case ir_binop_pow:
322 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
323 for (unsigned c = 0; c < op[0]->type->components(); c++) {
324 data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]);
325 }
326 break;
327
328 case ir_binop_dot:
329 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
330 data.f[0] = 0;
331 for (unsigned c = 0; c < op[0]->type->components(); c++) {
332 switch (op[0]->type->base_type) {
333 case GLSL_TYPE_UINT:
334 data.u[0] += op[0]->value.u[c] * op[1]->value.u[c];
335 break;
336 case GLSL_TYPE_INT:
337 data.i[0] += op[0]->value.i[c] * op[1]->value.i[c];
338 break;
339 case GLSL_TYPE_FLOAT:
340 data.f[0] += op[0]->value.f[c] * op[1]->value.f[c];
341 break;
342 default:
343 assert(0);
344 }
345 }
346
347 break;
348 case ir_binop_min:
349 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
350 for (unsigned c = 0, c0 = 0, c1 = 0;
351 c < components;
352 c0 += c0_inc, c1 += c1_inc, c++) {
353
354 switch (op[0]->type->base_type) {
355 case GLSL_TYPE_UINT:
356 data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]);
357 break;
358 case GLSL_TYPE_INT:
359 data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]);
360 break;
361 case GLSL_TYPE_FLOAT:
362 data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]);
363 break;
364 default:
365 assert(0);
366 }
367 }
368
369 break;
370 case ir_binop_max:
371 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
372 for (unsigned c = 0, c0 = 0, c1 = 0;
373 c < components;
374 c0 += c0_inc, c1 += c1_inc, c++) {
375
376 switch (op[0]->type->base_type) {
377 case GLSL_TYPE_UINT:
378 data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]);
379 break;
380 case GLSL_TYPE_INT:
381 data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]);
382 break;
383 case GLSL_TYPE_FLOAT:
384 data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]);
385 break;
386 default:
387 assert(0);
388 }
389 }
390 break;
391
392 case ir_binop_cross:
393 assert(op[0]->type == glsl_type::vec3_type);
394 assert(op[1]->type == glsl_type::vec3_type);
395 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
396 op[1]->value.f[1] * op[0]->value.f[2]);
397 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
398 op[1]->value.f[2] * op[0]->value.f[0]);
399 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
400 op[1]->value.f[0] * op[0]->value.f[1]);
401 break;
402
403 case ir_binop_add:
404 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
405 for (unsigned c = 0, c0 = 0, c1 = 0;
406 c < components;
407 c0 += c0_inc, c1 += c1_inc, c++) {
408
409 switch (op[0]->type->base_type) {
410 case GLSL_TYPE_UINT:
411 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
412 break;
413 case GLSL_TYPE_INT:
414 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
415 break;
416 case GLSL_TYPE_FLOAT:
417 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
418 break;
419 default:
420 assert(0);
421 }
422 }
423
424 break;
425 case ir_binop_sub:
426 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
427 for (unsigned c = 0, c0 = 0, c1 = 0;
428 c < components;
429 c0 += c0_inc, c1 += c1_inc, c++) {
430
431 switch (op[0]->type->base_type) {
432 case GLSL_TYPE_UINT:
433 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
434 break;
435 case GLSL_TYPE_INT:
436 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
437 break;
438 case GLSL_TYPE_FLOAT:
439 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
440 break;
441 default:
442 assert(0);
443 }
444 }
445
446 break;
447 case ir_binop_mul:
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;
452 c < components;
453 c0 += c0_inc, c1 += c1_inc, c++) {
454
455 switch (op[0]->type->base_type) {
456 case GLSL_TYPE_UINT:
457 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
458 break;
459 case GLSL_TYPE_INT:
460 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
461 break;
462 case GLSL_TYPE_FLOAT:
463 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
464 break;
465 default:
466 assert(0);
467 }
468 }
469 } else {
470 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
471
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.
474 *
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.
477 *
478 * For mat*vec, the vector is treated as a column vector. Since
479 * matrix_columns is 1 for vectors, this just works.
480 */
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];
489 }
490 }
491 }
492 }
493
494 break;
495 case ir_binop_div:
496 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
497 for (unsigned c = 0, c0 = 0, c1 = 0;
498 c < components;
499 c0 += c0_inc, c1 += c1_inc, c++) {
500
501 switch (op[0]->type->base_type) {
502 case GLSL_TYPE_UINT:
503 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
504 break;
505 case GLSL_TYPE_INT:
506 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
507 break;
508 case GLSL_TYPE_FLOAT:
509 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
510 break;
511 default:
512 assert(0);
513 }
514 }
515
516 break;
517 case ir_binop_mod:
518 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
519 for (unsigned c = 0, c0 = 0, c1 = 0;
520 c < components;
521 c0 += c0_inc, c1 += c1_inc, c++) {
522
523 switch (op[0]->type->base_type) {
524 case GLSL_TYPE_UINT:
525 data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
526 break;
527 case GLSL_TYPE_INT:
528 data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
529 break;
530 case GLSL_TYPE_FLOAT:
531 /* We don't use fmod because it rounds toward zero; GLSL specifies
532 * the use of floor.
533 */
534 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]
535 * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
536 break;
537 default:
538 assert(0);
539 }
540 }
541
542 break;
543
544 case ir_binop_logic_and:
545 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
546 for (unsigned c = 0; c < op[0]->type->components(); c++)
547 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
548 break;
549 case ir_binop_logic_xor:
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_or:
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
560 case ir_binop_less:
561 switch (op[0]->type->base_type) {
562 case GLSL_TYPE_UINT:
563 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
564 break;
565 case GLSL_TYPE_INT:
566 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
567 break;
568 case GLSL_TYPE_FLOAT:
569 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
570 break;
571 default:
572 assert(0);
573 }
574 break;
575 case ir_binop_greater:
576 switch (op[0]->type->base_type) {
577 case GLSL_TYPE_UINT:
578 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
579 break;
580 case GLSL_TYPE_INT:
581 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
582 break;
583 case GLSL_TYPE_FLOAT:
584 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
585 break;
586 default:
587 assert(0);
588 }
589 break;
590 case ir_binop_lequal:
591 switch (op[0]->type->base_type) {
592 case GLSL_TYPE_UINT:
593 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
594 break;
595 case GLSL_TYPE_INT:
596 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
597 break;
598 case GLSL_TYPE_FLOAT:
599 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
600 break;
601 default:
602 assert(0);
603 }
604 break;
605 case ir_binop_gequal:
606 switch (op[0]->type->base_type) {
607 case GLSL_TYPE_UINT:
608 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
609 break;
610 case GLSL_TYPE_INT:
611 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
612 break;
613 case GLSL_TYPE_FLOAT:
614 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
615 break;
616 default:
617 assert(0);
618 }
619 break;
620
621 case ir_binop_equal:
622 data.b[0] = op[0]->has_value(op[1]);
623 break;
624 case ir_binop_nequal:
625 data.b[0] = !op[0]->has_value(op[1]);
626 break;
627
628 default:
629 /* FINISHME: Should handle all expression types. */
630 return NULL;
631 }
632
633 return new(ctx) ir_constant(this->type, &data);
634 }
635
636
637 ir_constant *
638 ir_texture::constant_expression_value()
639 {
640 /* texture lookups aren't constant expressions */
641 return NULL;
642 }
643
644
645 ir_constant *
646 ir_swizzle::constant_expression_value()
647 {
648 ir_constant *v = this->val->constant_expression_value();
649
650 if (v != NULL) {
651 ir_constant_data data;
652
653 const unsigned swiz_idx[4] = {
654 this->mask.x, this->mask.y, this->mask.z, this->mask.w
655 };
656
657 for (unsigned i = 0; i < this->mask.num_components; i++) {
658 switch (v->type->base_type) {
659 case GLSL_TYPE_UINT:
660 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
661 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
662 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
663 default: assert(!"Should not get here."); break;
664 }
665 }
666
667 void *ctx = talloc_parent(this);
668 return new(ctx) ir_constant(this->type, &data);
669 }
670 return NULL;
671 }
672
673
674 ir_constant *
675 ir_dereference_variable::constant_expression_value()
676 {
677 /* This may occur during compile and var->type is glsl_type::error_type */
678 if (!var)
679 return NULL;
680
681 return var->constant_value ? var->constant_value->clone(NULL) : NULL;
682 }
683
684
685 ir_constant *
686 ir_dereference_array::constant_expression_value()
687 {
688 void *ctx = talloc_parent(this);
689 ir_constant *array = this->array->constant_expression_value();
690 ir_constant *idx = this->array_index->constant_expression_value();
691
692 if ((array != NULL) && (idx != NULL)) {
693 if (array->type->is_matrix()) {
694 /* Array access of a matrix results in a vector.
695 */
696 const unsigned column = idx->value.u[0];
697
698 const glsl_type *const column_type = array->type->column_type();
699
700 /* Offset in the constant matrix to the first element of the column
701 * to be extracted.
702 */
703 const unsigned mat_idx = column * column_type->vector_elements;
704
705 ir_constant_data data;
706
707 switch (column_type->base_type) {
708 case GLSL_TYPE_UINT:
709 case GLSL_TYPE_INT:
710 for (unsigned i = 0; i < column_type->vector_elements; i++)
711 data.u[i] = array->value.u[mat_idx + i];
712
713 break;
714
715 case GLSL_TYPE_FLOAT:
716 for (unsigned i = 0; i < column_type->vector_elements; i++)
717 data.f[i] = array->value.f[mat_idx + i];
718
719 break;
720
721 default:
722 assert(!"Should not get here.");
723 break;
724 }
725
726 return new(ctx) ir_constant(column_type, &data);
727 } else if (array->type->is_vector()) {
728 const unsigned component = idx->value.u[0];
729
730 return new(ctx) ir_constant(array, component);
731 } else {
732 const unsigned index = idx->value.u[0];
733 return array->get_array_element(index)->clone(NULL);
734 }
735 }
736 return NULL;
737 }
738
739
740 ir_constant *
741 ir_dereference_record::constant_expression_value()
742 {
743 ir_constant *v = this->record->constant_expression_value();
744
745 return (v != NULL) ? v->get_record_field(this->field) : NULL;
746 }
747
748
749 ir_constant *
750 ir_assignment::constant_expression_value()
751 {
752 /* FINISHME: Handle CEs involving assignment (return RHS) */
753 return NULL;
754 }
755
756
757 ir_constant *
758 ir_constant::constant_expression_value()
759 {
760 return this;
761 }
762
763
764 ir_constant *
765 ir_call::constant_expression_value()
766 {
767 if (this->type == glsl_type::error_type)
768 return NULL;
769
770 /* From the GLSL 1.20 spec, page 23:
771 * "Function calls to user-defined functions (non-built-in functions)
772 * cannot be used to form constant expressions."
773 */
774 if (!this->callee->is_built_in)
775 return NULL;
776
777 unsigned num_parameters = 0;
778
779 /* Check if all parameters are constant */
780 ir_constant *op[3];
781 foreach_list(n, &this->actual_parameters) {
782 ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value();
783 if (constant == NULL)
784 return NULL;
785
786 op[num_parameters] = constant;
787
788 assert(num_parameters < 3);
789 num_parameters++;
790 }
791
792 /* Individual cases below can either:
793 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
794 * - Fill "data" with appopriate constant data
795 * - Return an ir_constant directly.
796 */
797 void *mem_ctx = talloc_parent(this);
798 ir_expression *expr = NULL;
799
800 ir_constant_data data;
801 memset(&data, 0, sizeof(data));
802
803 const char *callee = this->callee_name();
804 if (strcmp(callee, "abs") == 0) {
805 expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL);
806 } else if (strcmp(callee, "all") == 0) {
807 assert(op[0]->type->is_boolean());
808 for (unsigned c = 0; c < op[0]->type->components(); c++) {
809 if (!op[0]->value.b[c])
810 return new(mem_ctx) ir_constant(false);
811 }
812 return new(mem_ctx) ir_constant(true);
813 } else if (strcmp(callee, "any") == 0) {
814 assert(op[0]->type->is_boolean());
815 for (unsigned c = 0; c < op[0]->type->components(); c++) {
816 if (op[0]->value.b[c])
817 return new(mem_ctx) ir_constant(true);
818 }
819 return new(mem_ctx) ir_constant(false);
820 } else if (strcmp(callee, "acos") == 0) {
821 assert(op[0]->type->is_float());
822 for (unsigned c = 0; c < op[0]->type->components(); c++)
823 data.f[c] = acosf(op[0]->value.f[c]);
824 } else if (strcmp(callee, "asin") == 0) {
825 assert(op[0]->type->is_float());
826 for (unsigned c = 0; c < op[0]->type->components(); c++)
827 data.f[c] = asinf(op[0]->value.f[c]);
828 } else if (strcmp(callee, "atan") == 0) {
829 assert(op[0]->type->is_float());
830 if (num_parameters == 2) {
831 assert(op[1]->type->is_float());
832 for (unsigned c = 0; c < op[0]->type->components(); c++)
833 data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]);
834 } else {
835 for (unsigned c = 0; c < op[0]->type->components(); c++)
836 data.f[c] = atanf(op[0]->value.f[c]);
837 }
838 } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) {
839 return ir_constant::zero(mem_ctx, this->type);
840 } else if (strcmp(callee, "ceil") == 0) {
841 expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL);
842 } else if (strcmp(callee, "clamp") == 0) {
843 return NULL; /* FINISHME: implement this */
844 } else if (strcmp(callee, "cos") == 0) {
845 expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL);
846 } else if (strcmp(callee, "cosh") == 0) {
847 assert(op[0]->type->is_float());
848 for (unsigned c = 0; c < op[0]->type->components(); c++)
849 data.f[c] = coshf(op[0]->value.f[c]);
850 } else if (strcmp(callee, "cross") == 0) {
851 expr = new(mem_ctx) ir_expression(ir_binop_cross, type, op[0], op[1]);
852 } else if (strcmp(callee, "degrees") == 0) {
853 assert(op[0]->type->is_float());
854 for (unsigned c = 0; c < op[0]->type->components(); c++)
855 data.f[c] = 180.0/M_PI * op[0]->value.f[c];
856 } else if (strcmp(callee, "distance") == 0) {
857 assert(op[0]->type->is_float() && op[1]->type->is_float());
858 float length_squared = 0.0;
859 for (unsigned c = 0; c < op[0]->type->components(); c++) {
860 float t = op[0]->value.f[c] - op[1]->value.f[c];
861 length_squared += t * t;
862 }
863 return new(mem_ctx) ir_constant(sqrtf(length_squared));
864 } else if (strcmp(callee, "dot") == 0) {
865 expr = new(mem_ctx) ir_expression(ir_binop_dot, type, op[0], op[1]);
866 } else if (strcmp(callee, "equal") == 0) {
867 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
868 for (unsigned c = 0; c < op[0]->type->components(); c++) {
869 switch (op[0]->type->base_type) {
870 case GLSL_TYPE_UINT:
871 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
872 break;
873 case GLSL_TYPE_INT:
874 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
875 break;
876 case GLSL_TYPE_FLOAT:
877 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
878 break;
879 default:
880 assert(!"Should not get here.");
881 }
882 }
883 } else if (strcmp(callee, "exp") == 0) {
884 expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL);
885 } else if (strcmp(callee, "exp2") == 0) {
886 expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL);
887 } else if (strcmp(callee, "faceforward") == 0) {
888 return NULL; /* FINISHME: implement this */
889 } else if (strcmp(callee, "floor") == 0) {
890 expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL);
891 } else if (strcmp(callee, "fract") == 0) {
892 expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL);
893 } else if (strcmp(callee, "fwidth") == 0) {
894 return ir_constant::zero(mem_ctx, this->type);
895 } else if (strcmp(callee, "greaterThan") == 0) {
896 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
897 for (unsigned c = 0; c < op[0]->type->components(); c++) {
898 switch (op[0]->type->base_type) {
899 case GLSL_TYPE_UINT:
900 data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
901 break;
902 case GLSL_TYPE_INT:
903 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
904 break;
905 case GLSL_TYPE_FLOAT:
906 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
907 break;
908 default:
909 assert(!"Should not get here.");
910 }
911 }
912 } else if (strcmp(callee, "greaterThanEqual") == 0) {
913 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
914 for (unsigned c = 0; c < op[0]->type->components(); c++) {
915 switch (op[0]->type->base_type) {
916 case GLSL_TYPE_UINT:
917 data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c];
918 break;
919 case GLSL_TYPE_INT:
920 data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c];
921 break;
922 case GLSL_TYPE_FLOAT:
923 data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c];
924 break;
925 default:
926 assert(!"Should not get here.");
927 }
928 }
929 } else if (strcmp(callee, "inversesqrt") == 0) {
930 expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL);
931 } else if (strcmp(callee, "length") == 0) {
932 return NULL; /* FINISHME: implement this */
933 } else if (strcmp(callee, "lessThan") == 0) {
934 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
935 for (unsigned c = 0; c < op[0]->type->components(); c++) {
936 switch (op[0]->type->base_type) {
937 case GLSL_TYPE_UINT:
938 data.b[c] = op[0]->value.u[c] < op[1]->value.u[c];
939 break;
940 case GLSL_TYPE_INT:
941 data.b[c] = op[0]->value.i[c] < op[1]->value.i[c];
942 break;
943 case GLSL_TYPE_FLOAT:
944 data.b[c] = op[0]->value.f[c] < op[1]->value.f[c];
945 break;
946 default:
947 assert(!"Should not get here.");
948 }
949 }
950 } else if (strcmp(callee, "lessThanEqual") == 0) {
951 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
952 for (unsigned c = 0; c < op[0]->type->components(); c++) {
953 switch (op[0]->type->base_type) {
954 case GLSL_TYPE_UINT:
955 data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c];
956 break;
957 case GLSL_TYPE_INT:
958 data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c];
959 break;
960 case GLSL_TYPE_FLOAT:
961 data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c];
962 break;
963 default:
964 assert(!"Should not get here.");
965 }
966 }
967 } else if (strcmp(callee, "log") == 0) {
968 expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL);
969 } else if (strcmp(callee, "log2") == 0) {
970 expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL);
971 } else if (strcmp(callee, "matrixCompMult") == 0) {
972 return NULL; /* FINISHME: implement this */
973 } else if (strcmp(callee, "max") == 0) {
974 expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]);
975 } else if (strcmp(callee, "min") == 0) {
976 expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]);
977 } else if (strcmp(callee, "mix") == 0) {
978 return NULL; /* FINISHME: implement this */
979 } else if (strcmp(callee, "mod") == 0) {
980 expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]);
981 } else if (strcmp(callee, "normalize") == 0) {
982 return NULL; /* FINISHME: implement this */
983 } else if (strcmp(callee, "not") == 0) {
984 expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL);
985 } else if (strcmp(callee, "notEqual") == 0) {
986 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
987 for (unsigned c = 0; c < op[0]->type->components(); c++) {
988 switch (op[0]->type->base_type) {
989 case GLSL_TYPE_UINT:
990 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
991 break;
992 case GLSL_TYPE_INT:
993 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
994 break;
995 case GLSL_TYPE_FLOAT:
996 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
997 break;
998 default:
999 assert(!"Should not get here.");
1000 }
1001 }
1002 } else if (strcmp(callee, "outerProduct") == 0) {
1003 return NULL; /* FINISHME: implement this */
1004 } else if (strcmp(callee, "pow") == 0) {
1005 expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]);
1006 } else if (strcmp(callee, "radians") == 0) {
1007 assert(op[0]->type->is_float());
1008 for (unsigned c = 0; c < op[0]->type->components(); c++)
1009 data.f[c] = M_PI/180.0 * op[0]->value.f[c];
1010 } else if (strcmp(callee, "reflect") == 0) {
1011 return NULL; /* FINISHME: implement this */
1012 } else if (strcmp(callee, "refract") == 0) {
1013 return NULL; /* FINISHME: implement this */
1014 } else if (strcmp(callee, "sign") == 0) {
1015 expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
1016 } else if (strcmp(callee, "sin") == 0) {
1017 expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL);
1018 } else if (strcmp(callee, "sinh") == 0) {
1019 assert(op[0]->type->is_float());
1020 for (unsigned c = 0; c < op[0]->type->components(); c++)
1021 data.f[c] = sinhf(op[0]->value.f[c]);
1022 } else if (strcmp(callee, "smoothstep") == 0) {
1023 return NULL; /* FINISHME: implement this */
1024 } else if (strcmp(callee, "sqrt") == 0) {
1025 expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL);
1026 } else if (strcmp(callee, "step") == 0) {
1027 return NULL; /* FINISHME: implement this */
1028 } else if (strcmp(callee, "tan") == 0) {
1029 assert(op[0]->type->is_float());
1030 for (unsigned c = 0; c < op[0]->type->components(); c++)
1031 data.f[c] = tanf(op[0]->value.f[c]);
1032 } else if (strcmp(callee, "tanh") == 0) {
1033 assert(op[0]->type->is_float());
1034 for (unsigned c = 0; c < op[0]->type->components(); c++)
1035 data.f[c] = tanhf(op[0]->value.f[c]);
1036 } else if (strcmp(callee, "transpose") == 0) {
1037 return NULL; /* FINISHME: implement this */
1038 } else {
1039 /* Unsupported builtin - some are not allowed in constant expressions. */
1040 return NULL;
1041 }
1042
1043 if (expr != NULL)
1044 return expr->constant_expression_value();
1045
1046 return new(mem_ctx) ir_constant(this->type, &data);
1047 }