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