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