| /************************************************************************** |
| * |
| * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
| * All Rights Reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the |
| * "Software"), to deal in the Software without restriction, including |
| * without limitation the rights to use, copy, modify, merge, publish, |
| * distribute, sub license, and/or sell copies of the Software, and to |
| * permit persons to whom the Software is furnished to do so, subject to |
| * the following conditions: |
| * |
| * The above copyright notice and this permission notice (including the |
| * next paragraph) shall be included in all copies or substantial portions |
| * of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
| * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR |
| * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| * |
| **************************************************************************/ |
| |
| #include "util/u_debug.h" |
| #include "util/u_string.h" |
| #include "tgsi_dump_c.h" |
| #include "tgsi_build.h" |
| #include "tgsi_info.h" |
| #include "tgsi_parse.h" |
| |
| static void |
| dump_enum( |
| const unsigned e, |
| const char **enums, |
| const unsigned enums_count ) |
| { |
| if (e >= enums_count) { |
| debug_printf( "%u", e ); |
| } |
| else { |
| debug_printf( "%s", enums[e] ); |
| } |
| } |
| |
| #define EOL() debug_printf( "\n" ) |
| #define TXT(S) debug_printf( "%s", S ) |
| #define CHR(C) debug_printf( "%c", C ) |
| #define UIX(I) debug_printf( "0x%x", I ) |
| #define UID(I) debug_printf( "%u", I ) |
| #define SID(I) debug_printf( "%d", I ) |
| #define FLT(F) debug_printf( "%10.4f", F ) |
| #define ENM(E,ENUMS) dump_enum( E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) |
| |
| static const char *TGSI_PROCESSOR_TYPES[] = |
| { |
| "PROCESSOR_FRAGMENT", |
| "PROCESSOR_VERTEX", |
| "PROCESSOR_GEOMETRY" |
| }; |
| |
| static const char *TGSI_TOKEN_TYPES[] = |
| { |
| "TOKEN_TYPE_DECLARATION", |
| "TOKEN_TYPE_IMMEDIATE", |
| "TOKEN_TYPE_INSTRUCTION" |
| }; |
| |
| static const char *TGSI_FILES[TGSI_FILE_COUNT] = |
| { |
| "FILE_NULL", |
| "FILE_CONSTANT", |
| "FILE_INPUT", |
| "FILE_OUTPUT", |
| "FILE_TEMPORARY", |
| "FILE_SAMPLER", |
| "FILE_ADDRESS", |
| "FILE_IMMEDIATE", |
| "FILE_LOOP", |
| "FILE_PREDICATE" |
| }; |
| |
| static const char *TGSI_INTERPOLATES[] = |
| { |
| "INTERPOLATE_CONSTANT", |
| "INTERPOLATE_LINEAR", |
| "INTERPOLATE_PERSPECTIVE" |
| }; |
| |
| static const char *TGSI_SEMANTICS[] = |
| { |
| "SEMANTIC_POSITION", |
| "SEMANTIC_COLOR", |
| "SEMANTIC_BCOLOR", |
| "SEMANTIC_FOG", |
| "SEMANTIC_PSIZE", |
| "SEMANTIC_GENERIC", |
| "SEMANTIC_NORMAL" |
| }; |
| |
| static const char *TGSI_IMMS[] = |
| { |
| "IMM_FLOAT32" |
| }; |
| |
| static const char *TGSI_SATS[] = |
| { |
| "SAT_NONE", |
| "SAT_ZERO_ONE", |
| "SAT_MINUS_PLUS_ONE" |
| }; |
| |
| static const char *TGSI_SWIZZLES[] = |
| { |
| "SWIZZLE_X", |
| "SWIZZLE_Y", |
| "SWIZZLE_Z", |
| "SWIZZLE_W" |
| }; |
| |
| static const char *TGSI_TEXTURES[] = |
| { |
| "TEXTURE_UNKNOWN", |
| "TEXTURE_1D", |
| "TEXTURE_2D", |
| "TEXTURE_3D", |
| "TEXTURE_CUBE", |
| "TEXTURE_RECT", |
| "TEXTURE_SHADOW1D", |
| "TEXTURE_SHADOW2D", |
| "TEXTURE_SHADOWRECT" |
| }; |
| |
| static const char *TGSI_WRITEMASKS[] = |
| { |
| "0", |
| "WRITEMASK_X", |
| "WRITEMASK_Y", |
| "WRITEMASK_XY", |
| "WRITEMASK_Z", |
| "WRITEMASK_XZ", |
| "WRITEMASK_YZ", |
| "WRITEMASK_XYZ", |
| "WRITEMASK_W", |
| "WRITEMASK_XW", |
| "WRITEMASK_YW", |
| "WRITEMASK_XYW", |
| "WRITEMASK_ZW", |
| "WRITEMASK_XZW", |
| "WRITEMASK_YZW", |
| "WRITEMASK_XYZW" |
| }; |
| |
| static void |
| dump_declaration_verbose( |
| struct tgsi_full_declaration *decl, |
| unsigned ignored, |
| unsigned deflt, |
| struct tgsi_full_declaration *fd ) |
| { |
| TXT( "\nFile : " ); |
| ENM( decl->Declaration.File, TGSI_FILES ); |
| if( deflt || fd->Declaration.UsageMask != decl->Declaration.UsageMask ) { |
| TXT( "\nUsageMask : " ); |
| if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) { |
| CHR( 'X' ); |
| } |
| if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) { |
| CHR( 'Y' ); |
| } |
| if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) { |
| CHR( 'Z' ); |
| } |
| if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) { |
| CHR( 'W' ); |
| } |
| } |
| if( deflt || fd->Declaration.Interpolate != decl->Declaration.Interpolate ) { |
| TXT( "\nInterpolate: " ); |
| ENM( decl->Declaration.Interpolate, TGSI_INTERPOLATES ); |
| } |
| if( deflt || fd->Declaration.Semantic != decl->Declaration.Semantic ) { |
| TXT( "\nSemantic : " ); |
| UID( decl->Declaration.Semantic ); |
| } |
| if (deflt || fd->Declaration.Centroid != decl->Declaration.Centroid) { |
| TXT("\nCentroid : "); |
| UID(decl->Declaration.Centroid); |
| } |
| if (deflt || fd->Declaration.Invariant != decl->Declaration.Invariant) { |
| TXT("\nInvariant : "); |
| UID(decl->Declaration.Invariant); |
| } |
| if( ignored ) { |
| TXT( "\nPadding : " ); |
| UIX( decl->Declaration.Padding ); |
| } |
| |
| EOL(); |
| TXT( "\nFirst: " ); |
| UID( decl->Range.First ); |
| TXT( "\nLast : " ); |
| UID( decl->Range.Last ); |
| |
| if( decl->Declaration.Semantic ) { |
| EOL(); |
| TXT( "\nName : " ); |
| ENM( decl->Semantic.Name, TGSI_SEMANTICS ); |
| TXT( "\nIndex: " ); |
| UID( decl->Semantic.Index ); |
| if( ignored ) { |
| TXT( "\nPadding : " ); |
| UIX( decl->Semantic.Padding ); |
| } |
| } |
| } |
| |
| static void |
| dump_immediate_verbose( |
| struct tgsi_full_immediate *imm, |
| unsigned ignored ) |
| { |
| unsigned i; |
| |
| TXT( "\nDataType : " ); |
| ENM( imm->Immediate.DataType, TGSI_IMMS ); |
| if( ignored ) { |
| TXT( "\nPadding : " ); |
| UIX( imm->Immediate.Padding ); |
| } |
| |
| assert( imm->Immediate.NrTokens <= 4 + 1 ); |
| for( i = 0; i < imm->Immediate.NrTokens - 1; i++ ) { |
| EOL(); |
| switch( imm->Immediate.DataType ) { |
| case TGSI_IMM_FLOAT32: |
| TXT( "\nFloat: " ); |
| FLT( imm->u[i].Float ); |
| break; |
| |
| default: |
| assert( 0 ); |
| } |
| } |
| } |
| |
| static void |
| dump_instruction_verbose( |
| struct tgsi_full_instruction *inst, |
| unsigned ignored, |
| unsigned deflt, |
| struct tgsi_full_instruction *fi ) |
| { |
| unsigned i; |
| |
| TXT( "\nOpcode : OPCODE_" ); |
| TXT( tgsi_get_opcode_info( inst->Instruction.Opcode )->mnemonic ); |
| if( deflt || fi->Instruction.Saturate != inst->Instruction.Saturate ) { |
| TXT( "\nSaturate : " ); |
| ENM( inst->Instruction.Saturate, TGSI_SATS ); |
| } |
| if( deflt || fi->Instruction.NumDstRegs != inst->Instruction.NumDstRegs ) { |
| TXT( "\nNumDstRegs : " ); |
| UID( inst->Instruction.NumDstRegs ); |
| } |
| if( deflt || fi->Instruction.NumSrcRegs != inst->Instruction.NumSrcRegs ) { |
| TXT( "\nNumSrcRegs : " ); |
| UID( inst->Instruction.NumSrcRegs ); |
| } |
| if (deflt || fi->Instruction.Predicate != inst->Instruction.Predicate) { |
| TXT("\nPredicate : "); |
| UID(inst->Instruction.Predicate); |
| } |
| if (deflt || fi->Instruction.Label != inst->Instruction.Label) { |
| TXT("\nLabel : "); |
| UID(inst->Instruction.Label); |
| } |
| if (deflt || fi->Instruction.Texture != inst->Instruction.Texture) { |
| TXT("\nTexture : "); |
| UID(inst->Instruction.Texture); |
| } |
| if( ignored ) { |
| TXT( "\nPadding : " ); |
| UIX( inst->Instruction.Padding ); |
| } |
| |
| if (deflt || inst->Instruction.Label) { |
| EOL(); |
| if (deflt || fi->Label.Label != inst->Label.Label) { |
| TXT( "\nLabel : " ); |
| UID(inst->Label.Label); |
| } |
| if( ignored ) { |
| TXT( "\nPadding : " ); |
| UIX(inst->Label.Padding); |
| } |
| } |
| |
| if (deflt || inst->Instruction.Texture) { |
| EOL(); |
| if (deflt || fi->Texture.Texture != inst->Texture.Texture) { |
| TXT( "\nTexture : " ); |
| ENM(inst->Texture.Texture, TGSI_TEXTURES); |
| } |
| if( ignored ) { |
| TXT( "\nPadding : " ); |
| UIX(inst->Texture.Padding); |
| } |
| } |
| |
| for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { |
| struct tgsi_full_dst_register *dst = &inst->Dst[i]; |
| struct tgsi_full_dst_register *fd = &fi->Dst[i]; |
| |
| EOL(); |
| TXT( "\nFile : " ); |
| ENM( dst->Register.File, TGSI_FILES ); |
| if( deflt || fd->Register.WriteMask != dst->Register.WriteMask ) { |
| TXT( "\nWriteMask: " ); |
| ENM( dst->Register.WriteMask, TGSI_WRITEMASKS ); |
| } |
| if( ignored ) { |
| if( deflt || fd->Register.Indirect != dst->Register.Indirect ) { |
| TXT( "\nIndirect : " ); |
| UID( dst->Register.Indirect ); |
| } |
| if( deflt || fd->Register.Dimension != dst->Register.Dimension ) { |
| TXT( "\nDimension: " ); |
| UID( dst->Register.Dimension ); |
| } |
| } |
| if( deflt || fd->Register.Index != dst->Register.Index ) { |
| TXT( "\nIndex : " ); |
| SID( dst->Register.Index ); |
| } |
| if( ignored ) { |
| TXT( "\nPadding : " ); |
| UIX( dst->Register.Padding ); |
| } |
| } |
| |
| for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { |
| struct tgsi_full_src_register *src = &inst->Src[i]; |
| struct tgsi_full_src_register *fs = &fi->Src[i]; |
| |
| EOL(); |
| TXT( "\nFile : "); |
| ENM( src->Register.File, TGSI_FILES ); |
| if( deflt || fs->Register.SwizzleX != src->Register.SwizzleX ) { |
| TXT( "\nSwizzleX : " ); |
| ENM( src->Register.SwizzleX, TGSI_SWIZZLES ); |
| } |
| if( deflt || fs->Register.SwizzleY != src->Register.SwizzleY ) { |
| TXT( "\nSwizzleY : " ); |
| ENM( src->Register.SwizzleY, TGSI_SWIZZLES ); |
| } |
| if( deflt || fs->Register.SwizzleZ != src->Register.SwizzleZ ) { |
| TXT( "\nSwizzleZ : " ); |
| ENM( src->Register.SwizzleZ, TGSI_SWIZZLES ); |
| } |
| if( deflt || fs->Register.SwizzleW != src->Register.SwizzleW ) { |
| TXT( "\nSwizzleW : " ); |
| ENM( src->Register.SwizzleW, TGSI_SWIZZLES ); |
| } |
| if (deflt || fs->Register.Absolute != src->Register.Absolute) { |
| TXT("\nAbsolute : "); |
| UID(src->Register.Absolute); |
| } |
| if( deflt || fs->Register.Negate != src->Register.Negate ) { |
| TXT( "\nNegate : " ); |
| UID( src->Register.Negate ); |
| } |
| if( ignored ) { |
| if( deflt || fs->Register.Indirect != src->Register.Indirect ) { |
| TXT( "\nIndirect : " ); |
| UID( src->Register.Indirect ); |
| } |
| if( deflt || fs->Register.Dimension != src->Register.Dimension ) { |
| TXT( "\nDimension: " ); |
| UID( src->Register.Dimension ); |
| } |
| } |
| if( deflt || fs->Register.Index != src->Register.Index ) { |
| TXT( "\nIndex : " ); |
| SID( src->Register.Index ); |
| } |
| } |
| } |
| |
| void |
| tgsi_dump_c( |
| const struct tgsi_token *tokens, |
| uint flags ) |
| { |
| struct tgsi_parse_context parse; |
| struct tgsi_full_instruction fi; |
| struct tgsi_full_declaration fd; |
| uint ignored = flags & TGSI_DUMP_C_IGNORED; |
| uint deflt = flags & TGSI_DUMP_C_DEFAULT; |
| |
| tgsi_parse_init( &parse, tokens ); |
| |
| TXT( "tgsi-dump begin -----------------" ); |
| |
| TXT( "\nHeaderSize: " ); |
| UID( parse.FullHeader.Header.HeaderSize ); |
| TXT( "\nBodySize : " ); |
| UID( parse.FullHeader.Header.BodySize ); |
| TXT( "\nProcessor : " ); |
| ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES ); |
| EOL(); |
| |
| fi = tgsi_default_full_instruction(); |
| fd = tgsi_default_full_declaration(); |
| |
| while( !tgsi_parse_end_of_tokens( &parse ) ) { |
| tgsi_parse_token( &parse ); |
| |
| TXT( "\nType : " ); |
| ENM( parse.FullToken.Token.Type, TGSI_TOKEN_TYPES ); |
| if( ignored ) { |
| TXT( "\nSize : " ); |
| UID( parse.FullToken.Token.NrTokens ); |
| } |
| |
| switch( parse.FullToken.Token.Type ) { |
| case TGSI_TOKEN_TYPE_DECLARATION: |
| dump_declaration_verbose( |
| &parse.FullToken.FullDeclaration, |
| ignored, |
| deflt, |
| &fd ); |
| break; |
| |
| case TGSI_TOKEN_TYPE_IMMEDIATE: |
| dump_immediate_verbose( |
| &parse.FullToken.FullImmediate, |
| ignored ); |
| break; |
| |
| case TGSI_TOKEN_TYPE_INSTRUCTION: |
| dump_instruction_verbose( |
| &parse.FullToken.FullInstruction, |
| ignored, |
| deflt, |
| &fi ); |
| break; |
| |
| default: |
| assert( 0 ); |
| } |
| |
| EOL(); |
| } |
| |
| TXT( "\ntgsi-dump end -------------------\n" ); |
| |
| tgsi_parse_free( &parse ); |
| } |