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