1 /************************************************************************** 2 * 3 * Copyright 2007 VMware, Inc. 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 VMWARE 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.Array = 0; 113 declaration.Atomic = 0; 114 declaration.MemType = TGSI_MEMORY_TYPE_GLOBAL; 115 declaration.Padding = 0; 116 117 return declaration; 118 } 119 120 static struct tgsi_declaration 121 tgsi_build_declaration( 122 unsigned file, 123 unsigned usage_mask, 124 unsigned interpolate, 125 unsigned dimension, 126 unsigned semantic, 127 unsigned invariant, 128 unsigned local, 129 unsigned array, 130 unsigned atomic, 131 unsigned mem_type, 132 struct tgsi_header *header ) 133 { 134 struct tgsi_declaration declaration; 135 136 assert( file < TGSI_FILE_COUNT ); 137 assert( interpolate < TGSI_INTERPOLATE_COUNT ); 138 139 declaration = tgsi_default_declaration(); 140 declaration.File = file; 141 declaration.UsageMask = usage_mask; 142 declaration.Interpolate = interpolate; 143 declaration.Dimension = dimension; 144 declaration.Semantic = semantic; 145 declaration.Invariant = invariant; 146 declaration.Local = local; 147 declaration.Array = array; 148 declaration.Atomic = atomic; 149 declaration.MemType = mem_type; 150 header_bodysize_grow( header ); 151 152 return declaration; 153 } 154 155 static struct tgsi_declaration_range 156 tgsi_default_declaration_range( void ) 157 { 158 struct tgsi_declaration_range dr; 159 160 dr.First = 0; 161 dr.Last = 0; 162 163 return dr; 164 } 165 166 static struct tgsi_declaration_range 167 tgsi_build_declaration_range( 168 unsigned first, 169 unsigned last, 170 struct tgsi_declaration *declaration, 171 struct tgsi_header *header ) 172 { 173 struct tgsi_declaration_range declaration_range; 174 175 assert( last >= first ); 176 assert( last <= 0xFFFF ); 177 178 declaration_range.First = first; 179 declaration_range.Last = last; 180 181 declaration_grow( declaration, header ); 182 183 return declaration_range; 184 } 185 186 static struct tgsi_declaration_dimension 187 tgsi_build_declaration_dimension(unsigned index_2d, 188 struct tgsi_declaration *declaration, 189 struct tgsi_header *header) 190 { 191 struct tgsi_declaration_dimension dd; 192 193 assert(index_2d <= 0xFFFF); 194 195 dd.Index2D = index_2d; 196 dd.Padding = 0; 197 198 declaration_grow(declaration, header); 199 200 return dd; 201 } 202 203 static struct tgsi_declaration_interp 204 tgsi_default_declaration_interp( void ) 205 { 206 struct tgsi_declaration_interp di; 207 208 di.Interpolate = TGSI_INTERPOLATE_CONSTANT; 209 di.Location = TGSI_INTERPOLATE_LOC_CENTER; 210 di.CylindricalWrap = 0; 211 di.Padding = 0; 212 213 return di; 214 } 215 216 static struct tgsi_declaration_interp 217 tgsi_build_declaration_interp(unsigned interpolate, 218 unsigned interpolate_location, 219 unsigned cylindrical_wrap, 220 struct tgsi_declaration *declaration, 221 struct tgsi_header *header) 222 { 223 struct tgsi_declaration_interp di; 224 225 di.Interpolate = interpolate; 226 di.Location = interpolate_location; 227 di.CylindricalWrap = cylindrical_wrap; 228 di.Padding = 0; 229 230 declaration_grow(declaration, header); 231 232 return di; 233 } 234 235 static struct tgsi_declaration_semantic 236 tgsi_default_declaration_semantic( void ) 237 { 238 struct tgsi_declaration_semantic ds; 239 240 ds.Name = TGSI_SEMANTIC_POSITION; 241 ds.Index = 0; 242 ds.StreamX = 0; 243 ds.StreamY = 0; 244 ds.StreamZ = 0; 245 ds.StreamW = 0; 246 247 return ds; 248 } 249 250 static struct tgsi_declaration_semantic 251 tgsi_build_declaration_semantic( 252 unsigned semantic_name, 253 unsigned semantic_index, 254 unsigned streamx, 255 unsigned streamy, 256 unsigned streamz, 257 unsigned streamw, 258 struct tgsi_declaration *declaration, 259 struct tgsi_header *header ) 260 { 261 struct tgsi_declaration_semantic ds; 262 263 assert( semantic_name <= TGSI_SEMANTIC_COUNT ); 264 assert( semantic_index <= 0xFFFF ); 265 266 ds.Name = semantic_name; 267 ds.Index = semantic_index; 268 ds.StreamX = streamx; 269 ds.StreamY = streamy; 270 ds.StreamZ = streamz; 271 ds.StreamW = streamw; 272 273 declaration_grow( declaration, header ); 274 275 return ds; 276 } 277 278 static struct tgsi_declaration_image 279 tgsi_default_declaration_image(void) 280 { 281 struct tgsi_declaration_image di; 282 283 di.Resource = TGSI_TEXTURE_BUFFER; 284 di.Raw = 0; 285 di.Writable = 0; 286 di.Format = 0; 287 di.Padding = 0; 288 289 return di; 290 } 291 292 static struct tgsi_declaration_image 293 tgsi_build_declaration_image(unsigned texture, 294 unsigned format, 295 unsigned raw, 296 unsigned writable, 297 struct tgsi_declaration *declaration, 298 struct tgsi_header *header) 299 { 300 struct tgsi_declaration_image di; 301 302 di = tgsi_default_declaration_image(); 303 di.Resource = texture; 304 di.Format = format; 305 di.Raw = raw; 306 di.Writable = writable; 307 308 declaration_grow(declaration, header); 309 310 return di; 311 } 312 313 static struct tgsi_declaration_sampler_view 314 tgsi_default_declaration_sampler_view(void) 315 { 316 struct tgsi_declaration_sampler_view dsv; 317 318 dsv.Resource = TGSI_TEXTURE_BUFFER; 319 dsv.ReturnTypeX = TGSI_RETURN_TYPE_UNORM; 320 dsv.ReturnTypeY = TGSI_RETURN_TYPE_UNORM; 321 dsv.ReturnTypeZ = TGSI_RETURN_TYPE_UNORM; 322 dsv.ReturnTypeW = TGSI_RETURN_TYPE_UNORM; 323 324 return dsv; 325 } 326 327 static struct tgsi_declaration_sampler_view 328 tgsi_build_declaration_sampler_view(unsigned texture, 329 unsigned return_type_x, 330 unsigned return_type_y, 331 unsigned return_type_z, 332 unsigned return_type_w, 333 struct tgsi_declaration *declaration, 334 struct tgsi_header *header) 335 { 336 struct tgsi_declaration_sampler_view dsv; 337 338 dsv = tgsi_default_declaration_sampler_view(); 339 dsv.Resource = texture; 340 dsv.ReturnTypeX = return_type_x; 341 dsv.ReturnTypeY = return_type_y; 342 dsv.ReturnTypeZ = return_type_z; 343 dsv.ReturnTypeW = return_type_w; 344 345 declaration_grow(declaration, header); 346 347 return dsv; 348 } 349 350 351 static struct tgsi_declaration_array 352 tgsi_default_declaration_array( void ) 353 { 354 struct tgsi_declaration_array a; 355 356 a.ArrayID = 0; 357 a.Padding = 0; 358 359 return a; 360 } 361 362 static struct tgsi_declaration_array 363 tgsi_build_declaration_array(unsigned arrayid, 364 struct tgsi_declaration *declaration, 365 struct tgsi_header *header) 366 { 367 struct tgsi_declaration_array da; 368 369 da = tgsi_default_declaration_array(); 370 da.ArrayID = arrayid; 371 372 declaration_grow(declaration, header); 373 374 return da; 375 } 376 377 struct tgsi_full_declaration 378 tgsi_default_full_declaration( void ) 379 { 380 struct tgsi_full_declaration full_declaration; 381 382 full_declaration.Declaration = tgsi_default_declaration(); 383 full_declaration.Range = tgsi_default_declaration_range(); 384 full_declaration.Semantic = tgsi_default_declaration_semantic(); 385 full_declaration.Interp = tgsi_default_declaration_interp(); 386 full_declaration.Image = tgsi_default_declaration_image(); 387 full_declaration.SamplerView = tgsi_default_declaration_sampler_view(); 388 full_declaration.Array = tgsi_default_declaration_array(); 389 390 return full_declaration; 391 } 392 393 unsigned 394 tgsi_build_full_declaration( 395 const struct tgsi_full_declaration *full_decl, 396 struct tgsi_token *tokens, 397 struct tgsi_header *header, 398 unsigned maxsize ) 399 { 400 unsigned size = 0; 401 struct tgsi_declaration *declaration; 402 struct tgsi_declaration_range *dr; 403 404 if( maxsize <= size ) 405 return 0; 406 declaration = (struct tgsi_declaration *) &tokens[size]; 407 size++; 408 409 *declaration = tgsi_build_declaration( 410 full_decl->Declaration.File, 411 full_decl->Declaration.UsageMask, 412 full_decl->Declaration.Interpolate, 413 full_decl->Declaration.Dimension, 414 full_decl->Declaration.Semantic, 415 full_decl->Declaration.Invariant, 416 full_decl->Declaration.Local, 417 full_decl->Declaration.Array, 418 full_decl->Declaration.Atomic, 419 full_decl->Declaration.MemType, 420 header ); 421 422 if (maxsize <= size) 423 return 0; 424 dr = (struct tgsi_declaration_range *) &tokens[size]; 425 size++; 426 427 *dr = tgsi_build_declaration_range( 428 full_decl->Range.First, 429 full_decl->Range.Last, 430 declaration, 431 header ); 432 433 if (full_decl->Declaration.Dimension) { 434 struct tgsi_declaration_dimension *dd; 435 436 if (maxsize <= size) { 437 return 0; 438 } 439 dd = (struct tgsi_declaration_dimension *)&tokens[size]; 440 size++; 441 442 *dd = tgsi_build_declaration_dimension(full_decl->Dim.Index2D, 443 declaration, 444 header); 445 } 446 447 if (full_decl->Declaration.Interpolate) { 448 struct tgsi_declaration_interp *di; 449 450 if (maxsize <= size) { 451 return 0; 452 } 453 di = (struct tgsi_declaration_interp *)&tokens[size]; 454 size++; 455 456 *di = tgsi_build_declaration_interp(full_decl->Interp.Interpolate, 457 full_decl->Interp.Location, 458 full_decl->Interp.CylindricalWrap, 459 declaration, 460 header); 461 } 462 463 if( full_decl->Declaration.Semantic ) { 464 struct tgsi_declaration_semantic *ds; 465 466 if( maxsize <= size ) 467 return 0; 468 ds = (struct tgsi_declaration_semantic *) &tokens[size]; 469 size++; 470 471 *ds = tgsi_build_declaration_semantic( 472 full_decl->Semantic.Name, 473 full_decl->Semantic.Index, 474 full_decl->Semantic.StreamX, 475 full_decl->Semantic.StreamY, 476 full_decl->Semantic.StreamZ, 477 full_decl->Semantic.StreamW, 478 declaration, 479 header ); 480 } 481 482 if (full_decl->Declaration.File == TGSI_FILE_IMAGE) { 483 struct tgsi_declaration_image *di; 484 485 if (maxsize <= size) { 486 return 0; 487 } 488 di = (struct tgsi_declaration_image *)&tokens[size]; 489 size++; 490 491 *di = tgsi_build_declaration_image(full_decl->Image.Resource, 492 full_decl->Image.Format, 493 full_decl->Image.Raw, 494 full_decl->Image.Writable, 495 declaration, 496 header); 497 } 498 499 if (full_decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) { 500 struct tgsi_declaration_sampler_view *dsv; 501 502 if (maxsize <= size) { 503 return 0; 504 } 505 dsv = (struct tgsi_declaration_sampler_view *)&tokens[size]; 506 size++; 507 508 *dsv = tgsi_build_declaration_sampler_view( 509 full_decl->SamplerView.Resource, 510 full_decl->SamplerView.ReturnTypeX, 511 full_decl->SamplerView.ReturnTypeY, 512 full_decl->SamplerView.ReturnTypeZ, 513 full_decl->SamplerView.ReturnTypeW, 514 declaration, 515 header); 516 } 517 518 if (full_decl->Declaration.Array) { 519 struct tgsi_declaration_array *da; 520 521 if (maxsize <= size) { 522 return 0; 523 } 524 da = (struct tgsi_declaration_array *)&tokens[size]; 525 size++; 526 *da = tgsi_build_declaration_array( 527 full_decl->Array.ArrayID, 528 declaration, 529 header); 530 } 531 return size; 532 } 533 534 /* 535 * immediate 536 */ 537 538 static struct tgsi_immediate 539 tgsi_default_immediate( void ) 540 { 541 struct tgsi_immediate immediate; 542 543 immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE; 544 immediate.NrTokens = 1; 545 immediate.DataType = TGSI_IMM_FLOAT32; 546 immediate.Padding = 0; 547 548 return immediate; 549 } 550 551 static struct tgsi_immediate 552 tgsi_build_immediate( 553 struct tgsi_header *header, 554 unsigned type ) 555 { 556 struct tgsi_immediate immediate; 557 558 immediate = tgsi_default_immediate(); 559 immediate.DataType = type; 560 561 header_bodysize_grow( header ); 562 563 return immediate; 564 } 565 566 struct tgsi_full_immediate 567 tgsi_default_full_immediate( void ) 568 { 569 struct tgsi_full_immediate fullimm; 570 571 fullimm.Immediate = tgsi_default_immediate(); 572 fullimm.u[0].Float = 0.0f; 573 fullimm.u[1].Float = 0.0f; 574 fullimm.u[2].Float = 0.0f; 575 fullimm.u[3].Float = 0.0f; 576 577 return fullimm; 578 } 579 580 static void 581 immediate_grow( 582 struct tgsi_immediate *immediate, 583 struct tgsi_header *header ) 584 { 585 assert( immediate->NrTokens < 0xFF ); 586 587 immediate->NrTokens++; 588 589 header_bodysize_grow( header ); 590 } 591 592 unsigned 593 tgsi_build_full_immediate( 594 const struct tgsi_full_immediate *full_imm, 595 struct tgsi_token *tokens, 596 struct tgsi_header *header, 597 unsigned maxsize ) 598 { 599 unsigned size = 0, i; 600 struct tgsi_immediate *immediate; 601 602 if( maxsize <= size ) 603 return 0; 604 immediate = (struct tgsi_immediate *) &tokens[size]; 605 size++; 606 607 *immediate = tgsi_build_immediate( header, full_imm->Immediate.DataType ); 608 609 assert( full_imm->Immediate.NrTokens <= 4 + 1 ); 610 611 for( i = 0; i < full_imm->Immediate.NrTokens - 1; i++ ) { 612 union tgsi_immediate_data *data; 613 614 if( maxsize <= size ) 615 return 0; 616 617 data = (union tgsi_immediate_data *) &tokens[size]; 618 *data = full_imm->u[i]; 619 620 immediate_grow( immediate, header ); 621 size++; 622 } 623 624 return size; 625 } 626 627 /* 628 * instruction 629 */ 630 631 struct tgsi_instruction 632 tgsi_default_instruction( void ) 633 { 634 struct tgsi_instruction instruction; 635 636 instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION; 637 instruction.NrTokens = 0; 638 instruction.Opcode = TGSI_OPCODE_MOV; 639 instruction.Saturate = 0; 640 instruction.Predicate = 0; 641 instruction.NumDstRegs = 1; 642 instruction.NumSrcRegs = 1; 643 instruction.Label = 0; 644 instruction.Texture = 0; 645 instruction.Memory = 0; 646 instruction.Padding = 0; 647 648 return instruction; 649 } 650 651 static struct tgsi_instruction 652 tgsi_build_instruction(unsigned opcode, 653 unsigned saturate, 654 unsigned predicate, 655 unsigned num_dst_regs, 656 unsigned num_src_regs, 657 struct tgsi_header *header) 658 { 659 struct tgsi_instruction instruction; 660 661 assert (opcode <= TGSI_OPCODE_LAST); 662 assert (saturate <= 1); 663 assert (num_dst_regs <= 3); 664 assert (num_src_regs <= 15); 665 666 instruction = tgsi_default_instruction(); 667 instruction.Opcode = opcode; 668 instruction.Saturate = saturate; 669 instruction.Predicate = predicate; 670 instruction.NumDstRegs = num_dst_regs; 671 instruction.NumSrcRegs = num_src_regs; 672 673 header_bodysize_grow( header ); 674 675 return instruction; 676 } 677 678 static void 679 instruction_grow( 680 struct tgsi_instruction *instruction, 681 struct tgsi_header *header ) 682 { 683 assert (instruction->NrTokens < 0xFF); 684 685 instruction->NrTokens++; 686 687 header_bodysize_grow( header ); 688 } 689 690 struct tgsi_instruction_predicate 691 tgsi_default_instruction_predicate(void) 692 { 693 struct tgsi_instruction_predicate instruction_predicate; 694 695 instruction_predicate.SwizzleX = TGSI_SWIZZLE_X; 696 instruction_predicate.SwizzleY = TGSI_SWIZZLE_Y; 697 instruction_predicate.SwizzleZ = TGSI_SWIZZLE_Z; 698 instruction_predicate.SwizzleW = TGSI_SWIZZLE_W; 699 instruction_predicate.Negate = 0; 700 instruction_predicate.Index = 0; 701 instruction_predicate.Padding = 0; 702 703 return instruction_predicate; 704 } 705 706 static struct tgsi_instruction_predicate 707 tgsi_build_instruction_predicate(int index, 708 unsigned negate, 709 unsigned swizzleX, 710 unsigned swizzleY, 711 unsigned swizzleZ, 712 unsigned swizzleW, 713 struct tgsi_instruction *instruction, 714 struct tgsi_header *header) 715 { 716 struct tgsi_instruction_predicate instruction_predicate; 717 718 instruction_predicate = tgsi_default_instruction_predicate(); 719 instruction_predicate.SwizzleX = swizzleX; 720 instruction_predicate.SwizzleY = swizzleY; 721 instruction_predicate.SwizzleZ = swizzleZ; 722 instruction_predicate.SwizzleW = swizzleW; 723 instruction_predicate.Negate = negate; 724 instruction_predicate.Index = index; 725 726 instruction_grow(instruction, header); 727 728 return instruction_predicate; 729 } 730 731 static struct tgsi_instruction_label 732 tgsi_default_instruction_label( void ) 733 { 734 struct tgsi_instruction_label instruction_label; 735 736 instruction_label.Label = 0; 737 instruction_label.Padding = 0; 738 739 return instruction_label; 740 } 741 742 static struct tgsi_instruction_label 743 tgsi_build_instruction_label( 744 unsigned label, 745 struct tgsi_token *prev_token, 746 struct tgsi_instruction *instruction, 747 struct tgsi_header *header ) 748 { 749 struct tgsi_instruction_label instruction_label; 750 751 instruction_label.Label = label; 752 instruction_label.Padding = 0; 753 instruction->Label = 1; 754 755 instruction_grow( instruction, header ); 756 757 return instruction_label; 758 } 759 760 static struct tgsi_instruction_texture 761 tgsi_default_instruction_texture( void ) 762 { 763 struct tgsi_instruction_texture instruction_texture; 764 765 instruction_texture.Texture = TGSI_TEXTURE_UNKNOWN; 766 instruction_texture.NumOffsets = 0; 767 instruction_texture.Padding = 0; 768 769 return instruction_texture; 770 } 771 772 static struct tgsi_instruction_texture 773 tgsi_build_instruction_texture( 774 unsigned texture, 775 unsigned num_offsets, 776 struct tgsi_token *prev_token, 777 struct tgsi_instruction *instruction, 778 struct tgsi_header *header ) 779 { 780 struct tgsi_instruction_texture instruction_texture; 781 782 instruction_texture.Texture = texture; 783 instruction_texture.NumOffsets = num_offsets; 784 instruction_texture.Padding = 0; 785 instruction->Texture = 1; 786 787 instruction_grow( instruction, header ); 788 789 return instruction_texture; 790 } 791 792 static struct tgsi_instruction_memory 793 tgsi_default_instruction_memory( void ) 794 { 795 struct tgsi_instruction_memory instruction_memory; 796 797 instruction_memory.Qualifier = 0; 798 instruction_memory.Texture = 0; 799 instruction_memory.Format = 0; 800 instruction_memory.Padding = 0; 801 802 return instruction_memory; 803 } 804 805 static struct tgsi_instruction_memory 806 tgsi_build_instruction_memory( 807 unsigned qualifier, 808 unsigned texture, 809 unsigned format, 810 struct tgsi_token *prev_token, 811 struct tgsi_instruction *instruction, 812 struct tgsi_header *header ) 813 { 814 struct tgsi_instruction_memory instruction_memory; 815 816 instruction_memory.Qualifier = qualifier; 817 instruction_memory.Texture = texture; 818 instruction_memory.Format = format; 819 instruction_memory.Padding = 0; 820 instruction->Memory = 1; 821 822 instruction_grow( instruction, header ); 823 824 return instruction_memory; 825 } 826 827 static struct tgsi_texture_offset 828 tgsi_default_texture_offset( void ) 829 { 830 struct tgsi_texture_offset texture_offset; 831 832 texture_offset.Index = 0; 833 texture_offset.File = 0; 834 texture_offset.SwizzleX = 0; 835 texture_offset.SwizzleY = 0; 836 texture_offset.SwizzleZ = 0; 837 texture_offset.Padding = 0; 838 839 return texture_offset; 840 } 841 842 static struct tgsi_texture_offset 843 tgsi_build_texture_offset( 844 int index, int file, int swizzle_x, int swizzle_y, int swizzle_z, 845 struct tgsi_token *prev_token, 846 struct tgsi_instruction *instruction, 847 struct tgsi_header *header ) 848 { 849 struct tgsi_texture_offset texture_offset; 850 851 texture_offset.Index = index; 852 texture_offset.File = file; 853 texture_offset.SwizzleX = swizzle_x; 854 texture_offset.SwizzleY = swizzle_y; 855 texture_offset.SwizzleZ = swizzle_z; 856 texture_offset.Padding = 0; 857 858 instruction_grow( instruction, header ); 859 860 return texture_offset; 861 } 862 863 static struct tgsi_src_register 864 tgsi_default_src_register( void ) 865 { 866 struct tgsi_src_register src_register; 867 868 src_register.File = TGSI_FILE_NULL; 869 src_register.SwizzleX = TGSI_SWIZZLE_X; 870 src_register.SwizzleY = TGSI_SWIZZLE_Y; 871 src_register.SwizzleZ = TGSI_SWIZZLE_Z; 872 src_register.SwizzleW = TGSI_SWIZZLE_W; 873 src_register.Negate = 0; 874 src_register.Absolute = 0; 875 src_register.Indirect = 0; 876 src_register.Dimension = 0; 877 src_register.Index = 0; 878 879 return src_register; 880 } 881 882 static struct tgsi_src_register 883 tgsi_build_src_register( 884 unsigned file, 885 unsigned swizzle_x, 886 unsigned swizzle_y, 887 unsigned swizzle_z, 888 unsigned swizzle_w, 889 unsigned negate, 890 unsigned absolute, 891 unsigned indirect, 892 unsigned dimension, 893 int index, 894 struct tgsi_instruction *instruction, 895 struct tgsi_header *header ) 896 { 897 struct tgsi_src_register src_register; 898 899 assert( file < TGSI_FILE_COUNT ); 900 assert( swizzle_x <= TGSI_SWIZZLE_W ); 901 assert( swizzle_y <= TGSI_SWIZZLE_W ); 902 assert( swizzle_z <= TGSI_SWIZZLE_W ); 903 assert( swizzle_w <= TGSI_SWIZZLE_W ); 904 assert( negate <= 1 ); 905 assert( index >= -0x8000 && index <= 0x7FFF ); 906 907 src_register.File = file; 908 src_register.SwizzleX = swizzle_x; 909 src_register.SwizzleY = swizzle_y; 910 src_register.SwizzleZ = swizzle_z; 911 src_register.SwizzleW = swizzle_w; 912 src_register.Negate = negate; 913 src_register.Absolute = absolute; 914 src_register.Indirect = indirect; 915 src_register.Dimension = dimension; 916 src_register.Index = index; 917 918 instruction_grow( instruction, header ); 919 920 return src_register; 921 } 922 923 static struct tgsi_ind_register 924 tgsi_default_ind_register( void ) 925 { 926 struct tgsi_ind_register ind_register; 927 928 ind_register.File = TGSI_FILE_NULL; 929 ind_register.Index = 0; 930 ind_register.Swizzle = TGSI_SWIZZLE_X; 931 ind_register.ArrayID = 0; 932 933 return ind_register; 934 } 935 936 static struct tgsi_ind_register 937 tgsi_build_ind_register( 938 unsigned file, 939 unsigned swizzle, 940 int index, 941 unsigned arrayid, 942 struct tgsi_instruction *instruction, 943 struct tgsi_header *header ) 944 { 945 struct tgsi_ind_register ind_register; 946 947 assert( file < TGSI_FILE_COUNT ); 948 assert( swizzle <= TGSI_SWIZZLE_W ); 949 assert( index >= -0x8000 && index <= 0x7FFF ); 950 951 ind_register.File = file; 952 ind_register.Swizzle = swizzle; 953 ind_register.Index = index; 954 ind_register.ArrayID = arrayid; 955 956 instruction_grow( instruction, header ); 957 958 return ind_register; 959 } 960 961 static struct tgsi_dimension 962 tgsi_default_dimension( void ) 963 { 964 struct tgsi_dimension dimension; 965 966 dimension.Indirect = 0; 967 dimension.Dimension = 0; 968 dimension.Padding = 0; 969 dimension.Index = 0; 970 971 return dimension; 972 } 973 974 static struct tgsi_full_src_register 975 tgsi_default_full_src_register( void ) 976 { 977 struct tgsi_full_src_register full_src_register; 978 979 full_src_register.Register = tgsi_default_src_register(); 980 full_src_register.Indirect = tgsi_default_ind_register(); 981 full_src_register.Dimension = tgsi_default_dimension(); 982 full_src_register.DimIndirect = tgsi_default_ind_register(); 983 984 return full_src_register; 985 } 986 987 static struct tgsi_dimension 988 tgsi_build_dimension( 989 unsigned indirect, 990 unsigned index, 991 struct tgsi_instruction *instruction, 992 struct tgsi_header *header ) 993 { 994 struct tgsi_dimension dimension; 995 996 dimension.Indirect = indirect; 997 dimension.Dimension = 0; 998 dimension.Padding = 0; 999 dimension.Index = index; 1000 1001 instruction_grow( instruction, header ); 1002 1003 return dimension; 1004 } 1005 1006 static struct tgsi_dst_register 1007 tgsi_default_dst_register( void ) 1008 { 1009 struct tgsi_dst_register dst_register; 1010 1011 dst_register.File = TGSI_FILE_NULL; 1012 dst_register.WriteMask = TGSI_WRITEMASK_XYZW; 1013 dst_register.Indirect = 0; 1014 dst_register.Dimension = 0; 1015 dst_register.Index = 0; 1016 dst_register.Padding = 0; 1017 1018 return dst_register; 1019 } 1020 1021 static struct tgsi_dst_register 1022 tgsi_build_dst_register( 1023 unsigned file, 1024 unsigned mask, 1025 unsigned indirect, 1026 unsigned dimension, 1027 int index, 1028 struct tgsi_instruction *instruction, 1029 struct tgsi_header *header ) 1030 { 1031 struct tgsi_dst_register dst_register; 1032 1033 assert( file < TGSI_FILE_COUNT ); 1034 assert( mask <= TGSI_WRITEMASK_XYZW ); 1035 assert( index >= -32768 && index <= 32767 ); 1036 1037 dst_register.File = file; 1038 dst_register.WriteMask = mask; 1039 dst_register.Indirect = indirect; 1040 dst_register.Dimension = dimension; 1041 dst_register.Index = index; 1042 dst_register.Padding = 0; 1043 1044 instruction_grow( instruction, header ); 1045 1046 return dst_register; 1047 } 1048 1049 static struct tgsi_full_dst_register 1050 tgsi_default_full_dst_register( void ) 1051 { 1052 struct tgsi_full_dst_register full_dst_register; 1053 1054 full_dst_register.Register = tgsi_default_dst_register(); 1055 full_dst_register.Indirect = tgsi_default_ind_register(); 1056 full_dst_register.Dimension = tgsi_default_dimension(); 1057 full_dst_register.DimIndirect = tgsi_default_ind_register(); 1058 1059 return full_dst_register; 1060 } 1061 1062 struct tgsi_full_instruction 1063 tgsi_default_full_instruction( void ) 1064 { 1065 struct tgsi_full_instruction full_instruction; 1066 unsigned i; 1067 1068 full_instruction.Instruction = tgsi_default_instruction(); 1069 full_instruction.Predicate = tgsi_default_instruction_predicate(); 1070 full_instruction.Label = tgsi_default_instruction_label(); 1071 full_instruction.Texture = tgsi_default_instruction_texture(); 1072 full_instruction.Memory = tgsi_default_instruction_memory(); 1073 for( i = 0; i < TGSI_FULL_MAX_TEX_OFFSETS; i++ ) { 1074 full_instruction.TexOffsets[i] = tgsi_default_texture_offset(); 1075 } 1076 for( i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) { 1077 full_instruction.Dst[i] = tgsi_default_full_dst_register(); 1078 } 1079 for( i = 0; i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) { 1080 full_instruction.Src[i] = tgsi_default_full_src_register(); 1081 } 1082 1083 return full_instruction; 1084 } 1085 1086 unsigned 1087 tgsi_build_full_instruction( 1088 const struct tgsi_full_instruction *full_inst, 1089 struct tgsi_token *tokens, 1090 struct tgsi_header *header, 1091 unsigned maxsize ) 1092 { 1093 unsigned size = 0; 1094 unsigned i; 1095 struct tgsi_instruction *instruction; 1096 struct tgsi_token *prev_token; 1097 1098 if( maxsize <= size ) 1099 return 0; 1100 instruction = (struct tgsi_instruction *) &tokens[size]; 1101 size++; 1102 1103 *instruction = tgsi_build_instruction(full_inst->Instruction.Opcode, 1104 full_inst->Instruction.Saturate, 1105 full_inst->Instruction.Predicate, 1106 full_inst->Instruction.NumDstRegs, 1107 full_inst->Instruction.NumSrcRegs, 1108 header); 1109 prev_token = (struct tgsi_token *) instruction; 1110 1111 if (full_inst->Instruction.Predicate) { 1112 struct tgsi_instruction_predicate *instruction_predicate; 1113 1114 if (maxsize <= size) { 1115 return 0; 1116 } 1117 instruction_predicate = (struct tgsi_instruction_predicate *)&tokens[size]; 1118 size++; 1119 1120 *instruction_predicate = 1121 tgsi_build_instruction_predicate(full_inst->Predicate.Index, 1122 full_inst->Predicate.Negate, 1123 full_inst->Predicate.SwizzleX, 1124 full_inst->Predicate.SwizzleY, 1125 full_inst->Predicate.SwizzleZ, 1126 full_inst->Predicate.SwizzleW, 1127 instruction, 1128 header); 1129 } 1130 1131 if (full_inst->Instruction.Label) { 1132 struct tgsi_instruction_label *instruction_label; 1133 1134 if( maxsize <= size ) 1135 return 0; 1136 instruction_label = 1137 (struct tgsi_instruction_label *) &tokens[size]; 1138 size++; 1139 1140 *instruction_label = tgsi_build_instruction_label( 1141 full_inst->Label.Label, 1142 prev_token, 1143 instruction, 1144 header ); 1145 prev_token = (struct tgsi_token *) instruction_label; 1146 } 1147 1148 if (full_inst->Instruction.Texture) { 1149 struct tgsi_instruction_texture *instruction_texture; 1150 1151 if( maxsize <= size ) 1152 return 0; 1153 instruction_texture = 1154 (struct tgsi_instruction_texture *) &tokens[size]; 1155 size++; 1156 1157 *instruction_texture = tgsi_build_instruction_texture( 1158 full_inst->Texture.Texture, 1159 full_inst->Texture.NumOffsets, 1160 prev_token, 1161 instruction, 1162 header ); 1163 prev_token = (struct tgsi_token *) instruction_texture; 1164 1165 for (i = 0; i < full_inst->Texture.NumOffsets; i++) { 1166 struct tgsi_texture_offset *texture_offset; 1167 1168 if ( maxsize <= size ) 1169 return 0; 1170 texture_offset = (struct tgsi_texture_offset *)&tokens[size]; 1171 size++; 1172 *texture_offset = tgsi_build_texture_offset( 1173 full_inst->TexOffsets[i].Index, 1174 full_inst->TexOffsets[i].File, 1175 full_inst->TexOffsets[i].SwizzleX, 1176 full_inst->TexOffsets[i].SwizzleY, 1177 full_inst->TexOffsets[i].SwizzleZ, 1178 prev_token, 1179 instruction, 1180 header); 1181 prev_token = (struct tgsi_token *) texture_offset; 1182 } 1183 } 1184 1185 if (full_inst->Instruction.Memory) { 1186 struct tgsi_instruction_memory *instruction_memory; 1187 1188 if( maxsize <= size ) 1189 return 0; 1190 instruction_memory = 1191 (struct tgsi_instruction_memory *) &tokens[size]; 1192 size++; 1193 1194 *instruction_memory = tgsi_build_instruction_memory( 1195 full_inst->Memory.Qualifier, 1196 full_inst->Memory.Texture, 1197 full_inst->Memory.Format, 1198 prev_token, 1199 instruction, 1200 header ); 1201 prev_token = (struct tgsi_token *) instruction_memory; 1202 } 1203 1204 for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) { 1205 const struct tgsi_full_dst_register *reg = &full_inst->Dst[i]; 1206 struct tgsi_dst_register *dst_register; 1207 1208 if( maxsize <= size ) 1209 return 0; 1210 dst_register = (struct tgsi_dst_register *) &tokens[size]; 1211 size++; 1212 1213 *dst_register = tgsi_build_dst_register( 1214 reg->Register.File, 1215 reg->Register.WriteMask, 1216 reg->Register.Indirect, 1217 reg->Register.Dimension, 1218 reg->Register.Index, 1219 instruction, 1220 header ); 1221 1222 if( reg->Register.Indirect ) { 1223 struct tgsi_ind_register *ind; 1224 1225 if( maxsize <= size ) 1226 return 0; 1227 ind = (struct tgsi_ind_register *) &tokens[size]; 1228 size++; 1229 1230 *ind = tgsi_build_ind_register( 1231 reg->Indirect.File, 1232 reg->Indirect.Swizzle, 1233 reg->Indirect.Index, 1234 reg->Indirect.ArrayID, 1235 instruction, 1236 header ); 1237 } 1238 1239 if( reg->Register.Dimension ) { 1240 struct tgsi_dimension *dim; 1241 1242 assert( !reg->Dimension.Dimension ); 1243 1244 if( maxsize <= size ) 1245 return 0; 1246 dim = (struct tgsi_dimension *) &tokens[size]; 1247 size++; 1248 1249 *dim = tgsi_build_dimension( 1250 reg->Dimension.Indirect, 1251 reg->Dimension.Index, 1252 instruction, 1253 header ); 1254 1255 if( reg->Dimension.Indirect ) { 1256 struct tgsi_ind_register *ind; 1257 1258 if( maxsize <= size ) 1259 return 0; 1260 ind = (struct tgsi_ind_register *) &tokens[size]; 1261 size++; 1262 1263 *ind = tgsi_build_ind_register( 1264 reg->DimIndirect.File, 1265 reg->DimIndirect.Swizzle, 1266 reg->DimIndirect.Index, 1267 reg->DimIndirect.ArrayID, 1268 instruction, 1269 header ); 1270 } 1271 } 1272 } 1273 1274 for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) { 1275 const struct tgsi_full_src_register *reg = &full_inst->Src[i]; 1276 struct tgsi_src_register *src_register; 1277 1278 if( maxsize <= size ) 1279 return 0; 1280 src_register = (struct tgsi_src_register *) &tokens[size]; 1281 size++; 1282 1283 *src_register = tgsi_build_src_register( 1284 reg->Register.File, 1285 reg->Register.SwizzleX, 1286 reg->Register.SwizzleY, 1287 reg->Register.SwizzleZ, 1288 reg->Register.SwizzleW, 1289 reg->Register.Negate, 1290 reg->Register.Absolute, 1291 reg->Register.Indirect, 1292 reg->Register.Dimension, 1293 reg->Register.Index, 1294 instruction, 1295 header ); 1296 1297 if( reg->Register.Indirect ) { 1298 struct tgsi_ind_register *ind; 1299 1300 if( maxsize <= size ) 1301 return 0; 1302 ind = (struct tgsi_ind_register *) &tokens[size]; 1303 size++; 1304 1305 *ind = tgsi_build_ind_register( 1306 reg->Indirect.File, 1307 reg->Indirect.Swizzle, 1308 reg->Indirect.Index, 1309 reg->Indirect.ArrayID, 1310 instruction, 1311 header ); 1312 } 1313 1314 if( reg->Register.Dimension ) { 1315 struct tgsi_dimension *dim; 1316 1317 assert( !reg->Dimension.Dimension ); 1318 1319 if( maxsize <= size ) 1320 return 0; 1321 dim = (struct tgsi_dimension *) &tokens[size]; 1322 size++; 1323 1324 *dim = tgsi_build_dimension( 1325 reg->Dimension.Indirect, 1326 reg->Dimension.Index, 1327 instruction, 1328 header ); 1329 1330 if( reg->Dimension.Indirect ) { 1331 struct tgsi_ind_register *ind; 1332 1333 if( maxsize <= size ) 1334 return 0; 1335 ind = (struct tgsi_ind_register *) &tokens[size]; 1336 size++; 1337 1338 *ind = tgsi_build_ind_register( 1339 reg->DimIndirect.File, 1340 reg->DimIndirect.Swizzle, 1341 reg->DimIndirect.Index, 1342 reg->DimIndirect.ArrayID, 1343 instruction, 1344 header ); 1345 } 1346 } 1347 } 1348 1349 return size; 1350 } 1351 1352 static struct tgsi_property 1353 tgsi_default_property( void ) 1354 { 1355 struct tgsi_property property; 1356 1357 property.Type = TGSI_TOKEN_TYPE_PROPERTY; 1358 property.NrTokens = 1; 1359 property.PropertyName = TGSI_PROPERTY_GS_INPUT_PRIM; 1360 property.Padding = 0; 1361 1362 return property; 1363 } 1364 1365 static struct tgsi_property 1366 tgsi_build_property(unsigned property_name, 1367 struct tgsi_header *header) 1368 { 1369 struct tgsi_property property; 1370 1371 property = tgsi_default_property(); 1372 property.PropertyName = property_name; 1373 1374 header_bodysize_grow( header ); 1375 1376 return property; 1377 } 1378 1379 1380 struct tgsi_full_property 1381 tgsi_default_full_property( void ) 1382 { 1383 struct tgsi_full_property full_property; 1384 1385 full_property.Property = tgsi_default_property(); 1386 memset(full_property.u, 0, 1387 sizeof(struct tgsi_property_data) * 8); 1388 1389 return full_property; 1390 } 1391 1392 static void 1393 property_grow( 1394 struct tgsi_property *property, 1395 struct tgsi_header *header ) 1396 { 1397 assert( property->NrTokens < 0xFF ); 1398 1399 property->NrTokens++; 1400 1401 header_bodysize_grow( header ); 1402 } 1403 1404 static struct tgsi_property_data 1405 tgsi_build_property_data( 1406 unsigned value, 1407 struct tgsi_property *property, 1408 struct tgsi_header *header ) 1409 { 1410 struct tgsi_property_data property_data; 1411 1412 property_data.Data = value; 1413 1414 property_grow( property, header ); 1415 1416 return property_data; 1417 } 1418 1419 unsigned 1420 tgsi_build_full_property( 1421 const struct tgsi_full_property *full_prop, 1422 struct tgsi_token *tokens, 1423 struct tgsi_header *header, 1424 unsigned maxsize ) 1425 { 1426 unsigned size = 0, i; 1427 struct tgsi_property *property; 1428 1429 if( maxsize <= size ) 1430 return 0; 1431 property = (struct tgsi_property *) &tokens[size]; 1432 size++; 1433 1434 *property = tgsi_build_property( 1435 full_prop->Property.PropertyName, 1436 header ); 1437 1438 assert( full_prop->Property.NrTokens <= 8 + 1 ); 1439 1440 for( i = 0; i < full_prop->Property.NrTokens - 1; i++ ) { 1441 struct tgsi_property_data *data; 1442 1443 if( maxsize <= size ) 1444 return 0; 1445 data = (struct tgsi_property_data *) &tokens[size]; 1446 size++; 1447 1448 *data = tgsi_build_property_data( 1449 full_prop->u[i].Data, 1450 property, 1451 header ); 1452 } 1453 1454 return size; 1455 } 1456 1457 struct tgsi_full_src_register 1458 tgsi_full_src_register_from_dst(const struct tgsi_full_dst_register *dst) 1459 { 1460 struct tgsi_full_src_register src; 1461 src.Register = tgsi_default_src_register(); 1462 src.Register.File = dst->Register.File; 1463 src.Register.Indirect = dst->Register.Indirect; 1464 src.Register.Dimension = dst->Register.Dimension; 1465 src.Register.Index = dst->Register.Index; 1466 src.Indirect = dst->Indirect; 1467 src.Dimension = dst->Dimension; 1468 src.DimIndirect = dst->DimIndirect; 1469 return src; 1470 } 1471