ir.cpp revision 046bef235744e891e4a48076e1a3ff9a61a63092
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#include <string.h> 24#include "main/imports.h" 25#include "main/macros.h" 26#include "ir.h" 27#include "ir_visitor.h" 28#include "glsl_types.h" 29 30ir_rvalue::ir_rvalue() 31{ 32 this->type = glsl_type::error_type; 33} 34 35/** 36 * Modify the swizzle make to move one component to another 37 * 38 * \param m IR swizzle to be modified 39 * \param from Component in the RHS that is to be swizzled 40 * \param to Desired swizzle location of \c from 41 */ 42static void 43update_rhs_swizzle(ir_swizzle_mask &m, unsigned from, unsigned to) 44{ 45 switch (to) { 46 case 0: m.x = from; break; 47 case 1: m.y = from; break; 48 case 2: m.z = from; break; 49 case 3: m.w = from; break; 50 default: assert(!"Should not get here."); 51 } 52 53 m.num_components = MAX2(m.num_components, (to + 1)); 54} 55 56void 57ir_assignment::set_lhs(ir_rvalue *lhs) 58{ 59 while (lhs != NULL) { 60 ir_swizzle *swiz = lhs->as_swizzle(); 61 62 if (swiz == NULL) 63 break; 64 65 unsigned write_mask = 0; 66 ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 }; 67 68 for (unsigned i = 0; i < swiz->mask.num_components; i++) { 69 unsigned c = 0; 70 71 switch (i) { 72 case 0: c = swiz->mask.x; break; 73 case 1: c = swiz->mask.y; break; 74 case 2: c = swiz->mask.z; break; 75 case 3: c = swiz->mask.w; break; 76 default: assert(!"Should not get here."); 77 } 78 79 write_mask |= (((this->write_mask >> i) & 1) << c); 80 update_rhs_swizzle(rhs_swiz, i, c); 81 } 82 83 this->write_mask = write_mask; 84 lhs = swiz->val; 85 86 this->rhs = new(this) ir_swizzle(this->rhs, rhs_swiz); 87 } 88 89 assert((lhs == NULL) || lhs->as_dereference()); 90 91 this->lhs = (ir_dereference *) lhs; 92} 93 94ir_variable * 95ir_assignment::whole_variable_written() 96{ 97 ir_variable *v = this->lhs->whole_variable_referenced(); 98 99 if (v == NULL) 100 return NULL; 101 102 if (v->type->is_scalar()) 103 return v; 104 105 if (v->type->is_vector()) { 106 const unsigned mask = (1U << v->type->vector_elements) - 1; 107 108 if (mask != this->write_mask) 109 return NULL; 110 } 111 112 /* Either all the vector components are assigned or the variable is some 113 * composite type (and the whole thing is assigned. 114 */ 115 return v; 116} 117 118ir_assignment::ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, 119 ir_rvalue *condition, unsigned write_mask) 120{ 121 this->ir_type = ir_type_assignment; 122 this->condition = condition; 123 this->rhs = rhs; 124 this->lhs = lhs; 125 this->write_mask = write_mask; 126} 127 128ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, 129 ir_rvalue *condition) 130{ 131 this->ir_type = ir_type_assignment; 132 this->condition = condition; 133 this->rhs = rhs; 134 135 /* If the RHS is a vector type, assume that all components of the vector 136 * type are being written to the LHS. The write mask comes from the RHS 137 * because we can have a case where the LHS is a vec4 and the RHS is a 138 * vec3. In that case, the assignment is: 139 * 140 * (assign (...) (xyz) (var_ref lhs) (var_ref rhs)) 141 */ 142 if (rhs->type->is_vector()) 143 this->write_mask = (1U << rhs->type->vector_elements) - 1; 144 else if (rhs->type->is_scalar()) 145 this->write_mask = 1; 146 else 147 this->write_mask = 0; 148 149 this->set_lhs(lhs); 150} 151 152 153ir_expression::ir_expression(int op, const struct glsl_type *type, 154 ir_rvalue *op0, ir_rvalue *op1) 155{ 156 this->ir_type = ir_type_expression; 157 this->type = type; 158 this->operation = ir_expression_operation(op); 159 this->operands[0] = op0; 160 this->operands[1] = op1; 161} 162 163unsigned int 164ir_expression::get_num_operands(ir_expression_operation op) 165{ 166/* Update ir_print_visitor.cpp when updating this list. */ 167 const int num_operands[] = { 168 1, /* ir_unop_bit_not */ 169 1, /* ir_unop_logic_not */ 170 1, /* ir_unop_neg */ 171 1, /* ir_unop_abs */ 172 1, /* ir_unop_sign */ 173 1, /* ir_unop_rcp */ 174 1, /* ir_unop_rsq */ 175 1, /* ir_unop_sqrt */ 176 1, /* ir_unop_exp */ 177 1, /* ir_unop_log */ 178 1, /* ir_unop_exp2 */ 179 1, /* ir_unop_log2 */ 180 1, /* ir_unop_f2i */ 181 1, /* ir_unop_i2f */ 182 1, /* ir_unop_f2b */ 183 1, /* ir_unop_b2f */ 184 1, /* ir_unop_i2b */ 185 1, /* ir_unop_b2i */ 186 1, /* ir_unop_u2f */ 187 188 1, /* ir_unop_trunc */ 189 1, /* ir_unop_ceil */ 190 1, /* ir_unop_floor */ 191 1, /* ir_unop_fract */ 192 193 1, /* ir_unop_sin */ 194 1, /* ir_unop_cos */ 195 196 1, /* ir_unop_dFdx */ 197 1, /* ir_unop_dFdy */ 198 199 2, /* ir_binop_add */ 200 2, /* ir_binop_sub */ 201 2, /* ir_binop_mul */ 202 2, /* ir_binop_div */ 203 2, /* ir_binop_mod */ 204 205 2, /* ir_binop_less */ 206 2, /* ir_binop_greater */ 207 2, /* ir_binop_lequal */ 208 2, /* ir_binop_gequal */ 209 2, /* ir_binop_equal */ 210 2, /* ir_binop_nequal */ 211 212 2, /* ir_binop_lshift */ 213 2, /* ir_binop_rshift */ 214 2, /* ir_binop_bit_and */ 215 2, /* ir_binop_bit_xor */ 216 2, /* ir_binop_bit_or */ 217 218 2, /* ir_binop_logic_and */ 219 2, /* ir_binop_logic_xor */ 220 2, /* ir_binop_logic_or */ 221 222 2, /* ir_binop_dot */ 223 2, /* ir_binop_cross */ 224 2, /* ir_binop_min */ 225 2, /* ir_binop_max */ 226 227 2, /* ir_binop_pow */ 228 }; 229 230 assert(sizeof(num_operands) / sizeof(num_operands[0]) == ir_binop_pow + 1); 231 232 return num_operands[op]; 233} 234 235static const char *const operator_strs[] = { 236 "~", 237 "!", 238 "neg", 239 "abs", 240 "sign", 241 "rcp", 242 "rsq", 243 "sqrt", 244 "exp", 245 "log", 246 "exp2", 247 "log2", 248 "f2i", 249 "i2f", 250 "f2b", 251 "b2f", 252 "i2b", 253 "b2i", 254 "u2f", 255 "trunc", 256 "ceil", 257 "floor", 258 "fract", 259 "sin", 260 "cos", 261 "dFdx", 262 "dFdy", 263 "+", 264 "-", 265 "*", 266 "/", 267 "%", 268 "<", 269 ">", 270 "<=", 271 ">=", 272 "==", 273 "!=", 274 "<<", 275 ">>", 276 "&", 277 "^", 278 "|", 279 "&&", 280 "^^", 281 "||", 282 "dot", 283 "cross", 284 "min", 285 "max", 286 "pow", 287}; 288 289const char *ir_expression::operator_string() 290{ 291 assert((unsigned int) operation <= 292 sizeof(operator_strs) / sizeof(operator_strs[0])); 293 return operator_strs[operation]; 294} 295 296ir_expression_operation 297ir_expression::get_operator(const char *str) 298{ 299 const int operator_count = sizeof(operator_strs) / sizeof(operator_strs[0]); 300 for (int op = 0; op < operator_count; op++) { 301 if (strcmp(str, operator_strs[op]) == 0) 302 return (ir_expression_operation) op; 303 } 304 return (ir_expression_operation) -1; 305} 306 307ir_constant::ir_constant() 308{ 309 this->ir_type = ir_type_constant; 310} 311 312ir_constant::ir_constant(const struct glsl_type *type, 313 const ir_constant_data *data) 314{ 315 assert((type->base_type >= GLSL_TYPE_UINT) 316 && (type->base_type <= GLSL_TYPE_BOOL)); 317 318 this->ir_type = ir_type_constant; 319 this->type = type; 320 memcpy(& this->value, data, sizeof(this->value)); 321} 322 323ir_constant::ir_constant(float f) 324{ 325 this->ir_type = ir_type_constant; 326 this->type = glsl_type::float_type; 327 this->value.f[0] = f; 328} 329 330ir_constant::ir_constant(unsigned int u) 331{ 332 this->ir_type = ir_type_constant; 333 this->type = glsl_type::uint_type; 334 this->value.u[0] = u; 335} 336 337ir_constant::ir_constant(int i) 338{ 339 this->ir_type = ir_type_constant; 340 this->type = glsl_type::int_type; 341 this->value.i[0] = i; 342} 343 344ir_constant::ir_constant(bool b) 345{ 346 this->ir_type = ir_type_constant; 347 this->type = glsl_type::bool_type; 348 this->value.b[0] = b; 349} 350 351ir_constant::ir_constant(const ir_constant *c, unsigned i) 352{ 353 this->ir_type = ir_type_constant; 354 this->type = c->type->get_base_type(); 355 356 switch (this->type->base_type) { 357 case GLSL_TYPE_UINT: this->value.u[0] = c->value.u[i]; break; 358 case GLSL_TYPE_INT: this->value.i[0] = c->value.i[i]; break; 359 case GLSL_TYPE_FLOAT: this->value.f[0] = c->value.f[i]; break; 360 case GLSL_TYPE_BOOL: this->value.b[0] = c->value.b[i]; break; 361 default: assert(!"Should not get here."); break; 362 } 363} 364 365ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) 366{ 367 this->ir_type = ir_type_constant; 368 this->type = type; 369 370 assert(type->is_scalar() || type->is_vector() || type->is_matrix() 371 || type->is_record() || type->is_array()); 372 373 if (type->is_array()) { 374 this->array_elements = talloc_array(this, ir_constant *, type->length); 375 unsigned i = 0; 376 foreach_list(node, value_list) { 377 ir_constant *value = (ir_constant *) node; 378 assert(value->as_constant() != NULL); 379 380 this->array_elements[i++] = value; 381 } 382 return; 383 } 384 385 /* If the constant is a record, the types of each of the entries in 386 * value_list must be a 1-for-1 match with the structure components. Each 387 * entry must also be a constant. Just move the nodes from the value_list 388 * to the list in the ir_constant. 389 */ 390 /* FINISHME: Should there be some type checking and / or assertions here? */ 391 /* FINISHME: Should the new constant take ownership of the nodes from 392 * FINISHME: value_list, or should it make copies? 393 */ 394 if (type->is_record()) { 395 value_list->move_nodes_to(& this->components); 396 return; 397 } 398 399 400 ir_constant *value = (ir_constant *) (value_list->head); 401 402 /* Use each component from each entry in the value_list to initialize one 403 * component of the constant being constructed. 404 */ 405 for (unsigned i = 0; i < type->components(); /* empty */) { 406 assert(value->as_constant() != NULL); 407 assert(!value->is_tail_sentinel()); 408 409 for (unsigned j = 0; j < value->type->components(); j++) { 410 switch (type->base_type) { 411 case GLSL_TYPE_UINT: 412 this->value.u[i] = value->get_uint_component(j); 413 break; 414 case GLSL_TYPE_INT: 415 this->value.i[i] = value->get_int_component(j); 416 break; 417 case GLSL_TYPE_FLOAT: 418 this->value.f[i] = value->get_float_component(j); 419 break; 420 case GLSL_TYPE_BOOL: 421 this->value.b[i] = value->get_bool_component(j); 422 break; 423 default: 424 /* FINISHME: What to do? Exceptions are not the answer. 425 */ 426 break; 427 } 428 429 i++; 430 if (i >= type->components()) 431 break; 432 } 433 434 value = (ir_constant *) value->next; 435 } 436} 437 438ir_constant * 439ir_constant::zero(void *mem_ctx, const glsl_type *type) 440{ 441 assert(type->is_numeric()); 442 443 ir_constant *c = new(mem_ctx) ir_constant; 444 c->type = type; 445 memset(&c->value, 0, sizeof(c->value)); 446 447 return c; 448} 449 450bool 451ir_constant::get_bool_component(unsigned i) const 452{ 453 switch (this->type->base_type) { 454 case GLSL_TYPE_UINT: return this->value.u[i] != 0; 455 case GLSL_TYPE_INT: return this->value.i[i] != 0; 456 case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0; 457 case GLSL_TYPE_BOOL: return this->value.b[i]; 458 default: assert(!"Should not get here."); break; 459 } 460 461 /* Must return something to make the compiler happy. This is clearly an 462 * error case. 463 */ 464 return false; 465} 466 467float 468ir_constant::get_float_component(unsigned i) const 469{ 470 switch (this->type->base_type) { 471 case GLSL_TYPE_UINT: return (float) this->value.u[i]; 472 case GLSL_TYPE_INT: return (float) this->value.i[i]; 473 case GLSL_TYPE_FLOAT: return this->value.f[i]; 474 case GLSL_TYPE_BOOL: return this->value.b[i] ? 1.0 : 0.0; 475 default: assert(!"Should not get here."); break; 476 } 477 478 /* Must return something to make the compiler happy. This is clearly an 479 * error case. 480 */ 481 return 0.0; 482} 483 484int 485ir_constant::get_int_component(unsigned i) const 486{ 487 switch (this->type->base_type) { 488 case GLSL_TYPE_UINT: return this->value.u[i]; 489 case GLSL_TYPE_INT: return this->value.i[i]; 490 case GLSL_TYPE_FLOAT: return (int) this->value.f[i]; 491 case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0; 492 default: assert(!"Should not get here."); break; 493 } 494 495 /* Must return something to make the compiler happy. This is clearly an 496 * error case. 497 */ 498 return 0; 499} 500 501unsigned 502ir_constant::get_uint_component(unsigned i) const 503{ 504 switch (this->type->base_type) { 505 case GLSL_TYPE_UINT: return this->value.u[i]; 506 case GLSL_TYPE_INT: return this->value.i[i]; 507 case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i]; 508 case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0; 509 default: assert(!"Should not get here."); break; 510 } 511 512 /* Must return something to make the compiler happy. This is clearly an 513 * error case. 514 */ 515 return 0; 516} 517 518ir_constant * 519ir_constant::get_array_element(unsigned i) const 520{ 521 assert(this->type->is_array()); 522 assert(i < this->type->length); 523 524 return array_elements[i]; 525} 526 527ir_constant * 528ir_constant::get_record_field(const char *name) 529{ 530 int idx = this->type->field_index(name); 531 532 if (idx < 0) 533 return NULL; 534 535 if (this->components.is_empty()) 536 return NULL; 537 538 exec_node *node = this->components.head; 539 for (int i = 0; i < idx; i++) { 540 node = node->next; 541 542 /* If the end of the list is encountered before the element matching the 543 * requested field is found, return NULL. 544 */ 545 if (node->is_tail_sentinel()) 546 return NULL; 547 } 548 549 return (ir_constant *) node; 550} 551 552 553bool 554ir_constant::has_value(const ir_constant *c) const 555{ 556 if (this->type != c->type) 557 return false; 558 559 if (this->type->is_array()) { 560 for (unsigned i = 0; i < this->type->length; i++) { 561 if (this->array_elements[i]->has_value(c->array_elements[i])) 562 return false; 563 } 564 return true; 565 } 566 567 if (this->type->base_type == GLSL_TYPE_STRUCT) { 568 const exec_node *a_node = this->components.head; 569 const exec_node *b_node = c->components.head; 570 571 while (!a_node->is_tail_sentinel()) { 572 assert(!b_node->is_tail_sentinel()); 573 574 const ir_constant *const a_field = (ir_constant *) a_node; 575 const ir_constant *const b_field = (ir_constant *) b_node; 576 577 if (!a_field->has_value(b_field)) 578 return false; 579 580 a_node = a_node->next; 581 b_node = b_node->next; 582 } 583 584 return true; 585 } 586 587 for (unsigned i = 0; i < this->type->components(); i++) { 588 switch (this->type->base_type) { 589 case GLSL_TYPE_UINT: 590 if (this->value.u[i] != c->value.u[i]) 591 return false; 592 break; 593 case GLSL_TYPE_INT: 594 if (this->value.i[i] != c->value.i[i]) 595 return false; 596 break; 597 case GLSL_TYPE_FLOAT: 598 if (this->value.f[i] != c->value.f[i]) 599 return false; 600 break; 601 case GLSL_TYPE_BOOL: 602 if (this->value.b[i] != c->value.b[i]) 603 return false; 604 break; 605 default: 606 assert(!"Should not get here."); 607 return false; 608 } 609 } 610 611 return true; 612} 613 614ir_dereference_variable::ir_dereference_variable(ir_variable *var) 615{ 616 this->ir_type = ir_type_dereference_variable; 617 this->var = var; 618 this->type = (var != NULL) ? var->type : glsl_type::error_type; 619} 620 621 622ir_dereference_array::ir_dereference_array(ir_rvalue *value, 623 ir_rvalue *array_index) 624{ 625 this->ir_type = ir_type_dereference_array; 626 this->array_index = array_index; 627 this->set_array(value); 628} 629 630 631ir_dereference_array::ir_dereference_array(ir_variable *var, 632 ir_rvalue *array_index) 633{ 634 void *ctx = talloc_parent(var); 635 636 this->ir_type = ir_type_dereference_array; 637 this->array_index = array_index; 638 this->set_array(new(ctx) ir_dereference_variable(var)); 639} 640 641 642void 643ir_dereference_array::set_array(ir_rvalue *value) 644{ 645 this->array = value; 646 this->type = glsl_type::error_type; 647 648 if (this->array != NULL) { 649 const glsl_type *const vt = this->array->type; 650 651 if (vt->is_array()) { 652 type = vt->element_type(); 653 } else if (vt->is_matrix()) { 654 type = vt->column_type(); 655 } else if (vt->is_vector()) { 656 type = vt->get_base_type(); 657 } 658 } 659} 660 661 662ir_dereference_record::ir_dereference_record(ir_rvalue *value, 663 const char *field) 664{ 665 this->ir_type = ir_type_dereference_record; 666 this->record = value; 667 this->field = talloc_strdup(this, field); 668 this->type = (this->record != NULL) 669 ? this->record->type->field_type(field) : glsl_type::error_type; 670} 671 672 673ir_dereference_record::ir_dereference_record(ir_variable *var, 674 const char *field) 675{ 676 void *ctx = talloc_parent(var); 677 678 this->ir_type = ir_type_dereference_record; 679 this->record = new(ctx) ir_dereference_variable(var); 680 this->field = talloc_strdup(this, field); 681 this->type = (this->record != NULL) 682 ? this->record->type->field_type(field) : glsl_type::error_type; 683} 684 685 686bool 687ir_dereference::is_lvalue() 688{ 689 ir_variable *var = this->variable_referenced(); 690 691 /* Every l-value derference chain eventually ends in a variable. 692 */ 693 if ((var == NULL) || var->read_only) 694 return false; 695 696 if (this->type->is_array() && !var->array_lvalue) 697 return false; 698 699 return true; 700} 701 702 703const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf" }; 704 705const char *ir_texture::opcode_string() 706{ 707 assert((unsigned int) op <= 708 sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0])); 709 return tex_opcode_strs[op]; 710} 711 712ir_texture_opcode 713ir_texture::get_opcode(const char *str) 714{ 715 const int count = sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]); 716 for (int op = 0; op < count; op++) { 717 if (strcmp(str, tex_opcode_strs[op]) == 0) 718 return (ir_texture_opcode) op; 719 } 720 return (ir_texture_opcode) -1; 721} 722 723 724void 725ir_texture::set_sampler(ir_dereference *sampler) 726{ 727 assert(sampler != NULL); 728 this->sampler = sampler; 729 730 switch (sampler->type->sampler_type) { 731 case GLSL_TYPE_FLOAT: 732 this->type = glsl_type::vec4_type; 733 break; 734 case GLSL_TYPE_INT: 735 this->type = glsl_type::ivec4_type; 736 break; 737 case GLSL_TYPE_UINT: 738 this->type = glsl_type::uvec4_type; 739 break; 740 } 741} 742 743 744void 745ir_swizzle::init_mask(const unsigned *comp, unsigned count) 746{ 747 assert((count >= 1) && (count <= 4)); 748 749 memset(&this->mask, 0, sizeof(this->mask)); 750 this->mask.num_components = count; 751 752 unsigned dup_mask = 0; 753 switch (count) { 754 case 4: 755 assert(comp[3] <= 3); 756 dup_mask |= (1U << comp[3]) 757 & ((1U << comp[0]) | (1U << comp[1]) | (1U << comp[2])); 758 this->mask.w = comp[3]; 759 760 case 3: 761 assert(comp[2] <= 3); 762 dup_mask |= (1U << comp[2]) 763 & ((1U << comp[0]) | (1U << comp[1])); 764 this->mask.z = comp[2]; 765 766 case 2: 767 assert(comp[1] <= 3); 768 dup_mask |= (1U << comp[1]) 769 & ((1U << comp[0])); 770 this->mask.y = comp[1]; 771 772 case 1: 773 assert(comp[0] <= 3); 774 this->mask.x = comp[0]; 775 } 776 777 this->mask.has_duplicates = dup_mask != 0; 778 779 /* Based on the number of elements in the swizzle and the base type 780 * (i.e., float, int, unsigned, or bool) of the vector being swizzled, 781 * generate the type of the resulting value. 782 */ 783 type = glsl_type::get_instance(val->type->base_type, mask.num_components, 1); 784} 785 786ir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z, 787 unsigned w, unsigned count) 788 : val(val) 789{ 790 const unsigned components[4] = { x, y, z, w }; 791 this->ir_type = ir_type_swizzle; 792 this->init_mask(components, count); 793} 794 795ir_swizzle::ir_swizzle(ir_rvalue *val, const unsigned *comp, 796 unsigned count) 797 : val(val) 798{ 799 this->ir_type = ir_type_swizzle; 800 this->init_mask(comp, count); 801} 802 803ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask) 804{ 805 this->ir_type = ir_type_swizzle; 806 this->val = val; 807 this->mask = mask; 808 this->type = glsl_type::get_instance(val->type->base_type, 809 mask.num_components, 1); 810} 811 812#define X 1 813#define R 5 814#define S 9 815#define I 13 816 817ir_swizzle * 818ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length) 819{ 820 void *ctx = talloc_parent(val); 821 822 /* For each possible swizzle character, this table encodes the value in 823 * \c idx_map that represents the 0th element of the vector. For invalid 824 * swizzle characters (e.g., 'k'), a special value is used that will allow 825 * detection of errors. 826 */ 827 static const unsigned char base_idx[26] = { 828 /* a b c d e f g h i j k l m */ 829 R, R, I, I, I, I, R, I, I, I, I, I, I, 830 /* n o p q r s t u v w x y z */ 831 I, I, S, S, R, S, S, I, I, X, X, X, X 832 }; 833 834 /* Each valid swizzle character has an entry in the previous table. This 835 * table encodes the base index encoded in the previous table plus the actual 836 * index of the swizzle character. When processing swizzles, the first 837 * character in the string is indexed in the previous table. Each character 838 * in the string is indexed in this table, and the value found there has the 839 * value form the first table subtracted. The result must be on the range 840 * [0,3]. 841 * 842 * For example, the string "wzyx" will get X from the first table. Each of 843 * the charcaters will get X+3, X+2, X+1, and X+0 from this table. After 844 * subtraction, the swizzle values are { 3, 2, 1, 0 }. 845 * 846 * The string "wzrg" will get X from the first table. Each of the characters 847 * will get X+3, X+2, R+0, and R+1 from this table. After subtraction, the 848 * swizzle values are { 3, 2, 4, 5 }. Since 4 and 5 are outside the range 849 * [0,3], the error is detected. 850 */ 851 static const unsigned char idx_map[26] = { 852 /* a b c d e f g h i j k l m */ 853 R+3, R+2, 0, 0, 0, 0, R+1, 0, 0, 0, 0, 0, 0, 854 /* n o p q r s t u v w x y z */ 855 0, 0, S+2, S+3, R+0, S+0, S+1, 0, 0, X+3, X+0, X+1, X+2 856 }; 857 858 int swiz_idx[4] = { 0, 0, 0, 0 }; 859 unsigned i; 860 861 862 /* Validate the first character in the swizzle string and look up the base 863 * index value as described above. 864 */ 865 if ((str[0] < 'a') || (str[0] > 'z')) 866 return NULL; 867 868 const unsigned base = base_idx[str[0] - 'a']; 869 870 871 for (i = 0; (i < 4) && (str[i] != '\0'); i++) { 872 /* Validate the next character, and, as described above, convert it to a 873 * swizzle index. 874 */ 875 if ((str[i] < 'a') || (str[i] > 'z')) 876 return NULL; 877 878 swiz_idx[i] = idx_map[str[i] - 'a'] - base; 879 if ((swiz_idx[i] < 0) || (swiz_idx[i] >= (int) vector_length)) 880 return NULL; 881 } 882 883 if (str[i] != '\0') 884 return NULL; 885 886 return new(ctx) ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2], 887 swiz_idx[3], i); 888} 889 890#undef X 891#undef R 892#undef S 893#undef I 894 895ir_variable * 896ir_swizzle::variable_referenced() 897{ 898 return this->val->variable_referenced(); 899} 900 901 902ir_variable::ir_variable(const struct glsl_type *type, const char *name, 903 ir_variable_mode mode) 904 : max_array_access(0), read_only(false), centroid(false), invariant(false), 905 mode(mode), interpolation(ir_var_smooth), array_lvalue(false) 906{ 907 this->ir_type = ir_type_variable; 908 this->type = type; 909 this->name = talloc_strdup(this, name); 910 this->location = -1; 911 this->warn_extension = NULL; 912 this->constant_value = NULL; 913 this->origin_upper_left = false; 914 this->pixel_center_integer = false; 915 916 if (type && type->base_type == GLSL_TYPE_SAMPLER) 917 this->read_only = true; 918} 919 920 921const char * 922ir_variable::interpolation_string() const 923{ 924 switch (this->interpolation) { 925 case ir_var_smooth: return "smooth"; 926 case ir_var_flat: return "flat"; 927 case ir_var_noperspective: return "noperspective"; 928 } 929 930 assert(!"Should not get here."); 931 return ""; 932} 933 934 935unsigned 936ir_variable::component_slots() const 937{ 938 /* FINISHME: Sparsely accessed arrays require fewer slots. */ 939 return this->type->component_slots(); 940} 941 942 943ir_function_signature::ir_function_signature(const glsl_type *return_type) 944 : return_type(return_type), is_defined(false), _function(NULL) 945{ 946 this->ir_type = ir_type_function_signature; 947 this->is_built_in = false; 948} 949 950 951const char * 952ir_function_signature::qualifiers_match(exec_list *params) 953{ 954 exec_list_iterator iter_a = parameters.iterator(); 955 exec_list_iterator iter_b = params->iterator(); 956 957 /* check that the qualifiers match. */ 958 while (iter_a.has_next()) { 959 ir_variable *a = (ir_variable *)iter_a.get(); 960 ir_variable *b = (ir_variable *)iter_b.get(); 961 962 if (a->read_only != b->read_only || 963 a->mode != b->mode || 964 a->interpolation != b->interpolation || 965 a->centroid != b->centroid) { 966 967 /* parameter a's qualifiers don't match */ 968 return a->name; 969 } 970 971 iter_a.next(); 972 iter_b.next(); 973 } 974 return NULL; 975} 976 977 978void 979ir_function_signature::replace_parameters(exec_list *new_params) 980{ 981 /* Destroy all of the previous parameter information. If the previous 982 * parameter information comes from the function prototype, it may either 983 * specify incorrect parameter names or not have names at all. 984 */ 985 foreach_iter(exec_list_iterator, iter, parameters) { 986 assert(((ir_instruction *) iter.get())->as_variable() != NULL); 987 988 iter.remove(); 989 } 990 991 new_params->move_nodes_to(¶meters); 992} 993 994 995ir_function::ir_function(const char *name) 996{ 997 this->ir_type = ir_type_function; 998 this->name = talloc_strdup(this, name); 999} 1000 1001 1002ir_call * 1003ir_call::get_error_instruction(void *ctx) 1004{ 1005 ir_call *call = new(ctx) ir_call; 1006 1007 call->type = glsl_type::error_type; 1008 return call; 1009} 1010 1011void 1012ir_call::set_callee(ir_function_signature *sig) 1013{ 1014 assert((this->type == NULL) || (this->type == sig->return_type)); 1015 1016 this->callee = sig; 1017} 1018 1019void 1020visit_exec_list(exec_list *list, ir_visitor *visitor) 1021{ 1022 foreach_iter(exec_list_iterator, iter, *list) { 1023 ((ir_instruction *)iter.get())->accept(visitor); 1024 } 1025} 1026 1027 1028static void 1029steal_memory(ir_instruction *ir, void *new_ctx) 1030{ 1031 ir_variable *var = ir->as_variable(); 1032 ir_constant *constant = ir->as_constant(); 1033 if (var != NULL && var->constant_value != NULL) 1034 steal_memory(var->constant_value, ir); 1035 1036 /* The components of aggregate constants are not visited by the normal 1037 * visitor, so steal their values by hand. 1038 */ 1039 if (constant != NULL) { 1040 if (constant->type->is_record()) { 1041 foreach_iter(exec_list_iterator, iter, constant->components) { 1042 ir_constant *field = (ir_constant *)iter.get(); 1043 steal_memory(field, ir); 1044 } 1045 } else if (constant->type->is_array()) { 1046 for (unsigned int i = 0; i < constant->type->length; i++) { 1047 steal_memory(constant->array_elements[i], ir); 1048 } 1049 } 1050 } 1051 1052 talloc_steal(new_ctx, ir); 1053} 1054 1055 1056void 1057reparent_ir(exec_list *list, void *mem_ctx) 1058{ 1059 foreach_list(node, list) { 1060 visit_tree((ir_instruction *) node, steal_memory, mem_ctx); 1061 } 1062} 1063