blob: a3ce6e7e591ef6ff0a76da281dd37bc661f07252 [file] [log] [blame]
Ian Romanick1cf43a42010-03-30 16:56:50 -07001/*
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#define NULL 0
Eric Anholt43ad37a2010-05-12 14:42:21 -070037#include <math.h>
Ian Romanick1cf43a42010-03-30 16:56:50 -070038#include "ir.h"
39#include "ir_visitor.h"
Eric Anholta576f9d2010-03-31 16:25:12 -100040#include "glsl_types.h"
Ian Romanick1cf43a42010-03-30 16:56:50 -070041
42/**
43 * Visitor class for evaluating constant expressions
44 */
45class ir_constant_visitor : public ir_visitor {
46public:
47 ir_constant_visitor()
48 : value(NULL)
49 {
50 /* empty */
51 }
52
53 virtual ~ir_constant_visitor()
54 {
55 /* empty */
56 }
57
58 /**
59 * \name Visit methods
60 *
61 * As typical for the visitor pattern, there must be one \c visit method for
62 * each concrete subclass of \c ir_instruction. Virtual base classes within
63 * the hierarchy should not have \c visit methods.
64 */
65 /*@{*/
66 virtual void visit(ir_variable *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070067 virtual void visit(ir_function_signature *);
68 virtual void visit(ir_function *);
69 virtual void visit(ir_expression *);
Kenneth Graunke26d74cd2010-05-26 17:42:03 -070070 virtual void visit(ir_texture *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070071 virtual void visit(ir_swizzle *);
Ian Romanickc7b10462010-05-19 13:20:12 +020072 virtual void visit(ir_dereference_variable *);
73 virtual void visit(ir_dereference_array *);
74 virtual void visit(ir_dereference_record *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070075 virtual void visit(ir_assignment *);
76 virtual void visit(ir_constant *);
77 virtual void visit(ir_call *);
78 virtual void visit(ir_return *);
79 virtual void visit(ir_if *);
Ian Romanickfad607a2010-04-05 16:16:07 -070080 virtual void visit(ir_loop *);
Ian Romanickf8e31e02010-04-05 16:28:15 -070081 virtual void visit(ir_loop_jump *);
Ian Romanick1cf43a42010-03-30 16:56:50 -070082 /*@}*/
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
95ir_constant *
96ir_instruction::constant_expression_value()
97{
98 ir_constant_visitor visitor;
99
100 this->accept(& visitor);
101 return visitor.value;
102}
103
104
105void
106ir_constant_visitor::visit(ir_variable *ir)
107{
108 (void) ir;
109 value = NULL;
110}
111
112
113void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700114ir_constant_visitor::visit(ir_function_signature *ir)
115{
116 (void) ir;
117 value = NULL;
118}
119
120
121void
122ir_constant_visitor::visit(ir_function *ir)
123{
124 (void) ir;
125 value = NULL;
126}
127
Ian Romanick1cf43a42010-03-30 16:56:50 -0700128void
129ir_constant_visitor::visit(ir_expression *ir)
130{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700131 value = NULL;
Eric Anholta576f9d2010-03-31 16:25:12 -1000132 ir_constant *op[2];
Eric Anholtd98da972010-04-01 18:25:11 -1000133 unsigned int operand, c;
134 unsigned u[16];
135 int i[16];
136 float f[16];
137 bool b[16];
138 const glsl_type *type = NULL;
Eric Anholt160d0922010-04-01 18:07:08 -1000139
Eric Anholtd98da972010-04-01 18:25:11 -1000140 for (operand = 0; operand < ir->get_num_operands(); operand++) {
141 op[operand] = ir->operands[operand]->constant_expression_value();
142 if (!op[operand])
Eric Anholt160d0922010-04-01 18:07:08 -1000143 return;
144 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000145
146 switch (ir->operation) {
Eric Anholt528bb852010-03-31 21:09:02 -1000147 case ir_unop_logic_not:
Eric Anholtd98da972010-04-01 18:25:11 -1000148 type = ir->operands[0]->type;
149 assert(type->base_type == GLSL_TYPE_BOOL);
150 for (c = 0; c < ir->operands[0]->type->components(); c++)
151 b[c] = !op[0]->value.b[c];
Eric Anholt528bb852010-03-31 21:09:02 -1000152 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700153
154 case ir_unop_f2i:
155 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
156 type = ir->type;
157 for (c = 0; c < ir->operands[0]->type->components(); c++) {
158 i[c] = op[0]->value.f[c];
159 }
160 break;
161 case ir_unop_i2f:
162 assert(op[0]->type->base_type == GLSL_TYPE_UINT ||
163 op[0]->type->base_type == GLSL_TYPE_INT);
164 type = ir->type;
165 for (c = 0; c < ir->operands[0]->type->components(); c++) {
166 if (op[0]->type->base_type == GLSL_TYPE_INT)
167 f[c] = op[0]->value.i[c];
168 else
169 f[c] = op[0]->value.u[c];
170 }
171 break;
Ian Romanick7dc2b712010-06-07 15:10:14 -0700172 case ir_unop_b2f:
173 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
174 type = ir->type;
175 for (c = 0; c < ir->operands[0]->type->components(); c++) {
176 f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
177 }
178 break;
179 case ir_unop_f2b:
180 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
181 type = ir->type;
182 for (c = 0; c < ir->operands[0]->type->components(); c++) {
183 b[c] = bool(op[0]->value.f[c]);
184 }
185 break;
Ian Romanick39d6dd32010-06-11 13:46:30 -0700186 case ir_unop_b2i:
187 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
188 type = ir->type;
189 for (c = 0; c < ir->operands[0]->type->components(); c++) {
190 u[c] = op[0]->value.b[c] ? 1 : 0;
191 i[c] = u[c];
192 }
193 break;
194 case ir_unop_i2b:
195 assert(op[0]->type->is_integer());
196 type = ir->type;
197 for (c = 0; c < ir->operands[0]->type->components(); c++) {
198 b[c] = bool(op[0]->value.u[c]);
199 }
200 break;
Eric Anholtaf186412010-04-06 10:53:57 -0700201
Eric Anholt43ad37a2010-05-12 14:42:21 -0700202 case ir_unop_neg:
203 type = ir->type;
204 for (c = 0; c < ir->operands[0]->type->components(); c++) {
205 switch (type->base_type) {
206 case GLSL_TYPE_UINT:
207 u[c] = -op[0]->value.u[c];
208 break;
209 case GLSL_TYPE_INT:
210 i[c] = -op[0]->value.i[c];
211 break;
212 case GLSL_TYPE_FLOAT:
213 f[c] = -op[0]->value.f[c];
214 break;
215 default:
216 assert(0);
217 }
218 }
219 break;
220
221 case ir_unop_abs:
222 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
223 type = ir->type;
224 for (c = 0; c < ir->operands[0]->type->components(); c++) {
225 switch (type->base_type) {
226 case GLSL_TYPE_UINT:
227 u[c] = op[0]->value.u[c];
228 break;
229 case GLSL_TYPE_INT:
230 i[c] = op[0]->value.i[c];
231 if (i[c] < 0)
232 i[c] = -i[c];
233 break;
234 case GLSL_TYPE_FLOAT:
235 f[c] = fabs(op[0]->value.f[c]);
236 break;
237 default:
238 assert(0);
239 }
240 }
241 break;
242
243 case ir_unop_rcp:
244 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
245 type = ir->type;
246 for (c = 0; c < ir->operands[0]->type->components(); c++) {
247 switch (type->base_type) {
248 case GLSL_TYPE_UINT:
249 if (op[0]->value.u[c] != 0.0)
250 u[c] = 1 / op[0]->value.u[c];
251 break;
252 case GLSL_TYPE_INT:
253 if (op[0]->value.i[c] != 0.0)
254 i[c] = 1 / op[0]->value.i[c];
255 break;
256 case GLSL_TYPE_FLOAT:
257 if (op[0]->value.f[c] != 0.0)
258 f[c] = 1.0 / op[0]->value.f[c];
259 break;
260 default:
261 assert(0);
262 }
263 }
264 break;
265
266 case ir_unop_rsq:
267 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
268 type = ir->type;
269 for (c = 0; c < ir->operands[0]->type->components(); c++) {
270 f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
271 }
272 break;
273
274 case ir_unop_sqrt:
275 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
276 type = ir->type;
277 for (c = 0; c < ir->operands[0]->type->components(); c++) {
278 f[c] = sqrtf(op[0]->value.f[c]);
279 }
280 break;
281
282 case ir_unop_exp:
283 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
284 type = ir->type;
285 for (c = 0; c < ir->operands[0]->type->components(); c++) {
286 f[c] = expf(op[0]->value.f[c]);
287 }
288 break;
289
290 case ir_unop_log:
291 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
292 type = ir->type;
293 for (c = 0; c < ir->operands[0]->type->components(); c++) {
294 f[c] = logf(op[0]->value.f[c]);
295 }
296 break;
297
Kenneth Graunked6a32d42010-06-09 15:22:35 -0700298 case ir_unop_dFdx:
299 case ir_unop_dFdy:
300 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
301 type = ir->type;
302 for (c = 0; c < ir->operands[0]->type->components(); c++) {
303 f[c] = 0.0;
304 }
305 break;
306
Eric Anholtd251b922010-04-01 18:35:42 -1000307 case ir_binop_add:
308 if (ir->operands[0]->type == ir->operands[1]->type) {
309 type = ir->operands[0]->type;
310 for (c = 0; c < ir->operands[0]->type->components(); c++) {
311 switch (ir->operands[0]->type->base_type) {
312 case GLSL_TYPE_UINT:
313 u[c] = op[0]->value.u[c] + op[1]->value.u[c];
314 break;
315 case GLSL_TYPE_INT:
316 i[c] = op[0]->value.i[c] + op[1]->value.i[c];
317 break;
318 case GLSL_TYPE_FLOAT:
319 f[c] = op[0]->value.f[c] + op[1]->value.f[c];
320 break;
321 default:
322 assert(0);
323 }
324 }
325 }
326 break;
327 case ir_binop_sub:
328 if (ir->operands[0]->type == ir->operands[1]->type) {
329 type = ir->operands[0]->type;
330 for (c = 0; c < ir->operands[0]->type->components(); c++) {
331 switch (ir->operands[0]->type->base_type) {
332 case GLSL_TYPE_UINT:
333 u[c] = op[0]->value.u[c] - op[1]->value.u[c];
334 break;
335 case GLSL_TYPE_INT:
336 i[c] = op[0]->value.i[c] - op[1]->value.i[c];
337 break;
338 case GLSL_TYPE_FLOAT:
339 f[c] = op[0]->value.f[c] - op[1]->value.f[c];
340 break;
341 default:
342 assert(0);
343 }
344 }
345 }
346 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000347 case ir_binop_mul:
Eric Anholtd98da972010-04-01 18:25:11 -1000348 if (ir->operands[0]->type == ir->operands[1]->type &&
349 !ir->operands[0]->type->is_matrix()) {
350 type = ir->operands[0]->type;
351 for (c = 0; c < ir->operands[0]->type->components(); c++) {
352 switch (ir->operands[0]->type->base_type) {
353 case GLSL_TYPE_UINT:
354 u[c] = op[0]->value.u[c] * op[1]->value.u[c];
355 break;
356 case GLSL_TYPE_INT:
357 i[c] = op[0]->value.i[c] * op[1]->value.i[c];
358 break;
359 case GLSL_TYPE_FLOAT:
360 f[c] = op[0]->value.f[c] * op[1]->value.f[c];
361 break;
362 default:
363 assert(0);
364 }
Eric Anholta576f9d2010-03-31 16:25:12 -1000365 }
366 }
367 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000368 case ir_binop_div:
369 if (ir->operands[0]->type == ir->operands[1]->type) {
370 type = ir->operands[0]->type;
371 for (c = 0; c < ir->operands[0]->type->components(); c++) {
372 switch (ir->operands[0]->type->base_type) {
373 case GLSL_TYPE_UINT:
374 u[c] = op[0]->value.u[c] / op[1]->value.u[c];
375 break;
376 case GLSL_TYPE_INT:
377 i[c] = op[0]->value.i[c] / op[1]->value.i[c];
378 break;
379 case GLSL_TYPE_FLOAT:
380 f[c] = op[0]->value.f[c] / op[1]->value.f[c];
381 break;
382 default:
383 assert(0);
384 }
385 }
386 }
387 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000388 case ir_binop_logic_and:
Eric Anholtd98da972010-04-01 18:25:11 -1000389 type = ir->operands[0]->type;
390 assert(type->base_type == GLSL_TYPE_BOOL);
391 for (c = 0; c < ir->operands[0]->type->components(); c++)
392 b[c] = op[0]->value.b[c] && op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000393 break;
Eric Anholtd251b922010-04-01 18:35:42 -1000394 case ir_binop_logic_xor:
395 type = ir->operands[0]->type;
396 assert(type->base_type == GLSL_TYPE_BOOL);
397 for (c = 0; c < ir->operands[0]->type->components(); c++)
398 b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
399 break;
Eric Anholta576f9d2010-03-31 16:25:12 -1000400 case ir_binop_logic_or:
Eric Anholtd98da972010-04-01 18:25:11 -1000401 type = ir->operands[0]->type;
402 assert(type->base_type == GLSL_TYPE_BOOL);
403 for (c = 0; c < ir->operands[0]->type->components(); c++)
404 b[c] = op[0]->value.b[c] || op[1]->value.b[c];
Eric Anholta576f9d2010-03-31 16:25:12 -1000405 break;
Eric Anholt85171c22010-04-06 09:55:45 -0700406
407 case ir_binop_less:
408 type = glsl_type::bool_type;
409 switch (ir->operands[0]->type->base_type) {
410 case GLSL_TYPE_UINT:
411 b[0] = op[0]->value.u[0] < op[1]->value.u[0];
412 break;
413 case GLSL_TYPE_INT:
414 b[0] = op[0]->value.i[0] < op[1]->value.i[0];
415 break;
416 case GLSL_TYPE_FLOAT:
417 b[0] = op[0]->value.f[0] < op[1]->value.f[0];
418 break;
419 default:
420 assert(0);
421 }
422 break;
423 case ir_binop_greater:
424 type = glsl_type::bool_type;
425 switch (ir->operands[0]->type->base_type) {
426 case GLSL_TYPE_UINT:
427 b[0] = op[0]->value.u[0] > op[1]->value.u[0];
428 break;
429 case GLSL_TYPE_INT:
430 b[0] = op[0]->value.i[0] > op[1]->value.i[0];
431 break;
432 case GLSL_TYPE_FLOAT:
433 b[0] = op[0]->value.f[0] > op[1]->value.f[0];
434 break;
435 default:
436 assert(0);
437 }
438 break;
439 case ir_binop_lequal:
440 type = glsl_type::bool_type;
441 switch (ir->operands[0]->type->base_type) {
442 case GLSL_TYPE_UINT:
443 b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
444 break;
445 case GLSL_TYPE_INT:
446 b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
447 break;
448 case GLSL_TYPE_FLOAT:
449 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_gequal:
456 type = glsl_type::bool_type;
457 switch (ir->operands[0]->type->base_type) {
458 case GLSL_TYPE_UINT:
459 b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
460 break;
461 case GLSL_TYPE_INT:
462 b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
463 break;
464 case GLSL_TYPE_FLOAT:
465 b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
466 break;
467 default:
468 assert(0);
469 }
470 break;
471
Eric Anholtec1949e2010-04-06 10:02:27 -0700472 case ir_binop_equal:
473 if (ir->operands[0]->type == ir->operands[1]->type) {
474 type = glsl_type::bool_type;
475 b[0] = true;
476 for (c = 0; c < ir->operands[0]->type->components(); c++) {
477 switch (ir->operands[0]->type->base_type) {
478 case GLSL_TYPE_UINT:
479 b[0] = b[0] && op[0]->value.u[c] == op[1]->value.u[c];
480 break;
481 case GLSL_TYPE_INT:
482 b[0] = b[0] && op[0]->value.i[c] == op[1]->value.i[c];
483 break;
484 case GLSL_TYPE_FLOAT:
485 b[0] = b[0] && op[0]->value.f[c] == op[1]->value.f[c];
486 break;
Ian Romanick77cce642010-04-07 16:48:42 -0700487 case GLSL_TYPE_BOOL:
488 b[0] = b[0] && op[0]->value.b[c] == op[1]->value.b[c];
489 break;
Eric Anholtec1949e2010-04-06 10:02:27 -0700490 default:
491 assert(0);
492 }
493 }
494 }
495 break;
496 case ir_binop_nequal:
497 if (ir->operands[0]->type == ir->operands[1]->type) {
498 type = glsl_type::bool_type;
499 b[0] = false;
500 for (c = 0; c < ir->operands[0]->type->components(); c++) {
501 switch (ir->operands[0]->type->base_type) {
502 case GLSL_TYPE_UINT:
503 b[0] = b[0] || op[0]->value.u[c] != op[1]->value.u[c];
504 break;
505 case GLSL_TYPE_INT:
506 b[0] = b[0] || op[0]->value.i[c] != op[1]->value.i[c];
507 break;
508 case GLSL_TYPE_FLOAT:
509 b[0] = b[0] || op[0]->value.f[c] != op[1]->value.f[c];
510 break;
Ian Romanick77cce642010-04-07 16:48:42 -0700511 case GLSL_TYPE_BOOL:
512 b[0] = b[0] || op[0]->value.b[c] != op[1]->value.b[c];
513 break;
Eric Anholtec1949e2010-04-06 10:02:27 -0700514 default:
515 assert(0);
516 }
517 }
518 }
519 break;
520
Eric Anholta576f9d2010-03-31 16:25:12 -1000521 default:
522 break;
523 }
Eric Anholtd98da972010-04-01 18:25:11 -1000524
525 if (type) {
526 switch (type->base_type) {
527 case GLSL_TYPE_UINT:
528 value = new ir_constant(type, u);
529 break;
530 case GLSL_TYPE_INT:
531 value = new ir_constant(type, i);
532 break;
533 case GLSL_TYPE_FLOAT:
534 value = new ir_constant(type, f);
535 break;
536 case GLSL_TYPE_BOOL:
537 value = new ir_constant(type, b);
538 break;
539 }
540 }
Ian Romanick1cf43a42010-03-30 16:56:50 -0700541}
542
543
544void
Kenneth Graunke26d74cd2010-05-26 17:42:03 -0700545ir_constant_visitor::visit(ir_texture *ir)
546{
547 // FINISHME: Do stuff with texture lookups
548 (void) ir;
549 value = NULL;
550}
551
552
553void
Ian Romanick1cf43a42010-03-30 16:56:50 -0700554ir_constant_visitor::visit(ir_swizzle *ir)
555{
Ian Romanickc2ba6192010-06-11 12:30:28 -0700556 ir_constant *v = ir->val->constant_expression_value();
557
558 this->value = NULL;
559
560 if (v != NULL) {
561 union {
562 float f[4];
563 unsigned u[4];
564 bool b[4];
565 } data;
566
567 const unsigned swiz_idx[4] = {
568 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w
569 };
570
571 for (unsigned i = 0; i < ir->mask.num_components; i++) {
572 switch (v->type->base_type) {
573 case GLSL_TYPE_UINT:
574 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
575 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
576 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
577 default: assert(!"Should not get here."); break;
578 }
579 }
580
581 this->value = new ir_constant(ir->type, &data);
582 }
Ian Romanick1cf43a42010-03-30 16:56:50 -0700583}
584
585
586void
Ian Romanickc7b10462010-05-19 13:20:12 +0200587ir_constant_visitor::visit(ir_dereference_variable *ir)
Ian Romanick1cf43a42010-03-30 16:56:50 -0700588{
Ian Romanick1cf43a42010-03-30 16:56:50 -0700589 value = NULL;
Eric Anholt326c6762010-04-06 10:30:54 -0700590
Ian Romanickc7b10462010-05-19 13:20:12 +0200591 ir_variable *var = ir->variable_referenced();
592 if (var && var->constant_value)
Ian Romanickd4b33ed2010-06-09 17:19:10 -0700593 value = var->constant_value->clone();
Ian Romanickc7b10462010-05-19 13:20:12 +0200594}
595
596
597void
598ir_constant_visitor::visit(ir_dereference_array *ir)
599{
Ian Romanick9b92af92010-06-11 12:20:12 -0700600 ir_constant *array = ir->array->constant_expression_value();
601 ir_constant *idx = ir->array_index->constant_expression_value();
602
603 this->value = NULL;
604
605 if ((array != NULL) && (idx != NULL)) {
606 if (array->type->is_matrix()) {
607 /* Array access of a matrix results in a vector.
608 */
609 const unsigned column = idx->value.u[0];
610
611 const glsl_type *const column_type = array->type->column_type();
612
613 /* Offset in the constant matrix to the first element of the column
614 * to be extracted.
615 */
616 const unsigned mat_idx = column * column_type->vector_elements;
617
618 union {
619 unsigned u[4];
620 float f[4];
621 } data;
622
623 switch (column_type->base_type) {
624 case GLSL_TYPE_UINT:
625 case GLSL_TYPE_INT:
626 for (unsigned i = 0; i < column_type->vector_elements; i++)
627 data.u[i] = array->value.u[mat_idx + i];
628
629 break;
630
631 case GLSL_TYPE_FLOAT:
632 for (unsigned i = 0; i < column_type->vector_elements; i++)
633 data.f[i] = array->value.f[mat_idx + i];
634
635 break;
636
637 default:
638 assert(!"Should not get here.");
639 break;
640 }
641
642 this->value = new ir_constant(column_type, &data);
643 } else if (array->type->is_vector()) {
644 const unsigned component = idx->value.u[0];
645
646 this->value = new ir_constant(array, component);
647 } else {
648 /* FINISHME: Handle access of constant arrays. */
649 }
650 }
Ian Romanickc7b10462010-05-19 13:20:12 +0200651}
652
653
654void
655ir_constant_visitor::visit(ir_dereference_record *ir)
656{
Ian Romanick253dede2010-06-09 17:30:19 -0700657 ir_constant *v = ir->record->constant_expression_value();
658
659 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
Ian Romanick1cf43a42010-03-30 16:56:50 -0700660}
661
662
663void
664ir_constant_visitor::visit(ir_assignment *ir)
665{
666 (void) ir;
667 value = NULL;
668}
669
670
671void
672ir_constant_visitor::visit(ir_constant *ir)
673{
674 value = ir;
675}
676
677
678void
679ir_constant_visitor::visit(ir_call *ir)
680{
681 (void) ir;
682 value = NULL;
683}
684
685
686void
687ir_constant_visitor::visit(ir_return *ir)
688{
689 (void) ir;
690 value = NULL;
691}
692
693
694void
695ir_constant_visitor::visit(ir_if *ir)
696{
697 (void) ir;
698 value = NULL;
699}
Ian Romanickfad607a2010-04-05 16:16:07 -0700700
701
702void
703ir_constant_visitor::visit(ir_loop *ir)
704{
705 (void) ir;
706 value = NULL;
707}
Ian Romanickf8e31e02010-04-05 16:28:15 -0700708
709
710void
711ir_constant_visitor::visit(ir_loop_jump *ir)
712{
713 (void) ir;
714 value = NULL;
715}