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