ir_constant_expression.cpp revision 1591693c7b415e9869157c711fe11263c95d74e7
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 = talloc_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 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 314 for (unsigned c = 0; c < op[0]->type->components(); c++) { 315 data.f[c] = 1.0F / sqrtf(op[0]->value.f[c]); 316 } 317 break; 318 319 case ir_unop_sqrt: 320 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 321 for (unsigned c = 0; c < op[0]->type->components(); c++) { 322 data.f[c] = sqrtf(op[0]->value.f[c]); 323 } 324 break; 325 326 case ir_unop_exp: 327 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 328 for (unsigned c = 0; c < op[0]->type->components(); c++) { 329 data.f[c] = expf(op[0]->value.f[c]); 330 } 331 break; 332 333 case ir_unop_exp2: 334 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 335 for (unsigned c = 0; c < op[0]->type->components(); c++) { 336 data.f[c] = exp2f(op[0]->value.f[c]); 337 } 338 break; 339 340 case ir_unop_log: 341 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 342 for (unsigned c = 0; c < op[0]->type->components(); c++) { 343 data.f[c] = logf(op[0]->value.f[c]); 344 } 345 break; 346 347 case ir_unop_log2: 348 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 349 for (unsigned c = 0; c < op[0]->type->components(); c++) { 350 data.f[c] = log2f(op[0]->value.f[c]); 351 } 352 break; 353 354 case ir_unop_dFdx: 355 case ir_unop_dFdy: 356 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 357 for (unsigned c = 0; c < op[0]->type->components(); c++) { 358 data.f[c] = 0.0; 359 } 360 break; 361 362 case ir_binop_pow: 363 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 364 for (unsigned c = 0; c < op[0]->type->components(); c++) { 365 data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]); 366 } 367 break; 368 369 case ir_binop_dot: 370 data.f[0] = dot(op[0], op[1]); 371 break; 372 373 case ir_binop_min: 374 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 375 for (unsigned c = 0, c0 = 0, c1 = 0; 376 c < components; 377 c0 += c0_inc, c1 += c1_inc, c++) { 378 379 switch (op[0]->type->base_type) { 380 case GLSL_TYPE_UINT: 381 data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]); 382 break; 383 case GLSL_TYPE_INT: 384 data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]); 385 break; 386 case GLSL_TYPE_FLOAT: 387 data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]); 388 break; 389 default: 390 assert(0); 391 } 392 } 393 394 break; 395 case ir_binop_max: 396 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 397 for (unsigned c = 0, c0 = 0, c1 = 0; 398 c < components; 399 c0 += c0_inc, c1 += c1_inc, c++) { 400 401 switch (op[0]->type->base_type) { 402 case GLSL_TYPE_UINT: 403 data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]); 404 break; 405 case GLSL_TYPE_INT: 406 data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]); 407 break; 408 case GLSL_TYPE_FLOAT: 409 data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]); 410 break; 411 default: 412 assert(0); 413 } 414 } 415 break; 416 417 case ir_binop_add: 418 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 419 for (unsigned c = 0, c0 = 0, c1 = 0; 420 c < components; 421 c0 += c0_inc, c1 += c1_inc, c++) { 422 423 switch (op[0]->type->base_type) { 424 case GLSL_TYPE_UINT: 425 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1]; 426 break; 427 case GLSL_TYPE_INT: 428 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1]; 429 break; 430 case GLSL_TYPE_FLOAT: 431 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1]; 432 break; 433 default: 434 assert(0); 435 } 436 } 437 438 break; 439 case ir_binop_sub: 440 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 441 for (unsigned c = 0, c0 = 0, c1 = 0; 442 c < components; 443 c0 += c0_inc, c1 += c1_inc, c++) { 444 445 switch (op[0]->type->base_type) { 446 case GLSL_TYPE_UINT: 447 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1]; 448 break; 449 case GLSL_TYPE_INT: 450 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1]; 451 break; 452 case GLSL_TYPE_FLOAT: 453 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]; 454 break; 455 default: 456 assert(0); 457 } 458 } 459 460 break; 461 case ir_binop_mul: 462 /* Check for equal types, or unequal types involving scalars */ 463 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix()) 464 || op0_scalar || op1_scalar) { 465 for (unsigned c = 0, c0 = 0, c1 = 0; 466 c < components; 467 c0 += c0_inc, c1 += c1_inc, c++) { 468 469 switch (op[0]->type->base_type) { 470 case GLSL_TYPE_UINT: 471 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1]; 472 break; 473 case GLSL_TYPE_INT: 474 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1]; 475 break; 476 case GLSL_TYPE_FLOAT: 477 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1]; 478 break; 479 default: 480 assert(0); 481 } 482 } 483 } else { 484 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix()); 485 486 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either 487 * matrix can be a GLSL vector, either N or P can be 1. 488 * 489 * For vec*mat, the vector is treated as a row vector. This 490 * means the vector is a 1-row x M-column matrix. 491 * 492 * For mat*vec, the vector is treated as a column vector. Since 493 * matrix_columns is 1 for vectors, this just works. 494 */ 495 const unsigned n = op[0]->type->is_vector() 496 ? 1 : op[0]->type->vector_elements; 497 const unsigned m = op[1]->type->vector_elements; 498 const unsigned p = op[1]->type->matrix_columns; 499 for (unsigned j = 0; j < p; j++) { 500 for (unsigned i = 0; i < n; i++) { 501 for (unsigned k = 0; k < m; k++) { 502 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j]; 503 } 504 } 505 } 506 } 507 508 break; 509 case ir_binop_div: 510 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 511 for (unsigned c = 0, c0 = 0, c1 = 0; 512 c < components; 513 c0 += c0_inc, c1 += c1_inc, c++) { 514 515 switch (op[0]->type->base_type) { 516 case GLSL_TYPE_UINT: 517 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1]; 518 break; 519 case GLSL_TYPE_INT: 520 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1]; 521 break; 522 case GLSL_TYPE_FLOAT: 523 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1]; 524 break; 525 default: 526 assert(0); 527 } 528 } 529 530 break; 531 case ir_binop_mod: 532 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 533 for (unsigned c = 0, c0 = 0, c1 = 0; 534 c < components; 535 c0 += c0_inc, c1 += c1_inc, c++) { 536 537 switch (op[0]->type->base_type) { 538 case GLSL_TYPE_UINT: 539 data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1]; 540 break; 541 case GLSL_TYPE_INT: 542 data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1]; 543 break; 544 case GLSL_TYPE_FLOAT: 545 /* We don't use fmod because it rounds toward zero; GLSL specifies 546 * the use of floor. 547 */ 548 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1] 549 * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]); 550 break; 551 default: 552 assert(0); 553 } 554 } 555 556 break; 557 558 case ir_binop_logic_and: 559 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 560 for (unsigned c = 0; c < op[0]->type->components(); c++) 561 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c]; 562 break; 563 case ir_binop_logic_xor: 564 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 565 for (unsigned c = 0; c < op[0]->type->components(); c++) 566 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c]; 567 break; 568 case ir_binop_logic_or: 569 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 570 for (unsigned c = 0; c < op[0]->type->components(); c++) 571 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c]; 572 break; 573 574 case ir_binop_less: 575 assert(op[0]->type == op[1]->type); 576 for (unsigned c = 0; c < op[0]->type->components(); c++) { 577 switch (op[0]->type->base_type) { 578 case GLSL_TYPE_UINT: 579 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0]; 580 break; 581 case GLSL_TYPE_INT: 582 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0]; 583 break; 584 case GLSL_TYPE_FLOAT: 585 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0]; 586 break; 587 default: 588 assert(0); 589 } 590 } 591 break; 592 case ir_binop_greater: 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[c] = op[0]->value.u[c] > op[1]->value.u[c]; 598 break; 599 case GLSL_TYPE_INT: 600 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c]; 601 break; 602 case GLSL_TYPE_FLOAT: 603 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c]; 604 break; 605 default: 606 assert(0); 607 } 608 } 609 break; 610 case ir_binop_lequal: 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[0] = op[0]->value.u[0] <= op[1]->value.u[0]; 616 break; 617 case GLSL_TYPE_INT: 618 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0]; 619 break; 620 case GLSL_TYPE_FLOAT: 621 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0]; 622 break; 623 default: 624 assert(0); 625 } 626 } 627 break; 628 case ir_binop_gequal: 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_equal: 647 assert(op[0]->type == op[1]->type); 648 for (unsigned c = 0; c < components; c++) { 649 switch (op[0]->type->base_type) { 650 case GLSL_TYPE_UINT: 651 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c]; 652 break; 653 case GLSL_TYPE_INT: 654 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c]; 655 break; 656 case GLSL_TYPE_FLOAT: 657 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c]; 658 break; 659 default: 660 assert(0); 661 } 662 } 663 break; 664 case ir_binop_nequal: 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_all_equal: 683 data.b[0] = op[0]->has_value(op[1]); 684 break; 685 case ir_binop_any_nequal: 686 data.b[0] = !op[0]->has_value(op[1]); 687 break; 688 689 case ir_binop_lshift: 690 for (unsigned c = 0, c0 = 0, c1 = 0; 691 c < components; 692 c0 += c0_inc, c1 += c1_inc, c++) { 693 694 if (op[0]->type->base_type == GLSL_TYPE_INT && 695 op[1]->type->base_type == GLSL_TYPE_INT) { 696 data.i[c] = op[0]->value.i[c0] << op[1]->value.i[c1]; 697 698 } else if (op[0]->type->base_type == GLSL_TYPE_INT && 699 op[1]->type->base_type == GLSL_TYPE_UINT) { 700 data.i[c] = op[0]->value.i[c0] << op[1]->value.u[c1]; 701 702 } else if (op[0]->type->base_type == GLSL_TYPE_UINT && 703 op[1]->type->base_type == GLSL_TYPE_INT) { 704 data.u[c] = op[0]->value.u[c0] << op[1]->value.i[c1]; 705 706 } else if (op[0]->type->base_type == GLSL_TYPE_UINT && 707 op[1]->type->base_type == GLSL_TYPE_UINT) { 708 data.u[c] = op[0]->value.u[c0] << op[1]->value.u[c1]; 709 } 710 } 711 break; 712 713 case ir_binop_rshift: 714 for (unsigned c = 0, c0 = 0, c1 = 0; 715 c < components; 716 c0 += c0_inc, c1 += c1_inc, c++) { 717 718 if (op[0]->type->base_type == GLSL_TYPE_INT && 719 op[1]->type->base_type == GLSL_TYPE_INT) { 720 data.i[c] = op[0]->value.i[c0] >> op[1]->value.i[c1]; 721 722 } else if (op[0]->type->base_type == GLSL_TYPE_INT && 723 op[1]->type->base_type == GLSL_TYPE_UINT) { 724 data.i[c] = op[0]->value.i[c0] >> op[1]->value.u[c1]; 725 726 } else if (op[0]->type->base_type == GLSL_TYPE_UINT && 727 op[1]->type->base_type == GLSL_TYPE_INT) { 728 data.u[c] = op[0]->value.u[c0] >> op[1]->value.i[c1]; 729 730 } else if (op[0]->type->base_type == GLSL_TYPE_UINT && 731 op[1]->type->base_type == GLSL_TYPE_UINT) { 732 data.u[c] = op[0]->value.u[c0] >> op[1]->value.u[c1]; 733 } 734 } 735 break; 736 737 case ir_binop_bit_and: 738 for (unsigned c = 0, c0 = 0, c1 = 0; 739 c < components; 740 c0 += c0_inc, c1 += c1_inc, c++) { 741 742 switch (op[0]->type->base_type) { 743 case GLSL_TYPE_INT: 744 data.i[c] = op[0]->value.i[c0] & op[1]->value.i[c1]; 745 break; 746 case GLSL_TYPE_UINT: 747 data.u[c] = op[0]->value.u[c0] & op[1]->value.u[c1]; 748 break; 749 default: 750 assert(0); 751 } 752 } 753 break; 754 755 case ir_binop_bit_or: 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_xor: 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_quadop_vector: 792 for (unsigned c = 0; c < this->type->vector_elements; c++) { 793 switch (this->type->base_type) { 794 case GLSL_TYPE_INT: 795 data.i[c] = op[c]->value.i[0]; 796 break; 797 case GLSL_TYPE_UINT: 798 data.u[c] = op[c]->value.u[0]; 799 break; 800 case GLSL_TYPE_FLOAT: 801 data.f[c] = op[c]->value.f[0]; 802 break; 803 default: 804 assert(0); 805 } 806 } 807 break; 808 809 default: 810 /* FINISHME: Should handle all expression types. */ 811 return NULL; 812 } 813 814 return new(ctx) ir_constant(this->type, &data); 815} 816 817 818ir_constant * 819ir_texture::constant_expression_value() 820{ 821 /* texture lookups aren't constant expressions */ 822 return NULL; 823} 824 825 826ir_constant * 827ir_swizzle::constant_expression_value() 828{ 829 ir_constant *v = this->val->constant_expression_value(); 830 831 if (v != NULL) { 832 ir_constant_data data = { { 0 } }; 833 834 const unsigned swiz_idx[4] = { 835 this->mask.x, this->mask.y, this->mask.z, this->mask.w 836 }; 837 838 for (unsigned i = 0; i < this->mask.num_components; i++) { 839 switch (v->type->base_type) { 840 case GLSL_TYPE_UINT: 841 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break; 842 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break; 843 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break; 844 default: assert(!"Should not get here."); break; 845 } 846 } 847 848 void *ctx = talloc_parent(this); 849 return new(ctx) ir_constant(this->type, &data); 850 } 851 return NULL; 852} 853 854 855ir_constant * 856ir_dereference_variable::constant_expression_value() 857{ 858 /* This may occur during compile and var->type is glsl_type::error_type */ 859 if (!var) 860 return NULL; 861 862 /* The constant_value of a uniform variable is its initializer, 863 * not the lifetime constant value of the uniform. 864 */ 865 if (var->mode == ir_var_uniform) 866 return NULL; 867 868 if (!var->constant_value) 869 return NULL; 870 871 return var->constant_value->clone(talloc_parent(var), NULL); 872} 873 874 875ir_constant * 876ir_dereference_array::constant_expression_value() 877{ 878 ir_constant *array = this->array->constant_expression_value(); 879 ir_constant *idx = this->array_index->constant_expression_value(); 880 881 if ((array != NULL) && (idx != NULL)) { 882 void *ctx = talloc_parent(this); 883 if (array->type->is_matrix()) { 884 /* Array access of a matrix results in a vector. 885 */ 886 const unsigned column = idx->value.u[0]; 887 888 const glsl_type *const column_type = array->type->column_type(); 889 890 /* Offset in the constant matrix to the first element of the column 891 * to be extracted. 892 */ 893 const unsigned mat_idx = column * column_type->vector_elements; 894 895 ir_constant_data data = { { 0 } }; 896 897 switch (column_type->base_type) { 898 case GLSL_TYPE_UINT: 899 case GLSL_TYPE_INT: 900 for (unsigned i = 0; i < column_type->vector_elements; i++) 901 data.u[i] = array->value.u[mat_idx + i]; 902 903 break; 904 905 case GLSL_TYPE_FLOAT: 906 for (unsigned i = 0; i < column_type->vector_elements; i++) 907 data.f[i] = array->value.f[mat_idx + i]; 908 909 break; 910 911 default: 912 assert(!"Should not get here."); 913 break; 914 } 915 916 return new(ctx) ir_constant(column_type, &data); 917 } else if (array->type->is_vector()) { 918 const unsigned component = idx->value.u[0]; 919 920 return new(ctx) ir_constant(array, component); 921 } else { 922 const unsigned index = idx->value.u[0]; 923 return array->get_array_element(index)->clone(ctx, NULL); 924 } 925 } 926 return NULL; 927} 928 929 930ir_constant * 931ir_dereference_record::constant_expression_value() 932{ 933 ir_constant *v = this->record->constant_expression_value(); 934 935 return (v != NULL) ? v->get_record_field(this->field) : NULL; 936} 937 938 939ir_constant * 940ir_assignment::constant_expression_value() 941{ 942 /* FINISHME: Handle CEs involving assignment (return RHS) */ 943 return NULL; 944} 945 946 947ir_constant * 948ir_constant::constant_expression_value() 949{ 950 return this; 951} 952 953 954ir_constant * 955ir_call::constant_expression_value() 956{ 957 if (this->type == glsl_type::error_type) 958 return NULL; 959 960 /* From the GLSL 1.20 spec, page 23: 961 * "Function calls to user-defined functions (non-built-in functions) 962 * cannot be used to form constant expressions." 963 */ 964 if (!this->callee->is_builtin) 965 return NULL; 966 967 unsigned num_parameters = 0; 968 969 /* Check if all parameters are constant */ 970 ir_constant *op[3]; 971 foreach_list(n, &this->actual_parameters) { 972 ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value(); 973 if (constant == NULL) 974 return NULL; 975 976 op[num_parameters] = constant; 977 978 assert(num_parameters < 3); 979 num_parameters++; 980 } 981 982 /* Individual cases below can either: 983 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes) 984 * - Fill "data" with appopriate constant data 985 * - Return an ir_constant directly. 986 */ 987 void *mem_ctx = talloc_parent(this); 988 ir_expression *expr = NULL; 989 990 ir_constant_data data; 991 memset(&data, 0, sizeof(data)); 992 993 const char *callee = this->callee_name(); 994 if (strcmp(callee, "abs") == 0) { 995 expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL); 996 } else if (strcmp(callee, "all") == 0) { 997 assert(op[0]->type->is_boolean()); 998 for (unsigned c = 0; c < op[0]->type->components(); c++) { 999 if (!op[0]->value.b[c]) 1000 return new(mem_ctx) ir_constant(false); 1001 } 1002 return new(mem_ctx) ir_constant(true); 1003 } else if (strcmp(callee, "any") == 0) { 1004 assert(op[0]->type->is_boolean()); 1005 for (unsigned c = 0; c < op[0]->type->components(); c++) { 1006 if (op[0]->value.b[c]) 1007 return new(mem_ctx) ir_constant(true); 1008 } 1009 return new(mem_ctx) ir_constant(false); 1010 } else if (strcmp(callee, "acos") == 0) { 1011 assert(op[0]->type->is_float()); 1012 for (unsigned c = 0; c < op[0]->type->components(); c++) 1013 data.f[c] = acosf(op[0]->value.f[c]); 1014 } else if (strcmp(callee, "acosh") == 0) { 1015 assert(op[0]->type->is_float()); 1016 for (unsigned c = 0; c < op[0]->type->components(); c++) 1017 data.f[c] = acoshf(op[0]->value.f[c]); 1018 } else if (strcmp(callee, "asin") == 0) { 1019 assert(op[0]->type->is_float()); 1020 for (unsigned c = 0; c < op[0]->type->components(); c++) 1021 data.f[c] = asinf(op[0]->value.f[c]); 1022 } else if (strcmp(callee, "asinh") == 0) { 1023 assert(op[0]->type->is_float()); 1024 for (unsigned c = 0; c < op[0]->type->components(); c++) 1025 data.f[c] = asinhf(op[0]->value.f[c]); 1026 } else if (strcmp(callee, "atan") == 0) { 1027 assert(op[0]->type->is_float()); 1028 if (num_parameters == 2) { 1029 assert(op[1]->type->is_float()); 1030 for (unsigned c = 0; c < op[0]->type->components(); c++) 1031 data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]); 1032 } else { 1033 for (unsigned c = 0; c < op[0]->type->components(); c++) 1034 data.f[c] = atanf(op[0]->value.f[c]); 1035 } 1036 } else if (strcmp(callee, "atanh") == 0) { 1037 assert(op[0]->type->is_float()); 1038 for (unsigned c = 0; c < op[0]->type->components(); c++) 1039 data.f[c] = atanhf(op[0]->value.f[c]); 1040 } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) { 1041 return ir_constant::zero(mem_ctx, this->type); 1042 } else if (strcmp(callee, "ceil") == 0) { 1043 expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL); 1044 } else if (strcmp(callee, "clamp") == 0) { 1045 assert(num_parameters == 3); 1046 unsigned c1_inc = op[1]->type->is_scalar() ? 0 : 1; 1047 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1; 1048 for (unsigned c = 0, c1 = 0, c2 = 0; 1049 c < op[0]->type->components(); 1050 c1 += c1_inc, c2 += c2_inc, c++) { 1051 1052 switch (op[0]->type->base_type) { 1053 case GLSL_TYPE_UINT: 1054 data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1], 1055 op[2]->value.u[c2]); 1056 break; 1057 case GLSL_TYPE_INT: 1058 data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1], 1059 op[2]->value.i[c2]); 1060 break; 1061 case GLSL_TYPE_FLOAT: 1062 data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1], 1063 op[2]->value.f[c2]); 1064 break; 1065 default: 1066 assert(!"Should not get here."); 1067 } 1068 } 1069 } else if (strcmp(callee, "cos") == 0) { 1070 expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL); 1071 } else if (strcmp(callee, "cosh") == 0) { 1072 assert(op[0]->type->is_float()); 1073 for (unsigned c = 0; c < op[0]->type->components(); c++) 1074 data.f[c] = coshf(op[0]->value.f[c]); 1075 } else if (strcmp(callee, "cross") == 0) { 1076 assert(op[0]->type == glsl_type::vec3_type); 1077 assert(op[1]->type == glsl_type::vec3_type); 1078 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] - 1079 op[1]->value.f[1] * op[0]->value.f[2]); 1080 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] - 1081 op[1]->value.f[2] * op[0]->value.f[0]); 1082 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] - 1083 op[1]->value.f[0] * op[0]->value.f[1]); 1084 } else if (strcmp(callee, "degrees") == 0) { 1085 assert(op[0]->type->is_float()); 1086 for (unsigned c = 0; c < op[0]->type->components(); c++) 1087 data.f[c] = 180.0F / M_PI * op[0]->value.f[c]; 1088 } else if (strcmp(callee, "distance") == 0) { 1089 assert(op[0]->type->is_float() && op[1]->type->is_float()); 1090 float length_squared = 0.0; 1091 for (unsigned c = 0; c < op[0]->type->components(); c++) { 1092 float t = op[0]->value.f[c] - op[1]->value.f[c]; 1093 length_squared += t * t; 1094 } 1095 return new(mem_ctx) ir_constant(sqrtf(length_squared)); 1096 } else if (strcmp(callee, "dot") == 0) { 1097 return new(mem_ctx) ir_constant(dot(op[0], op[1])); 1098 } else if (strcmp(callee, "equal") == 0) { 1099 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); 1100 for (unsigned c = 0; c < op[0]->type->components(); c++) { 1101 switch (op[0]->type->base_type) { 1102 case GLSL_TYPE_UINT: 1103 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c]; 1104 break; 1105 case GLSL_TYPE_INT: 1106 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c]; 1107 break; 1108 case GLSL_TYPE_FLOAT: 1109 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c]; 1110 break; 1111 case GLSL_TYPE_BOOL: 1112 data.b[c] = op[0]->value.b[c] == op[1]->value.b[c]; 1113 break; 1114 default: 1115 assert(!"Should not get here."); 1116 } 1117 } 1118 } else if (strcmp(callee, "exp") == 0) { 1119 expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL); 1120 } else if (strcmp(callee, "exp2") == 0) { 1121 expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL); 1122 } else if (strcmp(callee, "faceforward") == 0) { 1123 if (dot(op[2], op[1]) < 0) 1124 return op[0]; 1125 for (unsigned c = 0; c < op[0]->type->components(); c++) 1126 data.f[c] = -op[0]->value.f[c]; 1127 } else if (strcmp(callee, "floor") == 0) { 1128 expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL); 1129 } else if (strcmp(callee, "fract") == 0) { 1130 expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL); 1131 } else if (strcmp(callee, "fwidth") == 0) { 1132 return ir_constant::zero(mem_ctx, this->type); 1133 } else if (strcmp(callee, "greaterThan") == 0) { 1134 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); 1135 for (unsigned c = 0; c < op[0]->type->components(); c++) { 1136 switch (op[0]->type->base_type) { 1137 case GLSL_TYPE_UINT: 1138 data.b[c] = op[0]->value.u[c] > op[1]->value.u[c]; 1139 break; 1140 case GLSL_TYPE_INT: 1141 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c]; 1142 break; 1143 case GLSL_TYPE_FLOAT: 1144 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c]; 1145 break; 1146 default: 1147 assert(!"Should not get here."); 1148 } 1149 } 1150 } else if (strcmp(callee, "greaterThanEqual") == 0) { 1151 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); 1152 for (unsigned c = 0; c < op[0]->type->components(); c++) { 1153 switch (op[0]->type->base_type) { 1154 case GLSL_TYPE_UINT: 1155 data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c]; 1156 break; 1157 case GLSL_TYPE_INT: 1158 data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c]; 1159 break; 1160 case GLSL_TYPE_FLOAT: 1161 data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c]; 1162 break; 1163 default: 1164 assert(!"Should not get here."); 1165 } 1166 } 1167 } else if (strcmp(callee, "inversesqrt") == 0) { 1168 expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL); 1169 } else if (strcmp(callee, "length") == 0) { 1170 return new(mem_ctx) ir_constant(sqrtf(dot(op[0], op[0]))); 1171 } else if (strcmp(callee, "lessThan") == 0) { 1172 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); 1173 for (unsigned c = 0; c < op[0]->type->components(); c++) { 1174 switch (op[0]->type->base_type) { 1175 case GLSL_TYPE_UINT: 1176 data.b[c] = op[0]->value.u[c] < op[1]->value.u[c]; 1177 break; 1178 case GLSL_TYPE_INT: 1179 data.b[c] = op[0]->value.i[c] < op[1]->value.i[c]; 1180 break; 1181 case GLSL_TYPE_FLOAT: 1182 data.b[c] = op[0]->value.f[c] < op[1]->value.f[c]; 1183 break; 1184 default: 1185 assert(!"Should not get here."); 1186 } 1187 } 1188 } else if (strcmp(callee, "lessThanEqual") == 0) { 1189 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); 1190 for (unsigned c = 0; c < op[0]->type->components(); c++) { 1191 switch (op[0]->type->base_type) { 1192 case GLSL_TYPE_UINT: 1193 data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c]; 1194 break; 1195 case GLSL_TYPE_INT: 1196 data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c]; 1197 break; 1198 case GLSL_TYPE_FLOAT: 1199 data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c]; 1200 break; 1201 default: 1202 assert(!"Should not get here."); 1203 } 1204 } 1205 } else if (strcmp(callee, "log") == 0) { 1206 expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL); 1207 } else if (strcmp(callee, "log2") == 0) { 1208 expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL); 1209 } else if (strcmp(callee, "matrixCompMult") == 0) { 1210 assert(op[0]->type->is_float() && op[1]->type->is_float()); 1211 for (unsigned c = 0; c < op[0]->type->components(); c++) 1212 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c]; 1213 } else if (strcmp(callee, "max") == 0) { 1214 expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]); 1215 } else if (strcmp(callee, "min") == 0) { 1216 expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]); 1217 } else if (strcmp(callee, "mix") == 0) { 1218 assert(op[0]->type->is_float() && op[1]->type->is_float()); 1219 if (op[2]->type->is_float()) { 1220 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1; 1221 unsigned components = op[0]->type->components(); 1222 for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) { 1223 data.f[c] = op[0]->value.f[c] * (1 - op[2]->value.f[c2]) + 1224 op[1]->value.f[c] * op[2]->value.f[c2]; 1225 } 1226 } else { 1227 assert(op[2]->type->is_boolean()); 1228 for (unsigned c = 0; c < op[0]->type->components(); c++) 1229 data.f[c] = op[op[2]->value.b[c] ? 1 : 0]->value.f[c]; 1230 } 1231 } else if (strcmp(callee, "mod") == 0) { 1232 expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]); 1233 } else if (strcmp(callee, "normalize") == 0) { 1234 assert(op[0]->type->is_float()); 1235 float length = sqrtf(dot(op[0], op[0])); 1236 1237 if (length == 0) 1238 return ir_constant::zero(mem_ctx, this->type); 1239 1240 for (unsigned c = 0; c < op[0]->type->components(); c++) 1241 data.f[c] = op[0]->value.f[c] / length; 1242 } else if (strcmp(callee, "not") == 0) { 1243 expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL); 1244 } else if (strcmp(callee, "notEqual") == 0) { 1245 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); 1246 for (unsigned c = 0; c < op[0]->type->components(); c++) { 1247 switch (op[0]->type->base_type) { 1248 case GLSL_TYPE_UINT: 1249 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c]; 1250 break; 1251 case GLSL_TYPE_INT: 1252 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c]; 1253 break; 1254 case GLSL_TYPE_FLOAT: 1255 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c]; 1256 break; 1257 case GLSL_TYPE_BOOL: 1258 data.b[c] = op[0]->value.b[c] != op[1]->value.b[c]; 1259 break; 1260 default: 1261 assert(!"Should not get here."); 1262 } 1263 } 1264 } else if (strcmp(callee, "outerProduct") == 0) { 1265 assert(op[0]->type->is_vector() && op[1]->type->is_vector()); 1266 const unsigned m = op[0]->type->vector_elements; 1267 const unsigned n = op[1]->type->vector_elements; 1268 for (unsigned j = 0; j < n; j++) { 1269 for (unsigned i = 0; i < m; i++) { 1270 data.f[i+m*j] = op[0]->value.f[i] * op[1]->value.f[j]; 1271 } 1272 } 1273 } else if (strcmp(callee, "pow") == 0) { 1274 expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]); 1275 } else if (strcmp(callee, "radians") == 0) { 1276 assert(op[0]->type->is_float()); 1277 for (unsigned c = 0; c < op[0]->type->components(); c++) 1278 data.f[c] = M_PI / 180.0F * op[0]->value.f[c]; 1279 } else if (strcmp(callee, "reflect") == 0) { 1280 assert(op[0]->type->is_float()); 1281 float dot_NI = dot(op[1], op[0]); 1282 for (unsigned c = 0; c < op[0]->type->components(); c++) 1283 data.f[c] = op[0]->value.f[c] - 2 * dot_NI * op[1]->value.f[c]; 1284 } else if (strcmp(callee, "refract") == 0) { 1285 const float eta = op[2]->value.f[0]; 1286 const float dot_NI = dot(op[1], op[0]); 1287 const float k = 1.0F - eta * eta * (1.0F - dot_NI * dot_NI); 1288 if (k < 0.0) { 1289 return ir_constant::zero(mem_ctx, this->type); 1290 } else { 1291 for (unsigned c = 0; c < type->components(); c++) { 1292 data.f[c] = eta * op[0]->value.f[c] - (eta * dot_NI + sqrtf(k)) 1293 * op[1]->value.f[c]; 1294 } 1295 } 1296 } else if (strcmp(callee, "sign") == 0) { 1297 expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL); 1298 } else if (strcmp(callee, "sin") == 0) { 1299 expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL); 1300 } else if (strcmp(callee, "sinh") == 0) { 1301 assert(op[0]->type->is_float()); 1302 for (unsigned c = 0; c < op[0]->type->components(); c++) 1303 data.f[c] = sinhf(op[0]->value.f[c]); 1304 } else if (strcmp(callee, "smoothstep") == 0) { 1305 assert(num_parameters == 3); 1306 assert(op[1]->type == op[0]->type); 1307 unsigned edge_inc = op[0]->type->is_scalar() ? 0 : 1; 1308 for (unsigned c = 0, e = 0; c < type->components(); e += edge_inc, c++) { 1309 const float edge0 = op[0]->value.f[e]; 1310 const float edge1 = op[1]->value.f[e]; 1311 if (edge0 == edge1) { 1312 data.f[c] = 0.0; /* Avoid a crash - results are undefined anyway */ 1313 } else { 1314 const float numerator = op[2]->value.f[c] - edge0; 1315 const float denominator = edge1 - edge0; 1316 const float t = CLAMP(numerator/denominator, 0, 1); 1317 data.f[c] = t * t * (3 - 2 * t); 1318 } 1319 } 1320 } else if (strcmp(callee, "sqrt") == 0) { 1321 expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL); 1322 } else if (strcmp(callee, "step") == 0) { 1323 assert(op[0]->type->is_float() && op[1]->type->is_float()); 1324 /* op[0] (edge) may be either a scalar or a vector */ 1325 const unsigned c0_inc = op[0]->type->is_scalar() ? 0 : 1; 1326 for (unsigned c = 0, c0 = 0; c < type->components(); c0 += c0_inc, c++) 1327 data.f[c] = (op[1]->value.f[c] < op[0]->value.f[c0]) ? 0.0F : 1.0F; 1328 } else if (strcmp(callee, "tan") == 0) { 1329 assert(op[0]->type->is_float()); 1330 for (unsigned c = 0; c < op[0]->type->components(); c++) 1331 data.f[c] = tanf(op[0]->value.f[c]); 1332 } else if (strcmp(callee, "tanh") == 0) { 1333 assert(op[0]->type->is_float()); 1334 for (unsigned c = 0; c < op[0]->type->components(); c++) 1335 data.f[c] = tanhf(op[0]->value.f[c]); 1336 } else if (strcmp(callee, "transpose") == 0) { 1337 assert(op[0]->type->is_matrix()); 1338 const unsigned n = op[0]->type->vector_elements; 1339 const unsigned m = op[0]->type->matrix_columns; 1340 for (unsigned j = 0; j < m; j++) { 1341 for (unsigned i = 0; i < n; i++) { 1342 data.f[m*i+j] += op[0]->value.f[i+n*j]; 1343 } 1344 } 1345 } else { 1346 /* Unsupported builtin - some are not allowed in constant expressions. */ 1347 return NULL; 1348 } 1349 1350 if (expr != NULL) 1351 return expr->constant_expression_value(); 1352 1353 return new(mem_ctx) ir_constant(this->type, &data); 1354} 1355