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