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