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