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