tgsi_dump.c revision af69d88d
1/************************************************************************** 2 * 3 * Copyright 2007-2008 VMware, Inc. 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 VMWARE 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 "util/u_string.h" 30#include "util/u_math.h" 31#include "util/u_memory.h" 32#include "tgsi_dump.h" 33#include "tgsi_info.h" 34#include "tgsi_iterate.h" 35#include "tgsi_strings.h" 36 37 38/** Number of spaces to indent for IF/LOOP/etc */ 39static const int indent_spaces = 3; 40 41 42struct dump_ctx 43{ 44 struct tgsi_iterate_context iter; 45 46 uint instno; 47 uint immno; 48 int indent; 49 50 uint indentation; 51 52 void (*dump_printf)(struct dump_ctx *ctx, const char *format, ...); 53}; 54 55static void 56dump_ctx_printf(struct dump_ctx *ctx, const char *format, ...) 57{ 58 va_list ap; 59 (void)ctx; 60 va_start(ap, format); 61 _debug_vprintf(format, ap); 62 va_end(ap); 63} 64 65static void 66dump_enum( 67 struct dump_ctx *ctx, 68 uint e, 69 const char **enums, 70 uint enum_count ) 71{ 72 if (e >= enum_count) 73 ctx->dump_printf( ctx, "%u", e ); 74 else 75 ctx->dump_printf( ctx, "%s", enums[e] ); 76} 77 78#define EOL() ctx->dump_printf( ctx, "\n" ) 79#define TXT(S) ctx->dump_printf( ctx, "%s", S ) 80#define CHR(C) ctx->dump_printf( ctx, "%c", C ) 81#define UIX(I) ctx->dump_printf( ctx, "0x%x", I ) 82#define UID(I) ctx->dump_printf( ctx, "%u", I ) 83#define INSTID(I) ctx->dump_printf( ctx, "% 3u", I ) 84#define SID(I) ctx->dump_printf( ctx, "%d", I ) 85#define FLT(F) ctx->dump_printf( ctx, "%10.4f", F ) 86#define ENM(E,ENUMS) dump_enum( ctx, E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) 87 88const char * 89tgsi_swizzle_names[4] = 90{ 91 "x", 92 "y", 93 "z", 94 "w" 95}; 96 97static void 98_dump_register_src( 99 struct dump_ctx *ctx, 100 const struct tgsi_full_src_register *src ) 101{ 102 TXT(tgsi_file_name(src->Register.File)); 103 if (src->Register.Dimension) { 104 if (src->Dimension.Indirect) { 105 CHR( '[' ); 106 TXT(tgsi_file_name(src->DimIndirect.File)); 107 CHR( '[' ); 108 SID( src->DimIndirect.Index ); 109 TXT( "]." ); 110 ENM( src->DimIndirect.Swizzle, tgsi_swizzle_names ); 111 if (src->Dimension.Index != 0) { 112 if (src->Dimension.Index > 0) 113 CHR( '+' ); 114 SID( src->Dimension.Index ); 115 } 116 CHR( ']' ); 117 if (src->DimIndirect.ArrayID) { 118 CHR( '(' ); 119 SID( src->DimIndirect.ArrayID ); 120 CHR( ')' ); 121 } 122 } else { 123 CHR('['); 124 SID(src->Dimension.Index); 125 CHR(']'); 126 } 127 } 128 if (src->Register.Indirect) { 129 CHR( '[' ); 130 TXT(tgsi_file_name(src->Indirect.File)); 131 CHR( '[' ); 132 SID( src->Indirect.Index ); 133 TXT( "]." ); 134 ENM( src->Indirect.Swizzle, tgsi_swizzle_names ); 135 if (src->Register.Index != 0) { 136 if (src->Register.Index > 0) 137 CHR( '+' ); 138 SID( src->Register.Index ); 139 } 140 CHR( ']' ); 141 if (src->Indirect.ArrayID) { 142 CHR( '(' ); 143 SID( src->Indirect.ArrayID ); 144 CHR( ')' ); 145 } 146 } else { 147 CHR( '[' ); 148 SID( src->Register.Index ); 149 CHR( ']' ); 150 } 151} 152 153 154static void 155_dump_register_dst( 156 struct dump_ctx *ctx, 157 const struct tgsi_full_dst_register *dst ) 158{ 159 TXT(tgsi_file_name(dst->Register.File)); 160 if (dst->Register.Dimension) { 161 if (dst->Dimension.Indirect) { 162 CHR( '[' ); 163 TXT(tgsi_file_name(dst->DimIndirect.File)); 164 CHR( '[' ); 165 SID( dst->DimIndirect.Index ); 166 TXT( "]." ); 167 ENM( dst->DimIndirect.Swizzle, tgsi_swizzle_names ); 168 if (dst->Dimension.Index != 0) { 169 if (dst->Dimension.Index > 0) 170 CHR( '+' ); 171 SID( dst->Dimension.Index ); 172 } 173 CHR( ']' ); 174 if (dst->DimIndirect.ArrayID) { 175 CHR( '(' ); 176 SID( dst->DimIndirect.ArrayID ); 177 CHR( ')' ); 178 } 179 } else { 180 CHR('['); 181 SID(dst->Dimension.Index); 182 CHR(']'); 183 } 184 } 185 if (dst->Register.Indirect) { 186 CHR( '[' ); 187 TXT(tgsi_file_name(dst->Indirect.File)); 188 CHR( '[' ); 189 SID( dst->Indirect.Index ); 190 TXT( "]." ); 191 ENM( dst->Indirect.Swizzle, tgsi_swizzle_names ); 192 if (dst->Register.Index != 0) { 193 if (dst->Register.Index > 0) 194 CHR( '+' ); 195 SID( dst->Register.Index ); 196 } 197 CHR( ']' ); 198 if (dst->Indirect.ArrayID) { 199 CHR( '(' ); 200 SID( dst->Indirect.ArrayID ); 201 CHR( ')' ); 202 } 203 } else { 204 CHR( '[' ); 205 SID( dst->Register.Index ); 206 CHR( ']' ); 207 } 208} 209static void 210_dump_writemask( 211 struct dump_ctx *ctx, 212 uint writemask ) 213{ 214 if (writemask != TGSI_WRITEMASK_XYZW) { 215 CHR( '.' ); 216 if (writemask & TGSI_WRITEMASK_X) 217 CHR( 'x' ); 218 if (writemask & TGSI_WRITEMASK_Y) 219 CHR( 'y' ); 220 if (writemask & TGSI_WRITEMASK_Z) 221 CHR( 'z' ); 222 if (writemask & TGSI_WRITEMASK_W) 223 CHR( 'w' ); 224 } 225} 226 227static void 228dump_imm_data(struct tgsi_iterate_context *iter, 229 union tgsi_immediate_data *data, 230 unsigned num_tokens, 231 unsigned data_type) 232{ 233 struct dump_ctx *ctx = (struct dump_ctx *)iter; 234 unsigned i ; 235 236 TXT( " {" ); 237 238 assert( num_tokens <= 4 ); 239 for (i = 0; i < num_tokens; i++) { 240 switch (data_type) { 241 case TGSI_IMM_FLOAT32: 242 FLT( data[i].Float ); 243 break; 244 case TGSI_IMM_UINT32: 245 UID(data[i].Uint); 246 break; 247 case TGSI_IMM_INT32: 248 SID(data[i].Int); 249 break; 250 default: 251 assert( 0 ); 252 } 253 254 if (i < num_tokens - 1) 255 TXT( ", " ); 256 } 257 TXT( "}" ); 258} 259 260static boolean 261iter_declaration( 262 struct tgsi_iterate_context *iter, 263 struct tgsi_full_declaration *decl ) 264{ 265 struct dump_ctx *ctx = (struct dump_ctx *)iter; 266 267 TXT( "DCL " ); 268 269 TXT(tgsi_file_name(decl->Declaration.File)); 270 271 /* all geometry shader inputs are two dimensional */ 272 if (decl->Declaration.File == TGSI_FILE_INPUT && 273 iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) { 274 TXT("[]"); 275 } 276 277 if (decl->Declaration.Dimension) { 278 CHR('['); 279 SID(decl->Dim.Index2D); 280 CHR(']'); 281 } 282 283 CHR('['); 284 SID(decl->Range.First); 285 if (decl->Range.First != decl->Range.Last) { 286 TXT(".."); 287 SID(decl->Range.Last); 288 } 289 CHR(']'); 290 291 _dump_writemask( 292 ctx, 293 decl->Declaration.UsageMask ); 294 295 if (decl->Declaration.Array) { 296 TXT( ", ARRAY(" ); 297 SID(decl->Array.ArrayID); 298 CHR(')'); 299 } 300 301 if (decl->Declaration.Local) 302 TXT( ", LOCAL" ); 303 304 if (decl->Declaration.Semantic) { 305 TXT( ", " ); 306 ENM( decl->Semantic.Name, tgsi_semantic_names ); 307 if (decl->Semantic.Index != 0 || 308 decl->Semantic.Name == TGSI_SEMANTIC_TEXCOORD || 309 decl->Semantic.Name == TGSI_SEMANTIC_GENERIC) { 310 CHR( '[' ); 311 UID( decl->Semantic.Index ); 312 CHR( ']' ); 313 } 314 } 315 316 if (decl->Declaration.File == TGSI_FILE_RESOURCE) { 317 TXT(", "); 318 ENM(decl->Resource.Resource, tgsi_texture_names); 319 if (decl->Resource.Writable) 320 TXT(", WR"); 321 if (decl->Resource.Raw) 322 TXT(", RAW"); 323 } 324 325 if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) { 326 TXT(", "); 327 ENM(decl->SamplerView.Resource, tgsi_texture_names); 328 TXT(", "); 329 if ((decl->SamplerView.ReturnTypeX == decl->SamplerView.ReturnTypeY) && 330 (decl->SamplerView.ReturnTypeX == decl->SamplerView.ReturnTypeZ) && 331 (decl->SamplerView.ReturnTypeX == decl->SamplerView.ReturnTypeW)) { 332 ENM(decl->SamplerView.ReturnTypeX, tgsi_type_names); 333 } else { 334 ENM(decl->SamplerView.ReturnTypeX, tgsi_type_names); 335 TXT(", "); 336 ENM(decl->SamplerView.ReturnTypeY, tgsi_type_names); 337 TXT(", "); 338 ENM(decl->SamplerView.ReturnTypeZ, tgsi_type_names); 339 TXT(", "); 340 ENM(decl->SamplerView.ReturnTypeW, tgsi_type_names); 341 } 342 } 343 344 if (decl->Declaration.Interpolate) { 345 if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT && 346 decl->Declaration.File == TGSI_FILE_INPUT) 347 { 348 TXT( ", " ); 349 ENM( decl->Interp.Interpolate, tgsi_interpolate_names ); 350 } 351 352 if (decl->Interp.Location != TGSI_INTERPOLATE_LOC_CENTER) { 353 TXT( ", " ); 354 ENM( decl->Interp.Location, tgsi_interpolate_locations ); 355 } 356 357 if (decl->Interp.CylindricalWrap) { 358 TXT(", CYLWRAP_"); 359 if (decl->Interp.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_X) { 360 CHR('X'); 361 } 362 if (decl->Interp.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_Y) { 363 CHR('Y'); 364 } 365 if (decl->Interp.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_Z) { 366 CHR('Z'); 367 } 368 if (decl->Interp.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_W) { 369 CHR('W'); 370 } 371 } 372 } 373 374 if (decl->Declaration.Invariant) { 375 TXT( ", INVARIANT" ); 376 } 377 378 EOL(); 379 380 return TRUE; 381} 382 383void 384tgsi_dump_declaration( 385 const struct tgsi_full_declaration *decl ) 386{ 387 struct dump_ctx ctx; 388 389 ctx.dump_printf = dump_ctx_printf; 390 391 iter_declaration( &ctx.iter, (struct tgsi_full_declaration *)decl ); 392} 393 394static boolean 395iter_property( 396 struct tgsi_iterate_context *iter, 397 struct tgsi_full_property *prop ) 398{ 399 unsigned i; 400 struct dump_ctx *ctx = (struct dump_ctx *)iter; 401 402 TXT( "PROPERTY " ); 403 ENM(prop->Property.PropertyName, tgsi_property_names); 404 405 if (prop->Property.NrTokens > 1) 406 TXT(" "); 407 408 for (i = 0; i < prop->Property.NrTokens - 1; ++i) { 409 switch (prop->Property.PropertyName) { 410 case TGSI_PROPERTY_GS_INPUT_PRIM: 411 case TGSI_PROPERTY_GS_OUTPUT_PRIM: 412 ENM(prop->u[i].Data, tgsi_primitive_names); 413 break; 414 case TGSI_PROPERTY_FS_COORD_ORIGIN: 415 ENM(prop->u[i].Data, tgsi_fs_coord_origin_names); 416 break; 417 case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER: 418 ENM(prop->u[i].Data, tgsi_fs_coord_pixel_center_names); 419 break; 420 default: 421 SID( prop->u[i].Data ); 422 break; 423 } 424 if (i < prop->Property.NrTokens - 2) 425 TXT( ", " ); 426 } 427 EOL(); 428 429 return TRUE; 430} 431 432void tgsi_dump_property( 433 const struct tgsi_full_property *prop ) 434{ 435 struct dump_ctx ctx; 436 437 ctx.dump_printf = dump_ctx_printf; 438 439 iter_property( &ctx.iter, (struct tgsi_full_property *)prop ); 440} 441 442static boolean 443iter_immediate( 444 struct tgsi_iterate_context *iter, 445 struct tgsi_full_immediate *imm ) 446{ 447 struct dump_ctx *ctx = (struct dump_ctx *) iter; 448 449 TXT( "IMM[" ); 450 SID( ctx->immno++ ); 451 TXT( "] " ); 452 ENM( imm->Immediate.DataType, tgsi_immediate_type_names ); 453 454 dump_imm_data(iter, imm->u, imm->Immediate.NrTokens - 1, 455 imm->Immediate.DataType); 456 457 EOL(); 458 459 return TRUE; 460} 461 462void 463tgsi_dump_immediate( 464 const struct tgsi_full_immediate *imm ) 465{ 466 struct dump_ctx ctx; 467 468 ctx.dump_printf = dump_ctx_printf; 469 470 iter_immediate( &ctx.iter, (struct tgsi_full_immediate *)imm ); 471} 472 473static boolean 474iter_instruction( 475 struct tgsi_iterate_context *iter, 476 struct tgsi_full_instruction *inst ) 477{ 478 struct dump_ctx *ctx = (struct dump_ctx *) iter; 479 uint instno = ctx->instno++; 480 const struct tgsi_opcode_info *info = tgsi_get_opcode_info( inst->Instruction.Opcode ); 481 uint i; 482 boolean first_reg = TRUE; 483 484 INSTID( instno ); 485 TXT( ": " ); 486 487 ctx->indent -= info->pre_dedent; 488 for(i = 0; (int)i < ctx->indent; ++i) 489 TXT( " " ); 490 ctx->indent += info->post_indent; 491 492 if (inst->Instruction.Predicate) { 493 CHR( '(' ); 494 495 if (inst->Predicate.Negate) 496 CHR( '!' ); 497 498 TXT( "PRED[" ); 499 SID( inst->Predicate.Index ); 500 CHR( ']' ); 501 502 if (inst->Predicate.SwizzleX != TGSI_SWIZZLE_X || 503 inst->Predicate.SwizzleY != TGSI_SWIZZLE_Y || 504 inst->Predicate.SwizzleZ != TGSI_SWIZZLE_Z || 505 inst->Predicate.SwizzleW != TGSI_SWIZZLE_W) { 506 CHR( '.' ); 507 ENM( inst->Predicate.SwizzleX, tgsi_swizzle_names ); 508 ENM( inst->Predicate.SwizzleY, tgsi_swizzle_names ); 509 ENM( inst->Predicate.SwizzleZ, tgsi_swizzle_names ); 510 ENM( inst->Predicate.SwizzleW, tgsi_swizzle_names ); 511 } 512 513 TXT( ") " ); 514 } 515 516 TXT( info->mnemonic ); 517 518 switch (inst->Instruction.Saturate) { 519 case TGSI_SAT_NONE: 520 break; 521 case TGSI_SAT_ZERO_ONE: 522 TXT( "_SAT" ); 523 break; 524 case TGSI_SAT_MINUS_PLUS_ONE: 525 TXT( "_SATNV" ); 526 break; 527 default: 528 assert( 0 ); 529 } 530 531 for (i = 0; i < inst->Instruction.NumDstRegs; i++) { 532 const struct tgsi_full_dst_register *dst = &inst->Dst[i]; 533 534 if (!first_reg) 535 CHR( ',' ); 536 CHR( ' ' ); 537 538 _dump_register_dst( ctx, dst ); 539 _dump_writemask( ctx, dst->Register.WriteMask ); 540 541 first_reg = FALSE; 542 } 543 544 for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { 545 const struct tgsi_full_src_register *src = &inst->Src[i]; 546 547 if (!first_reg) 548 CHR( ',' ); 549 CHR( ' ' ); 550 551 if (src->Register.Negate) 552 CHR( '-' ); 553 if (src->Register.Absolute) 554 CHR( '|' ); 555 556 _dump_register_src(ctx, src); 557 558 if (src->Register.SwizzleX != TGSI_SWIZZLE_X || 559 src->Register.SwizzleY != TGSI_SWIZZLE_Y || 560 src->Register.SwizzleZ != TGSI_SWIZZLE_Z || 561 src->Register.SwizzleW != TGSI_SWIZZLE_W) { 562 CHR( '.' ); 563 ENM( src->Register.SwizzleX, tgsi_swizzle_names ); 564 ENM( src->Register.SwizzleY, tgsi_swizzle_names ); 565 ENM( src->Register.SwizzleZ, tgsi_swizzle_names ); 566 ENM( src->Register.SwizzleW, tgsi_swizzle_names ); 567 } 568 569 if (src->Register.Absolute) 570 CHR( '|' ); 571 572 first_reg = FALSE; 573 } 574 575 if (inst->Instruction.Texture) { 576 TXT( ", " ); 577 ENM( inst->Texture.Texture, tgsi_texture_names ); 578 for (i = 0; i < inst->Texture.NumOffsets; i++) { 579 TXT( ", " ); 580 TXT(tgsi_file_name(inst->TexOffsets[i].File)); 581 CHR( '[' ); 582 SID( inst->TexOffsets[i].Index ); 583 CHR( ']' ); 584 CHR( '.' ); 585 ENM( inst->TexOffsets[i].SwizzleX, tgsi_swizzle_names); 586 ENM( inst->TexOffsets[i].SwizzleY, tgsi_swizzle_names); 587 ENM( inst->TexOffsets[i].SwizzleZ, tgsi_swizzle_names); 588 } 589 } 590 591 switch (inst->Instruction.Opcode) { 592 case TGSI_OPCODE_IF: 593 case TGSI_OPCODE_UIF: 594 case TGSI_OPCODE_ELSE: 595 case TGSI_OPCODE_BGNLOOP: 596 case TGSI_OPCODE_ENDLOOP: 597 case TGSI_OPCODE_CAL: 598 TXT( " :" ); 599 UID( inst->Label.Label ); 600 break; 601 } 602 603 /* update indentation */ 604 if (inst->Instruction.Opcode == TGSI_OPCODE_IF || 605 inst->Instruction.Opcode == TGSI_OPCODE_UIF || 606 inst->Instruction.Opcode == TGSI_OPCODE_ELSE || 607 inst->Instruction.Opcode == TGSI_OPCODE_BGNLOOP) { 608 ctx->indentation += indent_spaces; 609 } 610 611 EOL(); 612 613 return TRUE; 614} 615 616void 617tgsi_dump_instruction( 618 const struct tgsi_full_instruction *inst, 619 uint instno ) 620{ 621 struct dump_ctx ctx; 622 623 ctx.instno = instno; 624 ctx.immno = instno; 625 ctx.indent = 0; 626 ctx.dump_printf = dump_ctx_printf; 627 ctx.indentation = 0; 628 629 iter_instruction( &ctx.iter, (struct tgsi_full_instruction *)inst ); 630} 631 632static boolean 633prolog( 634 struct tgsi_iterate_context *iter ) 635{ 636 struct dump_ctx *ctx = (struct dump_ctx *) iter; 637 ENM( iter->processor.Processor, tgsi_processor_type_names ); 638 EOL(); 639 return TRUE; 640} 641 642void 643tgsi_dump( 644 const struct tgsi_token *tokens, 645 uint flags ) 646{ 647 struct dump_ctx ctx; 648 649 ctx.iter.prolog = prolog; 650 ctx.iter.iterate_instruction = iter_instruction; 651 ctx.iter.iterate_declaration = iter_declaration; 652 ctx.iter.iterate_immediate = iter_immediate; 653 ctx.iter.iterate_property = iter_property; 654 ctx.iter.epilog = NULL; 655 656 ctx.instno = 0; 657 ctx.immno = 0; 658 ctx.indent = 0; 659 ctx.dump_printf = dump_ctx_printf; 660 ctx.indentation = 0; 661 662 tgsi_iterate_shader( tokens, &ctx.iter ); 663} 664 665struct str_dump_ctx 666{ 667 struct dump_ctx base; 668 char *str; 669 char *ptr; 670 int left; 671}; 672 673static void 674str_dump_ctx_printf(struct dump_ctx *ctx, const char *format, ...) 675{ 676 struct str_dump_ctx *sctx = (struct str_dump_ctx *)ctx; 677 678 if(sctx->left > 1) { 679 int written; 680 va_list ap; 681 va_start(ap, format); 682 written = util_vsnprintf(sctx->ptr, sctx->left, format, ap); 683 va_end(ap); 684 685 /* Some complicated logic needed to handle the return value of 686 * vsnprintf: 687 */ 688 if (written > 0) { 689 written = MIN2(sctx->left, written); 690 sctx->ptr += written; 691 sctx->left -= written; 692 } 693 } 694} 695 696void 697tgsi_dump_str( 698 const struct tgsi_token *tokens, 699 uint flags, 700 char *str, 701 size_t size) 702{ 703 struct str_dump_ctx ctx; 704 705 ctx.base.iter.prolog = prolog; 706 ctx.base.iter.iterate_instruction = iter_instruction; 707 ctx.base.iter.iterate_declaration = iter_declaration; 708 ctx.base.iter.iterate_immediate = iter_immediate; 709 ctx.base.iter.iterate_property = iter_property; 710 ctx.base.iter.epilog = NULL; 711 712 ctx.base.instno = 0; 713 ctx.base.immno = 0; 714 ctx.base.indent = 0; 715 ctx.base.dump_printf = &str_dump_ctx_printf; 716 ctx.base.indentation = 0; 717 718 ctx.str = str; 719 ctx.str[0] = 0; 720 ctx.ptr = str; 721 ctx.left = (int)size; 722 723 tgsi_iterate_shader( tokens, &ctx.base.iter ); 724} 725 726void 727tgsi_dump_instruction_str( 728 const struct tgsi_full_instruction *inst, 729 uint instno, 730 char *str, 731 size_t size) 732{ 733 struct str_dump_ctx ctx; 734 735 ctx.base.instno = instno; 736 ctx.base.immno = instno; 737 ctx.base.indent = 0; 738 ctx.base.dump_printf = &str_dump_ctx_printf; 739 ctx.base.indentation = 0; 740 741 ctx.str = str; 742 ctx.str[0] = 0; 743 ctx.ptr = str; 744 ctx.left = (int)size; 745 746 iter_instruction( &ctx.base.iter, (struct tgsi_full_instruction *)inst ); 747} 748