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