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 "util/rounding.h" /* for _mesa_roundeven */ 39 #include "util/half_float.h" 40 #include "ir.h" 41 #include "compiler/glsl_types.h" 42 #include "util/hash_table.h" 43 44 static float 45 dot_f(ir_constant *op0, ir_constant *op1) 46 { 47 assert(op0->type->is_float() && op1->type->is_float()); 48 49 float result = 0; 50 for (unsigned c = 0; c < op0->type->components(); c++) 51 result += op0->value.f[c] * op1->value.f[c]; 52 53 return result; 54 } 55 56 static double 57 dot_d(ir_constant *op0, ir_constant *op1) 58 { 59 assert(op0->type->is_double() && op1->type->is_double()); 60 61 double result = 0; 62 for (unsigned c = 0; c < op0->type->components(); c++) 63 result += op0->value.d[c] * op1->value.d[c]; 64 65 return result; 66 } 67 68 /* This method is the only one supported by gcc. Unions in particular 69 * are iffy, and read-through-converted-pointer is killed by strict 70 * aliasing. OTOH, the compiler sees through the memcpy, so the 71 * resulting asm is reasonable. 72 */ 73 static float 74 bitcast_u2f(unsigned int u) 75 { 76 assert(sizeof(float) == sizeof(unsigned int)); 77 float f; 78 memcpy(&f, &u, sizeof(f)); 79 return f; 80 } 81 82 static unsigned int 83 bitcast_f2u(float f) 84 { 85 assert(sizeof(float) == sizeof(unsigned int)); 86 unsigned int u; 87 memcpy(&u, &f, sizeof(f)); 88 return u; 89 } 90 91 /** 92 * Evaluate one component of a floating-point 4x8 unpacking function. 93 */ 94 typedef uint8_t 95 (*pack_1x8_func_t)(float); 96 97 /** 98 * Evaluate one component of a floating-point 2x16 unpacking function. 99 */ 100 typedef uint16_t 101 (*pack_1x16_func_t)(float); 102 103 /** 104 * Evaluate one component of a floating-point 4x8 unpacking function. 105 */ 106 typedef float 107 (*unpack_1x8_func_t)(uint8_t); 108 109 /** 110 * Evaluate one component of a floating-point 2x16 unpacking function. 111 */ 112 typedef float 113 (*unpack_1x16_func_t)(uint16_t); 114 115 /** 116 * Evaluate a 2x16 floating-point packing function. 117 */ 118 static uint32_t 119 pack_2x16(pack_1x16_func_t pack_1x16, 120 float x, float y) 121 { 122 /* From section 8.4 of the GLSL ES 3.00 spec: 123 * 124 * packSnorm2x16 125 * ------------- 126 * The first component of the vector will be written to the least 127 * significant bits of the output; the last component will be written to 128 * the most significant bits. 129 * 130 * The specifications for the other packing functions contain similar 131 * language. 132 */ 133 uint32_t u = 0; 134 u |= ((uint32_t) pack_1x16(x) << 0); 135 u |= ((uint32_t) pack_1x16(y) << 16); 136 return u; 137 } 138 139 /** 140 * Evaluate a 4x8 floating-point packing function. 141 */ 142 static uint32_t 143 pack_4x8(pack_1x8_func_t pack_1x8, 144 float x, float y, float z, float w) 145 { 146 /* From section 8.4 of the GLSL 4.30 spec: 147 * 148 * packSnorm4x8 149 * ------------ 150 * The first component of the vector will be written to the least 151 * significant bits of the output; the last component will be written to 152 * the most significant bits. 153 * 154 * The specifications for the other packing functions contain similar 155 * language. 156 */ 157 uint32_t u = 0; 158 u |= ((uint32_t) pack_1x8(x) << 0); 159 u |= ((uint32_t) pack_1x8(y) << 8); 160 u |= ((uint32_t) pack_1x8(z) << 16); 161 u |= ((uint32_t) pack_1x8(w) << 24); 162 return u; 163 } 164 165 /** 166 * Evaluate a 2x16 floating-point unpacking function. 167 */ 168 static void 169 unpack_2x16(unpack_1x16_func_t unpack_1x16, 170 uint32_t u, 171 float *x, float *y) 172 { 173 /* From section 8.4 of the GLSL ES 3.00 spec: 174 * 175 * unpackSnorm2x16 176 * --------------- 177 * The first component of the returned vector will be extracted from 178 * the least significant bits of the input; the last component will be 179 * extracted from the most significant bits. 180 * 181 * The specifications for the other unpacking functions contain similar 182 * language. 183 */ 184 *x = unpack_1x16((uint16_t) (u & 0xffff)); 185 *y = unpack_1x16((uint16_t) (u >> 16)); 186 } 187 188 /** 189 * Evaluate a 4x8 floating-point unpacking function. 190 */ 191 static void 192 unpack_4x8(unpack_1x8_func_t unpack_1x8, uint32_t u, 193 float *x, float *y, float *z, float *w) 194 { 195 /* From section 8.4 of the GLSL 4.30 spec: 196 * 197 * unpackSnorm4x8 198 * -------------- 199 * The first component of the returned vector will be extracted from 200 * the least significant bits of the input; the last component will be 201 * extracted from the most significant bits. 202 * 203 * The specifications for the other unpacking functions contain similar 204 * language. 205 */ 206 *x = unpack_1x8((uint8_t) (u & 0xff)); 207 *y = unpack_1x8((uint8_t) (u >> 8)); 208 *z = unpack_1x8((uint8_t) (u >> 16)); 209 *w = unpack_1x8((uint8_t) (u >> 24)); 210 } 211 212 /** 213 * Evaluate one component of packSnorm4x8. 214 */ 215 static uint8_t 216 pack_snorm_1x8(float x) 217 { 218 /* From section 8.4 of the GLSL 4.30 spec: 219 * 220 * packSnorm4x8 221 * ------------ 222 * The conversion for component c of v to fixed point is done as 223 * follows: 224 * 225 * packSnorm4x8: round(clamp(c, -1, +1) * 127.0) 226 */ 227 return (uint8_t) 228 _mesa_lroundevenf(CLAMP(x, -1.0f, +1.0f) * 127.0f); 229 } 230 231 /** 232 * Evaluate one component of packSnorm2x16. 233 */ 234 static uint16_t 235 pack_snorm_1x16(float x) 236 { 237 /* From section 8.4 of the GLSL ES 3.00 spec: 238 * 239 * packSnorm2x16 240 * ------------- 241 * The conversion for component c of v to fixed point is done as 242 * follows: 243 * 244 * packSnorm2x16: round(clamp(c, -1, +1) * 32767.0) 245 */ 246 return (uint16_t) 247 _mesa_lroundevenf(CLAMP(x, -1.0f, +1.0f) * 32767.0f); 248 } 249 250 /** 251 * Evaluate one component of unpackSnorm4x8. 252 */ 253 static float 254 unpack_snorm_1x8(uint8_t u) 255 { 256 /* From section 8.4 of the GLSL 4.30 spec: 257 * 258 * unpackSnorm4x8 259 * -------------- 260 * The conversion for unpacked fixed-point value f to floating point is 261 * done as follows: 262 * 263 * unpackSnorm4x8: clamp(f / 127.0, -1, +1) 264 */ 265 return CLAMP((int8_t) u / 127.0f, -1.0f, +1.0f); 266 } 267 268 /** 269 * Evaluate one component of unpackSnorm2x16. 270 */ 271 static float 272 unpack_snorm_1x16(uint16_t u) 273 { 274 /* From section 8.4 of the GLSL ES 3.00 spec: 275 * 276 * unpackSnorm2x16 277 * --------------- 278 * The conversion for unpacked fixed-point value f to floating point is 279 * done as follows: 280 * 281 * unpackSnorm2x16: clamp(f / 32767.0, -1, +1) 282 */ 283 return CLAMP((int16_t) u / 32767.0f, -1.0f, +1.0f); 284 } 285 286 /** 287 * Evaluate one component packUnorm4x8. 288 */ 289 static uint8_t 290 pack_unorm_1x8(float x) 291 { 292 /* From section 8.4 of the GLSL 4.30 spec: 293 * 294 * packUnorm4x8 295 * ------------ 296 * The conversion for component c of v to fixed point is done as 297 * follows: 298 * 299 * packUnorm4x8: round(clamp(c, 0, +1) * 255.0) 300 */ 301 return (uint8_t) (int) _mesa_roundevenf(CLAMP(x, 0.0f, 1.0f) * 255.0f); 302 } 303 304 /** 305 * Evaluate one component packUnorm2x16. 306 */ 307 static uint16_t 308 pack_unorm_1x16(float x) 309 { 310 /* From section 8.4 of the GLSL ES 3.00 spec: 311 * 312 * packUnorm2x16 313 * ------------- 314 * The conversion for component c of v to fixed point is done as 315 * follows: 316 * 317 * packUnorm2x16: round(clamp(c, 0, +1) * 65535.0) 318 */ 319 return (uint16_t) (int) 320 _mesa_roundevenf(CLAMP(x, 0.0f, 1.0f) * 65535.0f); 321 } 322 323 /** 324 * Evaluate one component of unpackUnorm4x8. 325 */ 326 static float 327 unpack_unorm_1x8(uint8_t u) 328 { 329 /* From section 8.4 of the GLSL 4.30 spec: 330 * 331 * unpackUnorm4x8 332 * -------------- 333 * The conversion for unpacked fixed-point value f to floating point is 334 * done as follows: 335 * 336 * unpackUnorm4x8: f / 255.0 337 */ 338 return (float) u / 255.0f; 339 } 340 341 /** 342 * Evaluate one component of unpackUnorm2x16. 343 */ 344 static float 345 unpack_unorm_1x16(uint16_t u) 346 { 347 /* From section 8.4 of the GLSL ES 3.00 spec: 348 * 349 * unpackUnorm2x16 350 * --------------- 351 * The conversion for unpacked fixed-point value f to floating point is 352 * done as follows: 353 * 354 * unpackUnorm2x16: f / 65535.0 355 */ 356 return (float) u / 65535.0f; 357 } 358 359 /** 360 * Evaluate one component of packHalf2x16. 361 */ 362 static uint16_t 363 pack_half_1x16(float x) 364 { 365 return _mesa_float_to_half(x); 366 } 367 368 /** 369 * Evaluate one component of unpackHalf2x16. 370 */ 371 static float 372 unpack_half_1x16(uint16_t u) 373 { 374 return _mesa_half_to_float(u); 375 } 376 377 /** 378 * Get the constant that is ultimately referenced by an r-value, in a constant 379 * expression evaluation context. 380 * 381 * The offset is used when the reference is to a specific column of a matrix. 382 */ 383 static bool 384 constant_referenced(const ir_dereference *deref, 385 struct hash_table *variable_context, 386 ir_constant *&store, int &offset) 387 { 388 store = NULL; 389 offset = 0; 390 391 if (variable_context == NULL) 392 return false; 393 394 switch (deref->ir_type) { 395 case ir_type_dereference_array: { 396 const ir_dereference_array *const da = 397 (const ir_dereference_array *) deref; 398 399 ir_constant *const index_c = 400 da->array_index->constant_expression_value(variable_context); 401 402 if (!index_c || !index_c->type->is_scalar() || !index_c->type->is_integer()) 403 break; 404 405 const int index = index_c->type->base_type == GLSL_TYPE_INT ? 406 index_c->get_int_component(0) : 407 index_c->get_uint_component(0); 408 409 ir_constant *substore; 410 int suboffset; 411 412 const ir_dereference *const deref = da->array->as_dereference(); 413 if (!deref) 414 break; 415 416 if (!constant_referenced(deref, variable_context, substore, suboffset)) 417 break; 418 419 const glsl_type *const vt = da->array->type; 420 if (vt->is_array()) { 421 store = substore->get_array_element(index); 422 offset = 0; 423 } else if (vt->is_matrix()) { 424 store = substore; 425 offset = index * vt->vector_elements; 426 } else if (vt->is_vector()) { 427 store = substore; 428 offset = suboffset + index; 429 } 430 431 break; 432 } 433 434 case ir_type_dereference_record: { 435 const ir_dereference_record *const dr = 436 (const ir_dereference_record *) deref; 437 438 const ir_dereference *const deref = dr->record->as_dereference(); 439 if (!deref) 440 break; 441 442 ir_constant *substore; 443 int suboffset; 444 445 if (!constant_referenced(deref, variable_context, substore, suboffset)) 446 break; 447 448 /* Since we're dropping it on the floor... 449 */ 450 assert(suboffset == 0); 451 452 store = substore->get_record_field(dr->field); 453 break; 454 } 455 456 case ir_type_dereference_variable: { 457 const ir_dereference_variable *const dv = 458 (const ir_dereference_variable *) deref; 459 460 hash_entry *entry = _mesa_hash_table_search(variable_context, dv->var); 461 if (entry) 462 store = (ir_constant *) entry->data; 463 break; 464 } 465 466 default: 467 assert(!"Should not get here."); 468 break; 469 } 470 471 return store != NULL; 472 } 473 474 475 ir_constant * 476 ir_rvalue::constant_expression_value(struct hash_table *) 477 { 478 assert(this->type->is_error()); 479 return NULL; 480 } 481 482 static uint32_t 483 bitfield_reverse(uint32_t v) 484 { 485 /* http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious */ 486 uint32_t r = v; // r will be reversed bits of v; first get LSB of v 487 int s = sizeof(v) * CHAR_BIT - 1; // extra shift needed at end 488 489 for (v >>= 1; v; v >>= 1) { 490 r <<= 1; 491 r |= v & 1; 492 s--; 493 } 494 r <<= s; // shift when v's highest bits are zero 495 496 return r; 497 } 498 499 static int 500 find_msb_uint(uint32_t v) 501 { 502 int count = 0; 503 504 /* If v == 0, then the loop will terminate when count == 32. In that case 505 * 31-count will produce the -1 result required by GLSL findMSB(). 506 */ 507 while (((v & (1u << 31)) == 0) && count != 32) { 508 count++; 509 v <<= 1; 510 } 511 512 return 31 - count; 513 } 514 515 static int 516 find_msb_int(int32_t v) 517 { 518 /* If v is signed, findMSB() returns the position of the most significant 519 * zero bit. 520 */ 521 return find_msb_uint(v < 0 ? ~v : v); 522 } 523 524 static float 525 ldexpf_flush_subnormal(float x, int exp) 526 { 527 const float result = ldexpf(x, exp); 528 529 /* Flush subnormal values to zero. */ 530 return !isnormal(result) ? copysignf(0.0f, x) : result; 531 } 532 533 static double 534 ldexp_flush_subnormal(double x, int exp) 535 { 536 const double result = ldexp(x, exp); 537 538 /* Flush subnormal values to zero. */ 539 return !isnormal(result) ? copysign(0.0, x) : result; 540 } 541 542 static uint32_t 543 bitfield_extract_uint(uint32_t value, int offset, int bits) 544 { 545 if (bits == 0) 546 return 0; 547 else if (offset < 0 || bits < 0) 548 return 0; /* Undefined, per spec. */ 549 else if (offset + bits > 32) 550 return 0; /* Undefined, per spec. */ 551 else { 552 value <<= 32 - bits - offset; 553 value >>= 32 - bits; 554 return value; 555 } 556 } 557 558 static int32_t 559 bitfield_extract_int(int32_t value, int offset, int bits) 560 { 561 if (bits == 0) 562 return 0; 563 else if (offset < 0 || bits < 0) 564 return 0; /* Undefined, per spec. */ 565 else if (offset + bits > 32) 566 return 0; /* Undefined, per spec. */ 567 else { 568 value <<= 32 - bits - offset; 569 value >>= 32 - bits; 570 return value; 571 } 572 } 573 574 static uint32_t 575 bitfield_insert(uint32_t base, uint32_t insert, int offset, int bits) 576 { 577 if (bits == 0) 578 return base; 579 else if (offset < 0 || bits < 0) 580 return 0; /* Undefined, per spec. */ 581 else if (offset + bits > 32) 582 return 0; /* Undefined, per spec. */ 583 else { 584 unsigned insert_mask = ((1ull << bits) - 1) << offset; 585 586 insert <<= offset; 587 insert &= insert_mask; 588 base &= ~insert_mask; 589 590 return base | insert; 591 } 592 } 593 594 ir_constant * 595 ir_expression::constant_expression_value(struct hash_table *variable_context) 596 { 597 if (this->type->is_error()) 598 return NULL; 599 600 ir_constant *op[ARRAY_SIZE(this->operands)] = { NULL, }; 601 ir_constant_data data; 602 603 memset(&data, 0, sizeof(data)); 604 605 for (unsigned operand = 0; operand < this->get_num_operands(); operand++) { 606 op[operand] = this->operands[operand]->constant_expression_value(variable_context); 607 if (!op[operand]) 608 return NULL; 609 } 610 611 if (op[1] != NULL) 612 switch (this->operation) { 613 case ir_binop_lshift: 614 case ir_binop_rshift: 615 case ir_binop_ldexp: 616 case ir_binop_interpolate_at_offset: 617 case ir_binop_interpolate_at_sample: 618 case ir_binop_vector_extract: 619 case ir_triop_csel: 620 case ir_triop_bitfield_extract: 621 break; 622 623 default: 624 assert(op[0]->type->base_type == op[1]->type->base_type); 625 break; 626 } 627 628 bool op0_scalar = op[0]->type->is_scalar(); 629 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar(); 630 631 /* When iterating over a vector or matrix's components, we want to increase 632 * the loop counter. However, for scalars, we want to stay at 0. 633 */ 634 unsigned c0_inc = op0_scalar ? 0 : 1; 635 unsigned c1_inc = op1_scalar ? 0 : 1; 636 unsigned components; 637 if (op1_scalar || !op[1]) { 638 components = op[0]->type->components(); 639 } else { 640 components = op[1]->type->components(); 641 } 642 643 void *ctx = ralloc_parent(this); 644 645 /* Handle array operations here, rather than below. */ 646 if (op[0]->type->is_array()) { 647 assert(op[1] != NULL && op[1]->type->is_array()); 648 switch (this->operation) { 649 case ir_binop_all_equal: 650 return new(ctx) ir_constant(op[0]->has_value(op[1])); 651 case ir_binop_any_nequal: 652 return new(ctx) ir_constant(!op[0]->has_value(op[1])); 653 default: 654 break; 655 } 656 return NULL; 657 } 658 659 #include "ir_expression_operation_constant.h" 660 661 return new(ctx) ir_constant(this->type, &data); 662 } 663 664 665 ir_constant * 666 ir_texture::constant_expression_value(struct hash_table *) 667 { 668 /* texture lookups aren't constant expressions */ 669 return NULL; 670 } 671 672 673 ir_constant * 674 ir_swizzle::constant_expression_value(struct hash_table *variable_context) 675 { 676 ir_constant *v = this->val->constant_expression_value(variable_context); 677 678 if (v != NULL) { 679 ir_constant_data data = { { 0 } }; 680 681 const unsigned swiz_idx[4] = { 682 this->mask.x, this->mask.y, this->mask.z, this->mask.w 683 }; 684 685 for (unsigned i = 0; i < this->mask.num_components; i++) { 686 switch (v->type->base_type) { 687 case GLSL_TYPE_UINT: 688 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break; 689 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break; 690 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break; 691 case GLSL_TYPE_DOUBLE:data.d[i] = v->value.d[swiz_idx[i]]; break; 692 default: assert(!"Should not get here."); break; 693 } 694 } 695 696 void *ctx = ralloc_parent(this); 697 return new(ctx) ir_constant(this->type, &data); 698 } 699 return NULL; 700 } 701 702 703 ir_constant * 704 ir_dereference_variable::constant_expression_value(struct hash_table *variable_context) 705 { 706 assert(var); 707 708 /* Give priority to the context hashtable, if it exists */ 709 if (variable_context) { 710 hash_entry *entry = _mesa_hash_table_search(variable_context, var); 711 712 if(entry) 713 return (ir_constant *) entry->data; 714 } 715 716 /* The constant_value of a uniform variable is its initializer, 717 * not the lifetime constant value of the uniform. 718 */ 719 if (var->data.mode == ir_var_uniform) 720 return NULL; 721 722 if (!var->constant_value) 723 return NULL; 724 725 return var->constant_value->clone(ralloc_parent(var), NULL); 726 } 727 728 729 ir_constant * 730 ir_dereference_array::constant_expression_value(struct hash_table *variable_context) 731 { 732 ir_constant *array = this->array->constant_expression_value(variable_context); 733 ir_constant *idx = this->array_index->constant_expression_value(variable_context); 734 735 if ((array != NULL) && (idx != NULL)) { 736 void *ctx = ralloc_parent(this); 737 if (array->type->is_matrix()) { 738 /* Array access of a matrix results in a vector. 739 */ 740 const unsigned column = idx->value.u[0]; 741 742 const glsl_type *const column_type = array->type->column_type(); 743 744 /* Offset in the constant matrix to the first element of the column 745 * to be extracted. 746 */ 747 const unsigned mat_idx = column * column_type->vector_elements; 748 749 ir_constant_data data = { { 0 } }; 750 751 switch (column_type->base_type) { 752 case GLSL_TYPE_UINT: 753 case GLSL_TYPE_INT: 754 for (unsigned i = 0; i < column_type->vector_elements; i++) 755 data.u[i] = array->value.u[mat_idx + i]; 756 757 break; 758 759 case GLSL_TYPE_FLOAT: 760 for (unsigned i = 0; i < column_type->vector_elements; i++) 761 data.f[i] = array->value.f[mat_idx + i]; 762 763 break; 764 765 case GLSL_TYPE_DOUBLE: 766 for (unsigned i = 0; i < column_type->vector_elements; i++) 767 data.d[i] = array->value.d[mat_idx + i]; 768 769 break; 770 771 default: 772 assert(!"Should not get here."); 773 break; 774 } 775 776 return new(ctx) ir_constant(column_type, &data); 777 } else if (array->type->is_vector()) { 778 const unsigned component = idx->value.u[0]; 779 780 return new(ctx) ir_constant(array, component); 781 } else { 782 const unsigned index = idx->value.u[0]; 783 return array->get_array_element(index)->clone(ctx, NULL); 784 } 785 } 786 return NULL; 787 } 788 789 790 ir_constant * 791 ir_dereference_record::constant_expression_value(struct hash_table *) 792 { 793 ir_constant *v = this->record->constant_expression_value(); 794 795 return (v != NULL) ? v->get_record_field(this->field) : NULL; 796 } 797 798 799 ir_constant * 800 ir_assignment::constant_expression_value(struct hash_table *) 801 { 802 /* FINISHME: Handle CEs involving assignment (return RHS) */ 803 return NULL; 804 } 805 806 807 ir_constant * 808 ir_constant::constant_expression_value(struct hash_table *) 809 { 810 return this; 811 } 812 813 814 ir_constant * 815 ir_call::constant_expression_value(struct hash_table *variable_context) 816 { 817 return this->callee->constant_expression_value(&this->actual_parameters, variable_context); 818 } 819 820 821 bool ir_function_signature::constant_expression_evaluate_expression_list(const struct exec_list &body, 822 struct hash_table *variable_context, 823 ir_constant **result) 824 { 825 foreach_in_list(ir_instruction, inst, &body) { 826 switch(inst->ir_type) { 827 828 /* (declare () type symbol) */ 829 case ir_type_variable: { 830 ir_variable *var = inst->as_variable(); 831 _mesa_hash_table_insert(variable_context, var, ir_constant::zero(this, var->type)); 832 break; 833 } 834 835 /* (assign [condition] (write-mask) (ref) (value)) */ 836 case ir_type_assignment: { 837 ir_assignment *asg = inst->as_assignment(); 838 if (asg->condition) { 839 ir_constant *cond = asg->condition->constant_expression_value(variable_context); 840 if (!cond) 841 return false; 842 if (!cond->get_bool_component(0)) 843 break; 844 } 845 846 ir_constant *store = NULL; 847 int offset = 0; 848 849 if (!constant_referenced(asg->lhs, variable_context, store, offset)) 850 return false; 851 852 ir_constant *value = asg->rhs->constant_expression_value(variable_context); 853 854 if (!value) 855 return false; 856 857 store->copy_masked_offset(value, offset, asg->write_mask); 858 break; 859 } 860 861 /* (return (expression)) */ 862 case ir_type_return: 863 assert (result); 864 *result = inst->as_return()->value->constant_expression_value(variable_context); 865 return *result != NULL; 866 867 /* (call name (ref) (params))*/ 868 case ir_type_call: { 869 ir_call *call = inst->as_call(); 870 871 /* Just say no to void functions in constant expressions. We 872 * don't need them at that point. 873 */ 874 875 if (!call->return_deref) 876 return false; 877 878 ir_constant *store = NULL; 879 int offset = 0; 880 881 if (!constant_referenced(call->return_deref, variable_context, 882 store, offset)) 883 return false; 884 885 ir_constant *value = call->constant_expression_value(variable_context); 886 887 if(!value) 888 return false; 889 890 store->copy_offset(value, offset); 891 break; 892 } 893 894 /* (if condition (then-instructions) (else-instructions)) */ 895 case ir_type_if: { 896 ir_if *iif = inst->as_if(); 897 898 ir_constant *cond = iif->condition->constant_expression_value(variable_context); 899 if (!cond || !cond->type->is_boolean()) 900 return false; 901 902 exec_list &branch = cond->get_bool_component(0) ? iif->then_instructions : iif->else_instructions; 903 904 *result = NULL; 905 if (!constant_expression_evaluate_expression_list(branch, variable_context, result)) 906 return false; 907 908 /* If there was a return in the branch chosen, drop out now. */ 909 if (*result) 910 return true; 911 912 break; 913 } 914 915 /* Every other expression type, we drop out. */ 916 default: 917 return false; 918 } 919 } 920 921 /* Reaching the end of the block is not an error condition */ 922 if (result) 923 *result = NULL; 924 925 return true; 926 } 927 928 ir_constant * 929 ir_function_signature::constant_expression_value(exec_list *actual_parameters, struct hash_table *variable_context) 930 { 931 const glsl_type *type = this->return_type; 932 if (type == glsl_type::void_type) 933 return NULL; 934 935 /* From the GLSL 1.20 spec, page 23: 936 * "Function calls to user-defined functions (non-built-in functions) 937 * cannot be used to form constant expressions." 938 */ 939 if (!this->is_builtin()) 940 return NULL; 941 942 /* 943 * Of the builtin functions, only the texture lookups and the noise 944 * ones must not be used in constant expressions. They all include 945 * specific opcodes so they don't need to be special-cased at this 946 * point. 947 */ 948 949 /* Initialize the table of dereferencable names with the function 950 * parameters. Verify their const-ness on the way. 951 * 952 * We expect the correctness of the number of parameters to have 953 * been checked earlier. 954 */ 955 hash_table *deref_hash = _mesa_hash_table_create(NULL, _mesa_hash_pointer, 956 _mesa_key_pointer_equal); 957 958 /* If "origin" is non-NULL, then the function body is there. So we 959 * have to use the variable objects from the object with the body, 960 * but the parameter instanciation on the current object. 961 */ 962 const exec_node *parameter_info = origin ? origin->parameters.get_head_raw() : parameters.get_head_raw(); 963 964 foreach_in_list(ir_rvalue, n, actual_parameters) { 965 ir_constant *constant = n->constant_expression_value(variable_context); 966 if (constant == NULL) { 967 _mesa_hash_table_destroy(deref_hash, NULL); 968 return NULL; 969 } 970 971 972 ir_variable *var = (ir_variable *)parameter_info; 973 _mesa_hash_table_insert(deref_hash, var, constant); 974 975 parameter_info = parameter_info->next; 976 } 977 978 ir_constant *result = NULL; 979 980 /* Now run the builtin function until something non-constant 981 * happens or we get the result. 982 */ 983 if (constant_expression_evaluate_expression_list(origin ? origin->body : body, deref_hash, &result) && result) 984 result = result->clone(ralloc_parent(this), NULL); 985 986 _mesa_hash_table_destroy(deref_hash, NULL); 987 988 return result; 989 } 990