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