tgsi: Insert newlines after the statements, instead of before.
[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 "pipe/p_debug.h"
29 #include "tgsi_dump.h"
30 #include "tgsi_iterate.h"
31
32 struct dump_ctx
33 {
34 struct tgsi_iterate_context iter;
35
36 uint instno;
37 };
38
39 static void
40 dump_enum(
41 uint e,
42 const char **enums,
43 uint enum_count )
44 {
45 if (e >= enum_count)
46 debug_printf( "%u", e );
47 else
48 debug_printf( "%s", enums[e] );
49 }
50
51 #define EOL() debug_printf( "\n" )
52 #define TXT(S) debug_printf( "%s", S )
53 #define CHR(C) debug_printf( "%c", C )
54 #define UIX(I) debug_printf( "0x%x", I )
55 #define UID(I) debug_printf( "%u", I )
56 #define SID(I) debug_printf( "%d", I )
57 #define FLT(F) debug_printf( "%10.4f", F )
58 #define ENM(E,ENUMS) dump_enum( E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) )
59
60 static const char *processor_type_names[] =
61 {
62 "FRAG",
63 "VERT",
64 "GEOM"
65 };
66
67 static const char *file_names[] =
68 {
69 "NULL",
70 "CONST",
71 "IN",
72 "OUT",
73 "TEMP",
74 "SAMP",
75 "ADDR",
76 "IMM"
77 };
78
79 static const char *interpolate_names[] =
80 {
81 "CONSTANT",
82 "LINEAR",
83 "PERSPECTIVE"
84 };
85
86 static const char *semantic_names[] =
87 {
88 "POSITION",
89 "COLOR",
90 "BCOLOR",
91 "FOG",
92 "PSIZE",
93 "GENERIC",
94 "NORMAL"
95 };
96
97 static const char *immediate_type_names[] =
98 {
99 "FLT32"
100 };
101
102 static const char *opcode_names[TGSI_OPCODE_LAST] =
103 {
104 "ARL",
105 "MOV",
106 "LIT",
107 "RCP",
108 "RSQ",
109 "EXP",
110 "LOG",
111 "MUL",
112 "ADD",
113 "DP3",
114 "DP4",
115 "DST",
116 "MIN",
117 "MAX",
118 "SLT",
119 "SGE",
120 "MAD",
121 "SUB",
122 "LERP",
123 "CND",
124 "CND0",
125 "DOT2ADD",
126 "INDEX",
127 "NEGATE",
128 "FRAC",
129 "CLAMP",
130 "FLOOR",
131 "ROUND",
132 "EXPBASE2",
133 "LOGBASE2",
134 "POWER",
135 "CROSSPRODUCT",
136 "MULTIPLYMATRIX",
137 "ABS",
138 "RCC",
139 "DPH",
140 "COS",
141 "DDX",
142 "DDY",
143 "KILP",
144 "PK2H",
145 "PK2US",
146 "PK4B",
147 "PK4UB",
148 "RFL",
149 "SEQ",
150 "SFL",
151 "SGT",
152 "SIN",
153 "SLE",
154 "SNE",
155 "STR",
156 "TEX",
157 "TXD",
158 "TXP",
159 "UP2H",
160 "UP2US",
161 "UP4B",
162 "UP4UB",
163 "X2D",
164 "ARA",
165 "ARR",
166 "BRA",
167 "CAL",
168 "RET",
169 "SSG",
170 "CMP",
171 "SCS",
172 "TXB",
173 "NRM",
174 "DIV",
175 "DP2",
176 "TXL",
177 "BRK",
178 "IF",
179 "LOOP",
180 "REP",
181 "ELSE",
182 "ENDIF",
183 "ENDLOOP",
184 "ENDREP",
185 "PUSHA",
186 "POPA",
187 "CEIL",
188 "I2F",
189 "NOT",
190 "TRUNC",
191 "SHL",
192 "SHR",
193 "AND",
194 "OR",
195 "MOD",
196 "XOR",
197 "SAD",
198 "TXF",
199 "TXQ",
200 "CONT",
201 "EMIT",
202 "ENDPRIM",
203 "BGNLOOP2",
204 "BGNSUB",
205 "ENDLOOP2",
206 "ENDSUB",
207 "NOISE1",
208 "NOISE2",
209 "NOISE3",
210 "NOISE4",
211 "NOP",
212 "M4X3",
213 "M3X4",
214 "M3X3",
215 "M3X2",
216 "NRM4",
217 "CALLNZ",
218 "IFC",
219 "BREAKC",
220 "KIL",
221 "END",
222 "SWZ"
223 };
224
225 static const char *swizzle_names[] =
226 {
227 "x",
228 "y",
229 "z",
230 "w"
231 };
232
233 static const char *texture_names[] =
234 {
235 "UNKNOWN",
236 "1D",
237 "2D",
238 "3D",
239 "CUBE",
240 "RECT",
241 "SHADOW1D",
242 "SHADOW2D",
243 "SHADOWRECT"
244 };
245
246 static const char *extswizzle_names[] =
247 {
248 "x",
249 "y",
250 "z",
251 "w",
252 "0",
253 "1"
254 };
255
256 static const char *modulate_names[TGSI_MODULATE_COUNT] =
257 {
258 "",
259 "_2X",
260 "_4X",
261 "_8X",
262 "_D2",
263 "_D4",
264 "_D8"
265 };
266
267 static void
268 _dump_register_prefix(
269 uint file,
270 uint first,
271 uint last )
272 {
273
274
275 }
276
277 static void
278 _dump_register(
279 uint file,
280 int first,
281 int last )
282 {
283 ENM( file, file_names );
284 CHR( '[' );
285 SID( first );
286 if (first != last) {
287 TXT( ".." );
288 SID( last );
289 }
290 CHR( ']' );
291 }
292
293 static void
294 _dump_register_ind(
295 uint file,
296 int index,
297 uint ind_file,
298 int ind_index )
299 {
300 ENM( file, file_names );
301 CHR( '[' );
302 ENM( ind_file, file_names );
303 CHR( '[' );
304 SID( ind_index );
305 CHR( ']' );
306 if (index != 0) {
307 if (index > 0)
308 CHR( '+' );
309 SID( index );
310 }
311 CHR( ']' );
312 }
313
314 static void
315 _dump_writemask(
316 uint writemask )
317 {
318 if (writemask != TGSI_WRITEMASK_XYZW) {
319 CHR( '.' );
320 if (writemask & TGSI_WRITEMASK_X)
321 CHR( 'x' );
322 if (writemask & TGSI_WRITEMASK_Y)
323 CHR( 'y' );
324 if (writemask & TGSI_WRITEMASK_Z)
325 CHR( 'z' );
326 if (writemask & TGSI_WRITEMASK_W)
327 CHR( 'w' );
328 }
329 }
330
331 void
332 tgsi_dump_declaration(
333 const struct tgsi_full_declaration *decl )
334 {
335 TXT( "DCL " );
336
337 _dump_register(
338 decl->Declaration.File,
339 decl->DeclarationRange.First,
340 decl->DeclarationRange.Last );
341 _dump_writemask(
342 decl->Declaration.UsageMask );
343
344 if (decl->Declaration.Semantic) {
345 TXT( ", " );
346 ENM( decl->Semantic.SemanticName, semantic_names );
347 if (decl->Semantic.SemanticIndex != 0 ||
348 decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC) {
349 CHR( '[' );
350 UID( decl->Semantic.SemanticIndex );
351 CHR( ']' );
352 }
353 }
354
355 TXT( ", " );
356 ENM( decl->Declaration.Interpolate, interpolate_names );
357
358 EOL();
359 }
360
361 static boolean
362 iter_declaration(
363 struct tgsi_iterate_context *iter,
364 struct tgsi_full_declaration *decl )
365 {
366 tgsi_dump_declaration( decl );
367 return TRUE;
368 }
369
370 void
371 tgsi_dump_immediate(
372 const struct tgsi_full_immediate *imm )
373 {
374 uint i;
375
376 TXT( "\nIMM " );
377 ENM( imm->Immediate.DataType, immediate_type_names );
378
379 TXT( " { " );
380 for (i = 0; i < imm->Immediate.Size - 1; i++) {
381 switch (imm->Immediate.DataType) {
382 case TGSI_IMM_FLOAT32:
383 FLT( imm->u.ImmediateFloat32[i].Float );
384 break;
385 default:
386 assert( 0 );
387 }
388
389 if (i < imm->Immediate.Size - 2)
390 TXT( ", " );
391 }
392 TXT( " }" );
393 }
394
395 static boolean
396 iter_immediate(
397 struct tgsi_iterate_context *iter,
398 struct tgsi_full_immediate *imm )
399 {
400 tgsi_dump_immediate( imm );
401 return TRUE;
402 }
403
404 void
405 tgsi_dump_instruction(
406 const struct tgsi_full_instruction *inst,
407 uint instno )
408 {
409 uint i;
410 boolean first_reg = TRUE;
411
412 UID( instno );
413 CHR( ':' );
414 ENM( inst->Instruction.Opcode, opcode_names );
415
416 switch (inst->Instruction.Saturate) {
417 case TGSI_SAT_NONE:
418 break;
419 case TGSI_SAT_ZERO_ONE:
420 TXT( "_SAT" );
421 break;
422 case TGSI_SAT_MINUS_PLUS_ONE:
423 TXT( "_SATNV" );
424 break;
425 default:
426 assert( 0 );
427 }
428
429 for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
430 const struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
431
432 if (!first_reg)
433 CHR( ',' );
434 CHR( ' ' );
435
436 _dump_register(
437 dst->DstRegister.File,
438 dst->DstRegister.Index,
439 dst->DstRegister.Index );
440 ENM( dst->DstRegisterExtModulate.Modulate, modulate_names );
441 _dump_writemask( dst->DstRegister.WriteMask );
442
443 first_reg = FALSE;
444 }
445
446 for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
447 const struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i];
448
449 if (!first_reg)
450 CHR( ',' );
451 CHR( ' ' );
452
453 if (src->SrcRegisterExtMod.Negate)
454 TXT( "-(" );
455 if (src->SrcRegisterExtMod.Absolute)
456 CHR( '|' );
457 if (src->SrcRegisterExtMod.Scale2X)
458 TXT( "2*(" );
459 if (src->SrcRegisterExtMod.Bias)
460 CHR( '(' );
461 if (src->SrcRegisterExtMod.Complement)
462 TXT( "1-(" );
463 if (src->SrcRegister.Negate)
464 CHR( '-' );
465
466 if (src->SrcRegister.Indirect) {
467 _dump_register_ind(
468 src->SrcRegister.File,
469 src->SrcRegister.Index,
470 src->SrcRegisterInd.File,
471 src->SrcRegisterInd.Index );
472 }
473 else {
474 _dump_register(
475 src->SrcRegister.File,
476 src->SrcRegister.Index,
477 src->SrcRegister.Index );
478 }
479
480 if (src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X ||
481 src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y ||
482 src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z ||
483 src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W) {
484 CHR( '.' );
485 ENM( src->SrcRegister.SwizzleX, swizzle_names );
486 ENM( src->SrcRegister.SwizzleY, swizzle_names );
487 ENM( src->SrcRegister.SwizzleZ, swizzle_names );
488 ENM( src->SrcRegister.SwizzleW, swizzle_names );
489 }
490 if (src->SrcRegisterExtSwz.ExtSwizzleX != TGSI_EXTSWIZZLE_X ||
491 src->SrcRegisterExtSwz.ExtSwizzleY != TGSI_EXTSWIZZLE_Y ||
492 src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z ||
493 src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W) {
494 CHR( '.' );
495 if (src->SrcRegisterExtSwz.NegateX)
496 TXT("-");
497 ENM( src->SrcRegisterExtSwz.ExtSwizzleX, extswizzle_names );
498 if (src->SrcRegisterExtSwz.NegateY)
499 TXT("-");
500 ENM( src->SrcRegisterExtSwz.ExtSwizzleY, extswizzle_names );
501 if (src->SrcRegisterExtSwz.NegateZ)
502 TXT("-");
503 ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, extswizzle_names );
504 if (src->SrcRegisterExtSwz.NegateW)
505 TXT("-");
506 ENM( src->SrcRegisterExtSwz.ExtSwizzleW, extswizzle_names );
507 }
508
509 if (src->SrcRegisterExtMod.Complement)
510 CHR( ')' );
511 if (src->SrcRegisterExtMod.Bias)
512 TXT( ")-.5" );
513 if (src->SrcRegisterExtMod.Scale2X)
514 CHR( ')' );
515 if (src->SrcRegisterExtMod.Absolute)
516 CHR( '|' );
517 if (src->SrcRegisterExtMod.Negate)
518 CHR( ')' );
519
520 first_reg = FALSE;
521 }
522
523 if (inst->InstructionExtTexture.Texture != TGSI_TEXTURE_UNKNOWN) {
524 TXT( ", " );
525 ENM( inst->InstructionExtTexture.Texture, texture_names );
526 }
527
528 switch (inst->Instruction.Opcode) {
529 case TGSI_OPCODE_IF:
530 case TGSI_OPCODE_ELSE:
531 case TGSI_OPCODE_BGNLOOP2:
532 case TGSI_OPCODE_ENDLOOP2:
533 case TGSI_OPCODE_CAL:
534 TXT( " :" );
535 UID( inst->InstructionExtLabel.Label );
536 break;
537 }
538
539 EOL();
540 }
541
542 static boolean
543 iter_instruction(
544 struct tgsi_iterate_context *iter,
545 struct tgsi_full_instruction *inst )
546 {
547 struct dump_ctx *ctx = (struct dump_ctx *) iter;
548
549 tgsi_dump_instruction( inst, ctx->instno++ );
550 return TRUE;
551 }
552
553 static boolean
554 prolog(
555 struct tgsi_iterate_context *ctx )
556 {
557 ENM( ctx->processor.Processor, processor_type_names );
558 UID( ctx->version.MajorVersion );
559 CHR( '.' );
560 UID( ctx->version.MinorVersion );
561 EOL();
562 return TRUE;
563 }
564
565 void
566 tgsi_dump(
567 const struct tgsi_token *tokens,
568 uint flags )
569 {
570 struct dump_ctx ctx;
571
572 /* sanity checks */
573 assert( strcmp( opcode_names[TGSI_OPCODE_CONT], "CONT" ) == 0 );
574 assert( strcmp( opcode_names[TGSI_OPCODE_END], "END" ) == 0 );
575
576 ctx.iter.prolog = prolog;
577 ctx.iter.iterate_instruction = iter_instruction;
578 ctx.iter.iterate_declaration = iter_declaration;
579 ctx.iter.iterate_immediate = iter_immediate;
580 ctx.iter.epilog = NULL;
581
582 ctx.instno = 0;
583
584 tgsi_iterate_shader( tokens, &ctx.iter );
585 }