ir_constant_expression: Add support for ir_unop_trunc.
[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 ir_constant_data data;
134
135 memset(&data, 0, sizeof(data));
136
137 for (unsigned operand = 0; operand < ir->get_num_operands(); operand++) {
138 op[operand] = ir->operands[operand]->constant_expression_value();
139 if (!op[operand])
140 return;
141 }
142
143 if (op[1] != NULL)
144 assert(op[0]->type->base_type == op[1]->type->base_type);
145
146 bool op0_scalar = op[0]->type->is_scalar();
147 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
148
149 /* When iterating over a vector or matrix's components, we want to increase
150 * the loop counter. However, for scalars, we want to stay at 0.
151 */
152 unsigned c0_inc = op0_scalar ? 0 : 1;
153 unsigned c1_inc = op1_scalar ? 0 : 1;
154 unsigned components;
155 if (op1_scalar || !op[1]) {
156 components = op[0]->type->components();
157 } else {
158 components = op[1]->type->components();
159 }
160
161 switch (ir->operation) {
162 case ir_unop_logic_not:
163 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
164 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
165 data.b[c] = !op[0]->value.b[c];
166 break;
167
168 case ir_unop_f2i:
169 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
170 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
171 data.i[c] = op[0]->value.f[c];
172 }
173 break;
174 case ir_unop_i2f:
175 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
176 op[0]->type->base_type == GLSL_TYPE_INT);
177 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
178 if (op[0]->type->base_type == GLSL_TYPE_INT)
179 data.f[c] = op[0]->value.i[c];
180 else
181 data.f[c] = op[0]->value.u[c];
182 }
183 break;
184 case ir_unop_b2f:
185 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
186 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
187 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
188 }
189 break;
190 case ir_unop_f2b:
191 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
192 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
193 data.b[c] = bool(op[0]->value.f[c]);
194 }
195 break;
196 case ir_unop_b2i:
197 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
198 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
199 data.u[c] = op[0]->value.b[c] ? 1 : 0;
200 }
201 break;
202 case ir_unop_i2b:
203 assert(op[0]->type->is_integer());
204 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
205 data.b[c] = bool(op[0]->value.u[c]);
206 }
207 break;
208
209 case ir_unop_trunc:
210 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
211 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
212 data.f[c] = truncf(op[0]->value.f[c]);
213 }
214 break;
215
216 case ir_unop_fract:
217 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
218 switch (ir->type->base_type) {
219 case GLSL_TYPE_UINT:
220 data.u[c] = 0;
221 break;
222 case GLSL_TYPE_INT:
223 data.i[c] = 0;
224 break;
225 case GLSL_TYPE_FLOAT:
226 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
227 break;
228 default:
229 assert(0);
230 }
231 }
232 break;
233
234 case ir_unop_neg:
235 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
236 switch (ir->type->base_type) {
237 case GLSL_TYPE_UINT:
238 data.u[c] = -op[0]->value.u[c];
239 break;
240 case GLSL_TYPE_INT:
241 data.i[c] = -op[0]->value.i[c];
242 break;
243 case GLSL_TYPE_FLOAT:
244 data.f[c] = -op[0]->value.f[c];
245 break;
246 default:
247 assert(0);
248 }
249 }
250 break;
251
252 case ir_unop_abs:
253 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
254 switch (ir->type->base_type) {
255 case GLSL_TYPE_UINT:
256 data.u[c] = op[0]->value.u[c];
257 break;
258 case GLSL_TYPE_INT:
259 data.i[c] = op[0]->value.i[c];
260 if (data.i[c] < 0)
261 data.i[c] = -data.i[c];
262 break;
263 case GLSL_TYPE_FLOAT:
264 data.f[c] = fabs(op[0]->value.f[c]);
265 break;
266 default:
267 assert(0);
268 }
269 }
270 break;
271
272 case ir_unop_sign:
273 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
274 switch (ir->type->base_type) {
275 case GLSL_TYPE_UINT:
276 data.u[c] = op[0]->value.i[c] > 0;
277 break;
278 case GLSL_TYPE_INT:
279 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
280 break;
281 case GLSL_TYPE_FLOAT:
282 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
283 break;
284 default:
285 assert(0);
286 }
287 }
288 break;
289
290 case ir_unop_rcp:
291 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
292 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
293 switch (ir->type->base_type) {
294 case GLSL_TYPE_UINT:
295 if (op[0]->value.u[c] != 0.0)
296 data.u[c] = 1 / op[0]->value.u[c];
297 break;
298 case GLSL_TYPE_INT:
299 if (op[0]->value.i[c] != 0.0)
300 data.i[c] = 1 / op[0]->value.i[c];
301 break;
302 case GLSL_TYPE_FLOAT:
303 if (op[0]->value.f[c] != 0.0)
304 data.f[c] = 1.0 / op[0]->value.f[c];
305 break;
306 default:
307 assert(0);
308 }
309 }
310 break;
311
312 case ir_unop_rsq:
313 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
314 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
315 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
316 }
317 break;
318
319 case ir_unop_sqrt:
320 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
321 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
322 data.f[c] = sqrtf(op[0]->value.f[c]);
323 }
324 break;
325
326 case ir_unop_exp:
327 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
328 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
329 data.f[c] = expf(op[0]->value.f[c]);
330 }
331 break;
332
333 case ir_unop_exp2:
334 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
335 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
336 data.f[c] = exp2f(op[0]->value.f[c]);
337 }
338 break;
339
340 case ir_unop_log:
341 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
342 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
343 data.f[c] = logf(op[0]->value.f[c]);
344 }
345 break;
346
347 case ir_unop_log2:
348 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
349 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
350 data.f[c] = log2f(op[0]->value.f[c]);
351 }
352 break;
353
354 case ir_unop_dFdx:
355 case ir_unop_dFdy:
356 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
357 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
358 data.f[c] = 0.0;
359 }
360 break;
361
362 case ir_binop_dot:
363 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
364 data.f[0] = 0;
365 for (unsigned c = 0; c < op[0]->type->components(); c++) {
366 switch (ir->operands[0]->type->base_type) {
367 case GLSL_TYPE_UINT:
368 data.u[0] += op[0]->value.u[c] * op[1]->value.u[c];
369 break;
370 case GLSL_TYPE_INT:
371 data.i[0] += op[0]->value.i[c] * op[1]->value.i[c];
372 break;
373 case GLSL_TYPE_FLOAT:
374 data.f[0] += op[0]->value.f[c] * op[1]->value.f[c];
375 break;
376 default:
377 assert(0);
378 }
379 }
380
381 break;
382 case ir_binop_add:
383 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
384 for (unsigned c = 0, c0 = 0, c1 = 0;
385 c < components;
386 c0 += c0_inc, c1 += c1_inc, c++) {
387
388 switch (ir->operands[0]->type->base_type) {
389 case GLSL_TYPE_UINT:
390 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
391 break;
392 case GLSL_TYPE_INT:
393 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
394 break;
395 case GLSL_TYPE_FLOAT:
396 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
397 break;
398 default:
399 assert(0);
400 }
401 }
402
403 break;
404 case ir_binop_sub:
405 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
406 for (unsigned c = 0, c0 = 0, c1 = 0;
407 c < components;
408 c0 += c0_inc, c1 += c1_inc, c++) {
409
410 switch (ir->operands[0]->type->base_type) {
411 case GLSL_TYPE_UINT:
412 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
413 break;
414 case GLSL_TYPE_INT:
415 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
416 break;
417 case GLSL_TYPE_FLOAT:
418 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
419 break;
420 default:
421 assert(0);
422 }
423 }
424
425 break;
426 case ir_binop_mul:
427 /* Check for equal types, or unequal types involving scalars */
428 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
429 || op0_scalar || op1_scalar) {
430 for (unsigned c = 0, c0 = 0, c1 = 0;
431 c < components;
432 c0 += c0_inc, c1 += c1_inc, c++) {
433
434 switch (ir->operands[0]->type->base_type) {
435 case GLSL_TYPE_UINT:
436 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
437 break;
438 case GLSL_TYPE_INT:
439 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
440 break;
441 case GLSL_TYPE_FLOAT:
442 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
443 break;
444 default:
445 assert(0);
446 }
447 }
448 } else {
449 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
450
451 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
452 * matrix can be a GLSL vector, either N or P can be 1.
453 *
454 * For vec*mat, the vector is treated as a row vector. This
455 * means the vector is a 1-row x M-column matrix.
456 *
457 * For mat*vec, the vector is treated as a column vector. Since
458 * matrix_columns is 1 for vectors, this just works.
459 */
460 const unsigned n = op[0]->type->is_vector()
461 ? 1 : op[0]->type->vector_elements;
462 const unsigned m = op[1]->type->vector_elements;
463 const unsigned p = op[1]->type->matrix_columns;
464 for (unsigned j = 0; j < p; j++) {
465 for (unsigned i = 0; i < n; i++) {
466 for (unsigned k = 0; k < m; k++) {
467 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
468 }
469 }
470 }
471 }
472
473 break;
474 case ir_binop_div:
475 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
476 for (unsigned c = 0, c0 = 0, c1 = 0;
477 c < components;
478 c0 += c0_inc, c1 += c1_inc, c++) {
479
480 switch (ir->operands[0]->type->base_type) {
481 case GLSL_TYPE_UINT:
482 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
483 break;
484 case GLSL_TYPE_INT:
485 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
486 break;
487 case GLSL_TYPE_FLOAT:
488 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
489 break;
490 default:
491 assert(0);
492 }
493 }
494
495 break;
496 case ir_binop_logic_and:
497 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
498 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
499 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
500 break;
501 case ir_binop_logic_xor:
502 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
503 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
504 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
505 break;
506 case ir_binop_logic_or:
507 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
508 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
509 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
510 break;
511
512 case ir_binop_less:
513 switch (ir->operands[0]->type->base_type) {
514 case GLSL_TYPE_UINT:
515 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
516 break;
517 case GLSL_TYPE_INT:
518 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
519 break;
520 case GLSL_TYPE_FLOAT:
521 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
522 break;
523 default:
524 assert(0);
525 }
526 break;
527 case ir_binop_greater:
528 switch (ir->operands[0]->type->base_type) {
529 case GLSL_TYPE_UINT:
530 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
531 break;
532 case GLSL_TYPE_INT:
533 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
534 break;
535 case GLSL_TYPE_FLOAT:
536 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
537 break;
538 default:
539 assert(0);
540 }
541 break;
542 case ir_binop_lequal:
543 switch (ir->operands[0]->type->base_type) {
544 case GLSL_TYPE_UINT:
545 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
546 break;
547 case GLSL_TYPE_INT:
548 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
549 break;
550 case GLSL_TYPE_FLOAT:
551 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
552 break;
553 default:
554 assert(0);
555 }
556 break;
557 case ir_binop_gequal:
558 switch (ir->operands[0]->type->base_type) {
559 case GLSL_TYPE_UINT:
560 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
561 break;
562 case GLSL_TYPE_INT:
563 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
564 break;
565 case GLSL_TYPE_FLOAT:
566 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
567 break;
568 default:
569 assert(0);
570 }
571 break;
572
573 case ir_binop_equal:
574 data.b[0] = true;
575 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
576 switch (ir->operands[0]->type->base_type) {
577 case GLSL_TYPE_UINT:
578 data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c];
579 break;
580 case GLSL_TYPE_INT:
581 data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c];
582 break;
583 case GLSL_TYPE_FLOAT:
584 data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c];
585 break;
586 case GLSL_TYPE_BOOL:
587 data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c];
588 break;
589 default:
590 assert(0);
591 }
592 }
593 break;
594 case ir_binop_nequal:
595 data.b[0] = false;
596 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
597 switch (ir->operands[0]->type->base_type) {
598 case GLSL_TYPE_UINT:
599 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
600 break;
601 case GLSL_TYPE_INT:
602 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
603 break;
604 case GLSL_TYPE_FLOAT:
605 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
606 break;
607 case GLSL_TYPE_BOOL:
608 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
609 break;
610 default:
611 assert(0);
612 }
613 }
614 break;
615
616 default:
617 /* FINISHME: Should handle all expression types. */
618 return;
619 }
620
621 void *ctx = talloc_parent(ir);
622 this->value = new(ctx) ir_constant(ir->type, &data);
623 }
624
625
626 void
627 ir_constant_visitor::visit(ir_texture *ir)
628 {
629 // FINISHME: Do stuff with texture lookups
630 (void) ir;
631 value = NULL;
632 }
633
634
635 void
636 ir_constant_visitor::visit(ir_swizzle *ir)
637 {
638 ir_constant *v = ir->val->constant_expression_value();
639
640 this->value = NULL;
641
642 if (v != NULL) {
643 ir_constant_data data;
644
645 const unsigned swiz_idx[4] = {
646 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
647 };
648
649 for (unsigned i = 0; i < ir->mask.num_components; i++) {
650 switch (v->type->base_type) {
651 case GLSL_TYPE_UINT:
652 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
653 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
654 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
655 default: assert(!"Should not get here."); break;
656 }
657 }
658
659 void *ctx = talloc_parent(ir);
660 this->value = new(ctx) ir_constant(ir->type, &data);
661 }
662 }
663
664
665 void
666 ir_constant_visitor::visit(ir_dereference_variable *ir)
667 {
668 value = NULL;
669
670 ir_variable *var = ir->variable_referenced();
671 if (var && var->constant_value)
672 value = var->constant_value->clone(NULL);
673 }
674
675
676 void
677 ir_constant_visitor::visit(ir_dereference_array *ir)
678 {
679 void *ctx = talloc_parent(ir);
680 ir_constant *array = ir->array->constant_expression_value();
681 ir_constant *idx = ir->array_index->constant_expression_value();
682
683 this->value = NULL;
684
685 if ((array != NULL) && (idx != NULL)) {
686 if (array->type->is_matrix()) {
687 /* Array access of a matrix results in a vector.
688 */
689 const unsigned column = idx->value.u[0];
690
691 const glsl_type *const column_type = array->type->column_type();
692
693 /* Offset in the constant matrix to the first element of the column
694 * to be extracted.
695 */
696 const unsigned mat_idx = column * column_type->vector_elements;
697
698 ir_constant_data data;
699
700 switch (column_type->base_type) {
701 case GLSL_TYPE_UINT:
702 case GLSL_TYPE_INT:
703 for (unsigned i = 0; i < column_type->vector_elements; i++)
704 data.u[i] = array->value.u[mat_idx + i];
705
706 break;
707
708 case GLSL_TYPE_FLOAT:
709 for (unsigned i = 0; i < column_type->vector_elements; i++)
710 data.f[i] = array->value.f[mat_idx + i];
711
712 break;
713
714 default:
715 assert(!"Should not get here.");
716 break;
717 }
718
719 this->value = new(ctx) ir_constant(column_type, &data);
720 } else if (array->type->is_vector()) {
721 const unsigned component = idx->value.u[0];
722
723 this->value = new(ctx) ir_constant(array, component);
724 } else {
725 /* FINISHME: Handle access of constant arrays. */
726 }
727 }
728 }
729
730
731 void
732 ir_constant_visitor::visit(ir_dereference_record *ir)
733 {
734 ir_constant *v = ir->record->constant_expression_value();
735
736 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
737 }
738
739
740 void
741 ir_constant_visitor::visit(ir_assignment *ir)
742 {
743 (void) ir;
744 value = NULL;
745 }
746
747
748 void
749 ir_constant_visitor::visit(ir_constant *ir)
750 {
751 value = ir;
752 }
753
754
755 void
756 ir_constant_visitor::visit(ir_call *ir)
757 {
758 (void) ir;
759 value = NULL;
760 }
761
762
763 void
764 ir_constant_visitor::visit(ir_return *ir)
765 {
766 (void) ir;
767 value = NULL;
768 }
769
770
771 void
772 ir_constant_visitor::visit(ir_discard *ir)
773 {
774 (void) ir;
775 value = NULL;
776 }
777
778
779 void
780 ir_constant_visitor::visit(ir_if *ir)
781 {
782 (void) ir;
783 value = NULL;
784 }
785
786
787 void
788 ir_constant_visitor::visit(ir_loop *ir)
789 {
790 (void) ir;
791 value = NULL;
792 }
793
794
795 void
796 ir_constant_visitor::visit(ir_loop_jump *ir)
797 {
798 (void) ir;
799 value = NULL;
800 }