2fab03bb60efd37708cf3f3a08f8ea5a24f63cf4
[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 "ir.h"
38 #include "ir_visitor.h"
39 #include "glsl_types.h"
40
41 /**
42 * Visitor class for evaluating constant expressions
43 */
44 class ir_constant_visitor : public ir_visitor {
45 public:
46 ir_constant_visitor()
47 : value(NULL)
48 {
49 /* empty */
50 }
51
52 virtual ~ir_constant_visitor()
53 {
54 /* empty */
55 }
56
57 /**
58 * \name Visit methods
59 *
60 * As typical for the visitor pattern, there must be one \c visit method for
61 * each concrete subclass of \c ir_instruction. Virtual base classes within
62 * the hierarchy should not have \c visit methods.
63 */
64 /*@{*/
65 virtual void visit(ir_variable *);
66 virtual void visit(ir_function_signature *);
67 virtual void visit(ir_function *);
68 virtual void visit(ir_expression *);
69 virtual void visit(ir_texture *);
70 virtual void visit(ir_swizzle *);
71 virtual void visit(ir_dereference_variable *);
72 virtual void visit(ir_dereference_array *);
73 virtual void visit(ir_dereference_record *);
74 virtual void visit(ir_assignment *);
75 virtual void visit(ir_constant *);
76 virtual void visit(ir_call *);
77 virtual void visit(ir_return *);
78 virtual void visit(ir_discard *);
79 virtual void visit(ir_if *);
80 virtual void visit(ir_loop *);
81 virtual void visit(ir_loop_jump *);
82 /*@}*/
83
84 /**
85 * Value of the constant expression.
86 *
87 * \note
88 * This field will be \c NULL if the expression is not constant valued.
89 */
90 /* FINIHSME: This cannot hold values for constant arrays or structures. */
91 ir_constant *value;
92 };
93
94
95 ir_constant *
96 ir_instruction::constant_expression_value()
97 {
98 ir_constant_visitor visitor;
99
100 this->accept(& visitor);
101 return visitor.value;
102 }
103
104
105 void
106 ir_constant_visitor::visit(ir_variable *ir)
107 {
108 (void) ir;
109 value = NULL;
110 }
111
112
113 void
114 ir_constant_visitor::visit(ir_function_signature *ir)
115 {
116 (void) ir;
117 value = NULL;
118 }
119
120
121 void
122 ir_constant_visitor::visit(ir_function *ir)
123 {
124 (void) ir;
125 value = NULL;
126 }
127
128 void
129 ir_constant_visitor::visit(ir_expression *ir)
130 {
131 value = NULL;
132 ir_constant *op[2] = { NULL, NULL };
133 unsigned int operand, c;
134 ir_constant_data data;
135
136 memset(&data, 0, sizeof(data));
137
138 for (operand = 0; operand < ir->get_num_operands(); operand++) {
139 op[operand] = ir->operands[operand]->constant_expression_value();
140 if (!op[operand])
141 return;
142 }
143
144 if (op[1] != NULL)
145 assert(op[0]->type->base_type == op[1]->type->base_type);
146
147 bool op0_scalar = op[0]->type->is_scalar();
148 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
149
150 /* When iterating over a vector or matrix's components, we want to increase
151 * the loop counter. However, for scalars, we want to stay at 0.
152 */
153 unsigned c0_inc = op0_scalar ? 1 : 0;
154 unsigned c1_inc = op1_scalar ? 1 : 0;
155 unsigned components = op[op1_scalar ? 0 : 1]->type->components();
156
157 switch (ir->operation) {
158 case ir_unop_logic_not:
159 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
160 for (c = 0; c < ir->operands[0]->type->components(); c++)
161 data.b[c] = !op[0]->value.b[c];
162 break;
163
164 case ir_unop_f2i:
165 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
166 for (c = 0; c < ir->operands[0]->type->components(); c++) {
167 data.i[c] = op[0]->value.f[c];
168 }
169 break;
170 case ir_unop_i2f:
171 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
172 op[0]->type->base_type == GLSL_TYPE_INT);
173 for (c = 0; c < ir->operands[0]->type->components(); c++) {
174 if (op[0]->type->base_type == GLSL_TYPE_INT)
175 data.f[c] = op[0]->value.i[c];
176 else
177 data.f[c] = op[0]->value.u[c];
178 }
179 break;
180 case ir_unop_b2f:
181 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
182 for (c = 0; c < ir->operands[0]->type->components(); c++) {
183 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
184 }
185 break;
186 case ir_unop_f2b:
187 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
188 for (c = 0; c < ir->operands[0]->type->components(); c++) {
189 data.b[c] = bool(op[0]->value.f[c]);
190 }
191 break;
192 case ir_unop_b2i:
193 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
194 for (c = 0; c < ir->operands[0]->type->components(); c++) {
195 data.u[c] = op[0]->value.b[c] ? 1 : 0;
196 }
197 break;
198 case ir_unop_i2b:
199 assert(op[0]->type->is_integer());
200 for (c = 0; c < ir->operands[0]->type->components(); c++) {
201 data.b[c] = bool(op[0]->value.u[c]);
202 }
203 break;
204
205 case ir_unop_fract:
206 for (c = 0; c < ir->operands[0]->type->components(); c++) {
207 switch (ir->type->base_type) {
208 case GLSL_TYPE_UINT:
209 data.u[c] = 0;
210 break;
211 case GLSL_TYPE_INT:
212 data.i[c] = 0;
213 break;
214 case GLSL_TYPE_FLOAT:
215 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
216 break;
217 default:
218 assert(0);
219 }
220 }
221 break;
222
223 case ir_unop_neg:
224 for (c = 0; c < ir->operands[0]->type->components(); c++) {
225 switch (ir->type->base_type) {
226 case GLSL_TYPE_UINT:
227 data.u[c] = -op[0]->value.u[c];
228 break;
229 case GLSL_TYPE_INT:
230 data.i[c] = -op[0]->value.i[c];
231 break;
232 case GLSL_TYPE_FLOAT:
233 data.f[c] = -op[0]->value.f[c];
234 break;
235 default:
236 assert(0);
237 }
238 }
239 break;
240
241 case ir_unop_abs:
242 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
243 for (c = 0; c < ir->operands[0]->type->components(); c++) {
244 switch (ir->type->base_type) {
245 case GLSL_TYPE_UINT:
246 data.u[c] = op[0]->value.u[c];
247 break;
248 case GLSL_TYPE_INT:
249 data.i[c] = op[0]->value.i[c];
250 if (data.i[c] < 0)
251 data.i[c] = -data.i[c];
252 break;
253 case GLSL_TYPE_FLOAT:
254 data.f[c] = fabs(op[0]->value.f[c]);
255 break;
256 default:
257 assert(0);
258 }
259 }
260 break;
261
262 case ir_unop_rcp:
263 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
264 for (c = 0; c < ir->operands[0]->type->components(); c++) {
265 switch (ir->type->base_type) {
266 case GLSL_TYPE_UINT:
267 if (op[0]->value.u[c] != 0.0)
268 data.u[c] = 1 / op[0]->value.u[c];
269 break;
270 case GLSL_TYPE_INT:
271 if (op[0]->value.i[c] != 0.0)
272 data.i[c] = 1 / op[0]->value.i[c];
273 break;
274 case GLSL_TYPE_FLOAT:
275 if (op[0]->value.f[c] != 0.0)
276 data.f[c] = 1.0 / op[0]->value.f[c];
277 break;
278 default:
279 assert(0);
280 }
281 }
282 break;
283
284 case ir_unop_rsq:
285 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
286 for (c = 0; c < ir->operands[0]->type->components(); c++) {
287 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
288 }
289 break;
290
291 case ir_unop_sqrt:
292 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
293 for (c = 0; c < ir->operands[0]->type->components(); c++) {
294 data.f[c] = sqrtf(op[0]->value.f[c]);
295 }
296 break;
297
298 case ir_unop_exp:
299 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
300 for (c = 0; c < ir->operands[0]->type->components(); c++) {
301 data.f[c] = expf(op[0]->value.f[c]);
302 }
303 break;
304
305 case ir_unop_log:
306 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
307 for (c = 0; c < ir->operands[0]->type->components(); c++) {
308 data.f[c] = logf(op[0]->value.f[c]);
309 }
310 break;
311
312 case ir_unop_dFdx:
313 case ir_unop_dFdy:
314 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
315 for (c = 0; c < ir->operands[0]->type->components(); c++) {
316 data.f[c] = 0.0;
317 }
318 break;
319
320 case ir_binop_add:
321 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
322 for (unsigned c = 0, c0 = 0, c1 = 0;
323 c < components;
324 c0 += c0_inc, c1 += c1_inc, c++) {
325
326 switch (ir->operands[0]->type->base_type) {
327 case GLSL_TYPE_UINT:
328 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
329 break;
330 case GLSL_TYPE_INT:
331 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
332 break;
333 case GLSL_TYPE_FLOAT:
334 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
335 break;
336 default:
337 assert(0);
338 }
339 }
340
341 break;
342 case ir_binop_sub:
343 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
344 for (unsigned c = 0, c0 = 0, c1 = 0;
345 c < components;
346 c0 += c0_inc, c1 += c1_inc, c++) {
347
348 switch (ir->operands[0]->type->base_type) {
349 case GLSL_TYPE_UINT:
350 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
351 break;
352 case GLSL_TYPE_INT:
353 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
354 break;
355 case GLSL_TYPE_FLOAT:
356 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
357 break;
358 default:
359 assert(0);
360 }
361 }
362
363 break;
364 case ir_binop_mul:
365 if (ir->operands[0]->type == ir->operands[1]->type &&
366 !ir->operands[0]->type->is_matrix()) {
367 for (c = 0; c < ir->operands[0]->type->components(); c++) {
368 switch (ir->operands[0]->type->base_type) {
369 case GLSL_TYPE_UINT:
370 data.u[c] = op[0]->value.u[c] * op[1]->value.u[c];
371 break;
372 case GLSL_TYPE_INT:
373 data.i[c] = op[0]->value.i[c] * op[1]->value.i[c];
374 break;
375 case GLSL_TYPE_FLOAT:
376 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
377 break;
378 default:
379 assert(0);
380 }
381 }
382 } else
383 /* FINISHME: Support operations with non-equal types. */
384 return;
385
386 break;
387 case ir_binop_div:
388 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
389 for (unsigned c = 0, c0 = 0, c1 = 0;
390 c < components;
391 c0 += c0_inc, c1 += c1_inc, c++) {
392
393 switch (ir->operands[0]->type->base_type) {
394 case GLSL_TYPE_UINT:
395 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
396 break;
397 case GLSL_TYPE_INT:
398 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
399 break;
400 case GLSL_TYPE_FLOAT:
401 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
402 break;
403 default:
404 assert(0);
405 }
406 }
407
408 break;
409 case ir_binop_logic_and:
410 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
411 for (c = 0; c < ir->operands[0]->type->components(); c++)
412 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
413 break;
414 case ir_binop_logic_xor:
415 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
416 for (c = 0; c < ir->operands[0]->type->components(); c++)
417 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
418 break;
419 case ir_binop_logic_or:
420 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
421 for (c = 0; c < ir->operands[0]->type->components(); c++)
422 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
423 break;
424
425 case ir_binop_less:
426 switch (ir->operands[0]->type->base_type) {
427 case GLSL_TYPE_UINT:
428 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
429 break;
430 case GLSL_TYPE_INT:
431 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
432 break;
433 case GLSL_TYPE_FLOAT:
434 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
435 break;
436 default:
437 assert(0);
438 }
439 break;
440 case ir_binop_greater:
441 switch (ir->operands[0]->type->base_type) {
442 case GLSL_TYPE_UINT:
443 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
444 break;
445 case GLSL_TYPE_INT:
446 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
447 break;
448 case GLSL_TYPE_FLOAT:
449 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
450 break;
451 default:
452 assert(0);
453 }
454 break;
455 case ir_binop_lequal:
456 switch (ir->operands[0]->type->base_type) {
457 case GLSL_TYPE_UINT:
458 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
459 break;
460 case GLSL_TYPE_INT:
461 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
462 break;
463 case GLSL_TYPE_FLOAT:
464 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
465 break;
466 default:
467 assert(0);
468 }
469 break;
470 case ir_binop_gequal:
471 switch (ir->operands[0]->type->base_type) {
472 case GLSL_TYPE_UINT:
473 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
474 break;
475 case GLSL_TYPE_INT:
476 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
477 break;
478 case GLSL_TYPE_FLOAT:
479 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
480 break;
481 default:
482 assert(0);
483 }
484 break;
485
486 case ir_binop_equal:
487 data.b[0] = true;
488 for (c = 0; c < ir->operands[0]->type->components(); c++) {
489 switch (ir->operands[0]->type->base_type) {
490 case GLSL_TYPE_UINT:
491 data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
492 break;
493 case GLSL_TYPE_INT:
494 data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
495 break;
496 case GLSL_TYPE_FLOAT:
497 data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
498 break;
499 case GLSL_TYPE_BOOL:
500 data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
501 break;
502 default:
503 assert(0);
504 }
505 }
506 break;
507 case ir_binop_nequal:
508 data.b[0] = false;
509 for (c = 0; c < ir->operands[0]->type->components(); c++) {
510 switch (ir->operands[0]->type->base_type) {
511 case GLSL_TYPE_UINT:
512 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
513 break;
514 case GLSL_TYPE_INT:
515 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
516 break;
517 case GLSL_TYPE_FLOAT:
518 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
519 break;
520 case GLSL_TYPE_BOOL:
521 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
522 break;
523 default:
524 assert(0);
525 }
526 }
527 break;
528
529 default:
530 /* FINISHME: Should handle all expression types. */
531 return;
532 }
533
534 void *ctx = talloc_parent(ir);
535 this->value = new(ctx) ir_constant(ir->type, &data);
536 }
537
538
539 void
540 ir_constant_visitor::visit(ir_texture *ir)
541 {
542 // FINISHME: Do stuff with texture lookups
543 (void) ir;
544 value = NULL;
545 }
546
547
548 void
549 ir_constant_visitor::visit(ir_swizzle *ir)
550 {
551 ir_constant *v = ir->val->constant_expression_value();
552
553 this->value = NULL;
554
555 if (v != NULL) {
556 ir_constant_data data;
557
558 const unsigned swiz_idx[4] = {
559 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
560 };
561
562 for (unsigned i = 0; i < ir->mask.num_components; i++) {
563 switch (v->type->base_type) {
564 case GLSL_TYPE_UINT:
565 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
566 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
567 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
568 default: assert(!"Should not get here."); break;
569 }
570 }
571
572 void *ctx = talloc_parent(ir);
573 this->value = new(ctx) ir_constant(ir->type, &data);
574 }
575 }
576
577
578 void
579 ir_constant_visitor::visit(ir_dereference_variable *ir)
580 {
581 value = NULL;
582
583 ir_variable *var = ir->variable_referenced();
584 if (var && var->constant_value)
585 value = (ir_constant *)var->constant_value->clone(NULL);
586 }
587
588
589 void
590 ir_constant_visitor::visit(ir_dereference_array *ir)
591 {
592 void *ctx = talloc_parent(ir);
593 ir_constant *array = ir->array->constant_expression_value();
594 ir_constant *idx = ir->array_index->constant_expression_value();
595
596 this->value = NULL;
597
598 if ((array != NULL) && (idx != NULL)) {
599 if (array->type->is_matrix()) {
600 /* Array access of a matrix results in a vector.
601 */
602 const unsigned column = idx->value.u[0];
603
604 const glsl_type *const column_type = array->type->column_type();
605
606 /* Offset in the constant matrix to the first element of the column
607 * to be extracted.
608 */
609 const unsigned mat_idx = column * column_type->vector_elements;
610
611 ir_constant_data data;
612
613 switch (column_type->base_type) {
614 case GLSL_TYPE_UINT:
615 case GLSL_TYPE_INT:
616 for (unsigned i = 0; i < column_type->vector_elements; i++)
617 data.u[i] = array->value.u[mat_idx + i];
618
619 break;
620
621 case GLSL_TYPE_FLOAT:
622 for (unsigned i = 0; i < column_type->vector_elements; i++)
623 data.f[i] = array->value.f[mat_idx + i];
624
625 break;
626
627 default:
628 assert(!"Should not get here.");
629 break;
630 }
631
632 this->value = new(ctx) ir_constant(column_type, &data);
633 } else if (array->type->is_vector()) {
634 const unsigned component = idx->value.u[0];
635
636 this->value = new(ctx) ir_constant(array, component);
637 } else {
638 /* FINISHME: Handle access of constant arrays. */
639 }
640 }
641 }
642
643
644 void
645 ir_constant_visitor::visit(ir_dereference_record *ir)
646 {
647 ir_constant *v = ir->record->constant_expression_value();
648
649 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
650 }
651
652
653 void
654 ir_constant_visitor::visit(ir_assignment *ir)
655 {
656 (void) ir;
657 value = NULL;
658 }
659
660
661 void
662 ir_constant_visitor::visit(ir_constant *ir)
663 {
664 value = ir;
665 }
666
667
668 void
669 ir_constant_visitor::visit(ir_call *ir)
670 {
671 (void) ir;
672 value = NULL;
673 }
674
675
676 void
677 ir_constant_visitor::visit(ir_return *ir)
678 {
679 (void) ir;
680 value = NULL;
681 }
682
683
684 void
685 ir_constant_visitor::visit(ir_discard *ir)
686 {
687 (void) ir;
688 value = NULL;
689 }
690
691
692 void
693 ir_constant_visitor::visit(ir_if *ir)
694 {
695 (void) ir;
696 value = NULL;
697 }
698
699
700 void
701 ir_constant_visitor::visit(ir_loop *ir)
702 {
703 (void) ir;
704 value = NULL;
705 }
706
707
708 void
709 ir_constant_visitor::visit(ir_loop_jump *ir)
710 {
711 (void) ir;
712 value = NULL;
713 }