tgsi_build.c revision 2644952bd4dfa3b75112dee8dfd287a12d770705
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{ 501 struct tgsi_immediate immediate; 502 503 immediate = tgsi_default_immediate(); 504 505 header_bodysize_grow( header ); 506 507 return immediate; 508} 509 510struct tgsi_full_immediate 511tgsi_default_full_immediate( void ) 512{ 513 struct tgsi_full_immediate fullimm; 514 515 fullimm.Immediate = tgsi_default_immediate(); 516 fullimm.u[0].Float = 0.0f; 517 fullimm.u[1].Float = 0.0f; 518 fullimm.u[2].Float = 0.0f; 519 fullimm.u[3].Float = 0.0f; 520 521 return fullimm; 522} 523 524static void 525immediate_grow( 526 struct tgsi_immediate *immediate, 527 struct tgsi_header *header ) 528{ 529 assert( immediate->NrTokens < 0xFF ); 530 531 immediate->NrTokens++; 532 533 header_bodysize_grow( header ); 534} 535 536static union tgsi_immediate_data 537tgsi_build_immediate_float32( 538 float value, 539 struct tgsi_immediate *immediate, 540 struct tgsi_header *header ) 541{ 542 union tgsi_immediate_data immediate_data; 543 544 immediate_data.Float = value; 545 546 immediate_grow( immediate, header ); 547 548 return immediate_data; 549} 550 551unsigned 552tgsi_build_full_immediate( 553 const struct tgsi_full_immediate *full_imm, 554 struct tgsi_token *tokens, 555 struct tgsi_header *header, 556 unsigned maxsize ) 557{ 558 unsigned size = 0, i; 559 struct tgsi_immediate *immediate; 560 561 if( maxsize <= size ) 562 return 0; 563 immediate = (struct tgsi_immediate *) &tokens[size]; 564 size++; 565 566 *immediate = tgsi_build_immediate( header ); 567 568 assert( full_imm->Immediate.NrTokens <= 4 + 1 ); 569 570 for( i = 0; i < full_imm->Immediate.NrTokens - 1; i++ ) { 571 union tgsi_immediate_data *data; 572 573 if( maxsize <= size ) 574 return 0; 575 data = (union tgsi_immediate_data *) &tokens[size]; 576 size++; 577 578 *data = tgsi_build_immediate_float32( 579 full_imm->u[i].Float, 580 immediate, 581 header ); 582 } 583 584 return size; 585} 586 587/* 588 * instruction 589 */ 590 591struct tgsi_instruction 592tgsi_default_instruction( void ) 593{ 594 struct tgsi_instruction instruction; 595 596 instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION; 597 instruction.NrTokens = 0; 598 instruction.Opcode = TGSI_OPCODE_MOV; 599 instruction.Saturate = TGSI_SAT_NONE; 600 instruction.Predicate = 0; 601 instruction.NumDstRegs = 1; 602 instruction.NumSrcRegs = 1; 603 instruction.Label = 0; 604 instruction.Texture = 0; 605 instruction.Padding = 0; 606 607 return instruction; 608} 609 610static struct tgsi_instruction 611tgsi_build_instruction(unsigned opcode, 612 unsigned saturate, 613 unsigned predicate, 614 unsigned num_dst_regs, 615 unsigned num_src_regs, 616 struct tgsi_header *header) 617{ 618 struct tgsi_instruction instruction; 619 620 assert (opcode <= TGSI_OPCODE_LAST); 621 assert (saturate <= TGSI_SAT_MINUS_PLUS_ONE); 622 assert (num_dst_regs <= 3); 623 assert (num_src_regs <= 15); 624 625 instruction = tgsi_default_instruction(); 626 instruction.Opcode = opcode; 627 instruction.Saturate = saturate; 628 instruction.Predicate = predicate; 629 instruction.NumDstRegs = num_dst_regs; 630 instruction.NumSrcRegs = num_src_regs; 631 632 header_bodysize_grow( header ); 633 634 return instruction; 635} 636 637static void 638instruction_grow( 639 struct tgsi_instruction *instruction, 640 struct tgsi_header *header ) 641{ 642 assert (instruction->NrTokens < 0xFF); 643 644 instruction->NrTokens++; 645 646 header_bodysize_grow( header ); 647} 648 649struct tgsi_instruction_predicate 650tgsi_default_instruction_predicate(void) 651{ 652 struct tgsi_instruction_predicate instruction_predicate; 653 654 instruction_predicate.SwizzleX = TGSI_SWIZZLE_X; 655 instruction_predicate.SwizzleY = TGSI_SWIZZLE_Y; 656 instruction_predicate.SwizzleZ = TGSI_SWIZZLE_Z; 657 instruction_predicate.SwizzleW = TGSI_SWIZZLE_W; 658 instruction_predicate.Negate = 0; 659 instruction_predicate.Index = 0; 660 instruction_predicate.Padding = 0; 661 662 return instruction_predicate; 663} 664 665static struct tgsi_instruction_predicate 666tgsi_build_instruction_predicate(int index, 667 unsigned negate, 668 unsigned swizzleX, 669 unsigned swizzleY, 670 unsigned swizzleZ, 671 unsigned swizzleW, 672 struct tgsi_instruction *instruction, 673 struct tgsi_header *header) 674{ 675 struct tgsi_instruction_predicate instruction_predicate; 676 677 instruction_predicate = tgsi_default_instruction_predicate(); 678 instruction_predicate.SwizzleX = swizzleX; 679 instruction_predicate.SwizzleY = swizzleY; 680 instruction_predicate.SwizzleZ = swizzleZ; 681 instruction_predicate.SwizzleW = swizzleW; 682 instruction_predicate.Negate = negate; 683 instruction_predicate.Index = index; 684 685 instruction_grow(instruction, header); 686 687 return instruction_predicate; 688} 689 690static struct tgsi_instruction_label 691tgsi_default_instruction_label( void ) 692{ 693 struct tgsi_instruction_label instruction_label; 694 695 instruction_label.Label = 0; 696 instruction_label.Padding = 0; 697 698 return instruction_label; 699} 700 701static struct tgsi_instruction_label 702tgsi_build_instruction_label( 703 unsigned label, 704 struct tgsi_token *prev_token, 705 struct tgsi_instruction *instruction, 706 struct tgsi_header *header ) 707{ 708 struct tgsi_instruction_label instruction_label; 709 710 instruction_label.Label = label; 711 instruction_label.Padding = 0; 712 instruction->Label = 1; 713 714 instruction_grow( instruction, header ); 715 716 return instruction_label; 717} 718 719static struct tgsi_instruction_texture 720tgsi_default_instruction_texture( void ) 721{ 722 struct tgsi_instruction_texture instruction_texture; 723 724 instruction_texture.Texture = TGSI_BUFFER; 725 instruction_texture.NumOffsets = 0; 726 instruction_texture.Padding = 0; 727 728 return instruction_texture; 729} 730 731static struct tgsi_instruction_texture 732tgsi_build_instruction_texture( 733 unsigned texture, 734 unsigned num_offsets, 735 struct tgsi_token *prev_token, 736 struct tgsi_instruction *instruction, 737 struct tgsi_header *header ) 738{ 739 struct tgsi_instruction_texture instruction_texture; 740 741 instruction_texture.Texture = texture; 742 instruction_texture.NumOffsets = num_offsets; 743 instruction_texture.Padding = 0; 744 instruction->Texture = 1; 745 746 instruction_grow( instruction, header ); 747 748 return instruction_texture; 749} 750 751 752static struct tgsi_texture_offset 753tgsi_default_texture_offset( void ) 754{ 755 struct tgsi_texture_offset texture_offset; 756 757 texture_offset.Index = 0; 758 texture_offset.File = 0; 759 texture_offset.SwizzleX = 0; 760 texture_offset.SwizzleY = 0; 761 texture_offset.SwizzleZ = 0; 762 texture_offset.Padding = 0; 763 764 return texture_offset; 765} 766 767static struct tgsi_texture_offset 768tgsi_build_texture_offset( 769 int index, int file, int swizzle_x, int swizzle_y, int swizzle_z, 770 struct tgsi_token *prev_token, 771 struct tgsi_instruction *instruction, 772 struct tgsi_header *header ) 773{ 774 struct tgsi_texture_offset texture_offset; 775 776 texture_offset.Index = index; 777 texture_offset.File = file; 778 texture_offset.SwizzleX = swizzle_x; 779 texture_offset.SwizzleY = swizzle_y; 780 texture_offset.SwizzleZ = swizzle_z; 781 texture_offset.Padding = 0; 782 783 instruction_grow( instruction, header ); 784 785 return texture_offset; 786} 787 788static struct tgsi_src_register 789tgsi_default_src_register( void ) 790{ 791 struct tgsi_src_register src_register; 792 793 src_register.File = TGSI_FILE_NULL; 794 src_register.SwizzleX = TGSI_SWIZZLE_X; 795 src_register.SwizzleY = TGSI_SWIZZLE_Y; 796 src_register.SwizzleZ = TGSI_SWIZZLE_Z; 797 src_register.SwizzleW = TGSI_SWIZZLE_W; 798 src_register.Negate = 0; 799 src_register.Absolute = 0; 800 src_register.Indirect = 0; 801 src_register.Dimension = 0; 802 src_register.Index = 0; 803 804 return src_register; 805} 806 807static struct tgsi_src_register 808tgsi_build_src_register( 809 unsigned file, 810 unsigned swizzle_x, 811 unsigned swizzle_y, 812 unsigned swizzle_z, 813 unsigned swizzle_w, 814 unsigned negate, 815 unsigned absolute, 816 unsigned indirect, 817 unsigned dimension, 818 int index, 819 struct tgsi_instruction *instruction, 820 struct tgsi_header *header ) 821{ 822 struct tgsi_src_register src_register; 823 824 assert( file < TGSI_FILE_COUNT ); 825 assert( swizzle_x <= TGSI_SWIZZLE_W ); 826 assert( swizzle_y <= TGSI_SWIZZLE_W ); 827 assert( swizzle_z <= TGSI_SWIZZLE_W ); 828 assert( swizzle_w <= TGSI_SWIZZLE_W ); 829 assert( negate <= 1 ); 830 assert( index >= -0x8000 && index <= 0x7FFF ); 831 832 src_register.File = file; 833 src_register.SwizzleX = swizzle_x; 834 src_register.SwizzleY = swizzle_y; 835 src_register.SwizzleZ = swizzle_z; 836 src_register.SwizzleW = swizzle_w; 837 src_register.Negate = negate; 838 src_register.Absolute = absolute; 839 src_register.Indirect = indirect; 840 src_register.Dimension = dimension; 841 src_register.Index = index; 842 843 instruction_grow( instruction, header ); 844 845 return src_register; 846} 847 848static struct tgsi_dimension 849tgsi_default_dimension( void ) 850{ 851 struct tgsi_dimension dimension; 852 853 dimension.Indirect = 0; 854 dimension.Dimension = 0; 855 dimension.Padding = 0; 856 dimension.Index = 0; 857 858 return dimension; 859} 860 861static struct tgsi_full_src_register 862tgsi_default_full_src_register( void ) 863{ 864 struct tgsi_full_src_register full_src_register; 865 866 full_src_register.Register = tgsi_default_src_register(); 867 full_src_register.Indirect = tgsi_default_src_register(); 868 full_src_register.Dimension = tgsi_default_dimension(); 869 full_src_register.DimIndirect = tgsi_default_src_register(); 870 871 return full_src_register; 872} 873 874static struct tgsi_dimension 875tgsi_build_dimension( 876 unsigned indirect, 877 unsigned index, 878 struct tgsi_instruction *instruction, 879 struct tgsi_header *header ) 880{ 881 struct tgsi_dimension dimension; 882 883 dimension.Indirect = indirect; 884 dimension.Dimension = 0; 885 dimension.Padding = 0; 886 dimension.Index = index; 887 888 instruction_grow( instruction, header ); 889 890 return dimension; 891} 892 893static struct tgsi_dst_register 894tgsi_default_dst_register( void ) 895{ 896 struct tgsi_dst_register dst_register; 897 898 dst_register.File = TGSI_FILE_NULL; 899 dst_register.WriteMask = TGSI_WRITEMASK_XYZW; 900 dst_register.Indirect = 0; 901 dst_register.Dimension = 0; 902 dst_register.Index = 0; 903 dst_register.Padding = 0; 904 905 return dst_register; 906} 907 908static struct tgsi_dst_register 909tgsi_build_dst_register( 910 unsigned file, 911 unsigned mask, 912 unsigned indirect, 913 unsigned dimension, 914 int index, 915 struct tgsi_instruction *instruction, 916 struct tgsi_header *header ) 917{ 918 struct tgsi_dst_register dst_register; 919 920 assert( file < TGSI_FILE_COUNT ); 921 assert( mask <= TGSI_WRITEMASK_XYZW ); 922 assert( index >= -32768 && index <= 32767 ); 923 924 dst_register.File = file; 925 dst_register.WriteMask = mask; 926 dst_register.Indirect = indirect; 927 dst_register.Dimension = dimension; 928 dst_register.Index = index; 929 dst_register.Padding = 0; 930 931 instruction_grow( instruction, header ); 932 933 return dst_register; 934} 935 936static struct tgsi_full_dst_register 937tgsi_default_full_dst_register( void ) 938{ 939 struct tgsi_full_dst_register full_dst_register; 940 941 full_dst_register.Register = tgsi_default_dst_register(); 942 full_dst_register.Indirect = tgsi_default_src_register(); 943 full_dst_register.Dimension = tgsi_default_dimension(); 944 full_dst_register.DimIndirect = tgsi_default_src_register(); 945 946 return full_dst_register; 947} 948 949struct tgsi_full_instruction 950tgsi_default_full_instruction( void ) 951{ 952 struct tgsi_full_instruction full_instruction; 953 unsigned i; 954 955 full_instruction.Instruction = tgsi_default_instruction(); 956 full_instruction.Predicate = tgsi_default_instruction_predicate(); 957 full_instruction.Label = tgsi_default_instruction_label(); 958 full_instruction.Texture = tgsi_default_instruction_texture(); 959 for( i = 0; i < TGSI_FULL_MAX_TEX_OFFSETS; i++ ) { 960 full_instruction.TexOffsets[i] = tgsi_default_texture_offset(); 961 } 962 for( i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) { 963 full_instruction.Dst[i] = tgsi_default_full_dst_register(); 964 } 965 for( i = 0; i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) { 966 full_instruction.Src[i] = tgsi_default_full_src_register(); 967 } 968 969 return full_instruction; 970} 971 972unsigned 973tgsi_build_full_instruction( 974 const struct tgsi_full_instruction *full_inst, 975 struct tgsi_token *tokens, 976 struct tgsi_header *header, 977 unsigned maxsize ) 978{ 979 unsigned size = 0; 980 unsigned i; 981 struct tgsi_instruction *instruction; 982 struct tgsi_token *prev_token; 983 984 if( maxsize <= size ) 985 return 0; 986 instruction = (struct tgsi_instruction *) &tokens[size]; 987 size++; 988 989 *instruction = tgsi_build_instruction(full_inst->Instruction.Opcode, 990 full_inst->Instruction.Saturate, 991 full_inst->Instruction.Predicate, 992 full_inst->Instruction.NumDstRegs, 993 full_inst->Instruction.NumSrcRegs, 994 header); 995 prev_token = (struct tgsi_token *) instruction; 996 997 if (full_inst->Instruction.Predicate) { 998 struct tgsi_instruction_predicate *instruction_predicate; 999 1000 if (maxsize <= size) { 1001 return 0; 1002 } 1003 instruction_predicate = (struct tgsi_instruction_predicate *)&tokens[size]; 1004 size++; 1005 1006 *instruction_predicate = 1007 tgsi_build_instruction_predicate(full_inst->Predicate.Index, 1008 full_inst->Predicate.Negate, 1009 full_inst->Predicate.SwizzleX, 1010 full_inst->Predicate.SwizzleY, 1011 full_inst->Predicate.SwizzleZ, 1012 full_inst->Predicate.SwizzleW, 1013 instruction, 1014 header); 1015 } 1016 1017 if (full_inst->Instruction.Label) { 1018 struct tgsi_instruction_label *instruction_label; 1019 1020 if( maxsize <= size ) 1021 return 0; 1022 instruction_label = 1023 (struct tgsi_instruction_label *) &tokens[size]; 1024 size++; 1025 1026 *instruction_label = tgsi_build_instruction_label( 1027 full_inst->Label.Label, 1028 prev_token, 1029 instruction, 1030 header ); 1031 prev_token = (struct tgsi_token *) instruction_label; 1032 } 1033 1034 if (full_inst->Instruction.Texture) { 1035 struct tgsi_instruction_texture *instruction_texture; 1036 1037 if( maxsize <= size ) 1038 return 0; 1039 instruction_texture = 1040 (struct tgsi_instruction_texture *) &tokens[size]; 1041 size++; 1042 1043 *instruction_texture = tgsi_build_instruction_texture( 1044 full_inst->Texture.Texture, 1045 full_inst->Texture.NumOffsets, 1046 prev_token, 1047 instruction, 1048 header ); 1049 prev_token = (struct tgsi_token *) instruction_texture; 1050 1051 for (i = 0; i < full_inst->Texture.NumOffsets; i++) { 1052 struct tgsi_texture_offset *texture_offset; 1053 1054 if ( maxsize <= size ) 1055 return 0; 1056 texture_offset = (struct tgsi_texture_offset *)&tokens[size]; 1057 size++; 1058 *texture_offset = tgsi_build_texture_offset( 1059 full_inst->TexOffsets[i].Index, 1060 full_inst->TexOffsets[i].File, 1061 full_inst->TexOffsets[i].SwizzleX, 1062 full_inst->TexOffsets[i].SwizzleY, 1063 full_inst->TexOffsets[i].SwizzleZ, 1064 prev_token, 1065 instruction, 1066 header); 1067 prev_token = (struct tgsi_token *) texture_offset; 1068 } 1069 } 1070 for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) { 1071 const struct tgsi_full_dst_register *reg = &full_inst->Dst[i]; 1072 struct tgsi_dst_register *dst_register; 1073 1074 if( maxsize <= size ) 1075 return 0; 1076 dst_register = (struct tgsi_dst_register *) &tokens[size]; 1077 size++; 1078 1079 *dst_register = tgsi_build_dst_register( 1080 reg->Register.File, 1081 reg->Register.WriteMask, 1082 reg->Register.Indirect, 1083 reg->Register.Dimension, 1084 reg->Register.Index, 1085 instruction, 1086 header ); 1087 1088 if( reg->Register.Indirect ) { 1089 struct tgsi_src_register *ind; 1090 1091 if( maxsize <= size ) 1092 return 0; 1093 ind = (struct tgsi_src_register *) &tokens[size]; 1094 size++; 1095 1096 *ind = tgsi_build_src_register( 1097 reg->Indirect.File, 1098 reg->Indirect.SwizzleX, 1099 reg->Indirect.SwizzleY, 1100 reg->Indirect.SwizzleZ, 1101 reg->Indirect.SwizzleW, 1102 reg->Indirect.Negate, 1103 reg->Indirect.Absolute, 1104 reg->Indirect.Indirect, 1105 reg->Indirect.Dimension, 1106 reg->Indirect.Index, 1107 instruction, 1108 header ); 1109 } 1110 1111 if( reg->Register.Dimension ) { 1112 struct tgsi_dimension *dim; 1113 1114 assert( !reg->Dimension.Dimension ); 1115 1116 if( maxsize <= size ) 1117 return 0; 1118 dim = (struct tgsi_dimension *) &tokens[size]; 1119 size++; 1120 1121 *dim = tgsi_build_dimension( 1122 reg->Dimension.Indirect, 1123 reg->Dimension.Index, 1124 instruction, 1125 header ); 1126 1127 if( reg->Dimension.Indirect ) { 1128 struct tgsi_src_register *ind; 1129 1130 if( maxsize <= size ) 1131 return 0; 1132 ind = (struct tgsi_src_register *) &tokens[size]; 1133 size++; 1134 1135 *ind = tgsi_build_src_register( 1136 reg->DimIndirect.File, 1137 reg->DimIndirect.SwizzleX, 1138 reg->DimIndirect.SwizzleY, 1139 reg->DimIndirect.SwizzleZ, 1140 reg->DimIndirect.SwizzleW, 1141 reg->DimIndirect.Negate, 1142 reg->DimIndirect.Absolute, 1143 reg->DimIndirect.Indirect, 1144 reg->DimIndirect.Dimension, 1145 reg->DimIndirect.Index, 1146 instruction, 1147 header ); 1148 } 1149 } 1150 } 1151 1152 for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) { 1153 const struct tgsi_full_src_register *reg = &full_inst->Src[i]; 1154 struct tgsi_src_register *src_register; 1155 1156 if( maxsize <= size ) 1157 return 0; 1158 src_register = (struct tgsi_src_register *) &tokens[size]; 1159 size++; 1160 1161 *src_register = tgsi_build_src_register( 1162 reg->Register.File, 1163 reg->Register.SwizzleX, 1164 reg->Register.SwizzleY, 1165 reg->Register.SwizzleZ, 1166 reg->Register.SwizzleW, 1167 reg->Register.Negate, 1168 reg->Register.Absolute, 1169 reg->Register.Indirect, 1170 reg->Register.Dimension, 1171 reg->Register.Index, 1172 instruction, 1173 header ); 1174 1175 if( reg->Register.Indirect ) { 1176 struct tgsi_src_register *ind; 1177 1178 if( maxsize <= size ) 1179 return 0; 1180 ind = (struct tgsi_src_register *) &tokens[size]; 1181 size++; 1182 1183 *ind = tgsi_build_src_register( 1184 reg->Indirect.File, 1185 reg->Indirect.SwizzleX, 1186 reg->Indirect.SwizzleY, 1187 reg->Indirect.SwizzleZ, 1188 reg->Indirect.SwizzleW, 1189 reg->Indirect.Negate, 1190 reg->Indirect.Absolute, 1191 reg->Indirect.Indirect, 1192 reg->Indirect.Dimension, 1193 reg->Indirect.Index, 1194 instruction, 1195 header ); 1196 } 1197 1198 if( reg->Register.Dimension ) { 1199 struct tgsi_dimension *dim; 1200 1201 assert( !reg->Dimension.Dimension ); 1202 1203 if( maxsize <= size ) 1204 return 0; 1205 dim = (struct tgsi_dimension *) &tokens[size]; 1206 size++; 1207 1208 *dim = tgsi_build_dimension( 1209 reg->Dimension.Indirect, 1210 reg->Dimension.Index, 1211 instruction, 1212 header ); 1213 1214 if( reg->Dimension.Indirect ) { 1215 struct tgsi_src_register *ind; 1216 1217 if( maxsize <= size ) 1218 return 0; 1219 ind = (struct tgsi_src_register *) &tokens[size]; 1220 size++; 1221 1222 *ind = tgsi_build_src_register( 1223 reg->DimIndirect.File, 1224 reg->DimIndirect.SwizzleX, 1225 reg->DimIndirect.SwizzleY, 1226 reg->DimIndirect.SwizzleZ, 1227 reg->DimIndirect.SwizzleW, 1228 reg->DimIndirect.Negate, 1229 reg->DimIndirect.Absolute, 1230 reg->DimIndirect.Indirect, 1231 reg->DimIndirect.Dimension, 1232 reg->DimIndirect.Index, 1233 instruction, 1234 header ); 1235 } 1236 } 1237 } 1238 1239 return size; 1240} 1241 1242static struct tgsi_property 1243tgsi_default_property( void ) 1244{ 1245 struct tgsi_property property; 1246 1247 property.Type = TGSI_TOKEN_TYPE_PROPERTY; 1248 property.NrTokens = 1; 1249 property.PropertyName = TGSI_PROPERTY_GS_INPUT_PRIM; 1250 property.Padding = 0; 1251 1252 return property; 1253} 1254 1255static struct tgsi_property 1256tgsi_build_property(unsigned property_name, 1257 struct tgsi_header *header) 1258{ 1259 struct tgsi_property property; 1260 1261 property = tgsi_default_property(); 1262 property.PropertyName = property_name; 1263 1264 header_bodysize_grow( header ); 1265 1266 return property; 1267} 1268 1269 1270struct tgsi_full_property 1271tgsi_default_full_property( void ) 1272{ 1273 struct tgsi_full_property full_property; 1274 1275 full_property.Property = tgsi_default_property(); 1276 memset(full_property.u, 0, 1277 sizeof(struct tgsi_property_data) * 8); 1278 1279 return full_property; 1280} 1281 1282static void 1283property_grow( 1284 struct tgsi_property *property, 1285 struct tgsi_header *header ) 1286{ 1287 assert( property->NrTokens < 0xFF ); 1288 1289 property->NrTokens++; 1290 1291 header_bodysize_grow( header ); 1292} 1293 1294static struct tgsi_property_data 1295tgsi_build_property_data( 1296 unsigned value, 1297 struct tgsi_property *property, 1298 struct tgsi_header *header ) 1299{ 1300 struct tgsi_property_data property_data; 1301 1302 property_data.Data = value; 1303 1304 property_grow( property, header ); 1305 1306 return property_data; 1307} 1308 1309unsigned 1310tgsi_build_full_property( 1311 const struct tgsi_full_property *full_prop, 1312 struct tgsi_token *tokens, 1313 struct tgsi_header *header, 1314 unsigned maxsize ) 1315{ 1316 unsigned size = 0, i; 1317 struct tgsi_property *property; 1318 1319 if( maxsize <= size ) 1320 return 0; 1321 property = (struct tgsi_property *) &tokens[size]; 1322 size++; 1323 1324 *property = tgsi_build_property( 1325 full_prop->Property.PropertyName, 1326 header ); 1327 1328 assert( full_prop->Property.NrTokens <= 8 + 1 ); 1329 1330 for( i = 0; i < full_prop->Property.NrTokens - 1; i++ ) { 1331 struct tgsi_property_data *data; 1332 1333 if( maxsize <= size ) 1334 return 0; 1335 data = (struct tgsi_property_data *) &tokens[size]; 1336 size++; 1337 1338 *data = tgsi_build_property_data( 1339 full_prop->u[i].Data, 1340 property, 1341 header ); 1342 } 1343 1344 return size; 1345} 1346