tgsi_dump.c revision c208a2c791fa24c7c5887fc496738cbddbfafc72
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 32struct dump_ctx 33{ 34 struct tgsi_iterate_context iter; 35 36 uint instno; 37}; 38 39static void 40dump_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 60static const char *processor_type_names[] = 61{ 62 "FRAG", 63 "VERT", 64 "GEOM" 65}; 66 67static const char *file_names[] = 68{ 69 "NULL", 70 "CONST", 71 "IN", 72 "OUT", 73 "TEMP", 74 "SAMP", 75 "ADDR", 76 "IMM" 77}; 78 79static const char *interpolate_names[] = 80{ 81 "CONSTANT", 82 "LINEAR", 83 "PERSPECTIVE" 84}; 85 86static const char *semantic_names[] = 87{ 88 "POSITION", 89 "COLOR", 90 "BCOLOR", 91 "FOG", 92 "PSIZE", 93 "GENERIC", 94 "NORMAL" 95}; 96 97static const char *immediate_type_names[] = 98{ 99 "FLT32" 100}; 101 102static 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 225static const char *swizzle_names[] = 226{ 227 "x", 228 "y", 229 "z", 230 "w" 231}; 232 233static 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 246static const char *extswizzle_names[] = 247{ 248 "x", 249 "y", 250 "z", 251 "w", 252 "0", 253 "1" 254}; 255 256static const char *modulate_names[TGSI_MODULATE_COUNT] = 257{ 258 "", 259 "_2X", 260 "_4X", 261 "_8X", 262 "_D2", 263 "_D4", 264 "_D8" 265}; 266 267static void 268_dump_register_prefix( 269 uint file, 270 uint first, 271 uint last ) 272{ 273 274 275} 276 277static 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 293static 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 314static 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 331void 332tgsi_dump_declaration( 333 const struct tgsi_full_declaration *decl ) 334{ 335 TXT( "\nDCL " ); 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 359static boolean 360iter_declaration( 361 struct tgsi_iterate_context *iter, 362 struct tgsi_full_declaration *decl ) 363{ 364 tgsi_dump_declaration( decl ); 365 return TRUE; 366} 367 368void 369tgsi_dump_immediate( 370 const struct tgsi_full_immediate *imm ) 371{ 372 uint i; 373 374 TXT( "\nIMM " ); 375 ENM( imm->Immediate.DataType, immediate_type_names ); 376 377 TXT( " { " ); 378 for (i = 0; i < imm->Immediate.Size - 1; i++) { 379 switch (imm->Immediate.DataType) { 380 case TGSI_IMM_FLOAT32: 381 FLT( imm->u.ImmediateFloat32[i].Float ); 382 break; 383 default: 384 assert( 0 ); 385 } 386 387 if (i < imm->Immediate.Size - 2) 388 TXT( ", " ); 389 } 390 TXT( " }" ); 391} 392 393static boolean 394iter_immediate( 395 struct tgsi_iterate_context *iter, 396 struct tgsi_full_immediate *imm ) 397{ 398 tgsi_dump_immediate( imm ); 399 return TRUE; 400} 401 402void 403tgsi_dump_instruction( 404 const struct tgsi_full_instruction *inst, 405 uint instno ) 406{ 407 uint i; 408 boolean first_reg = TRUE; 409 410 EOL(); 411 UID( instno ); 412 CHR( ':' ); 413 ENM( inst->Instruction.Opcode, opcode_names ); 414 415 switch (inst->Instruction.Saturate) { 416 case TGSI_SAT_NONE: 417 break; 418 case TGSI_SAT_ZERO_ONE: 419 TXT( "_SAT" ); 420 break; 421 case TGSI_SAT_MINUS_PLUS_ONE: 422 TXT( "_SATNV" ); 423 break; 424 default: 425 assert( 0 ); 426 } 427 428 for (i = 0; i < inst->Instruction.NumDstRegs; i++) { 429 const struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; 430 431 if (!first_reg) 432 CHR( ',' ); 433 CHR( ' ' ); 434 435 _dump_register( 436 dst->DstRegister.File, 437 dst->DstRegister.Index, 438 dst->DstRegister.Index ); 439 ENM( dst->DstRegisterExtModulate.Modulate, modulate_names ); 440 _dump_writemask( dst->DstRegister.WriteMask ); 441 442 first_reg = FALSE; 443 } 444 445 for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { 446 const struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; 447 448 if (!first_reg) 449 CHR( ',' ); 450 CHR( ' ' ); 451 452 if (src->SrcRegisterExtMod.Negate) 453 TXT( "-(" ); 454 if (src->SrcRegisterExtMod.Absolute) 455 CHR( '|' ); 456 if (src->SrcRegisterExtMod.Scale2X) 457 TXT( "2*(" ); 458 if (src->SrcRegisterExtMod.Bias) 459 CHR( '(' ); 460 if (src->SrcRegisterExtMod.Complement) 461 TXT( "1-(" ); 462 if (src->SrcRegister.Negate) 463 CHR( '-' ); 464 465 if (src->SrcRegister.Indirect) { 466 _dump_register_ind( 467 src->SrcRegister.File, 468 src->SrcRegister.Index, 469 src->SrcRegisterInd.File, 470 src->SrcRegisterInd.Index ); 471 } 472 else { 473 _dump_register( 474 src->SrcRegister.File, 475 src->SrcRegister.Index, 476 src->SrcRegister.Index ); 477 } 478 479 if (src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X || 480 src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y || 481 src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z || 482 src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W) { 483 CHR( '.' ); 484 ENM( src->SrcRegister.SwizzleX, swizzle_names ); 485 ENM( src->SrcRegister.SwizzleY, swizzle_names ); 486 ENM( src->SrcRegister.SwizzleZ, swizzle_names ); 487 ENM( src->SrcRegister.SwizzleW, swizzle_names ); 488 } 489 if (src->SrcRegisterExtSwz.ExtSwizzleX != TGSI_EXTSWIZZLE_X || 490 src->SrcRegisterExtSwz.ExtSwizzleY != TGSI_EXTSWIZZLE_Y || 491 src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z || 492 src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W) { 493 CHR( '.' ); 494 if (src->SrcRegisterExtSwz.NegateX) 495 TXT("-"); 496 ENM( src->SrcRegisterExtSwz.ExtSwizzleX, extswizzle_names ); 497 if (src->SrcRegisterExtSwz.NegateY) 498 TXT("-"); 499 ENM( src->SrcRegisterExtSwz.ExtSwizzleY, extswizzle_names ); 500 if (src->SrcRegisterExtSwz.NegateZ) 501 TXT("-"); 502 ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, extswizzle_names ); 503 if (src->SrcRegisterExtSwz.NegateW) 504 TXT("-"); 505 ENM( src->SrcRegisterExtSwz.ExtSwizzleW, extswizzle_names ); 506 } 507 508 if (src->SrcRegisterExtMod.Complement) 509 CHR( ')' ); 510 if (src->SrcRegisterExtMod.Bias) 511 TXT( ")-.5" ); 512 if (src->SrcRegisterExtMod.Scale2X) 513 CHR( ')' ); 514 if (src->SrcRegisterExtMod.Absolute) 515 CHR( '|' ); 516 if (src->SrcRegisterExtMod.Negate) 517 CHR( ')' ); 518 519 first_reg = FALSE; 520 } 521 522 if (inst->InstructionExtTexture.Texture != TGSI_TEXTURE_UNKNOWN) { 523 TXT( ", " ); 524 ENM( inst->InstructionExtTexture.Texture, texture_names ); 525 } 526 527 switch (inst->Instruction.Opcode) { 528 case TGSI_OPCODE_IF: 529 case TGSI_OPCODE_ELSE: 530 case TGSI_OPCODE_BGNLOOP2: 531 case TGSI_OPCODE_ENDLOOP2: 532 case TGSI_OPCODE_CAL: 533 TXT( " :" ); 534 UID( inst->InstructionExtLabel.Label ); 535 break; 536 } 537} 538 539static boolean 540iter_instruction( 541 struct tgsi_iterate_context *iter, 542 struct tgsi_full_instruction *inst ) 543{ 544 struct dump_ctx *ctx = (struct dump_ctx *) iter; 545 546 tgsi_dump_instruction( inst, ctx->instno++ ); 547 return TRUE; 548} 549 550static boolean 551prolog( 552 struct tgsi_iterate_context *ctx ) 553{ 554 EOL(); 555 ENM( ctx->processor.Processor, processor_type_names ); 556 UID( ctx->version.MajorVersion ); 557 CHR( '.' ); 558 UID( ctx->version.MinorVersion ); 559 return TRUE; 560} 561 562void 563tgsi_dump( 564 const struct tgsi_token *tokens, 565 uint flags ) 566{ 567 struct dump_ctx ctx; 568 569 /* sanity checks */ 570 assert( strcmp( opcode_names[TGSI_OPCODE_CONT], "CONT" ) == 0 ); 571 assert( strcmp( opcode_names[TGSI_OPCODE_END], "END" ) == 0 ); 572 573 ctx.iter.prolog = prolog; 574 ctx.iter.iterate_instruction = iter_instruction; 575 ctx.iter.iterate_declaration = iter_declaration; 576 ctx.iter.iterate_immediate = iter_immediate; 577 ctx.iter.epilog = NULL; 578 579 ctx.instno = 0; 580 581 tgsi_iterate_shader( tokens, &ctx.iter ); 582} 583