tgsi_build.c revision 2083a276eb270b748d1c2668eb9faa5aadc8e700
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.NumOffsets = 0; 635 instruction_texture.Padding = 0; 636 637 return instruction_texture; 638} 639 640static struct tgsi_instruction_texture 641tgsi_build_instruction_texture( 642 unsigned texture, 643 unsigned num_offsets, 644 struct tgsi_token *prev_token, 645 struct tgsi_instruction *instruction, 646 struct tgsi_header *header ) 647{ 648 struct tgsi_instruction_texture instruction_texture; 649 650 instruction_texture.Texture = texture; 651 instruction_texture.NumOffsets = num_offsets; 652 instruction_texture.Padding = 0; 653 instruction->Texture = 1; 654 655 instruction_grow( instruction, header ); 656 657 return instruction_texture; 658} 659 660 661static struct tgsi_texture_offset 662tgsi_default_texture_offset( void ) 663{ 664 struct tgsi_texture_offset texture_offset; 665 666 texture_offset.Index = 0; 667 texture_offset.File = 0; 668 texture_offset.SwizzleX = 0; 669 texture_offset.SwizzleY = 0; 670 texture_offset.SwizzleZ = 0; 671 texture_offset.Padding = 0; 672 673 return texture_offset; 674} 675 676static struct tgsi_texture_offset 677tgsi_build_texture_offset( 678 int index, int file, int swizzle_x, int swizzle_y, int swizzle_z, 679 struct tgsi_token *prev_token, 680 struct tgsi_instruction *instruction, 681 struct tgsi_header *header ) 682{ 683 struct tgsi_texture_offset texture_offset; 684 685 texture_offset.Index = index; 686 texture_offset.File = file; 687 texture_offset.SwizzleX = swizzle_x; 688 texture_offset.SwizzleY = swizzle_y; 689 texture_offset.SwizzleZ = swizzle_z; 690 texture_offset.Padding = 0; 691 692 instruction_grow( instruction, header ); 693 694 return texture_offset; 695} 696 697static struct tgsi_src_register 698tgsi_default_src_register( void ) 699{ 700 struct tgsi_src_register src_register; 701 702 src_register.File = TGSI_FILE_NULL; 703 src_register.SwizzleX = TGSI_SWIZZLE_X; 704 src_register.SwizzleY = TGSI_SWIZZLE_Y; 705 src_register.SwizzleZ = TGSI_SWIZZLE_Z; 706 src_register.SwizzleW = TGSI_SWIZZLE_W; 707 src_register.Negate = 0; 708 src_register.Absolute = 0; 709 src_register.Indirect = 0; 710 src_register.Dimension = 0; 711 src_register.Index = 0; 712 713 return src_register; 714} 715 716static struct tgsi_src_register 717tgsi_build_src_register( 718 unsigned file, 719 unsigned swizzle_x, 720 unsigned swizzle_y, 721 unsigned swizzle_z, 722 unsigned swizzle_w, 723 unsigned negate, 724 unsigned absolute, 725 unsigned indirect, 726 unsigned dimension, 727 int index, 728 struct tgsi_instruction *instruction, 729 struct tgsi_header *header ) 730{ 731 struct tgsi_src_register src_register; 732 733 assert( file < TGSI_FILE_COUNT ); 734 assert( swizzle_x <= TGSI_SWIZZLE_W ); 735 assert( swizzle_y <= TGSI_SWIZZLE_W ); 736 assert( swizzle_z <= TGSI_SWIZZLE_W ); 737 assert( swizzle_w <= TGSI_SWIZZLE_W ); 738 assert( negate <= 1 ); 739 assert( index >= -0x8000 && index <= 0x7FFF ); 740 741 src_register.File = file; 742 src_register.SwizzleX = swizzle_x; 743 src_register.SwizzleY = swizzle_y; 744 src_register.SwizzleZ = swizzle_z; 745 src_register.SwizzleW = swizzle_w; 746 src_register.Negate = negate; 747 src_register.Absolute = absolute; 748 src_register.Indirect = indirect; 749 src_register.Dimension = dimension; 750 src_register.Index = index; 751 752 instruction_grow( instruction, header ); 753 754 return src_register; 755} 756 757static struct tgsi_dimension 758tgsi_default_dimension( void ) 759{ 760 struct tgsi_dimension dimension; 761 762 dimension.Indirect = 0; 763 dimension.Dimension = 0; 764 dimension.Padding = 0; 765 dimension.Index = 0; 766 767 return dimension; 768} 769 770static struct tgsi_full_src_register 771tgsi_default_full_src_register( void ) 772{ 773 struct tgsi_full_src_register full_src_register; 774 775 full_src_register.Register = tgsi_default_src_register(); 776 full_src_register.Indirect = tgsi_default_src_register(); 777 full_src_register.Dimension = tgsi_default_dimension(); 778 full_src_register.DimIndirect = tgsi_default_src_register(); 779 780 return full_src_register; 781} 782 783static struct tgsi_dimension 784tgsi_build_dimension( 785 unsigned indirect, 786 unsigned index, 787 struct tgsi_instruction *instruction, 788 struct tgsi_header *header ) 789{ 790 struct tgsi_dimension dimension; 791 792 dimension.Indirect = indirect; 793 dimension.Dimension = 0; 794 dimension.Padding = 0; 795 dimension.Index = index; 796 797 instruction_grow( instruction, header ); 798 799 return dimension; 800} 801 802static struct tgsi_dst_register 803tgsi_default_dst_register( void ) 804{ 805 struct tgsi_dst_register dst_register; 806 807 dst_register.File = TGSI_FILE_NULL; 808 dst_register.WriteMask = TGSI_WRITEMASK_XYZW; 809 dst_register.Indirect = 0; 810 dst_register.Dimension = 0; 811 dst_register.Index = 0; 812 dst_register.Padding = 0; 813 814 return dst_register; 815} 816 817static struct tgsi_dst_register 818tgsi_build_dst_register( 819 unsigned file, 820 unsigned mask, 821 unsigned indirect, 822 unsigned dimension, 823 int index, 824 struct tgsi_instruction *instruction, 825 struct tgsi_header *header ) 826{ 827 struct tgsi_dst_register dst_register; 828 829 assert( file < TGSI_FILE_COUNT ); 830 assert( mask <= TGSI_WRITEMASK_XYZW ); 831 assert( index >= -32768 && index <= 32767 ); 832 833 dst_register.File = file; 834 dst_register.WriteMask = mask; 835 dst_register.Indirect = indirect; 836 dst_register.Dimension = dimension; 837 dst_register.Index = index; 838 dst_register.Padding = 0; 839 840 instruction_grow( instruction, header ); 841 842 return dst_register; 843} 844 845static struct tgsi_full_dst_register 846tgsi_default_full_dst_register( void ) 847{ 848 struct tgsi_full_dst_register full_dst_register; 849 850 full_dst_register.Register = tgsi_default_dst_register(); 851 full_dst_register.Indirect = tgsi_default_src_register(); 852 full_dst_register.Dimension = tgsi_default_dimension(); 853 full_dst_register.DimIndirect = tgsi_default_src_register(); 854 855 return full_dst_register; 856} 857 858struct tgsi_full_instruction 859tgsi_default_full_instruction( void ) 860{ 861 struct tgsi_full_instruction full_instruction; 862 unsigned i; 863 864 full_instruction.Instruction = tgsi_default_instruction(); 865 full_instruction.Predicate = tgsi_default_instruction_predicate(); 866 full_instruction.Label = tgsi_default_instruction_label(); 867 full_instruction.Texture = tgsi_default_instruction_texture(); 868 for( i = 0; i < TGSI_FULL_MAX_TEX_OFFSETS; i++ ) { 869 full_instruction.TexOffsets[i] = tgsi_default_texture_offset(); 870 } 871 for( i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) { 872 full_instruction.Dst[i] = tgsi_default_full_dst_register(); 873 } 874 for( i = 0; i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) { 875 full_instruction.Src[i] = tgsi_default_full_src_register(); 876 } 877 878 return full_instruction; 879} 880 881unsigned 882tgsi_build_full_instruction( 883 const struct tgsi_full_instruction *full_inst, 884 struct tgsi_token *tokens, 885 struct tgsi_header *header, 886 unsigned maxsize ) 887{ 888 unsigned size = 0; 889 unsigned i; 890 struct tgsi_instruction *instruction; 891 struct tgsi_token *prev_token; 892 893 if( maxsize <= size ) 894 return 0; 895 instruction = (struct tgsi_instruction *) &tokens[size]; 896 size++; 897 898 *instruction = tgsi_build_instruction(full_inst->Instruction.Opcode, 899 full_inst->Instruction.Saturate, 900 full_inst->Instruction.Predicate, 901 full_inst->Instruction.NumDstRegs, 902 full_inst->Instruction.NumSrcRegs, 903 header); 904 prev_token = (struct tgsi_token *) instruction; 905 906 if (full_inst->Instruction.Predicate) { 907 struct tgsi_instruction_predicate *instruction_predicate; 908 909 if (maxsize <= size) { 910 return 0; 911 } 912 instruction_predicate = (struct tgsi_instruction_predicate *)&tokens[size]; 913 size++; 914 915 *instruction_predicate = 916 tgsi_build_instruction_predicate(full_inst->Predicate.Index, 917 full_inst->Predicate.Negate, 918 full_inst->Predicate.SwizzleX, 919 full_inst->Predicate.SwizzleY, 920 full_inst->Predicate.SwizzleZ, 921 full_inst->Predicate.SwizzleW, 922 instruction, 923 header); 924 } 925 926 if (full_inst->Instruction.Label) { 927 struct tgsi_instruction_label *instruction_label; 928 929 if( maxsize <= size ) 930 return 0; 931 instruction_label = 932 (struct tgsi_instruction_label *) &tokens[size]; 933 size++; 934 935 *instruction_label = tgsi_build_instruction_label( 936 full_inst->Label.Label, 937 prev_token, 938 instruction, 939 header ); 940 prev_token = (struct tgsi_token *) instruction_label; 941 } 942 943 if (full_inst->Instruction.Texture) { 944 struct tgsi_instruction_texture *instruction_texture; 945 946 if( maxsize <= size ) 947 return 0; 948 instruction_texture = 949 (struct tgsi_instruction_texture *) &tokens[size]; 950 size++; 951 952 *instruction_texture = tgsi_build_instruction_texture( 953 full_inst->Texture.Texture, 954 full_inst->Texture.NumOffsets, 955 prev_token, 956 instruction, 957 header ); 958 prev_token = (struct tgsi_token *) instruction_texture; 959 960 for (i = 0; i < full_inst->Texture.NumOffsets; i++) { 961 struct tgsi_texture_offset *texture_offset; 962 963 if ( maxsize <= size ) 964 return 0; 965 texture_offset = (struct tgsi_texture_offset *)&tokens[size]; 966 size++; 967 *texture_offset = tgsi_build_texture_offset( 968 full_inst->TexOffsets[i].Index, 969 full_inst->TexOffsets[i].File, 970 full_inst->TexOffsets[i].SwizzleX, 971 full_inst->TexOffsets[i].SwizzleY, 972 full_inst->TexOffsets[i].SwizzleZ, 973 prev_token, 974 instruction, 975 header); 976 prev_token = (struct tgsi_token *) texture_offset; 977 } 978 } 979 for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) { 980 const struct tgsi_full_dst_register *reg = &full_inst->Dst[i]; 981 struct tgsi_dst_register *dst_register; 982 983 if( maxsize <= size ) 984 return 0; 985 dst_register = (struct tgsi_dst_register *) &tokens[size]; 986 size++; 987 988 *dst_register = tgsi_build_dst_register( 989 reg->Register.File, 990 reg->Register.WriteMask, 991 reg->Register.Indirect, 992 reg->Register.Dimension, 993 reg->Register.Index, 994 instruction, 995 header ); 996 997 if( reg->Register.Indirect ) { 998 struct tgsi_src_register *ind; 999 1000 if( maxsize <= size ) 1001 return 0; 1002 ind = (struct tgsi_src_register *) &tokens[size]; 1003 size++; 1004 1005 *ind = tgsi_build_src_register( 1006 reg->Indirect.File, 1007 reg->Indirect.SwizzleX, 1008 reg->Indirect.SwizzleY, 1009 reg->Indirect.SwizzleZ, 1010 reg->Indirect.SwizzleW, 1011 reg->Indirect.Negate, 1012 reg->Indirect.Absolute, 1013 reg->Indirect.Indirect, 1014 reg->Indirect.Dimension, 1015 reg->Indirect.Index, 1016 instruction, 1017 header ); 1018 } 1019 1020 if( reg->Register.Dimension ) { 1021 struct tgsi_dimension *dim; 1022 1023 assert( !reg->Dimension.Dimension ); 1024 1025 if( maxsize <= size ) 1026 return 0; 1027 dim = (struct tgsi_dimension *) &tokens[size]; 1028 size++; 1029 1030 *dim = tgsi_build_dimension( 1031 reg->Dimension.Indirect, 1032 reg->Dimension.Index, 1033 instruction, 1034 header ); 1035 1036 if( reg->Dimension.Indirect ) { 1037 struct tgsi_src_register *ind; 1038 1039 if( maxsize <= size ) 1040 return 0; 1041 ind = (struct tgsi_src_register *) &tokens[size]; 1042 size++; 1043 1044 *ind = tgsi_build_src_register( 1045 reg->DimIndirect.File, 1046 reg->DimIndirect.SwizzleX, 1047 reg->DimIndirect.SwizzleY, 1048 reg->DimIndirect.SwizzleZ, 1049 reg->DimIndirect.SwizzleW, 1050 reg->DimIndirect.Negate, 1051 reg->DimIndirect.Absolute, 1052 reg->DimIndirect.Indirect, 1053 reg->DimIndirect.Dimension, 1054 reg->DimIndirect.Index, 1055 instruction, 1056 header ); 1057 } 1058 } 1059 } 1060 1061 for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) { 1062 const struct tgsi_full_src_register *reg = &full_inst->Src[i]; 1063 struct tgsi_src_register *src_register; 1064 1065 if( maxsize <= size ) 1066 return 0; 1067 src_register = (struct tgsi_src_register *) &tokens[size]; 1068 size++; 1069 1070 *src_register = tgsi_build_src_register( 1071 reg->Register.File, 1072 reg->Register.SwizzleX, 1073 reg->Register.SwizzleY, 1074 reg->Register.SwizzleZ, 1075 reg->Register.SwizzleW, 1076 reg->Register.Negate, 1077 reg->Register.Absolute, 1078 reg->Register.Indirect, 1079 reg->Register.Dimension, 1080 reg->Register.Index, 1081 instruction, 1082 header ); 1083 1084 if( reg->Register.Indirect ) { 1085 struct tgsi_src_register *ind; 1086 1087 if( maxsize <= size ) 1088 return 0; 1089 ind = (struct tgsi_src_register *) &tokens[size]; 1090 size++; 1091 1092 *ind = tgsi_build_src_register( 1093 reg->Indirect.File, 1094 reg->Indirect.SwizzleX, 1095 reg->Indirect.SwizzleY, 1096 reg->Indirect.SwizzleZ, 1097 reg->Indirect.SwizzleW, 1098 reg->Indirect.Negate, 1099 reg->Indirect.Absolute, 1100 reg->Indirect.Indirect, 1101 reg->Indirect.Dimension, 1102 reg->Indirect.Index, 1103 instruction, 1104 header ); 1105 } 1106 1107 if( reg->Register.Dimension ) { 1108 struct tgsi_dimension *dim; 1109 1110 assert( !reg->Dimension.Dimension ); 1111 1112 if( maxsize <= size ) 1113 return 0; 1114 dim = (struct tgsi_dimension *) &tokens[size]; 1115 size++; 1116 1117 *dim = tgsi_build_dimension( 1118 reg->Dimension.Indirect, 1119 reg->Dimension.Index, 1120 instruction, 1121 header ); 1122 1123 if( reg->Dimension.Indirect ) { 1124 struct tgsi_src_register *ind; 1125 1126 if( maxsize <= size ) 1127 return 0; 1128 ind = (struct tgsi_src_register *) &tokens[size]; 1129 size++; 1130 1131 *ind = tgsi_build_src_register( 1132 reg->DimIndirect.File, 1133 reg->DimIndirect.SwizzleX, 1134 reg->DimIndirect.SwizzleY, 1135 reg->DimIndirect.SwizzleZ, 1136 reg->DimIndirect.SwizzleW, 1137 reg->DimIndirect.Negate, 1138 reg->DimIndirect.Absolute, 1139 reg->DimIndirect.Indirect, 1140 reg->DimIndirect.Dimension, 1141 reg->DimIndirect.Index, 1142 instruction, 1143 header ); 1144 } 1145 } 1146 } 1147 1148 return size; 1149} 1150 1151static struct tgsi_property 1152tgsi_default_property( void ) 1153{ 1154 struct tgsi_property property; 1155 1156 property.Type = TGSI_TOKEN_TYPE_PROPERTY; 1157 property.NrTokens = 1; 1158 property.PropertyName = TGSI_PROPERTY_GS_INPUT_PRIM; 1159 property.Padding = 0; 1160 1161 return property; 1162} 1163 1164static struct tgsi_property 1165tgsi_build_property(unsigned property_name, 1166 struct tgsi_header *header) 1167{ 1168 struct tgsi_property property; 1169 1170 property = tgsi_default_property(); 1171 property.PropertyName = property_name; 1172 1173 header_bodysize_grow( header ); 1174 1175 return property; 1176} 1177 1178 1179struct tgsi_full_property 1180tgsi_default_full_property( void ) 1181{ 1182 struct tgsi_full_property full_property; 1183 1184 full_property.Property = tgsi_default_property(); 1185 memset(full_property.u, 0, 1186 sizeof(struct tgsi_property_data) * 8); 1187 1188 return full_property; 1189} 1190 1191static void 1192property_grow( 1193 struct tgsi_property *property, 1194 struct tgsi_header *header ) 1195{ 1196 assert( property->NrTokens < 0xFF ); 1197 1198 property->NrTokens++; 1199 1200 header_bodysize_grow( header ); 1201} 1202 1203static struct tgsi_property_data 1204tgsi_build_property_data( 1205 unsigned value, 1206 struct tgsi_property *property, 1207 struct tgsi_header *header ) 1208{ 1209 struct tgsi_property_data property_data; 1210 1211 property_data.Data = value; 1212 1213 property_grow( property, header ); 1214 1215 return property_data; 1216} 1217 1218unsigned 1219tgsi_build_full_property( 1220 const struct tgsi_full_property *full_prop, 1221 struct tgsi_token *tokens, 1222 struct tgsi_header *header, 1223 unsigned maxsize ) 1224{ 1225 unsigned size = 0, i; 1226 struct tgsi_property *property; 1227 1228 if( maxsize <= size ) 1229 return 0; 1230 property = (struct tgsi_property *) &tokens[size]; 1231 size++; 1232 1233 *property = tgsi_build_property( 1234 full_prop->Property.PropertyName, 1235 header ); 1236 1237 assert( full_prop->Property.NrTokens <= 8 + 1 ); 1238 1239 for( i = 0; i < full_prop->Property.NrTokens - 1; i++ ) { 1240 struct tgsi_property_data *data; 1241 1242 if( maxsize <= size ) 1243 return 0; 1244 data = (struct tgsi_property_data *) &tokens[size]; 1245 size++; 1246 1247 *data = tgsi_build_property_data( 1248 full_prop->u[i].Data, 1249 property, 1250 header ); 1251 } 1252 1253 return size; 1254} 1255