blob: 47fd1dd590eb71b95f77756fdff480b60660ce21 [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_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 );
}