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