ir_constant_expression: Add support for the "clamp" builtin.
[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 "main/macros.h"
38 #include "ir.h"
39 #include "ir_visitor.h"
40 #include "glsl_types.h"
41
42 static float
43 dot(ir_constant *op0, ir_constant *op1)
44 {
45 assert(op0->type->is_float() && op1->type->is_float());
46
47 float result = 0;
48 for (unsigned c = 0; c < op0->type->components(); c++)
49 result += op0->value.f[c] * op1->value.f[c];
50
51 return result;
52 }
53
54 ir_constant *
55 ir_expression::constant_expression_value()
56 {
57 ir_constant *op[2] = { NULL, NULL };
58 ir_constant_data data;
59
60 memset(&data, 0, sizeof(data));
61
62 for (unsigned operand = 0; operand < this->get_num_operands(); operand++) {
63 op[operand] = this->operands[operand]->constant_expression_value();
64 if (!op[operand])
65 return NULL;
66 }
67
68 if (op[1] != NULL)
69 assert(op[0]->type->base_type == op[1]->type->base_type);
70
71 bool op0_scalar = op[0]->type->is_scalar();
72 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
73
74 /* When iterating over a vector or matrix's components, we want to increase
75 * the loop counter. However, for scalars, we want to stay at 0.
76 */
77 unsigned c0_inc = op0_scalar ? 0 : 1;
78 unsigned c1_inc = op1_scalar ? 0 : 1;
79 unsigned components;
80 if (op1_scalar || !op[1]) {
81 components = op[0]->type->components();
82 } else {
83 components = op[1]->type->components();
84 }
85
86 void *ctx = talloc_parent(this);
87
88 /* Handle array operations here, rather than below. */
89 if (op[0]->type->is_array()) {
90 assert(op[1] != NULL && op[1]->type->is_array());
91 switch (this->operation) {
92 case ir_binop_equal:
93 return new(ctx) ir_constant(op[0]->has_value(op[1]));
94 case ir_binop_nequal:
95 return new(ctx) ir_constant(!op[0]->has_value(op[1]));
96 default:
97 break;
98 }
99 return NULL;
100 }
101
102 switch (this->operation) {
103 case ir_unop_logic_not:
104 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
105 for (unsigned c = 0; c < op[0]->type->components(); c++)
106 data.b[c] = !op[0]->value.b[c];
107 break;
108
109 case ir_unop_f2i:
110 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
111 for (unsigned c = 0; c < op[0]->type->components(); c++) {
112 data.i[c] = op[0]->value.f[c];
113 }
114 break;
115 case ir_unop_i2f:
116 assert(op[0]->type->base_type == GLSL_TYPE_INT);
117 for (unsigned c = 0; c < op[0]->type->components(); c++) {
118 data.f[c] = op[0]->value.i[c];
119 }
120 break;
121 case ir_unop_u2f:
122 assert(op[0]->type->base_type == GLSL_TYPE_UINT);
123 for (unsigned c = 0; c < op[0]->type->components(); c++) {
124 data.f[c] = op[0]->value.u[c];
125 }
126 break;
127 case ir_unop_b2f:
128 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
129 for (unsigned c = 0; c < op[0]->type->components(); c++) {
130 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0;
131 }
132 break;
133 case ir_unop_f2b:
134 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
135 for (unsigned c = 0; c < op[0]->type->components(); c++) {
136 data.b[c] = bool(op[0]->value.f[c]);
137 }
138 break;
139 case ir_unop_b2i:
140 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
141 for (unsigned c = 0; c < op[0]->type->components(); c++) {
142 data.u[c] = op[0]->value.b[c] ? 1 : 0;
143 }
144 break;
145 case ir_unop_i2b:
146 assert(op[0]->type->is_integer());
147 for (unsigned c = 0; c < op[0]->type->components(); c++) {
148 data.b[c] = bool(op[0]->value.u[c]);
149 }
150 break;
151
152 case ir_unop_trunc:
153 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
154 for (unsigned c = 0; c < op[0]->type->components(); c++) {
155 data.f[c] = truncf(op[0]->value.f[c]);
156 }
157 break;
158
159 case ir_unop_ceil:
160 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
161 for (unsigned c = 0; c < op[0]->type->components(); c++) {
162 data.f[c] = ceilf(op[0]->value.f[c]);
163 }
164 break;
165
166 case ir_unop_floor:
167 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
168 for (unsigned c = 0; c < op[0]->type->components(); c++) {
169 data.f[c] = floorf(op[0]->value.f[c]);
170 }
171 break;
172
173 case ir_unop_fract:
174 for (unsigned c = 0; c < op[0]->type->components(); c++) {
175 switch (this->type->base_type) {
176 case GLSL_TYPE_UINT:
177 data.u[c] = 0;
178 break;
179 case GLSL_TYPE_INT:
180 data.i[c] = 0;
181 break;
182 case GLSL_TYPE_FLOAT:
183 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
184 break;
185 default:
186 assert(0);
187 }
188 }
189 break;
190
191 case ir_unop_sin:
192 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
193 for (unsigned c = 0; c < op[0]->type->components(); c++) {
194 data.f[c] = sinf(op[0]->value.f[c]);
195 }
196 break;
197
198 case ir_unop_cos:
199 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
200 for (unsigned c = 0; c < op[0]->type->components(); c++) {
201 data.f[c] = cosf(op[0]->value.f[c]);
202 }
203 break;
204
205 case ir_unop_neg:
206 for (unsigned c = 0; c < op[0]->type->components(); c++) {
207 switch (this->type->base_type) {
208 case GLSL_TYPE_UINT:
209 data.u[c] = -op[0]->value.u[c];
210 break;
211 case GLSL_TYPE_INT:
212 data.i[c] = -op[0]->value.i[c];
213 break;
214 case GLSL_TYPE_FLOAT:
215 data.f[c] = -op[0]->value.f[c];
216 break;
217 default:
218 assert(0);
219 }
220 }
221 break;
222
223 case ir_unop_abs:
224 for (unsigned c = 0; c < op[0]->type->components(); c++) {
225 switch (this->type->base_type) {
226 case GLSL_TYPE_UINT:
227 data.u[c] = op[0]->value.u[c];
228 break;
229 case GLSL_TYPE_INT:
230 data.i[c] = op[0]->value.i[c];
231 if (data.i[c] < 0)
232 data.i[c] = -data.i[c];
233 break;
234 case GLSL_TYPE_FLOAT:
235 data.f[c] = fabs(op[0]->value.f[c]);
236 break;
237 default:
238 assert(0);
239 }
240 }
241 break;
242
243 case ir_unop_sign:
244 for (unsigned c = 0; c < op[0]->type->components(); c++) {
245 switch (this->type->base_type) {
246 case GLSL_TYPE_UINT:
247 data.u[c] = op[0]->value.i[c] > 0;
248 break;
249 case GLSL_TYPE_INT:
250 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
251 break;
252 case GLSL_TYPE_FLOAT:
253 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
254 break;
255 default:
256 assert(0);
257 }
258 }
259 break;
260
261 case ir_unop_rcp:
262 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
263 for (unsigned c = 0; c < op[0]->type->components(); c++) {
264 switch (this->type->base_type) {
265 case GLSL_TYPE_UINT:
266 if (op[0]->value.u[c] != 0.0)
267 data.u[c] = 1 / op[0]->value.u[c];
268 break;
269 case GLSL_TYPE_INT:
270 if (op[0]->value.i[c] != 0.0)
271 data.i[c] = 1 / op[0]->value.i[c];
272 break;
273 case GLSL_TYPE_FLOAT:
274 if (op[0]->value.f[c] != 0.0)
275 data.f[c] = 1.0 / op[0]->value.f[c];
276 break;
277 default:
278 assert(0);
279 }
280 }
281 break;
282
283 case ir_unop_rsq:
284 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
285 for (unsigned c = 0; c < op[0]->type->components(); c++) {
286 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]);
287 }
288 break;
289
290 case ir_unop_sqrt:
291 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
292 for (unsigned c = 0; c < op[0]->type->components(); c++) {
293 data.f[c] = sqrtf(op[0]->value.f[c]);
294 }
295 break;
296
297 case ir_unop_exp:
298 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
299 for (unsigned c = 0; c < op[0]->type->components(); c++) {
300 data.f[c] = expf(op[0]->value.f[c]);
301 }
302 break;
303
304 case ir_unop_exp2:
305 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
306 for (unsigned c = 0; c < op[0]->type->components(); c++) {
307 data.f[c] = exp2f(op[0]->value.f[c]);
308 }
309 break;
310
311 case ir_unop_log:
312 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
313 for (unsigned c = 0; c < op[0]->type->components(); c++) {
314 data.f[c] = logf(op[0]->value.f[c]);
315 }
316 break;
317
318 case ir_unop_log2:
319 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
320 for (unsigned c = 0; c < op[0]->type->components(); c++) {
321 data.f[c] = log2f(op[0]->value.f[c]);
322 }
323 break;
324
325 case ir_unop_dFdx:
326 case ir_unop_dFdy:
327 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
328 for (unsigned c = 0; c < op[0]->type->components(); c++) {
329 data.f[c] = 0.0;
330 }
331 break;
332
333 case ir_binop_pow:
334 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
335 for (unsigned c = 0; c < op[0]->type->components(); c++) {
336 data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]);
337 }
338 break;
339
340 case ir_binop_dot:
341 data.f[0] = dot(op[0], op[1]);
342 break;
343
344 case ir_binop_min:
345 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
346 for (unsigned c = 0, c0 = 0, c1 = 0;
347 c < components;
348 c0 += c0_inc, c1 += c1_inc, c++) {
349
350 switch (op[0]->type->base_type) {
351 case GLSL_TYPE_UINT:
352 data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]);
353 break;
354 case GLSL_TYPE_INT:
355 data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]);
356 break;
357 case GLSL_TYPE_FLOAT:
358 data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]);
359 break;
360 default:
361 assert(0);
362 }
363 }
364
365 break;
366 case ir_binop_max:
367 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
368 for (unsigned c = 0, c0 = 0, c1 = 0;
369 c < components;
370 c0 += c0_inc, c1 += c1_inc, c++) {
371
372 switch (op[0]->type->base_type) {
373 case GLSL_TYPE_UINT:
374 data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]);
375 break;
376 case GLSL_TYPE_INT:
377 data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]);
378 break;
379 case GLSL_TYPE_FLOAT:
380 data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]);
381 break;
382 default:
383 assert(0);
384 }
385 }
386 break;
387
388 case ir_binop_cross:
389 assert(op[0]->type == glsl_type::vec3_type);
390 assert(op[1]->type == glsl_type::vec3_type);
391 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
392 op[1]->value.f[1] * op[0]->value.f[2]);
393 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
394 op[1]->value.f[2] * op[0]->value.f[0]);
395 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
396 op[1]->value.f[0] * op[0]->value.f[1]);
397 break;
398
399 case ir_binop_add:
400 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
401 for (unsigned c = 0, c0 = 0, c1 = 0;
402 c < components;
403 c0 += c0_inc, c1 += c1_inc, c++) {
404
405 switch (op[0]->type->base_type) {
406 case GLSL_TYPE_UINT:
407 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
408 break;
409 case GLSL_TYPE_INT:
410 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
411 break;
412 case GLSL_TYPE_FLOAT:
413 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
414 break;
415 default:
416 assert(0);
417 }
418 }
419
420 break;
421 case ir_binop_sub:
422 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
423 for (unsigned c = 0, c0 = 0, c1 = 0;
424 c < components;
425 c0 += c0_inc, c1 += c1_inc, c++) {
426
427 switch (op[0]->type->base_type) {
428 case GLSL_TYPE_UINT:
429 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
430 break;
431 case GLSL_TYPE_INT:
432 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
433 break;
434 case GLSL_TYPE_FLOAT:
435 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
436 break;
437 default:
438 assert(0);
439 }
440 }
441
442 break;
443 case ir_binop_mul:
444 /* Check for equal types, or unequal types involving scalars */
445 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
446 || op0_scalar || op1_scalar) {
447 for (unsigned c = 0, c0 = 0, c1 = 0;
448 c < components;
449 c0 += c0_inc, c1 += c1_inc, c++) {
450
451 switch (op[0]->type->base_type) {
452 case GLSL_TYPE_UINT:
453 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
454 break;
455 case GLSL_TYPE_INT:
456 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
457 break;
458 case GLSL_TYPE_FLOAT:
459 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
460 break;
461 default:
462 assert(0);
463 }
464 }
465 } else {
466 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
467
468 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either
469 * matrix can be a GLSL vector, either N or P can be 1.
470 *
471 * For vec*mat, the vector is treated as a row vector. This
472 * means the vector is a 1-row x M-column matrix.
473 *
474 * For mat*vec, the vector is treated as a column vector. Since
475 * matrix_columns is 1 for vectors, this just works.
476 */
477 const unsigned n = op[0]->type->is_vector()
478 ? 1 : op[0]->type->vector_elements;
479 const unsigned m = op[1]->type->vector_elements;
480 const unsigned p = op[1]->type->matrix_columns;
481 for (unsigned j = 0; j < p; j++) {
482 for (unsigned i = 0; i < n; i++) {
483 for (unsigned k = 0; k < m; k++) {
484 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
485 }
486 }
487 }
488 }
489
490 break;
491 case ir_binop_div:
492 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
493 for (unsigned c = 0, c0 = 0, c1 = 0;
494 c < components;
495 c0 += c0_inc, c1 += c1_inc, c++) {
496
497 switch (op[0]->type->base_type) {
498 case GLSL_TYPE_UINT:
499 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
500 break;
501 case GLSL_TYPE_INT:
502 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
503 break;
504 case GLSL_TYPE_FLOAT:
505 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
506 break;
507 default:
508 assert(0);
509 }
510 }
511
512 break;
513 case ir_binop_mod:
514 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
515 for (unsigned c = 0, c0 = 0, c1 = 0;
516 c < components;
517 c0 += c0_inc, c1 += c1_inc, c++) {
518
519 switch (op[0]->type->base_type) {
520 case GLSL_TYPE_UINT:
521 data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
522 break;
523 case GLSL_TYPE_INT:
524 data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
525 break;
526 case GLSL_TYPE_FLOAT:
527 /* We don't use fmod because it rounds toward zero; GLSL specifies
528 * the use of floor.
529 */
530 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]
531 * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
532 break;
533 default:
534 assert(0);
535 }
536 }
537
538 break;
539
540 case ir_binop_logic_and:
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 case ir_binop_logic_xor:
546 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
547 for (unsigned c = 0; c < op[0]->type->components(); c++)
548 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
549 break;
550 case ir_binop_logic_or:
551 assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
552 for (unsigned c = 0; c < op[0]->type->components(); c++)
553 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
554 break;
555
556 case ir_binop_less:
557 switch (op[0]->type->base_type) {
558 case GLSL_TYPE_UINT:
559 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
560 break;
561 case GLSL_TYPE_INT:
562 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
563 break;
564 case GLSL_TYPE_FLOAT:
565 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
566 break;
567 default:
568 assert(0);
569 }
570 break;
571 case ir_binop_greater:
572 switch (op[0]->type->base_type) {
573 case GLSL_TYPE_UINT:
574 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
575 break;
576 case GLSL_TYPE_INT:
577 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
578 break;
579 case GLSL_TYPE_FLOAT:
580 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
581 break;
582 default:
583 assert(0);
584 }
585 break;
586 case ir_binop_lequal:
587 switch (op[0]->type->base_type) {
588 case GLSL_TYPE_UINT:
589 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
590 break;
591 case GLSL_TYPE_INT:
592 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
593 break;
594 case GLSL_TYPE_FLOAT:
595 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
596 break;
597 default:
598 assert(0);
599 }
600 break;
601 case ir_binop_gequal:
602 switch (op[0]->type->base_type) {
603 case GLSL_TYPE_UINT:
604 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
605 break;
606 case GLSL_TYPE_INT:
607 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
608 break;
609 case GLSL_TYPE_FLOAT:
610 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
611 break;
612 default:
613 assert(0);
614 }
615 break;
616
617 case ir_binop_equal:
618 data.b[0] = op[0]->has_value(op[1]);
619 break;
620 case ir_binop_nequal:
621 data.b[0] = !op[0]->has_value(op[1]);
622 break;
623
624 default:
625 /* FINISHME: Should handle all expression types. */
626 return NULL;
627 }
628
629 return new(ctx) ir_constant(this->type, &data);
630 }
631
632
633 ir_constant *
634 ir_texture::constant_expression_value()
635 {
636 /* texture lookups aren't constant expressions */
637 return NULL;
638 }
639
640
641 ir_constant *
642 ir_swizzle::constant_expression_value()
643 {
644 ir_constant *v = this->val->constant_expression_value();
645
646 if (v != NULL) {
647 ir_constant_data data;
648
649 const unsigned swiz_idx[4] = {
650 this->mask.x, this->mask.y, this->mask.z, this->mask.w
651 };
652
653 for (unsigned i = 0; i < this->mask.num_components; i++) {
654 switch (v->type->base_type) {
655 case GLSL_TYPE_UINT:
656 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break;
657 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
658 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break;
659 default: assert(!"Should not get here."); break;
660 }
661 }
662
663 void *ctx = talloc_parent(this);
664 return new(ctx) ir_constant(this->type, &data);
665 }
666 return NULL;
667 }
668
669
670 ir_constant *
671 ir_dereference_variable::constant_expression_value()
672 {
673 /* This may occur during compile and var->type is glsl_type::error_type */
674 if (!var)
675 return NULL;
676
677 return var->constant_value ? var->constant_value->clone(NULL) : NULL;
678 }
679
680
681 ir_constant *
682 ir_dereference_array::constant_expression_value()
683 {
684 void *ctx = talloc_parent(this);
685 ir_constant *array = this->array->constant_expression_value();
686 ir_constant *idx = this->array_index->constant_expression_value();
687
688 if ((array != NULL) && (idx != NULL)) {
689 if (array->type->is_matrix()) {
690 /* Array access of a matrix results in a vector.
691 */
692 const unsigned column = idx->value.u[0];
693
694 const glsl_type *const column_type = array->type->column_type();
695
696 /* Offset in the constant matrix to the first element of the column
697 * to be extracted.
698 */
699 const unsigned mat_idx = column * column_type->vector_elements;
700
701 ir_constant_data data;
702
703 switch (column_type->base_type) {
704 case GLSL_TYPE_UINT:
705 case GLSL_TYPE_INT:
706 for (unsigned i = 0; i < column_type->vector_elements; i++)
707 data.u[i] = array->value.u[mat_idx + i];
708
709 break;
710
711 case GLSL_TYPE_FLOAT:
712 for (unsigned i = 0; i < column_type->vector_elements; i++)
713 data.f[i] = array->value.f[mat_idx + i];
714
715 break;
716
717 default:
718 assert(!"Should not get here.");
719 break;
720 }
721
722 return new(ctx) ir_constant(column_type, &data);
723 } else if (array->type->is_vector()) {
724 const unsigned component = idx->value.u[0];
725
726 return new(ctx) ir_constant(array, component);
727 } else {
728 const unsigned index = idx->value.u[0];
729 return array->get_array_element(index)->clone(NULL);
730 }
731 }
732 return NULL;
733 }
734
735
736 ir_constant *
737 ir_dereference_record::constant_expression_value()
738 {
739 ir_constant *v = this->record->constant_expression_value();
740
741 return (v != NULL) ? v->get_record_field(this->field) : NULL;
742 }
743
744
745 ir_constant *
746 ir_assignment::constant_expression_value()
747 {
748 /* FINISHME: Handle CEs involving assignment (return RHS) */
749 return NULL;
750 }
751
752
753 ir_constant *
754 ir_constant::constant_expression_value()
755 {
756 return this;
757 }
758
759
760 ir_constant *
761 ir_call::constant_expression_value()
762 {
763 if (this->type == glsl_type::error_type)
764 return NULL;
765
766 /* From the GLSL 1.20 spec, page 23:
767 * "Function calls to user-defined functions (non-built-in functions)
768 * cannot be used to form constant expressions."
769 */
770 if (!this->callee->is_built_in)
771 return NULL;
772
773 unsigned num_parameters = 0;
774
775 /* Check if all parameters are constant */
776 ir_constant *op[3];
777 foreach_list(n, &this->actual_parameters) {
778 ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value();
779 if (constant == NULL)
780 return NULL;
781
782 op[num_parameters] = constant;
783
784 assert(num_parameters < 3);
785 num_parameters++;
786 }
787
788 /* Individual cases below can either:
789 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
790 * - Fill "data" with appopriate constant data
791 * - Return an ir_constant directly.
792 */
793 void *mem_ctx = talloc_parent(this);
794 ir_expression *expr = NULL;
795
796 ir_constant_data data;
797 memset(&data, 0, sizeof(data));
798
799 const char *callee = this->callee_name();
800 if (strcmp(callee, "abs") == 0) {
801 expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL);
802 } else if (strcmp(callee, "all") == 0) {
803 assert(op[0]->type->is_boolean());
804 for (unsigned c = 0; c < op[0]->type->components(); c++) {
805 if (!op[0]->value.b[c])
806 return new(mem_ctx) ir_constant(false);
807 }
808 return new(mem_ctx) ir_constant(true);
809 } else if (strcmp(callee, "any") == 0) {
810 assert(op[0]->type->is_boolean());
811 for (unsigned c = 0; c < op[0]->type->components(); c++) {
812 if (op[0]->value.b[c])
813 return new(mem_ctx) ir_constant(true);
814 }
815 return new(mem_ctx) ir_constant(false);
816 } else if (strcmp(callee, "acos") == 0) {
817 assert(op[0]->type->is_float());
818 for (unsigned c = 0; c < op[0]->type->components(); c++)
819 data.f[c] = acosf(op[0]->value.f[c]);
820 } else if (strcmp(callee, "asin") == 0) {
821 assert(op[0]->type->is_float());
822 for (unsigned c = 0; c < op[0]->type->components(); c++)
823 data.f[c] = asinf(op[0]->value.f[c]);
824 } else if (strcmp(callee, "atan") == 0) {
825 assert(op[0]->type->is_float());
826 if (num_parameters == 2) {
827 assert(op[1]->type->is_float());
828 for (unsigned c = 0; c < op[0]->type->components(); c++)
829 data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]);
830 } else {
831 for (unsigned c = 0; c < op[0]->type->components(); c++)
832 data.f[c] = atanf(op[0]->value.f[c]);
833 }
834 } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) {
835 return ir_constant::zero(mem_ctx, this->type);
836 } else if (strcmp(callee, "ceil") == 0) {
837 expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL);
838 } else if (strcmp(callee, "clamp") == 0) {
839 assert(num_parameters == 3);
840 unsigned c1_inc = op[1]->type->is_scalar() ? 0 : 1;
841 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
842 for (unsigned c = 0, c1 = 0, c2 = 0;
843 c < op[0]->type->components();
844 c1 += c1_inc, c2 += c2_inc, c++) {
845
846 switch (op[0]->type->base_type) {
847 case GLSL_TYPE_UINT:
848 data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1],
849 op[2]->value.u[c2]);
850 break;
851 case GLSL_TYPE_INT:
852 data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1],
853 op[2]->value.u[c2]);
854 break;
855 case GLSL_TYPE_FLOAT:
856 data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1],
857 op[2]->value.f[c2]);
858 break;
859 default:
860 assert(!"Should not get here.");
861 }
862 }
863 } else if (strcmp(callee, "cos") == 0) {
864 expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL);
865 } else if (strcmp(callee, "cosh") == 0) {
866 assert(op[0]->type->is_float());
867 for (unsigned c = 0; c < op[0]->type->components(); c++)
868 data.f[c] = coshf(op[0]->value.f[c]);
869 } else if (strcmp(callee, "cross") == 0) {
870 expr = new(mem_ctx) ir_expression(ir_binop_cross, type, op[0], op[1]);
871 } else if (strcmp(callee, "degrees") == 0) {
872 assert(op[0]->type->is_float());
873 for (unsigned c = 0; c < op[0]->type->components(); c++)
874 data.f[c] = 180.0/M_PI * op[0]->value.f[c];
875 } else if (strcmp(callee, "distance") == 0) {
876 assert(op[0]->type->is_float() && op[1]->type->is_float());
877 float length_squared = 0.0;
878 for (unsigned c = 0; c < op[0]->type->components(); c++) {
879 float t = op[0]->value.f[c] - op[1]->value.f[c];
880 length_squared += t * t;
881 }
882 return new(mem_ctx) ir_constant(sqrtf(length_squared));
883 } else if (strcmp(callee, "dot") == 0) {
884 return new(mem_ctx) ir_constant(dot(op[0], op[1]));
885 } else if (strcmp(callee, "equal") == 0) {
886 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
887 for (unsigned c = 0; c < op[0]->type->components(); c++) {
888 switch (op[0]->type->base_type) {
889 case GLSL_TYPE_UINT:
890 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
891 break;
892 case GLSL_TYPE_INT:
893 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
894 break;
895 case GLSL_TYPE_FLOAT:
896 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
897 break;
898 default:
899 assert(!"Should not get here.");
900 }
901 }
902 } else if (strcmp(callee, "exp") == 0) {
903 expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL);
904 } else if (strcmp(callee, "exp2") == 0) {
905 expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL);
906 } else if (strcmp(callee, "faceforward") == 0) {
907 if (dot(op[2], op[1]) < 0)
908 return op[0];
909 for (unsigned c = 0; c < op[0]->type->components(); c++)
910 data.f[c] = -op[0]->value.f[c];
911 } else if (strcmp(callee, "floor") == 0) {
912 expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL);
913 } else if (strcmp(callee, "fract") == 0) {
914 expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL);
915 } else if (strcmp(callee, "fwidth") == 0) {
916 return ir_constant::zero(mem_ctx, this->type);
917 } else if (strcmp(callee, "greaterThan") == 0) {
918 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
919 for (unsigned c = 0; c < op[0]->type->components(); c++) {
920 switch (op[0]->type->base_type) {
921 case GLSL_TYPE_UINT:
922 data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
923 break;
924 case GLSL_TYPE_INT:
925 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
926 break;
927 case GLSL_TYPE_FLOAT:
928 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
929 break;
930 default:
931 assert(!"Should not get here.");
932 }
933 }
934 } else if (strcmp(callee, "greaterThanEqual") == 0) {
935 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
936 for (unsigned c = 0; c < op[0]->type->components(); c++) {
937 switch (op[0]->type->base_type) {
938 case GLSL_TYPE_UINT:
939 data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c];
940 break;
941 case GLSL_TYPE_INT:
942 data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c];
943 break;
944 case GLSL_TYPE_FLOAT:
945 data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c];
946 break;
947 default:
948 assert(!"Should not get here.");
949 }
950 }
951 } else if (strcmp(callee, "inversesqrt") == 0) {
952 expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL);
953 } else if (strcmp(callee, "length") == 0) {
954 return new(mem_ctx) ir_constant(sqrtf(dot(op[0], op[0])));
955 } else if (strcmp(callee, "lessThan") == 0) {
956 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
957 for (unsigned c = 0; c < op[0]->type->components(); c++) {
958 switch (op[0]->type->base_type) {
959 case GLSL_TYPE_UINT:
960 data.b[c] = op[0]->value.u[c] < op[1]->value.u[c];
961 break;
962 case GLSL_TYPE_INT:
963 data.b[c] = op[0]->value.i[c] < op[1]->value.i[c];
964 break;
965 case GLSL_TYPE_FLOAT:
966 data.b[c] = op[0]->value.f[c] < op[1]->value.f[c];
967 break;
968 default:
969 assert(!"Should not get here.");
970 }
971 }
972 } else if (strcmp(callee, "lessThanEqual") == 0) {
973 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
974 for (unsigned c = 0; c < op[0]->type->components(); c++) {
975 switch (op[0]->type->base_type) {
976 case GLSL_TYPE_UINT:
977 data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c];
978 break;
979 case GLSL_TYPE_INT:
980 data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c];
981 break;
982 case GLSL_TYPE_FLOAT:
983 data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c];
984 break;
985 default:
986 assert(!"Should not get here.");
987 }
988 }
989 } else if (strcmp(callee, "log") == 0) {
990 expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL);
991 } else if (strcmp(callee, "log2") == 0) {
992 expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL);
993 } else if (strcmp(callee, "matrixCompMult") == 0) {
994 assert(op[0]->type->is_float() && op[1]->type->is_float());
995 for (unsigned c = 0; c < op[0]->type->components(); c++)
996 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
997 } else if (strcmp(callee, "max") == 0) {
998 expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]);
999 } else if (strcmp(callee, "min") == 0) {
1000 expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]);
1001 } else if (strcmp(callee, "mix") == 0) {
1002 return NULL; /* FINISHME: implement this */
1003 } else if (strcmp(callee, "mod") == 0) {
1004 expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]);
1005 } else if (strcmp(callee, "normalize") == 0) {
1006 assert(op[0]->type->is_float());
1007 float length = sqrtf(dot(op[0], op[0]));
1008
1009 if (length == 0)
1010 return ir_constant::zero(mem_ctx, this->type);
1011
1012 for (unsigned c = 0; c < op[0]->type->components(); c++)
1013 data.f[c] = op[0]->value.f[c] / length;
1014 } else if (strcmp(callee, "not") == 0) {
1015 expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL);
1016 } else if (strcmp(callee, "notEqual") == 0) {
1017 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
1018 for (unsigned c = 0; c < op[0]->type->components(); c++) {
1019 switch (op[0]->type->base_type) {
1020 case GLSL_TYPE_UINT:
1021 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
1022 break;
1023 case GLSL_TYPE_INT:
1024 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
1025 break;
1026 case GLSL_TYPE_FLOAT:
1027 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
1028 break;
1029 default:
1030 assert(!"Should not get here.");
1031 }
1032 }
1033 } else if (strcmp(callee, "outerProduct") == 0) {
1034 return NULL; /* FINISHME: implement this */
1035 } else if (strcmp(callee, "pow") == 0) {
1036 expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]);
1037 } else if (strcmp(callee, "radians") == 0) {
1038 assert(op[0]->type->is_float());
1039 for (unsigned c = 0; c < op[0]->type->components(); c++)
1040 data.f[c] = M_PI/180.0 * op[0]->value.f[c];
1041 } else if (strcmp(callee, "reflect") == 0) {
1042 assert(op[0]->type->is_float());
1043 float dot_NI = dot(op[1], op[0]);
1044 for (unsigned c = 0; c < op[0]->type->components(); c++)
1045 data.f[c] = op[0]->value.f[c] - 2 * dot_NI * op[1]->value.f[c];
1046 } else if (strcmp(callee, "refract") == 0) {
1047 const float eta = op[2]->value.f[0];
1048 const float dot_NI = dot(op[1], op[0]);
1049 const float k = 1.0 - eta * eta * (1.0 - dot_NI * dot_NI);
1050 if (k < 0.0) {
1051 return ir_constant::zero(mem_ctx, this->type);
1052 } else {
1053 for (unsigned c = 0; c < type->components(); c++) {
1054 data.f[c] = eta * op[0]->value.f[c] - (eta * dot_NI + sqrtf(k))
1055 * op[1]->value.f[c];
1056 }
1057 }
1058 } else if (strcmp(callee, "sign") == 0) {
1059 expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
1060 } else if (strcmp(callee, "sin") == 0) {
1061 expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL);
1062 } else if (strcmp(callee, "sinh") == 0) {
1063 assert(op[0]->type->is_float());
1064 for (unsigned c = 0; c < op[0]->type->components(); c++)
1065 data.f[c] = sinhf(op[0]->value.f[c]);
1066 } else if (strcmp(callee, "smoothstep") == 0) {
1067 return NULL; /* FINISHME: implement this */
1068 } else if (strcmp(callee, "sqrt") == 0) {
1069 expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL);
1070 } else if (strcmp(callee, "step") == 0) {
1071 assert(op[0]->type->is_float() && op[1]->type->is_float());
1072 /* op[0] (edge) may be either a scalar or a vector */
1073 const unsigned c0_inc = op[0]->type->is_scalar() ? 0 : 1;
1074 for (unsigned c = 0, c0 = 0; c < type->components(); c0 += c0_inc, c++)
1075 data.f[c] = (op[1]->value.f[c] < op[0]->value.f[c0]) ? 0.0 : 1.0;
1076 } else if (strcmp(callee, "tan") == 0) {
1077 assert(op[0]->type->is_float());
1078 for (unsigned c = 0; c < op[0]->type->components(); c++)
1079 data.f[c] = tanf(op[0]->value.f[c]);
1080 } else if (strcmp(callee, "tanh") == 0) {
1081 assert(op[0]->type->is_float());
1082 for (unsigned c = 0; c < op[0]->type->components(); c++)
1083 data.f[c] = tanhf(op[0]->value.f[c]);
1084 } else if (strcmp(callee, "transpose") == 0) {
1085 return NULL; /* FINISHME: implement this */
1086 } else {
1087 /* Unsupported builtin - some are not allowed in constant expressions. */
1088 return NULL;
1089 }
1090
1091 if (expr != NULL)
1092 return expr->constant_expression_value();
1093
1094 return new(mem_ctx) ir_constant(this->type, &data);
1095 }