1 /************************************************************************** 2 * 3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 #include "util/u_debug.h" 29 #include "pipe/p_format.h" 30 #include "pipe/p_shader_tokens.h" 31 #include "tgsi_build.h" 32 #include "tgsi_parse.h" 33 34 35 /* 36 * header 37 */ 38 39 struct tgsi_header 40 tgsi_build_header( void ) 41 { 42 struct tgsi_header header; 43 44 header.HeaderSize = 1; 45 header.BodySize = 0; 46 47 return header; 48 } 49 50 static void 51 header_headersize_grow( struct tgsi_header *header ) 52 { 53 assert( header->HeaderSize < 0xFF ); 54 assert( header->BodySize == 0 ); 55 56 header->HeaderSize++; 57 } 58 59 static void 60 header_bodysize_grow( struct tgsi_header *header ) 61 { 62 assert( header->BodySize < 0xFFFFFF ); 63 64 header->BodySize++; 65 } 66 67 struct tgsi_processor 68 tgsi_build_processor( 69 unsigned type, 70 struct tgsi_header *header ) 71 { 72 struct tgsi_processor processor; 73 74 processor.Processor = type; 75 processor.Padding = 0; 76 77 header_headersize_grow( header ); 78 79 return processor; 80 } 81 82 /* 83 * declaration 84 */ 85 86 static void 87 declaration_grow( 88 struct tgsi_declaration *declaration, 89 struct tgsi_header *header ) 90 { 91 assert( declaration->NrTokens < 0xFF ); 92 93 declaration->NrTokens++; 94 95 header_bodysize_grow( header ); 96 } 97 98 static struct tgsi_declaration 99 tgsi_default_declaration( void ) 100 { 101 struct tgsi_declaration declaration; 102 103 declaration.Type = TGSI_TOKEN_TYPE_DECLARATION; 104 declaration.NrTokens = 1; 105 declaration.File = TGSI_FILE_NULL; 106 declaration.UsageMask = TGSI_WRITEMASK_XYZW; 107 declaration.Interpolate = 0; 108 declaration.Dimension = 0; 109 declaration.Semantic = 0; 110 declaration.Invariant = 0; 111 declaration.Local = 0; 112 declaration.Padding = 0; 113 114 return declaration; 115 } 116 117 static struct tgsi_declaration 118 tgsi_build_declaration( 119 unsigned file, 120 unsigned usage_mask, 121 unsigned interpolate, 122 unsigned dimension, 123 unsigned semantic, 124 unsigned invariant, 125 unsigned local, 126 struct tgsi_header *header ) 127 { 128 struct tgsi_declaration declaration; 129 130 assert( file < TGSI_FILE_COUNT ); 131 assert( interpolate < TGSI_INTERPOLATE_COUNT ); 132 133 declaration = tgsi_default_declaration(); 134 declaration.File = file; 135 declaration.UsageMask = usage_mask; 136 declaration.Interpolate = interpolate; 137 declaration.Dimension = dimension; 138 declaration.Semantic = semantic; 139 declaration.Invariant = invariant; 140 declaration.Local = local; 141 142 header_bodysize_grow( header ); 143 144 return declaration; 145 } 146 147 static struct tgsi_declaration_range 148 tgsi_default_declaration_range( void ) 149 { 150 struct tgsi_declaration_range dr; 151 152 dr.First = 0; 153 dr.Last = 0; 154 155 return dr; 156 } 157 158 static struct tgsi_declaration_range 159 tgsi_build_declaration_range( 160 unsigned first, 161 unsigned last, 162 struct tgsi_declaration *declaration, 163 struct tgsi_header *header ) 164 { 165 struct tgsi_declaration_range declaration_range; 166 167 assert( last >= first ); 168 assert( last <= 0xFFFF ); 169 170 declaration_range.First = first; 171 declaration_range.Last = last; 172 173 declaration_grow( declaration, header ); 174 175 return declaration_range; 176 } 177 178 static struct tgsi_declaration_dimension 179 tgsi_build_declaration_dimension(unsigned index_2d, 180 struct tgsi_declaration *declaration, 181 struct tgsi_header *header) 182 { 183 struct tgsi_declaration_dimension dd; 184 185 assert(index_2d <= 0xFFFF); 186 187 dd.Index2D = index_2d; 188 dd.Padding = 0; 189 190 declaration_grow(declaration, header); 191 192 return dd; 193 } 194 195 static struct tgsi_declaration_interp 196 tgsi_default_declaration_interp( void ) 197 { 198 struct tgsi_declaration_interp di; 199 200 di.Interpolate = TGSI_INTERPOLATE_CONSTANT; 201 di.Centroid = 0; 202 di.CylindricalWrap = 0; 203 di.Padding = 0; 204 205 return di; 206 } 207 208 static struct tgsi_declaration_interp 209 tgsi_build_declaration_interp(unsigned interpolate, 210 unsigned centroid, 211 unsigned cylindrical_wrap, 212 struct tgsi_declaration *declaration, 213 struct tgsi_header *header) 214 { 215 struct tgsi_declaration_interp di; 216 217 di.Interpolate = interpolate; 218 di.Centroid = centroid; 219 di.CylindricalWrap = cylindrical_wrap; 220 di.Padding = 0; 221 222 declaration_grow(declaration, header); 223 224 return di; 225 } 226 227 static struct tgsi_declaration_semantic 228 tgsi_default_declaration_semantic( void ) 229 { 230 struct tgsi_declaration_semantic ds; 231 232 ds.Name = TGSI_SEMANTIC_POSITION; 233 ds.Index = 0; 234 ds.Padding = 0; 235 236 return ds; 237 } 238 239 static struct tgsi_declaration_semantic 240 tgsi_build_declaration_semantic( 241 unsigned semantic_name, 242 unsigned semantic_index, 243 struct tgsi_declaration *declaration, 244 struct tgsi_header *header ) 245 { 246 struct tgsi_declaration_semantic ds; 247 248 assert( semantic_name <= TGSI_SEMANTIC_COUNT ); 249 assert( semantic_index <= 0xFFFF ); 250 251 ds.Name = semantic_name; 252 ds.Index = semantic_index; 253 ds.Padding = 0; 254 255 declaration_grow( declaration, header ); 256 257 return ds; 258 } 259 260 static struct tgsi_declaration_resource 261 tgsi_default_declaration_resource(void) 262 { 263 struct tgsi_declaration_resource dr; 264 265 dr.Resource = TGSI_TEXTURE_BUFFER; 266 dr.Raw = 0; 267 dr.Writable = 0; 268 dr.Padding = 0; 269 270 return dr; 271 } 272 273 static struct tgsi_declaration_resource 274 tgsi_build_declaration_resource(unsigned texture, 275 unsigned raw, 276 unsigned writable, 277 struct tgsi_declaration *declaration, 278 struct tgsi_header *header) 279 { 280 struct tgsi_declaration_resource dr; 281 282 dr = tgsi_default_declaration_resource(); 283 dr.Resource = texture; 284 dr.Raw = raw; 285 dr.Writable = writable; 286 287 declaration_grow(declaration, header); 288 289 return dr; 290 } 291 292 static struct tgsi_declaration_sampler_view 293 tgsi_default_declaration_sampler_view(void) 294 { 295 struct tgsi_declaration_sampler_view dsv; 296 297 dsv.Resource = TGSI_TEXTURE_BUFFER; 298 dsv.ReturnTypeX = PIPE_TYPE_UNORM; 299 dsv.ReturnTypeY = PIPE_TYPE_UNORM; 300 dsv.ReturnTypeZ = PIPE_TYPE_UNORM; 301 dsv.ReturnTypeW = PIPE_TYPE_UNORM; 302 303 return dsv; 304 } 305 306 static struct tgsi_declaration_sampler_view 307 tgsi_build_declaration_sampler_view(unsigned texture, 308 unsigned return_type_x, 309 unsigned return_type_y, 310 unsigned return_type_z, 311 unsigned return_type_w, 312 struct tgsi_declaration *declaration, 313 struct tgsi_header *header) 314 { 315 struct tgsi_declaration_sampler_view dsv; 316 317 dsv = tgsi_default_declaration_sampler_view(); 318 dsv.Resource = texture; 319 dsv.ReturnTypeX = return_type_x; 320 dsv.ReturnTypeY = return_type_y; 321 dsv.ReturnTypeZ = return_type_z; 322 dsv.ReturnTypeW = return_type_w; 323 324 declaration_grow(declaration, header); 325 326 return dsv; 327 } 328 329 330 struct tgsi_full_declaration 331 tgsi_default_full_declaration( void ) 332 { 333 struct tgsi_full_declaration full_declaration; 334 335 full_declaration.Declaration = tgsi_default_declaration(); 336 full_declaration.Range = tgsi_default_declaration_range(); 337 full_declaration.Semantic = tgsi_default_declaration_semantic(); 338 full_declaration.Interp = tgsi_default_declaration_interp(); 339 full_declaration.ImmediateData.u = NULL; 340 full_declaration.Resource = tgsi_default_declaration_resource(); 341 full_declaration.SamplerView = tgsi_default_declaration_sampler_view(); 342 343 return full_declaration; 344 } 345 346 unsigned 347 tgsi_build_full_declaration( 348 const struct tgsi_full_declaration *full_decl, 349 struct tgsi_token *tokens, 350 struct tgsi_header *header, 351 unsigned maxsize ) 352 { 353 unsigned size = 0; 354 struct tgsi_declaration *declaration; 355 struct tgsi_declaration_range *dr; 356 357 if( maxsize <= size ) 358 return 0; 359 declaration = (struct tgsi_declaration *) &tokens[size]; 360 size++; 361 362 *declaration = tgsi_build_declaration( 363 full_decl->Declaration.File, 364 full_decl->Declaration.UsageMask, 365 full_decl->Declaration.Interpolate, 366 full_decl->Declaration.Dimension, 367 full_decl->Declaration.Semantic, 368 full_decl->Declaration.Invariant, 369 full_decl->Declaration.Local, 370 header ); 371 372 if (maxsize <= size) 373 return 0; 374 dr = (struct tgsi_declaration_range *) &tokens[size]; 375 size++; 376 377 *dr = tgsi_build_declaration_range( 378 full_decl->Range.First, 379 full_decl->Range.Last, 380 declaration, 381 header ); 382 383 if (full_decl->Declaration.Dimension) { 384 struct tgsi_declaration_dimension *dd; 385 386 if (maxsize <= size) { 387 return 0; 388 } 389 dd = (struct tgsi_declaration_dimension *)&tokens[size]; 390 size++; 391 392 *dd = tgsi_build_declaration_dimension(full_decl->Dim.Index2D, 393 declaration, 394 header); 395 } 396 397 if (full_decl->Declaration.Interpolate) { 398 struct tgsi_declaration_interp *di; 399 400 if (maxsize <= size) { 401 return 0; 402 } 403 di = (struct tgsi_declaration_interp *)&tokens[size]; 404 size++; 405 406 *di = tgsi_build_declaration_interp(full_decl->Interp.Interpolate, 407 full_decl->Interp.Centroid, 408 full_decl->Interp.CylindricalWrap, 409 declaration, 410 header); 411 } 412 413 if( full_decl->Declaration.Semantic ) { 414 struct tgsi_declaration_semantic *ds; 415 416 if( maxsize <= size ) 417 return 0; 418 ds = (struct tgsi_declaration_semantic *) &tokens[size]; 419 size++; 420 421 *ds = tgsi_build_declaration_semantic( 422 full_decl->Semantic.Name, 423 full_decl->Semantic.Index, 424 declaration, 425 header ); 426 } 427 428 if (full_decl->Declaration.File == TGSI_FILE_IMMEDIATE_ARRAY) { 429 unsigned i, j; 430 union tgsi_immediate_data *data; 431 432 for (i = 0; i <= dr->Last; ++i) { 433 for (j = 0; j < 4; ++j) { 434 unsigned idx = i*4 + j; 435 if (maxsize <= size) 436 return 0; 437 data = (union tgsi_immediate_data *) &tokens[size]; 438 ++size; 439 440 *data = full_decl->ImmediateData.u[idx]; 441 declaration_grow( declaration, header ); 442 } 443 } 444 } 445 446 if (full_decl->Declaration.File == TGSI_FILE_RESOURCE) { 447 struct tgsi_declaration_resource *dr; 448 449 if (maxsize <= size) { 450 return 0; 451 } 452 dr = (struct tgsi_declaration_resource *)&tokens[size]; 453 size++; 454 455 *dr = tgsi_build_declaration_resource(full_decl->Resource.Resource, 456 full_decl->Resource.Raw, 457 full_decl->Resource.Writable, 458 declaration, 459 header); 460 } 461 462 if (full_decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) { 463 struct tgsi_declaration_sampler_view *dsv; 464 465 if (maxsize <= size) { 466 return 0; 467 } 468 dsv = (struct tgsi_declaration_sampler_view *)&tokens[size]; 469 size++; 470 471 *dsv = tgsi_build_declaration_sampler_view( 472 full_decl->SamplerView.Resource, 473 full_decl->SamplerView.ReturnTypeX, 474 full_decl->SamplerView.ReturnTypeY, 475 full_decl->SamplerView.ReturnTypeZ, 476 full_decl->SamplerView.ReturnTypeW, 477 declaration, 478 header); 479 } 480 481 return size; 482 } 483 484 /* 485 * immediate 486 */ 487 488 static struct tgsi_immediate 489 tgsi_default_immediate( void ) 490 { 491 struct tgsi_immediate immediate; 492 493 immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE; 494 immediate.NrTokens = 1; 495 immediate.DataType = TGSI_IMM_FLOAT32; 496 immediate.Padding = 0; 497 498 return immediate; 499 } 500 501 static struct tgsi_immediate 502 tgsi_build_immediate( 503 struct tgsi_header *header, 504 unsigned type ) 505 { 506 struct tgsi_immediate immediate; 507 508 immediate = tgsi_default_immediate(); 509 immediate.DataType = type; 510 511 header_bodysize_grow( header ); 512 513 return immediate; 514 } 515 516 struct tgsi_full_immediate 517 tgsi_default_full_immediate( void ) 518 { 519 struct tgsi_full_immediate fullimm; 520 521 fullimm.Immediate = tgsi_default_immediate(); 522 fullimm.u[0].Float = 0.0f; 523 fullimm.u[1].Float = 0.0f; 524 fullimm.u[2].Float = 0.0f; 525 fullimm.u[3].Float = 0.0f; 526 527 return fullimm; 528 } 529 530 static void 531 immediate_grow( 532 struct tgsi_immediate *immediate, 533 struct tgsi_header *header ) 534 { 535 assert( immediate->NrTokens < 0xFF ); 536 537 immediate->NrTokens++; 538 539 header_bodysize_grow( header ); 540 } 541 542 unsigned 543 tgsi_build_full_immediate( 544 const struct tgsi_full_immediate *full_imm, 545 struct tgsi_token *tokens, 546 struct tgsi_header *header, 547 unsigned maxsize ) 548 { 549 unsigned size = 0, i; 550 struct tgsi_immediate *immediate; 551 552 if( maxsize <= size ) 553 return 0; 554 immediate = (struct tgsi_immediate *) &tokens[size]; 555 size++; 556 557 *immediate = tgsi_build_immediate( header, full_imm->Immediate.DataType ); 558 559 assert( full_imm->Immediate.NrTokens <= 4 + 1 ); 560 561 for( i = 0; i < full_imm->Immediate.NrTokens - 1; i++ ) { 562 union tgsi_immediate_data *data; 563 564 if( maxsize <= size ) 565 return 0; 566 567 data = (union tgsi_immediate_data *) &tokens[size]; 568 *data = full_imm->u[i]; 569 570 immediate_grow( immediate, header ); 571 size++; 572 } 573 574 return size; 575 } 576 577 /* 578 * instruction 579 */ 580 581 struct tgsi_instruction 582 tgsi_default_instruction( void ) 583 { 584 struct tgsi_instruction instruction; 585 586 instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION; 587 instruction.NrTokens = 0; 588 instruction.Opcode = TGSI_OPCODE_MOV; 589 instruction.Saturate = TGSI_SAT_NONE; 590 instruction.Predicate = 0; 591 instruction.NumDstRegs = 1; 592 instruction.NumSrcRegs = 1; 593 instruction.Label = 0; 594 instruction.Texture = 0; 595 instruction.Padding = 0; 596 597 return instruction; 598 } 599 600 static struct tgsi_instruction 601 tgsi_build_instruction(unsigned opcode, 602 unsigned saturate, 603 unsigned predicate, 604 unsigned num_dst_regs, 605 unsigned num_src_regs, 606 struct tgsi_header *header) 607 { 608 struct tgsi_instruction instruction; 609 610 assert (opcode <= TGSI_OPCODE_LAST); 611 assert (saturate <= TGSI_SAT_MINUS_PLUS_ONE); 612 assert (num_dst_regs <= 3); 613 assert (num_src_regs <= 15); 614 615 instruction = tgsi_default_instruction(); 616 instruction.Opcode = opcode; 617 instruction.Saturate = saturate; 618 instruction.Predicate = predicate; 619 instruction.NumDstRegs = num_dst_regs; 620 instruction.NumSrcRegs = num_src_regs; 621 622 header_bodysize_grow( header ); 623 624 return instruction; 625 } 626 627 static void 628 instruction_grow( 629 struct tgsi_instruction *instruction, 630 struct tgsi_header *header ) 631 { 632 assert (instruction->NrTokens < 0xFF); 633 634 instruction->NrTokens++; 635 636 header_bodysize_grow( header ); 637 } 638 639 struct tgsi_instruction_predicate 640 tgsi_default_instruction_predicate(void) 641 { 642 struct tgsi_instruction_predicate instruction_predicate; 643 644 instruction_predicate.SwizzleX = TGSI_SWIZZLE_X; 645 instruction_predicate.SwizzleY = TGSI_SWIZZLE_Y; 646 instruction_predicate.SwizzleZ = TGSI_SWIZZLE_Z; 647 instruction_predicate.SwizzleW = TGSI_SWIZZLE_W; 648 instruction_predicate.Negate = 0; 649 instruction_predicate.Index = 0; 650 instruction_predicate.Padding = 0; 651 652 return instruction_predicate; 653 } 654 655 static struct tgsi_instruction_predicate 656 tgsi_build_instruction_predicate(int index, 657 unsigned negate, 658 unsigned swizzleX, 659 unsigned swizzleY, 660 unsigned swizzleZ, 661 unsigned swizzleW, 662 struct tgsi_instruction *instruction, 663 struct tgsi_header *header) 664 { 665 struct tgsi_instruction_predicate instruction_predicate; 666 667 instruction_predicate = tgsi_default_instruction_predicate(); 668 instruction_predicate.SwizzleX = swizzleX; 669 instruction_predicate.SwizzleY = swizzleY; 670 instruction_predicate.SwizzleZ = swizzleZ; 671 instruction_predicate.SwizzleW = swizzleW; 672 instruction_predicate.Negate = negate; 673 instruction_predicate.Index = index; 674 675 instruction_grow(instruction, header); 676 677 return instruction_predicate; 678 } 679 680 static struct tgsi_instruction_label 681 tgsi_default_instruction_label( void ) 682 { 683 struct tgsi_instruction_label instruction_label; 684 685 instruction_label.Label = 0; 686 instruction_label.Padding = 0; 687 688 return instruction_label; 689 } 690 691 static struct tgsi_instruction_label 692 tgsi_build_instruction_label( 693 unsigned label, 694 struct tgsi_token *prev_token, 695 struct tgsi_instruction *instruction, 696 struct tgsi_header *header ) 697 { 698 struct tgsi_instruction_label instruction_label; 699 700 instruction_label.Label = label; 701 instruction_label.Padding = 0; 702 instruction->Label = 1; 703 704 instruction_grow( instruction, header ); 705 706 return instruction_label; 707 } 708 709 static struct tgsi_instruction_texture 710 tgsi_default_instruction_texture( void ) 711 { 712 struct tgsi_instruction_texture instruction_texture; 713 714 instruction_texture.Texture = TGSI_TEXTURE_UNKNOWN; 715 instruction_texture.NumOffsets = 0; 716 instruction_texture.Padding = 0; 717 718 return instruction_texture; 719 } 720 721 static struct tgsi_instruction_texture 722 tgsi_build_instruction_texture( 723 unsigned texture, 724 unsigned num_offsets, 725 struct tgsi_token *prev_token, 726 struct tgsi_instruction *instruction, 727 struct tgsi_header *header ) 728 { 729 struct tgsi_instruction_texture instruction_texture; 730 731 instruction_texture.Texture = texture; 732 instruction_texture.NumOffsets = num_offsets; 733 instruction_texture.Padding = 0; 734 instruction->Texture = 1; 735 736 instruction_grow( instruction, header ); 737 738 return instruction_texture; 739 } 740 741 742 static struct tgsi_texture_offset 743 tgsi_default_texture_offset( void ) 744 { 745 struct tgsi_texture_offset texture_offset; 746 747 texture_offset.Index = 0; 748 texture_offset.File = 0; 749 texture_offset.SwizzleX = 0; 750 texture_offset.SwizzleY = 0; 751 texture_offset.SwizzleZ = 0; 752 texture_offset.Padding = 0; 753 754 return texture_offset; 755 } 756 757 static struct tgsi_texture_offset 758 tgsi_build_texture_offset( 759 int index, int file, int swizzle_x, int swizzle_y, int swizzle_z, 760 struct tgsi_token *prev_token, 761 struct tgsi_instruction *instruction, 762 struct tgsi_header *header ) 763 { 764 struct tgsi_texture_offset texture_offset; 765 766 texture_offset.Index = index; 767 texture_offset.File = file; 768 texture_offset.SwizzleX = swizzle_x; 769 texture_offset.SwizzleY = swizzle_y; 770 texture_offset.SwizzleZ = swizzle_z; 771 texture_offset.Padding = 0; 772 773 instruction_grow( instruction, header ); 774 775 return texture_offset; 776 } 777 778 static struct tgsi_src_register 779 tgsi_default_src_register( void ) 780 { 781 struct tgsi_src_register src_register; 782 783 src_register.File = TGSI_FILE_NULL; 784 src_register.SwizzleX = TGSI_SWIZZLE_X; 785 src_register.SwizzleY = TGSI_SWIZZLE_Y; 786 src_register.SwizzleZ = TGSI_SWIZZLE_Z; 787 src_register.SwizzleW = TGSI_SWIZZLE_W; 788 src_register.Negate = 0; 789 src_register.Absolute = 0; 790 src_register.Indirect = 0; 791 src_register.Dimension = 0; 792 src_register.Index = 0; 793 794 return src_register; 795 } 796 797 static struct tgsi_src_register 798 tgsi_build_src_register( 799 unsigned file, 800 unsigned swizzle_x, 801 unsigned swizzle_y, 802 unsigned swizzle_z, 803 unsigned swizzle_w, 804 unsigned negate, 805 unsigned absolute, 806 unsigned indirect, 807 unsigned dimension, 808 int index, 809 struct tgsi_instruction *instruction, 810 struct tgsi_header *header ) 811 { 812 struct tgsi_src_register src_register; 813 814 assert( file < TGSI_FILE_COUNT ); 815 assert( swizzle_x <= TGSI_SWIZZLE_W ); 816 assert( swizzle_y <= TGSI_SWIZZLE_W ); 817 assert( swizzle_z <= TGSI_SWIZZLE_W ); 818 assert( swizzle_w <= TGSI_SWIZZLE_W ); 819 assert( negate <= 1 ); 820 assert( index >= -0x8000 && index <= 0x7FFF ); 821 822 src_register.File = file; 823 src_register.SwizzleX = swizzle_x; 824 src_register.SwizzleY = swizzle_y; 825 src_register.SwizzleZ = swizzle_z; 826 src_register.SwizzleW = swizzle_w; 827 src_register.Negate = negate; 828 src_register.Absolute = absolute; 829 src_register.Indirect = indirect; 830 src_register.Dimension = dimension; 831 src_register.Index = index; 832 833 instruction_grow( instruction, header ); 834 835 return src_register; 836 } 837 838 static struct tgsi_dimension 839 tgsi_default_dimension( void ) 840 { 841 struct tgsi_dimension dimension; 842 843 dimension.Indirect = 0; 844 dimension.Dimension = 0; 845 dimension.Padding = 0; 846 dimension.Index = 0; 847 848 return dimension; 849 } 850 851 static struct tgsi_full_src_register 852 tgsi_default_full_src_register( void ) 853 { 854 struct tgsi_full_src_register full_src_register; 855 856 full_src_register.Register = tgsi_default_src_register(); 857 full_src_register.Indirect = tgsi_default_src_register(); 858 full_src_register.Dimension = tgsi_default_dimension(); 859 full_src_register.DimIndirect = tgsi_default_src_register(); 860 861 return full_src_register; 862 } 863 864 static struct tgsi_dimension 865 tgsi_build_dimension( 866 unsigned indirect, 867 unsigned index, 868 struct tgsi_instruction *instruction, 869 struct tgsi_header *header ) 870 { 871 struct tgsi_dimension dimension; 872 873 dimension.Indirect = indirect; 874 dimension.Dimension = 0; 875 dimension.Padding = 0; 876 dimension.Index = index; 877 878 instruction_grow( instruction, header ); 879 880 return dimension; 881 } 882 883 static struct tgsi_dst_register 884 tgsi_default_dst_register( void ) 885 { 886 struct tgsi_dst_register dst_register; 887 888 dst_register.File = TGSI_FILE_NULL; 889 dst_register.WriteMask = TGSI_WRITEMASK_XYZW; 890 dst_register.Indirect = 0; 891 dst_register.Dimension = 0; 892 dst_register.Index = 0; 893 dst_register.Padding = 0; 894 895 return dst_register; 896 } 897 898 static struct tgsi_dst_register 899 tgsi_build_dst_register( 900 unsigned file, 901 unsigned mask, 902 unsigned indirect, 903 unsigned dimension, 904 int index, 905 struct tgsi_instruction *instruction, 906 struct tgsi_header *header ) 907 { 908 struct tgsi_dst_register dst_register; 909 910 assert( file < TGSI_FILE_COUNT ); 911 assert( mask <= TGSI_WRITEMASK_XYZW ); 912 assert( index >= -32768 && index <= 32767 ); 913 914 dst_register.File = file; 915 dst_register.WriteMask = mask; 916 dst_register.Indirect = indirect; 917 dst_register.Dimension = dimension; 918 dst_register.Index = index; 919 dst_register.Padding = 0; 920 921 instruction_grow( instruction, header ); 922 923 return dst_register; 924 } 925 926 static struct tgsi_full_dst_register 927 tgsi_default_full_dst_register( void ) 928 { 929 struct tgsi_full_dst_register full_dst_register; 930 931 full_dst_register.Register = tgsi_default_dst_register(); 932 full_dst_register.Indirect = tgsi_default_src_register(); 933 full_dst_register.Dimension = tgsi_default_dimension(); 934 full_dst_register.DimIndirect = tgsi_default_src_register(); 935 936 return full_dst_register; 937 } 938 939 struct tgsi_full_instruction 940 tgsi_default_full_instruction( void ) 941 { 942 struct tgsi_full_instruction full_instruction; 943 unsigned i; 944 945 full_instruction.Instruction = tgsi_default_instruction(); 946 full_instruction.Predicate = tgsi_default_instruction_predicate(); 947 full_instruction.Label = tgsi_default_instruction_label(); 948 full_instruction.Texture = tgsi_default_instruction_texture(); 949 for( i = 0; i < TGSI_FULL_MAX_TEX_OFFSETS; i++ ) { 950 full_instruction.TexOffsets[i] = tgsi_default_texture_offset(); 951 } 952 for( i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) { 953 full_instruction.Dst[i] = tgsi_default_full_dst_register(); 954 } 955 for( i = 0; i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) { 956 full_instruction.Src[i] = tgsi_default_full_src_register(); 957 } 958 959 return full_instruction; 960 } 961 962 unsigned 963 tgsi_build_full_instruction( 964 const struct tgsi_full_instruction *full_inst, 965 struct tgsi_token *tokens, 966 struct tgsi_header *header, 967 unsigned maxsize ) 968 { 969 unsigned size = 0; 970 unsigned i; 971 struct tgsi_instruction *instruction; 972 struct tgsi_token *prev_token; 973 974 if( maxsize <= size ) 975 return 0; 976 instruction = (struct tgsi_instruction *) &tokens[size]; 977 size++; 978 979 *instruction = tgsi_build_instruction(full_inst->Instruction.Opcode, 980 full_inst->Instruction.Saturate, 981 full_inst->Instruction.Predicate, 982 full_inst->Instruction.NumDstRegs, 983 full_inst->Instruction.NumSrcRegs, 984 header); 985 prev_token = (struct tgsi_token *) instruction; 986 987 if (full_inst->Instruction.Predicate) { 988 struct tgsi_instruction_predicate *instruction_predicate; 989 990 if (maxsize <= size) { 991 return 0; 992 } 993 instruction_predicate = (struct tgsi_instruction_predicate *)&tokens[size]; 994 size++; 995 996 *instruction_predicate = 997 tgsi_build_instruction_predicate(full_inst->Predicate.Index, 998 full_inst->Predicate.Negate, 999 full_inst->Predicate.SwizzleX, 1000 full_inst->Predicate.SwizzleY, 1001 full_inst->Predicate.SwizzleZ, 1002 full_inst->Predicate.SwizzleW, 1003 instruction, 1004 header); 1005 } 1006 1007 if (full_inst->Instruction.Label) { 1008 struct tgsi_instruction_label *instruction_label; 1009 1010 if( maxsize <= size ) 1011 return 0; 1012 instruction_label = 1013 (struct tgsi_instruction_label *) &tokens[size]; 1014 size++; 1015 1016 *instruction_label = tgsi_build_instruction_label( 1017 full_inst->Label.Label, 1018 prev_token, 1019 instruction, 1020 header ); 1021 prev_token = (struct tgsi_token *) instruction_label; 1022 } 1023 1024 if (full_inst->Instruction.Texture) { 1025 struct tgsi_instruction_texture *instruction_texture; 1026 1027 if( maxsize <= size ) 1028 return 0; 1029 instruction_texture = 1030 (struct tgsi_instruction_texture *) &tokens[size]; 1031 size++; 1032 1033 *instruction_texture = tgsi_build_instruction_texture( 1034 full_inst->Texture.Texture, 1035 full_inst->Texture.NumOffsets, 1036 prev_token, 1037 instruction, 1038 header ); 1039 prev_token = (struct tgsi_token *) instruction_texture; 1040 1041 for (i = 0; i < full_inst->Texture.NumOffsets; i++) { 1042 struct tgsi_texture_offset *texture_offset; 1043 1044 if ( maxsize <= size ) 1045 return 0; 1046 texture_offset = (struct tgsi_texture_offset *)&tokens[size]; 1047 size++; 1048 *texture_offset = tgsi_build_texture_offset( 1049 full_inst->TexOffsets[i].Index, 1050 full_inst->TexOffsets[i].File, 1051 full_inst->TexOffsets[i].SwizzleX, 1052 full_inst->TexOffsets[i].SwizzleY, 1053 full_inst->TexOffsets[i].SwizzleZ, 1054 prev_token, 1055 instruction, 1056 header); 1057 prev_token = (struct tgsi_token *) texture_offset; 1058 } 1059 } 1060 for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) { 1061 const struct tgsi_full_dst_register *reg = &full_inst->Dst[i]; 1062 struct tgsi_dst_register *dst_register; 1063 1064 if( maxsize <= size ) 1065 return 0; 1066 dst_register = (struct tgsi_dst_register *) &tokens[size]; 1067 size++; 1068 1069 *dst_register = tgsi_build_dst_register( 1070 reg->Register.File, 1071 reg->Register.WriteMask, 1072 reg->Register.Indirect, 1073 reg->Register.Dimension, 1074 reg->Register.Index, 1075 instruction, 1076 header ); 1077 1078 if( reg->Register.Indirect ) { 1079 struct tgsi_src_register *ind; 1080 1081 if( maxsize <= size ) 1082 return 0; 1083 ind = (struct tgsi_src_register *) &tokens[size]; 1084 size++; 1085 1086 *ind = tgsi_build_src_register( 1087 reg->Indirect.File, 1088 reg->Indirect.SwizzleX, 1089 reg->Indirect.SwizzleY, 1090 reg->Indirect.SwizzleZ, 1091 reg->Indirect.SwizzleW, 1092 reg->Indirect.Negate, 1093 reg->Indirect.Absolute, 1094 reg->Indirect.Indirect, 1095 reg->Indirect.Dimension, 1096 reg->Indirect.Index, 1097 instruction, 1098 header ); 1099 } 1100 1101 if( reg->Register.Dimension ) { 1102 struct tgsi_dimension *dim; 1103 1104 assert( !reg->Dimension.Dimension ); 1105 1106 if( maxsize <= size ) 1107 return 0; 1108 dim = (struct tgsi_dimension *) &tokens[size]; 1109 size++; 1110 1111 *dim = tgsi_build_dimension( 1112 reg->Dimension.Indirect, 1113 reg->Dimension.Index, 1114 instruction, 1115 header ); 1116 1117 if( reg->Dimension.Indirect ) { 1118 struct tgsi_src_register *ind; 1119 1120 if( maxsize <= size ) 1121 return 0; 1122 ind = (struct tgsi_src_register *) &tokens[size]; 1123 size++; 1124 1125 *ind = tgsi_build_src_register( 1126 reg->DimIndirect.File, 1127 reg->DimIndirect.SwizzleX, 1128 reg->DimIndirect.SwizzleY, 1129 reg->DimIndirect.SwizzleZ, 1130 reg->DimIndirect.SwizzleW, 1131 reg->DimIndirect.Negate, 1132 reg->DimIndirect.Absolute, 1133 reg->DimIndirect.Indirect, 1134 reg->DimIndirect.Dimension, 1135 reg->DimIndirect.Index, 1136 instruction, 1137 header ); 1138 } 1139 } 1140 } 1141 1142 for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) { 1143 const struct tgsi_full_src_register *reg = &full_inst->Src[i]; 1144 struct tgsi_src_register *src_register; 1145 1146 if( maxsize <= size ) 1147 return 0; 1148 src_register = (struct tgsi_src_register *) &tokens[size]; 1149 size++; 1150 1151 *src_register = tgsi_build_src_register( 1152 reg->Register.File, 1153 reg->Register.SwizzleX, 1154 reg->Register.SwizzleY, 1155 reg->Register.SwizzleZ, 1156 reg->Register.SwizzleW, 1157 reg->Register.Negate, 1158 reg->Register.Absolute, 1159 reg->Register.Indirect, 1160 reg->Register.Dimension, 1161 reg->Register.Index, 1162 instruction, 1163 header ); 1164 1165 if( reg->Register.Indirect ) { 1166 struct tgsi_src_register *ind; 1167 1168 if( maxsize <= size ) 1169 return 0; 1170 ind = (struct tgsi_src_register *) &tokens[size]; 1171 size++; 1172 1173 *ind = tgsi_build_src_register( 1174 reg->Indirect.File, 1175 reg->Indirect.SwizzleX, 1176 reg->Indirect.SwizzleY, 1177 reg->Indirect.SwizzleZ, 1178 reg->Indirect.SwizzleW, 1179 reg->Indirect.Negate, 1180 reg->Indirect.Absolute, 1181 reg->Indirect.Indirect, 1182 reg->Indirect.Dimension, 1183 reg->Indirect.Index, 1184 instruction, 1185 header ); 1186 } 1187 1188 if( reg->Register.Dimension ) { 1189 struct tgsi_dimension *dim; 1190 1191 assert( !reg->Dimension.Dimension ); 1192 1193 if( maxsize <= size ) 1194 return 0; 1195 dim = (struct tgsi_dimension *) &tokens[size]; 1196 size++; 1197 1198 *dim = tgsi_build_dimension( 1199 reg->Dimension.Indirect, 1200 reg->Dimension.Index, 1201 instruction, 1202 header ); 1203 1204 if( reg->Dimension.Indirect ) { 1205 struct tgsi_src_register *ind; 1206 1207 if( maxsize <= size ) 1208 return 0; 1209 ind = (struct tgsi_src_register *) &tokens[size]; 1210 size++; 1211 1212 *ind = tgsi_build_src_register( 1213 reg->DimIndirect.File, 1214 reg->DimIndirect.SwizzleX, 1215 reg->DimIndirect.SwizzleY, 1216 reg->DimIndirect.SwizzleZ, 1217 reg->DimIndirect.SwizzleW, 1218 reg->DimIndirect.Negate, 1219 reg->DimIndirect.Absolute, 1220 reg->DimIndirect.Indirect, 1221 reg->DimIndirect.Dimension, 1222 reg->DimIndirect.Index, 1223 instruction, 1224 header ); 1225 } 1226 } 1227 } 1228 1229 return size; 1230 } 1231 1232 static struct tgsi_property 1233 tgsi_default_property( void ) 1234 { 1235 struct tgsi_property property; 1236 1237 property.Type = TGSI_TOKEN_TYPE_PROPERTY; 1238 property.NrTokens = 1; 1239 property.PropertyName = TGSI_PROPERTY_GS_INPUT_PRIM; 1240 property.Padding = 0; 1241 1242 return property; 1243 } 1244 1245 static struct tgsi_property 1246 tgsi_build_property(unsigned property_name, 1247 struct tgsi_header *header) 1248 { 1249 struct tgsi_property property; 1250 1251 property = tgsi_default_property(); 1252 property.PropertyName = property_name; 1253 1254 header_bodysize_grow( header ); 1255 1256 return property; 1257 } 1258 1259 1260 struct tgsi_full_property 1261 tgsi_default_full_property( void ) 1262 { 1263 struct tgsi_full_property full_property; 1264 1265 full_property.Property = tgsi_default_property(); 1266 memset(full_property.u, 0, 1267 sizeof(struct tgsi_property_data) * 8); 1268 1269 return full_property; 1270 } 1271 1272 static void 1273 property_grow( 1274 struct tgsi_property *property, 1275 struct tgsi_header *header ) 1276 { 1277 assert( property->NrTokens < 0xFF ); 1278 1279 property->NrTokens++; 1280 1281 header_bodysize_grow( header ); 1282 } 1283 1284 static struct tgsi_property_data 1285 tgsi_build_property_data( 1286 unsigned value, 1287 struct tgsi_property *property, 1288 struct tgsi_header *header ) 1289 { 1290 struct tgsi_property_data property_data; 1291 1292 property_data.Data = value; 1293 1294 property_grow( property, header ); 1295 1296 return property_data; 1297 } 1298 1299 unsigned 1300 tgsi_build_full_property( 1301 const struct tgsi_full_property *full_prop, 1302 struct tgsi_token *tokens, 1303 struct tgsi_header *header, 1304 unsigned maxsize ) 1305 { 1306 unsigned size = 0, i; 1307 struct tgsi_property *property; 1308 1309 if( maxsize <= size ) 1310 return 0; 1311 property = (struct tgsi_property *) &tokens[size]; 1312 size++; 1313 1314 *property = tgsi_build_property( 1315 full_prop->Property.PropertyName, 1316 header ); 1317 1318 assert( full_prop->Property.NrTokens <= 8 + 1 ); 1319 1320 for( i = 0; i < full_prop->Property.NrTokens - 1; i++ ) { 1321 struct tgsi_property_data *data; 1322 1323 if( maxsize <= size ) 1324 return 0; 1325 data = (struct tgsi_property_data *) &tokens[size]; 1326 size++; 1327 1328 *data = tgsi_build_property_data( 1329 full_prop->u[i].Data, 1330 property, 1331 header ); 1332 } 1333 1334 return size; 1335 } 1336