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