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