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 39struct tgsi_header 40tgsi_build_header( void ) 41{ 42 struct tgsi_header header; 43 44 header.HeaderSize = 1; 45 header.BodySize = 0; 46 47 return header; 48} 49 50static void 51header_headersize_grow( struct tgsi_header *header ) 52{ 53 assert( header->HeaderSize < 0xFF ); 54 assert( header->BodySize == 0 ); 55 56 header->HeaderSize++; 57} 58 59static void 60header_bodysize_grow( struct tgsi_header *header ) 61{ 62 assert( header->BodySize < 0xFFFFFF ); 63 64 header->BodySize++; 65} 66 67struct tgsi_processor 68tgsi_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 86static void 87declaration_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 98static struct tgsi_declaration 99tgsi_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 120static struct tgsi_declaration 121tgsi_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 155static struct tgsi_declaration_range 156tgsi_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 166static struct tgsi_declaration_dimension 167tgsi_default_declaration_dimension() 168{ 169 struct tgsi_declaration_dimension dim; 170 171 dim.Index2D = 0; 172 173 return dim; 174} 175 176static struct tgsi_declaration_range 177tgsi_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 196static struct tgsi_declaration_dimension 197tgsi_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 213static struct tgsi_declaration_interp 214tgsi_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 226static struct tgsi_declaration_interp 227tgsi_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 245static struct tgsi_declaration_semantic 246tgsi_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 260static struct tgsi_declaration_semantic 261tgsi_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 288static struct tgsi_declaration_image 289tgsi_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 302static struct tgsi_declaration_image 303tgsi_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 323static struct tgsi_declaration_sampler_view 324tgsi_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 337static struct tgsi_declaration_sampler_view 338tgsi_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 361static struct tgsi_declaration_array 362tgsi_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 372static struct tgsi_declaration_array 373tgsi_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 387struct tgsi_full_declaration 388tgsi_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 404unsigned 405tgsi_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 549static struct tgsi_immediate 550tgsi_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 562static struct tgsi_immediate 563tgsi_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 577struct tgsi_full_immediate 578tgsi_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 591static void 592immediate_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 603unsigned 604tgsi_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; 611 int i; 612 struct tgsi_immediate *immediate; 613 614 if( maxsize <= size ) 615 return 0; 616 immediate = (struct tgsi_immediate *) &tokens[size]; 617 size++; 618 619 *immediate = tgsi_build_immediate( header, full_imm->Immediate.DataType ); 620 621 assert( full_imm->Immediate.NrTokens <= 4 + 1 ); 622 623 for( i = 0; i < full_imm->Immediate.NrTokens - 1; i++ ) { 624 union tgsi_immediate_data *data; 625 626 if( maxsize <= size ) 627 return 0; 628 629 data = (union tgsi_immediate_data *) &tokens[size]; 630 *data = full_imm->u[i]; 631 632 immediate_grow( immediate, header ); 633 size++; 634 } 635 636 return size; 637} 638 639/* 640 * instruction 641 */ 642 643struct tgsi_instruction 644tgsi_default_instruction( void ) 645{ 646 struct tgsi_instruction instruction; 647 648 instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION; 649 instruction.NrTokens = 0; 650 instruction.Opcode = TGSI_OPCODE_MOV; 651 instruction.Saturate = 0; 652 instruction.NumDstRegs = 1; 653 instruction.NumSrcRegs = 1; 654 instruction.Label = 0; 655 instruction.Texture = 0; 656 instruction.Memory = 0; 657 instruction.Precise = 0; 658 instruction.Padding = 0; 659 660 return instruction; 661} 662 663static struct tgsi_instruction 664tgsi_build_instruction(enum tgsi_opcode opcode, 665 unsigned saturate, 666 unsigned precise, 667 unsigned num_dst_regs, 668 unsigned num_src_regs, 669 struct tgsi_header *header) 670{ 671 struct tgsi_instruction instruction; 672 673 assert (opcode <= TGSI_OPCODE_LAST); 674 assert (saturate <= 1); 675 assert (num_dst_regs <= 3); 676 assert (num_src_regs <= 15); 677 678 instruction = tgsi_default_instruction(); 679 instruction.Opcode = opcode; 680 instruction.Saturate = saturate; 681 instruction.Precise = precise; 682 instruction.NumDstRegs = num_dst_regs; 683 instruction.NumSrcRegs = num_src_regs; 684 685 header_bodysize_grow( header ); 686 687 return instruction; 688} 689 690static void 691instruction_grow( 692 struct tgsi_instruction *instruction, 693 struct tgsi_header *header ) 694{ 695 assert (instruction->NrTokens < 0xFF); 696 697 instruction->NrTokens++; 698 699 header_bodysize_grow( header ); 700} 701 702static struct tgsi_instruction_label 703tgsi_default_instruction_label( void ) 704{ 705 struct tgsi_instruction_label instruction_label; 706 707 instruction_label.Label = 0; 708 instruction_label.Padding = 0; 709 710 return instruction_label; 711} 712 713static struct tgsi_instruction_label 714tgsi_build_instruction_label( 715 unsigned label, 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 730static struct tgsi_instruction_texture 731tgsi_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 743static struct tgsi_instruction_texture 744tgsi_build_instruction_texture( 745 unsigned texture, 746 unsigned num_offsets, 747 unsigned return_type, 748 struct tgsi_instruction *instruction, 749 struct tgsi_header *header ) 750{ 751 struct tgsi_instruction_texture instruction_texture; 752 753 instruction_texture.Texture = texture; 754 instruction_texture.NumOffsets = num_offsets; 755 instruction_texture.ReturnType = return_type; 756 instruction_texture.Padding = 0; 757 instruction->Texture = 1; 758 759 instruction_grow( instruction, header ); 760 761 return instruction_texture; 762} 763 764static struct tgsi_instruction_memory 765tgsi_default_instruction_memory( void ) 766{ 767 struct tgsi_instruction_memory instruction_memory; 768 769 instruction_memory.Qualifier = 0; 770 instruction_memory.Texture = 0; 771 instruction_memory.Format = 0; 772 instruction_memory.Padding = 0; 773 774 return instruction_memory; 775} 776 777static struct tgsi_instruction_memory 778tgsi_build_instruction_memory( 779 unsigned qualifier, 780 unsigned texture, 781 unsigned format, 782 struct tgsi_instruction *instruction, 783 struct tgsi_header *header ) 784{ 785 struct tgsi_instruction_memory instruction_memory; 786 787 instruction_memory.Qualifier = qualifier; 788 instruction_memory.Texture = texture; 789 instruction_memory.Format = format; 790 instruction_memory.Padding = 0; 791 instruction->Memory = 1; 792 793 instruction_grow( instruction, header ); 794 795 return instruction_memory; 796} 797 798static struct tgsi_texture_offset 799tgsi_default_texture_offset( void ) 800{ 801 struct tgsi_texture_offset texture_offset; 802 803 texture_offset.Index = 0; 804 texture_offset.File = 0; 805 texture_offset.SwizzleX = 0; 806 texture_offset.SwizzleY = 0; 807 texture_offset.SwizzleZ = 0; 808 texture_offset.Padding = 0; 809 810 return texture_offset; 811} 812 813static struct tgsi_texture_offset 814tgsi_build_texture_offset( 815 int index, int file, int swizzle_x, int swizzle_y, int swizzle_z, 816 struct tgsi_instruction *instruction, 817 struct tgsi_header *header ) 818{ 819 struct tgsi_texture_offset texture_offset; 820 821 texture_offset.Index = index; 822 texture_offset.File = file; 823 texture_offset.SwizzleX = swizzle_x; 824 texture_offset.SwizzleY = swizzle_y; 825 texture_offset.SwizzleZ = swizzle_z; 826 texture_offset.Padding = 0; 827 828 instruction_grow( instruction, header ); 829 830 return texture_offset; 831} 832 833static struct tgsi_src_register 834tgsi_default_src_register( void ) 835{ 836 struct tgsi_src_register src_register; 837 838 src_register.File = TGSI_FILE_NULL; 839 src_register.SwizzleX = TGSI_SWIZZLE_X; 840 src_register.SwizzleY = TGSI_SWIZZLE_Y; 841 src_register.SwizzleZ = TGSI_SWIZZLE_Z; 842 src_register.SwizzleW = TGSI_SWIZZLE_W; 843 src_register.Negate = 0; 844 src_register.Absolute = 0; 845 src_register.Indirect = 0; 846 src_register.Dimension = 0; 847 src_register.Index = 0; 848 849 return src_register; 850} 851 852static struct tgsi_src_register 853tgsi_build_src_register( 854 unsigned file, 855 unsigned swizzle_x, 856 unsigned swizzle_y, 857 unsigned swizzle_z, 858 unsigned swizzle_w, 859 unsigned negate, 860 unsigned absolute, 861 unsigned indirect, 862 unsigned dimension, 863 int index, 864 struct tgsi_instruction *instruction, 865 struct tgsi_header *header ) 866{ 867 struct tgsi_src_register src_register; 868 869 assert( file < TGSI_FILE_COUNT ); 870 assert( swizzle_x <= TGSI_SWIZZLE_W ); 871 assert( swizzle_y <= TGSI_SWIZZLE_W ); 872 assert( swizzle_z <= TGSI_SWIZZLE_W ); 873 assert( swizzle_w <= TGSI_SWIZZLE_W ); 874 assert( negate <= 1 ); 875 assert( index >= -0x8000 && index <= 0x7FFF ); 876 877 src_register.File = file; 878 src_register.SwizzleX = swizzle_x; 879 src_register.SwizzleY = swizzle_y; 880 src_register.SwizzleZ = swizzle_z; 881 src_register.SwizzleW = swizzle_w; 882 src_register.Negate = negate; 883 src_register.Absolute = absolute; 884 src_register.Indirect = indirect; 885 src_register.Dimension = dimension; 886 src_register.Index = index; 887 888 instruction_grow( instruction, header ); 889 890 return src_register; 891} 892 893static struct tgsi_ind_register 894tgsi_default_ind_register( void ) 895{ 896 struct tgsi_ind_register ind_register; 897 898 ind_register.File = TGSI_FILE_NULL; 899 ind_register.Index = 0; 900 ind_register.Swizzle = TGSI_SWIZZLE_X; 901 ind_register.ArrayID = 0; 902 903 return ind_register; 904} 905 906static struct tgsi_ind_register 907tgsi_build_ind_register( 908 unsigned file, 909 unsigned swizzle, 910 int index, 911 unsigned arrayid, 912 struct tgsi_instruction *instruction, 913 struct tgsi_header *header ) 914{ 915 struct tgsi_ind_register ind_register; 916 917 assert( file < TGSI_FILE_COUNT ); 918 assert( swizzle <= TGSI_SWIZZLE_W ); 919 assert( index >= -0x8000 && index <= 0x7FFF ); 920 921 ind_register.File = file; 922 ind_register.Swizzle = swizzle; 923 ind_register.Index = index; 924 ind_register.ArrayID = arrayid; 925 926 instruction_grow( instruction, header ); 927 928 return ind_register; 929} 930 931static struct tgsi_dimension 932tgsi_default_dimension( void ) 933{ 934 struct tgsi_dimension dimension; 935 936 dimension.Indirect = 0; 937 dimension.Dimension = 0; 938 dimension.Padding = 0; 939 dimension.Index = 0; 940 941 return dimension; 942} 943 944static struct tgsi_full_src_register 945tgsi_default_full_src_register( void ) 946{ 947 struct tgsi_full_src_register full_src_register; 948 949 full_src_register.Register = tgsi_default_src_register(); 950 full_src_register.Indirect = tgsi_default_ind_register(); 951 full_src_register.Dimension = tgsi_default_dimension(); 952 full_src_register.DimIndirect = tgsi_default_ind_register(); 953 954 return full_src_register; 955} 956 957static struct tgsi_dimension 958tgsi_build_dimension( 959 unsigned indirect, 960 unsigned index, 961 struct tgsi_instruction *instruction, 962 struct tgsi_header *header ) 963{ 964 struct tgsi_dimension dimension; 965 966 dimension.Indirect = indirect; 967 dimension.Dimension = 0; 968 dimension.Padding = 0; 969 dimension.Index = index; 970 971 instruction_grow( instruction, header ); 972 973 return dimension; 974} 975 976static struct tgsi_dst_register 977tgsi_default_dst_register( void ) 978{ 979 struct tgsi_dst_register dst_register; 980 981 dst_register.File = TGSI_FILE_NULL; 982 dst_register.WriteMask = TGSI_WRITEMASK_XYZW; 983 dst_register.Indirect = 0; 984 dst_register.Dimension = 0; 985 dst_register.Index = 0; 986 dst_register.Padding = 0; 987 988 return dst_register; 989} 990 991static struct tgsi_dst_register 992tgsi_build_dst_register( 993 unsigned file, 994 unsigned mask, 995 unsigned indirect, 996 unsigned dimension, 997 int index, 998 struct tgsi_instruction *instruction, 999 struct tgsi_header *header ) 1000{ 1001 struct tgsi_dst_register dst_register; 1002 1003 assert( file < TGSI_FILE_COUNT ); 1004 assert( mask <= TGSI_WRITEMASK_XYZW ); 1005 assert( index >= -32768 && index <= 32767 ); 1006 1007 dst_register.File = file; 1008 dst_register.WriteMask = mask; 1009 dst_register.Indirect = indirect; 1010 dst_register.Dimension = dimension; 1011 dst_register.Index = index; 1012 dst_register.Padding = 0; 1013 1014 instruction_grow( instruction, header ); 1015 1016 return dst_register; 1017} 1018 1019static struct tgsi_full_dst_register 1020tgsi_default_full_dst_register( void ) 1021{ 1022 struct tgsi_full_dst_register full_dst_register; 1023 1024 full_dst_register.Register = tgsi_default_dst_register(); 1025 full_dst_register.Indirect = tgsi_default_ind_register(); 1026 full_dst_register.Dimension = tgsi_default_dimension(); 1027 full_dst_register.DimIndirect = tgsi_default_ind_register(); 1028 1029 return full_dst_register; 1030} 1031 1032struct tgsi_full_instruction 1033tgsi_default_full_instruction( void ) 1034{ 1035 struct tgsi_full_instruction full_instruction; 1036 unsigned i; 1037 1038 full_instruction.Instruction = tgsi_default_instruction(); 1039 full_instruction.Label = tgsi_default_instruction_label(); 1040 full_instruction.Texture = tgsi_default_instruction_texture(); 1041 full_instruction.Memory = tgsi_default_instruction_memory(); 1042 for( i = 0; i < TGSI_FULL_MAX_TEX_OFFSETS; i++ ) { 1043 full_instruction.TexOffsets[i] = tgsi_default_texture_offset(); 1044 } 1045 for( i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) { 1046 full_instruction.Dst[i] = tgsi_default_full_dst_register(); 1047 } 1048 for( i = 0; i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) { 1049 full_instruction.Src[i] = tgsi_default_full_src_register(); 1050 } 1051 1052 return full_instruction; 1053} 1054 1055unsigned 1056tgsi_build_full_instruction( 1057 const struct tgsi_full_instruction *full_inst, 1058 struct tgsi_token *tokens, 1059 struct tgsi_header *header, 1060 unsigned maxsize ) 1061{ 1062 unsigned size = 0; 1063 unsigned i; 1064 struct tgsi_instruction *instruction; 1065 1066 if( maxsize <= size ) 1067 return 0; 1068 instruction = (struct tgsi_instruction *) &tokens[size]; 1069 size++; 1070 1071 *instruction = tgsi_build_instruction(full_inst->Instruction.Opcode, 1072 full_inst->Instruction.Saturate, 1073 full_inst->Instruction.Precise, 1074 full_inst->Instruction.NumDstRegs, 1075 full_inst->Instruction.NumSrcRegs, 1076 header); 1077 1078 if (full_inst->Instruction.Label) { 1079 struct tgsi_instruction_label *instruction_label; 1080 1081 if( maxsize <= size ) 1082 return 0; 1083 instruction_label = 1084 (struct tgsi_instruction_label *) &tokens[size]; 1085 size++; 1086 1087 *instruction_label = tgsi_build_instruction_label( 1088 full_inst->Label.Label, 1089 instruction, 1090 header ); 1091 } 1092 1093 if (full_inst->Instruction.Texture) { 1094 struct tgsi_instruction_texture *instruction_texture; 1095 1096 if( maxsize <= size ) 1097 return 0; 1098 instruction_texture = 1099 (struct tgsi_instruction_texture *) &tokens[size]; 1100 size++; 1101 1102 *instruction_texture = tgsi_build_instruction_texture( 1103 full_inst->Texture.Texture, 1104 full_inst->Texture.NumOffsets, 1105 full_inst->Texture.ReturnType, 1106 instruction, 1107 header ); 1108 1109 for (i = 0; i < full_inst->Texture.NumOffsets; i++) { 1110 struct tgsi_texture_offset *texture_offset; 1111 1112 if ( maxsize <= size ) 1113 return 0; 1114 texture_offset = (struct tgsi_texture_offset *)&tokens[size]; 1115 size++; 1116 *texture_offset = tgsi_build_texture_offset( 1117 full_inst->TexOffsets[i].Index, 1118 full_inst->TexOffsets[i].File, 1119 full_inst->TexOffsets[i].SwizzleX, 1120 full_inst->TexOffsets[i].SwizzleY, 1121 full_inst->TexOffsets[i].SwizzleZ, 1122 instruction, 1123 header); 1124 } 1125 } 1126 1127 if (full_inst->Instruction.Memory) { 1128 struct tgsi_instruction_memory *instruction_memory; 1129 1130 if( maxsize <= size ) 1131 return 0; 1132 instruction_memory = 1133 (struct tgsi_instruction_memory *) &tokens[size]; 1134 size++; 1135 1136 *instruction_memory = tgsi_build_instruction_memory( 1137 full_inst->Memory.Qualifier, 1138 full_inst->Memory.Texture, 1139 full_inst->Memory.Format, 1140 instruction, 1141 header ); 1142 } 1143 1144 for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) { 1145 const struct tgsi_full_dst_register *reg = &full_inst->Dst[i]; 1146 struct tgsi_dst_register *dst_register; 1147 1148 if( maxsize <= size ) 1149 return 0; 1150 dst_register = (struct tgsi_dst_register *) &tokens[size]; 1151 size++; 1152 1153 *dst_register = tgsi_build_dst_register( 1154 reg->Register.File, 1155 reg->Register.WriteMask, 1156 reg->Register.Indirect, 1157 reg->Register.Dimension, 1158 reg->Register.Index, 1159 instruction, 1160 header ); 1161 1162 if( reg->Register.Indirect ) { 1163 struct tgsi_ind_register *ind; 1164 1165 if( maxsize <= size ) 1166 return 0; 1167 ind = (struct tgsi_ind_register *) &tokens[size]; 1168 size++; 1169 1170 *ind = tgsi_build_ind_register( 1171 reg->Indirect.File, 1172 reg->Indirect.Swizzle, 1173 reg->Indirect.Index, 1174 reg->Indirect.ArrayID, 1175 instruction, 1176 header ); 1177 } 1178 1179 if( reg->Register.Dimension ) { 1180 struct tgsi_dimension *dim; 1181 1182 assert( !reg->Dimension.Dimension ); 1183 1184 if( maxsize <= size ) 1185 return 0; 1186 dim = (struct tgsi_dimension *) &tokens[size]; 1187 size++; 1188 1189 *dim = tgsi_build_dimension( 1190 reg->Dimension.Indirect, 1191 reg->Dimension.Index, 1192 instruction, 1193 header ); 1194 1195 if( reg->Dimension.Indirect ) { 1196 struct tgsi_ind_register *ind; 1197 1198 if( maxsize <= size ) 1199 return 0; 1200 ind = (struct tgsi_ind_register *) &tokens[size]; 1201 size++; 1202 1203 *ind = tgsi_build_ind_register( 1204 reg->DimIndirect.File, 1205 reg->DimIndirect.Swizzle, 1206 reg->DimIndirect.Index, 1207 reg->DimIndirect.ArrayID, 1208 instruction, 1209 header ); 1210 } 1211 } 1212 } 1213 1214 for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) { 1215 const struct tgsi_full_src_register *reg = &full_inst->Src[i]; 1216 struct tgsi_src_register *src_register; 1217 1218 if( maxsize <= size ) 1219 return 0; 1220 src_register = (struct tgsi_src_register *) &tokens[size]; 1221 size++; 1222 1223 *src_register = tgsi_build_src_register( 1224 reg->Register.File, 1225 reg->Register.SwizzleX, 1226 reg->Register.SwizzleY, 1227 reg->Register.SwizzleZ, 1228 reg->Register.SwizzleW, 1229 reg->Register.Negate, 1230 reg->Register.Absolute, 1231 reg->Register.Indirect, 1232 reg->Register.Dimension, 1233 reg->Register.Index, 1234 instruction, 1235 header ); 1236 1237 if( reg->Register.Indirect ) { 1238 struct tgsi_ind_register *ind; 1239 1240 if( maxsize <= size ) 1241 return 0; 1242 ind = (struct tgsi_ind_register *) &tokens[size]; 1243 size++; 1244 1245 *ind = tgsi_build_ind_register( 1246 reg->Indirect.File, 1247 reg->Indirect.Swizzle, 1248 reg->Indirect.Index, 1249 reg->Indirect.ArrayID, 1250 instruction, 1251 header ); 1252 } 1253 1254 if( reg->Register.Dimension ) { 1255 struct tgsi_dimension *dim; 1256 1257 assert( !reg->Dimension.Dimension ); 1258 1259 if( maxsize <= size ) 1260 return 0; 1261 dim = (struct tgsi_dimension *) &tokens[size]; 1262 size++; 1263 1264 *dim = tgsi_build_dimension( 1265 reg->Dimension.Indirect, 1266 reg->Dimension.Index, 1267 instruction, 1268 header ); 1269 1270 if( reg->Dimension.Indirect ) { 1271 struct tgsi_ind_register *ind; 1272 1273 if( maxsize <= size ) 1274 return 0; 1275 ind = (struct tgsi_ind_register *) &tokens[size]; 1276 size++; 1277 1278 *ind = tgsi_build_ind_register( 1279 reg->DimIndirect.File, 1280 reg->DimIndirect.Swizzle, 1281 reg->DimIndirect.Index, 1282 reg->DimIndirect.ArrayID, 1283 instruction, 1284 header ); 1285 } 1286 } 1287 } 1288 1289 return size; 1290} 1291 1292static struct tgsi_property 1293tgsi_default_property( void ) 1294{ 1295 struct tgsi_property property; 1296 1297 property.Type = TGSI_TOKEN_TYPE_PROPERTY; 1298 property.NrTokens = 1; 1299 property.PropertyName = TGSI_PROPERTY_GS_INPUT_PRIM; 1300 property.Padding = 0; 1301 1302 return property; 1303} 1304 1305static struct tgsi_property 1306tgsi_build_property(unsigned property_name, 1307 struct tgsi_header *header) 1308{ 1309 struct tgsi_property property; 1310 1311 property = tgsi_default_property(); 1312 property.PropertyName = property_name; 1313 1314 header_bodysize_grow( header ); 1315 1316 return property; 1317} 1318 1319 1320struct tgsi_full_property 1321tgsi_default_full_property( void ) 1322{ 1323 struct tgsi_full_property full_property; 1324 1325 full_property.Property = tgsi_default_property(); 1326 memset(full_property.u, 0, 1327 sizeof(struct tgsi_property_data) * 8); 1328 1329 return full_property; 1330} 1331 1332static void 1333property_grow( 1334 struct tgsi_property *property, 1335 struct tgsi_header *header ) 1336{ 1337 assert( property->NrTokens < 0xFF ); 1338 1339 property->NrTokens++; 1340 1341 header_bodysize_grow( header ); 1342} 1343 1344static struct tgsi_property_data 1345tgsi_build_property_data( 1346 unsigned value, 1347 struct tgsi_property *property, 1348 struct tgsi_header *header ) 1349{ 1350 struct tgsi_property_data property_data; 1351 1352 property_data.Data = value; 1353 1354 property_grow( property, header ); 1355 1356 return property_data; 1357} 1358 1359unsigned 1360tgsi_build_full_property( 1361 const struct tgsi_full_property *full_prop, 1362 struct tgsi_token *tokens, 1363 struct tgsi_header *header, 1364 unsigned maxsize ) 1365{ 1366 unsigned size = 0; 1367 int i; 1368 struct tgsi_property *property; 1369 1370 if( maxsize <= size ) 1371 return 0; 1372 property = (struct tgsi_property *) &tokens[size]; 1373 size++; 1374 1375 *property = tgsi_build_property( 1376 full_prop->Property.PropertyName, 1377 header ); 1378 1379 assert( full_prop->Property.NrTokens <= 8 + 1 ); 1380 1381 for( i = 0; i < full_prop->Property.NrTokens - 1; i++ ) { 1382 struct tgsi_property_data *data; 1383 1384 if( maxsize <= size ) 1385 return 0; 1386 data = (struct tgsi_property_data *) &tokens[size]; 1387 size++; 1388 1389 *data = tgsi_build_property_data( 1390 full_prop->u[i].Data, 1391 property, 1392 header ); 1393 } 1394 1395 return size; 1396} 1397 1398struct tgsi_full_src_register 1399tgsi_full_src_register_from_dst(const struct tgsi_full_dst_register *dst) 1400{ 1401 struct tgsi_full_src_register src; 1402 src.Register = tgsi_default_src_register(); 1403 src.Register.File = dst->Register.File; 1404 src.Register.Indirect = dst->Register.Indirect; 1405 src.Register.Dimension = dst->Register.Dimension; 1406 src.Register.Index = dst->Register.Index; 1407 src.Indirect = dst->Indirect; 1408 src.Dimension = dst->Dimension; 1409 src.DimIndirect = dst->DimIndirect; 1410 return src; 1411} 1412