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