blob: 4648051e29e5a1ea178bf272926f7e756b2c06a0 [file] [log] [blame]
/**************************************************************************
*
* 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_INSTRUCTION_EXTS[] =
{
"",
"INSTRUCTION_EXT_TYPE_LABEL",
"INSTRUCTION_EXT_TYPE_TEXTURE"
};
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_SRC_REGISTER_EXTS[] =
{
"",
"SRC_REGISTER_EXT_TYPE_MOD"
};
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 const char *TGSI_DST_REGISTER_EXTS[] =
{
"",
"DST_REGISTER_EXT_TYPE_MODULATE"
};
static const char *TGSI_MODULATES[] =
{
"MODULATE_1X",
"MODULATE_2X",
"MODULATE_4X",
"MODULATE_8X",
"MODULATE_HALF",
"MODULATE_QUARTER",
"MODULATE_EIGHTH"
};
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( ignored ) {
TXT( "\nPadding : " );
UIX( decl->Declaration.Padding );
}
EOL();
TXT( "\nFirst: " );
UID( decl->DeclarationRange.First );
TXT( "\nLast : " );
UID( decl->DeclarationRange.Last );
if( decl->Declaration.Semantic ) {
EOL();
TXT( "\nSemanticName : " );
ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS );
TXT( "\nSemanticIndex: " );
UID( decl->Semantic.SemanticIndex );
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( ignored ) {
TXT( "\nPadding : " );
UIX( inst->Instruction.Padding );
}
if( deflt || tgsi_compare_instruction_ext_label( inst->InstructionExtLabel, fi->InstructionExtLabel ) ) {
EOL();
TXT( "\nType : " );
ENM( inst->InstructionExtLabel.Type, TGSI_INSTRUCTION_EXTS );
if( deflt || fi->InstructionExtLabel.Label != inst->InstructionExtLabel.Label ) {
TXT( "\nLabel : " );
UID( inst->InstructionExtLabel.Label );
}
if( ignored ) {
TXT( "\nPadding : " );
UIX( inst->InstructionExtLabel.Padding );
if( deflt || fi->InstructionExtLabel.Extended != inst->InstructionExtLabel.Extended ) {
TXT( "\nExtended: " );
UID( inst->InstructionExtLabel.Extended );
}
}
}
if( deflt || tgsi_compare_instruction_ext_texture( inst->InstructionExtTexture, fi->InstructionExtTexture ) ) {
EOL();
TXT( "\nType : " );
ENM( inst->InstructionExtTexture.Type, TGSI_INSTRUCTION_EXTS );
if( deflt || fi->InstructionExtTexture.Texture != inst->InstructionExtTexture.Texture ) {
TXT( "\nTexture : " );
ENM( inst->InstructionExtTexture.Texture, TGSI_TEXTURES );
}
if( ignored ) {
TXT( "\nPadding : " );
UIX( inst->InstructionExtTexture.Padding );
if( deflt || fi->InstructionExtTexture.Extended != inst->InstructionExtTexture.Extended ) {
TXT( "\nExtended: " );
UID( inst->InstructionExtTexture.Extended );
}
}
}
for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) {
struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
struct tgsi_full_dst_register *fd = &fi->FullDstRegisters[i];
EOL();
TXT( "\nFile : " );
ENM( dst->DstRegister.File, TGSI_FILES );
if( deflt || fd->DstRegister.WriteMask != dst->DstRegister.WriteMask ) {
TXT( "\nWriteMask: " );
ENM( dst->DstRegister.WriteMask, TGSI_WRITEMASKS );
}
if( ignored ) {
if( deflt || fd->DstRegister.Indirect != dst->DstRegister.Indirect ) {
TXT( "\nIndirect : " );
UID( dst->DstRegister.Indirect );
}
if( deflt || fd->DstRegister.Dimension != dst->DstRegister.Dimension ) {
TXT( "\nDimension: " );
UID( dst->DstRegister.Dimension );
}
}
if( deflt || fd->DstRegister.Index != dst->DstRegister.Index ) {
TXT( "\nIndex : " );
SID( dst->DstRegister.Index );
}
if( ignored ) {
TXT( "\nPadding : " );
UIX( dst->DstRegister.Padding );
if( deflt || fd->DstRegister.Extended != dst->DstRegister.Extended ) {
TXT( "\nExtended : " );
UID( dst->DstRegister.Extended );
}
}
if( deflt || tgsi_compare_dst_register_ext_modulate( dst->DstRegisterExtModulate, fd->DstRegisterExtModulate ) ) {
EOL();
TXT( "\nType : " );
ENM( dst->DstRegisterExtModulate.Type, TGSI_DST_REGISTER_EXTS );
if( deflt || fd->DstRegisterExtModulate.Modulate != dst->DstRegisterExtModulate.Modulate ) {
TXT( "\nModulate: " );
ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES );
}
if( ignored ) {
TXT( "\nPadding : " );
UIX( dst->DstRegisterExtModulate.Padding );
if( deflt || fd->DstRegisterExtModulate.Extended != dst->DstRegisterExtModulate.Extended ) {
TXT( "\nExtended: " );
UID( dst->DstRegisterExtModulate.Extended );
}
}
}
}
for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) {
struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i];
struct tgsi_full_src_register *fs = &fi->FullSrcRegisters[i];
EOL();
TXT( "\nFile : ");
ENM( src->SrcRegister.File, TGSI_FILES );
if( deflt || fs->SrcRegister.SwizzleX != src->SrcRegister.SwizzleX ) {
TXT( "\nSwizzleX : " );
ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES );
}
if( deflt || fs->SrcRegister.SwizzleY != src->SrcRegister.SwizzleY ) {
TXT( "\nSwizzleY : " );
ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES );
}
if( deflt || fs->SrcRegister.SwizzleZ != src->SrcRegister.SwizzleZ ) {
TXT( "\nSwizzleZ : " );
ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES );
}
if( deflt || fs->SrcRegister.SwizzleW != src->SrcRegister.SwizzleW ) {
TXT( "\nSwizzleW : " );
ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES );
}
if( deflt || fs->SrcRegister.Negate != src->SrcRegister.Negate ) {
TXT( "\nNegate : " );
UID( src->SrcRegister.Negate );
}
if( ignored ) {
if( deflt || fs->SrcRegister.Indirect != src->SrcRegister.Indirect ) {
TXT( "\nIndirect : " );
UID( src->SrcRegister.Indirect );
}
if( deflt || fs->SrcRegister.Dimension != src->SrcRegister.Dimension ) {
TXT( "\nDimension: " );
UID( src->SrcRegister.Dimension );
}
}
if( deflt || fs->SrcRegister.Index != src->SrcRegister.Index ) {
TXT( "\nIndex : " );
SID( src->SrcRegister.Index );
}
if( ignored ) {
if( deflt || fs->SrcRegister.Extended != src->SrcRegister.Extended ) {
TXT( "\nExtended : " );
UID( src->SrcRegister.Extended );
}
}
if( deflt || tgsi_compare_src_register_ext_mod( src->SrcRegisterExtMod, fs->SrcRegisterExtMod ) ) {
EOL();
TXT( "\nType : " );
ENM( src->SrcRegisterExtMod.Type, TGSI_SRC_REGISTER_EXTS );
if( deflt || fs->SrcRegisterExtMod.Complement != src->SrcRegisterExtMod.Complement ) {
TXT( "\nComplement: " );
UID( src->SrcRegisterExtMod.Complement );
}
if( deflt || fs->SrcRegisterExtMod.Bias != src->SrcRegisterExtMod.Bias ) {
TXT( "\nBias : " );
UID( src->SrcRegisterExtMod.Bias );
}
if( deflt || fs->SrcRegisterExtMod.Scale2X != src->SrcRegisterExtMod.Scale2X ) {
TXT( "\nScale2X : " );
UID( src->SrcRegisterExtMod.Scale2X );
}
if( deflt || fs->SrcRegisterExtMod.Absolute != src->SrcRegisterExtMod.Absolute ) {
TXT( "\nAbsolute : " );
UID( src->SrcRegisterExtMod.Absolute );
}
if( deflt || fs->SrcRegisterExtMod.Negate != src->SrcRegisterExtMod.Negate ) {
TXT( "\nNegate : " );
UID( src->SrcRegisterExtMod.Negate );
}
if( ignored ) {
TXT( "\nPadding : " );
UIX( src->SrcRegisterExtMod.Padding );
if( deflt || fs->SrcRegisterExtMod.Extended != src->SrcRegisterExtMod.Extended ) {
TXT( "\nExtended : " );
UID( src->SrcRegisterExtMod.Extended );
}
}
}
}
}
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( "\nMajorVersion: " );
UID( parse.FullVersion.Version.MajorVersion );
TXT( "\nMinorVersion: " );
UID( parse.FullVersion.Version.MinorVersion );
EOL();
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 );
if( deflt || parse.FullToken.Token.Extended ) {
TXT( "\nExtended : " );
UID( parse.FullToken.Token.Extended );
}
}
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 );
}