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