ir_constant_expression: Add support for ir_unop_sin.
[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_ceil:
217 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
218 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
219 data.f[c] = ceilf(op[0]->value.f[c]);
220 }
221 break;
222
223 case ir_unop_floor:
224 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
225 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
226 data.f[c] = floorf(op[0]->value.f[c]);
227 }
228 break;
229
230 case ir_unop_fract:
231 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
232 switch (ir->type->base_type) {
233 case GLSL_TYPE_UINT:
234 data.u[c] = 0;
235 break;
236 case GLSL_TYPE_INT:
237 data.i[c] = 0;
238 break;
239 case GLSL_TYPE_FLOAT:
240 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
241 break;
242 default:
243 assert(0);
244 }
245 }
246 break;
247
248 case ir_unop_sin:
249 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
250 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
251 data.f[c] = sinf(op[0]->value.f[c]);
252 }
253 break;
254
255 case ir_unop_neg:
256 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
257 switch (ir->type->base_type) {
258 case GLSL_TYPE_UINT:
259 data.u[c] = -op[0]->value.u[c];
260 break;
261 case GLSL_TYPE_INT:
262 data.i[c] = -op[0]->value.i[c];
263 break;
264 case GLSL_TYPE_FLOAT:
265 data.f[c] = -op[0]->value.f[c];
266 break;
267 default:
268 assert(0);
269 }
270 }
271 break;
272
273 case ir_unop_abs:
274 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
275 switch (ir->type->base_type) {
276 case GLSL_TYPE_UINT:
277 data.u[c] = op[0]->value.u[c];
278 break;
279 case GLSL_TYPE_INT:
280 data.i[c] = op[0]->value.i[c];
281 if (data.i[c] < 0)
282 data.i[c] = -data.i[c];
283 break;
284 case GLSL_TYPE_FLOAT:
285 data.f[c] = fabs(op[0]->value.f[c]);
286 break;
287 default:
288 assert(0);
289 }
290 }
291 break;
292
293 case ir_unop_sign:
294 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
295 switch (ir->type->base_type) {
296 case GLSL_TYPE_UINT:
297 data.u[c] = op[0]->value.i[c] > 0;
298 break;
299 case GLSL_TYPE_INT:
300 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
301 break;
302 case GLSL_TYPE_FLOAT:
303 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
304 break;
305 default:
306 assert(0);
307 }
308 }
309 break;
310
311 case ir_unop_rcp:
312 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
313 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
314 switch (ir->type->base_type) {
315 case GLSL_TYPE_UINT:
316 if (op[0]->value.u[c] != 0.0)
317 data.u[c] = 1 / op[0]->value.u[c];
318 break;
319 case GLSL_TYPE_INT:
320 if (op[0]->value.i[c] != 0.0)
321 data.i[c] = 1 / op[0]->value.i[c];
322 break;
323 case GLSL_TYPE_FLOAT:
324 if (op[0]->value.f[c] != 0.0)
325 data.f[c] = 1.0 / op[0]->value.f[c];
326 break;
327 default:
328 assert(0);
329 }
330 }
331 break;
332
333 case ir_unop_rsq:
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] = 1.0 / sqrtf(op[0]->value.f[c]);
337 }
338 break;
339
340 case ir_unop_sqrt:
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] = sqrtf(op[0]->value.f[c]);
344 }
345 break;
346
347 case ir_unop_exp:
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] = expf(op[0]->value.f[c]);
351 }
352 break;
353
354 case ir_unop_exp2:
355 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
356 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
357 data.f[c] = exp2f(op[0]->value.f[c]);
358 }
359 break;
360
361 case ir_unop_log:
362 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
363 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
364 data.f[c] = logf(op[0]->value.f[c]);
365 }
366 break;
367
368 case ir_unop_log2:
369 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
370 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
371 data.f[c] = log2f(op[0]->value.f[c]);
372 }
373 break;
374
375 case ir_unop_dFdx:
376 case ir_unop_dFdy:
377 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
378 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
379 data.f[c] = 0.0;
380 }
381 break;
382
383 case ir_binop_dot:
384 assert(op[0]->type->is_vector() && op[1]->type->is_vector());
385 data.f[0] = 0;
386 for (unsigned c = 0; c < op[0]->type->components(); c++) {
387 switch (ir->operands[0]->type->base_type) {
388 case GLSL_TYPE_UINT:
389 data.u[0] += op[0]->value.u[c] * op[1]->value.u[c];
390 break;
391 case GLSL_TYPE_INT:
392 data.i[0] += op[0]->value.i[c] * op[1]->value.i[c];
393 break;
394 case GLSL_TYPE_FLOAT:
395 data.f[0] += op[0]->value.f[c] * op[1]->value.f[c];
396 break;
397 default:
398 assert(0);
399 }
400 }
401
402 break;
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 (ir->operands[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 (ir->operands[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 (ir->operands[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 (ir->operands[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_logic_and:
518 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
519 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
520 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
521 break;
522 case ir_binop_logic_xor:
523 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
524 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
525 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
526 break;
527 case ir_binop_logic_or:
528 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
529 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++)
530 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
531 break;
532
533 case ir_binop_less:
534 switch (ir->operands[0]->type->base_type) {
535 case GLSL_TYPE_UINT:
536 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
537 break;
538 case GLSL_TYPE_INT:
539 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
540 break;
541 case GLSL_TYPE_FLOAT:
542 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
543 break;
544 default:
545 assert(0);
546 }
547 break;
548 case ir_binop_greater:
549 switch (ir->operands[0]->type->base_type) {
550 case GLSL_TYPE_UINT:
551 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
552 break;
553 case GLSL_TYPE_INT:
554 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
555 break;
556 case GLSL_TYPE_FLOAT:
557 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
558 break;
559 default:
560 assert(0);
561 }
562 break;
563 case ir_binop_lequal:
564 switch (ir->operands[0]->type->base_type) {
565 case GLSL_TYPE_UINT:
566 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
567 break;
568 case GLSL_TYPE_INT:
569 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
570 break;
571 case GLSL_TYPE_FLOAT:
572 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
573 break;
574 default:
575 assert(0);
576 }
577 break;
578 case ir_binop_gequal:
579 switch (ir->operands[0]->type->base_type) {
580 case GLSL_TYPE_UINT:
581 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
582 break;
583 case GLSL_TYPE_INT:
584 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
585 break;
586 case GLSL_TYPE_FLOAT:
587 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
588 break;
589 default:
590 assert(0);
591 }
592 break;
593
594 case ir_binop_equal:
595 data.b[0] = true;
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 case ir_binop_nequal:
616 data.b[0] = false;
617 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) {
618 switch (ir->operands[0]->type->base_type) {
619 case GLSL_TYPE_UINT:
620 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c];
621 break;
622 case GLSL_TYPE_INT:
623 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c];
624 break;
625 case GLSL_TYPE_FLOAT:
626 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c];
627 break;
628 case GLSL_TYPE_BOOL:
629 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c];
630 break;
631 default:
632 assert(0);
633 }
634 }
635 break;
636
637 default:
638 /* FINISHME: Should handle all expression types. */
639 return;
640 }
641
642 void *ctx = talloc_parent(ir);
643 this->value = new(ctx) ir_constant(ir->type, &data);
644 }
645
646
647 void
648 ir_constant_visitor::visit(ir_texture *ir)
649 {
650 // FINISHME: Do stuff with texture lookups
651 (void) ir;
652 value = NULL;
653 }
654
655
656 void
657 ir_constant_visitor::visit(ir_swizzle *ir)
658 {
659 ir_constant *v = ir->val->constant_expression_value();
660
661 this->value = NULL;
662
663 if (v != NULL) {
664 ir_constant_data data;
665
666 const unsigned swiz_idx[4] = {
667 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
668 };
669
670 for (unsigned i = 0; i < ir->mask.num_components; i++) {
671 switch (v->type->base_type) {
672 case GLSL_TYPE_UINT:
673 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
674 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
675 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
676 default: assert(!"Should not get here."); break;
677 }
678 }
679
680 void *ctx = talloc_parent(ir);
681 this->value = new(ctx) ir_constant(ir->type, &data);
682 }
683 }
684
685
686 void
687 ir_constant_visitor::visit(ir_dereference_variable *ir)
688 {
689 value = NULL;
690
691 ir_variable *var = ir->variable_referenced();
692 if (var && var->constant_value)
693 value = var->constant_value->clone(NULL);
694 }
695
696
697 void
698 ir_constant_visitor::visit(ir_dereference_array *ir)
699 {
700 void *ctx = talloc_parent(ir);
701 ir_constant *array = ir->array->constant_expression_value();
702 ir_constant *idx = ir->array_index->constant_expression_value();
703
704 this->value = NULL;
705
706 if ((array != NULL) && (idx != NULL)) {
707 if (array->type->is_matrix()) {
708 /* Array access of a matrix results in a vector.
709 */
710 const unsigned column = idx->value.u[0];
711
712 const glsl_type *const column_type = array->type->column_type();
713
714 /* Offset in the constant matrix to the first element of the column
715 * to be extracted.
716 */
717 const unsigned mat_idx = column * column_type->vector_elements;
718
719 ir_constant_data data;
720
721 switch (column_type->base_type) {
722 case GLSL_TYPE_UINT:
723 case GLSL_TYPE_INT:
724 for (unsigned i = 0; i < column_type->vector_elements; i++)
725 data.u[i] = array->value.u[mat_idx + i];
726
727 break;
728
729 case GLSL_TYPE_FLOAT:
730 for (unsigned i = 0; i < column_type->vector_elements; i++)
731 data.f[i] = array->value.f[mat_idx + i];
732
733 break;
734
735 default:
736 assert(!"Should not get here.");
737 break;
738 }
739
740 this->value = new(ctx) ir_constant(column_type, &data);
741 } else if (array->type->is_vector()) {
742 const unsigned component = idx->value.u[0];
743
744 this->value = new(ctx) ir_constant(array, component);
745 } else {
746 /* FINISHME: Handle access of constant arrays. */
747 }
748 }
749 }
750
751
752 void
753 ir_constant_visitor::visit(ir_dereference_record *ir)
754 {
755 ir_constant *v = ir->record->constant_expression_value();
756
757 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
758 }
759
760
761 void
762 ir_constant_visitor::visit(ir_assignment *ir)
763 {
764 (void) ir;
765 value = NULL;
766 }
767
768
769 void
770 ir_constant_visitor::visit(ir_constant *ir)
771 {
772 value = ir;
773 }
774
775
776 void
777 ir_constant_visitor::visit(ir_call *ir)
778 {
779 (void) ir;
780 value = NULL;
781 }
782
783
784 void
785 ir_constant_visitor::visit(ir_return *ir)
786 {
787 (void) ir;
788 value = NULL;
789 }
790
791
792 void
793 ir_constant_visitor::visit(ir_discard *ir)
794 {
795 (void) ir;
796 value = NULL;
797 }
798
799
800 void
801 ir_constant_visitor::visit(ir_if *ir)
802 {
803 (void) ir;
804 value = NULL;
805 }
806
807
808 void
809 ir_constant_visitor::visit(ir_loop *ir)
810 {
811 (void) ir;
812 value = NULL;
813 }
814
815
816 void
817 ir_constant_visitor::visit(ir_loop_jump *ir)
818 {
819 (void) ir;
820 value = NULL;
821 }