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