14a49301eSmrg/************************************************************************** 24a49301eSmrg * 3af69d88dSmrg * Copyright 2007-2008 VMware, Inc. 44a49301eSmrg * All Rights Reserved. 54a49301eSmrg * 64a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a 74a49301eSmrg * copy of this software and associated documentation files (the 84a49301eSmrg * "Software"), to deal in the Software without restriction, including 94a49301eSmrg * without limitation the rights to use, copy, modify, merge, publish, 104a49301eSmrg * distribute, sub license, and/or sell copies of the Software, and to 114a49301eSmrg * permit persons to whom the Software is furnished to do so, subject to 124a49301eSmrg * the following conditions: 134a49301eSmrg * 144a49301eSmrg * The above copyright notice and this permission notice (including the 154a49301eSmrg * next paragraph) shall be included in all copies or substantial portions 164a49301eSmrg * of the Software. 174a49301eSmrg * 184a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 194a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 204a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21af69d88dSmrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 224a49301eSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 234a49301eSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 244a49301eSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 254a49301eSmrg * 264a49301eSmrg **************************************************************************/ 274a49301eSmrg 2801e04c3fSmrg#include <inttypes.h> 2901e04c3fSmrg 304a49301eSmrg#include "util/u_debug.h" 314a49301eSmrg#include "util/u_string.h" 324a49301eSmrg#include "util/u_math.h" 334a49301eSmrg#include "util/u_memory.h" 3401e04c3fSmrg#include "util/u_math.h" 354a49301eSmrg#include "tgsi_dump.h" 364a49301eSmrg#include "tgsi_info.h" 374a49301eSmrg#include "tgsi_iterate.h" 38af69d88dSmrg#include "tgsi_strings.h" 394a49301eSmrg 404a49301eSmrg 414a49301eSmrg/** Number of spaces to indent for IF/LOOP/etc */ 424a49301eSmrgstatic const int indent_spaces = 3; 434a49301eSmrg 444a49301eSmrg 454a49301eSmrgstruct dump_ctx 464a49301eSmrg{ 474a49301eSmrg struct tgsi_iterate_context iter; 484a49301eSmrg 4901e04c3fSmrg boolean dump_float_as_hex; 5001e04c3fSmrg 514a49301eSmrg uint instno; 52af69d88dSmrg uint immno; 534a49301eSmrg int indent; 544a49301eSmrg 554a49301eSmrg uint indentation; 5601e04c3fSmrg FILE *file; 574a49301eSmrg 58af69d88dSmrg void (*dump_printf)(struct dump_ctx *ctx, const char *format, ...); 594a49301eSmrg}; 604a49301eSmrg 614a49301eSmrgstatic void 624a49301eSmrgdump_ctx_printf(struct dump_ctx *ctx, const char *format, ...) 634a49301eSmrg{ 644a49301eSmrg va_list ap; 654a49301eSmrg (void)ctx; 664a49301eSmrg va_start(ap, format); 6701e04c3fSmrg if (ctx->file) 6801e04c3fSmrg vfprintf(ctx->file, format, ap); 6901e04c3fSmrg else 7001e04c3fSmrg _debug_vprintf(format, ap); 714a49301eSmrg va_end(ap); 724a49301eSmrg} 734a49301eSmrg 744a49301eSmrgstatic void 754a49301eSmrgdump_enum( 764a49301eSmrg struct dump_ctx *ctx, 774a49301eSmrg uint e, 784a49301eSmrg const char **enums, 794a49301eSmrg uint enum_count ) 804a49301eSmrg{ 814a49301eSmrg if (e >= enum_count) 82af69d88dSmrg ctx->dump_printf( ctx, "%u", e ); 834a49301eSmrg else 84af69d88dSmrg ctx->dump_printf( ctx, "%s", enums[e] ); 854a49301eSmrg} 864a49301eSmrg 87af69d88dSmrg#define EOL() ctx->dump_printf( ctx, "\n" ) 88af69d88dSmrg#define TXT(S) ctx->dump_printf( ctx, "%s", S ) 89af69d88dSmrg#define CHR(C) ctx->dump_printf( ctx, "%c", C ) 90af69d88dSmrg#define UIX(I) ctx->dump_printf( ctx, "0x%x", I ) 91af69d88dSmrg#define UID(I) ctx->dump_printf( ctx, "%u", I ) 9201e04c3fSmrg#define SI64D(I) ctx->dump_printf( ctx, "%"PRId64, I ) 9301e04c3fSmrg#define UI64D(I) ctx->dump_printf( ctx, "%"PRIu64, I ) 94af69d88dSmrg#define INSTID(I) ctx->dump_printf( ctx, "% 3u", I ) 95af69d88dSmrg#define SID(I) ctx->dump_printf( ctx, "%d", I ) 96af69d88dSmrg#define FLT(F) ctx->dump_printf( ctx, "%10.4f", F ) 9701e04c3fSmrg#define DBL(D) ctx->dump_printf( ctx, "%10.8f", D ) 9801e04c3fSmrg#define HFLT(F) ctx->dump_printf( ctx, "0x%08x", fui((F)) ) 994a49301eSmrg#define ENM(E,ENUMS) dump_enum( ctx, E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) 1004a49301eSmrg 1013464ebd5Sriastradhconst char * 1023464ebd5Sriastradhtgsi_swizzle_names[4] = 1034a49301eSmrg{ 1044a49301eSmrg "x", 1054a49301eSmrg "y", 1064a49301eSmrg "z", 1074a49301eSmrg "w" 1084a49301eSmrg}; 1094a49301eSmrg 110cdc920a0Smrgstatic void 111cdc920a0Smrg_dump_register_src( 112cdc920a0Smrg struct dump_ctx *ctx, 113cdc920a0Smrg const struct tgsi_full_src_register *src ) 114cdc920a0Smrg{ 115af69d88dSmrg TXT(tgsi_file_name(src->Register.File)); 116cdc920a0Smrg if (src->Register.Dimension) { 1173464ebd5Sriastradh if (src->Dimension.Indirect) { 1183464ebd5Sriastradh CHR( '[' ); 119af69d88dSmrg TXT(tgsi_file_name(src->DimIndirect.File)); 1203464ebd5Sriastradh CHR( '[' ); 1213464ebd5Sriastradh SID( src->DimIndirect.Index ); 1223464ebd5Sriastradh TXT( "]." ); 123af69d88dSmrg ENM( src->DimIndirect.Swizzle, tgsi_swizzle_names ); 1243464ebd5Sriastradh if (src->Dimension.Index != 0) { 1253464ebd5Sriastradh if (src->Dimension.Index > 0) 1263464ebd5Sriastradh CHR( '+' ); 1273464ebd5Sriastradh SID( src->Dimension.Index ); 1283464ebd5Sriastradh } 1293464ebd5Sriastradh CHR( ']' ); 130af69d88dSmrg if (src->DimIndirect.ArrayID) { 131af69d88dSmrg CHR( '(' ); 132af69d88dSmrg SID( src->DimIndirect.ArrayID ); 133af69d88dSmrg CHR( ')' ); 134af69d88dSmrg } 1353464ebd5Sriastradh } else { 1363464ebd5Sriastradh CHR('['); 1373464ebd5Sriastradh SID(src->Dimension.Index); 1383464ebd5Sriastradh CHR(']'); 1393464ebd5Sriastradh } 140cdc920a0Smrg } 141cdc920a0Smrg if (src->Register.Indirect) { 142cdc920a0Smrg CHR( '[' ); 143af69d88dSmrg TXT(tgsi_file_name(src->Indirect.File)); 144cdc920a0Smrg CHR( '[' ); 145cdc920a0Smrg SID( src->Indirect.Index ); 146cdc920a0Smrg TXT( "]." ); 147af69d88dSmrg ENM( src->Indirect.Swizzle, tgsi_swizzle_names ); 148cdc920a0Smrg if (src->Register.Index != 0) { 149cdc920a0Smrg if (src->Register.Index > 0) 150cdc920a0Smrg CHR( '+' ); 151cdc920a0Smrg SID( src->Register.Index ); 152cdc920a0Smrg } 153cdc920a0Smrg CHR( ']' ); 154af69d88dSmrg if (src->Indirect.ArrayID) { 155af69d88dSmrg CHR( '(' ); 156af69d88dSmrg SID( src->Indirect.ArrayID ); 157af69d88dSmrg CHR( ')' ); 158af69d88dSmrg } 159cdc920a0Smrg } else { 160cdc920a0Smrg CHR( '[' ); 161cdc920a0Smrg SID( src->Register.Index ); 162cdc920a0Smrg CHR( ']' ); 163cdc920a0Smrg } 164cdc920a0Smrg} 165cdc920a0Smrg 1663464ebd5Sriastradh 1674a49301eSmrgstatic void 1683464ebd5Sriastradh_dump_register_dst( 1694a49301eSmrg struct dump_ctx *ctx, 1703464ebd5Sriastradh const struct tgsi_full_dst_register *dst ) 1714a49301eSmrg{ 172af69d88dSmrg TXT(tgsi_file_name(dst->Register.File)); 1733464ebd5Sriastradh if (dst->Register.Dimension) { 1743464ebd5Sriastradh if (dst->Dimension.Indirect) { 1753464ebd5Sriastradh CHR( '[' ); 176af69d88dSmrg TXT(tgsi_file_name(dst->DimIndirect.File)); 1773464ebd5Sriastradh CHR( '[' ); 1783464ebd5Sriastradh SID( dst->DimIndirect.Index ); 1793464ebd5Sriastradh TXT( "]." ); 180af69d88dSmrg ENM( dst->DimIndirect.Swizzle, tgsi_swizzle_names ); 1813464ebd5Sriastradh if (dst->Dimension.Index != 0) { 1823464ebd5Sriastradh if (dst->Dimension.Index > 0) 1833464ebd5Sriastradh CHR( '+' ); 1843464ebd5Sriastradh SID( dst->Dimension.Index ); 1853464ebd5Sriastradh } 1863464ebd5Sriastradh CHR( ']' ); 187af69d88dSmrg if (dst->DimIndirect.ArrayID) { 188af69d88dSmrg CHR( '(' ); 189af69d88dSmrg SID( dst->DimIndirect.ArrayID ); 190af69d88dSmrg CHR( ')' ); 191af69d88dSmrg } 1923464ebd5Sriastradh } else { 1933464ebd5Sriastradh CHR('['); 1943464ebd5Sriastradh SID(dst->Dimension.Index); 1953464ebd5Sriastradh CHR(']'); 1963464ebd5Sriastradh } 1973464ebd5Sriastradh } 1983464ebd5Sriastradh if (dst->Register.Indirect) { 1993464ebd5Sriastradh CHR( '[' ); 200af69d88dSmrg TXT(tgsi_file_name(dst->Indirect.File)); 2013464ebd5Sriastradh CHR( '[' ); 2023464ebd5Sriastradh SID( dst->Indirect.Index ); 2033464ebd5Sriastradh TXT( "]." ); 204af69d88dSmrg ENM( dst->Indirect.Swizzle, tgsi_swizzle_names ); 2053464ebd5Sriastradh if (dst->Register.Index != 0) { 2063464ebd5Sriastradh if (dst->Register.Index > 0) 2073464ebd5Sriastradh CHR( '+' ); 2083464ebd5Sriastradh SID( dst->Register.Index ); 2093464ebd5Sriastradh } 2103464ebd5Sriastradh CHR( ']' ); 211af69d88dSmrg if (dst->Indirect.ArrayID) { 212af69d88dSmrg CHR( '(' ); 213af69d88dSmrg SID( dst->Indirect.ArrayID ); 214af69d88dSmrg CHR( ')' ); 215af69d88dSmrg } 2163464ebd5Sriastradh } else { 2173464ebd5Sriastradh CHR( '[' ); 2183464ebd5Sriastradh SID( dst->Register.Index ); 2193464ebd5Sriastradh CHR( ']' ); 2204a49301eSmrg } 2214a49301eSmrg} 2224a49301eSmrgstatic void 2234a49301eSmrg_dump_writemask( 2244a49301eSmrg struct dump_ctx *ctx, 2254a49301eSmrg uint writemask ) 2264a49301eSmrg{ 2274a49301eSmrg if (writemask != TGSI_WRITEMASK_XYZW) { 2284a49301eSmrg CHR( '.' ); 2294a49301eSmrg if (writemask & TGSI_WRITEMASK_X) 2304a49301eSmrg CHR( 'x' ); 2314a49301eSmrg if (writemask & TGSI_WRITEMASK_Y) 2324a49301eSmrg CHR( 'y' ); 2334a49301eSmrg if (writemask & TGSI_WRITEMASK_Z) 2344a49301eSmrg CHR( 'z' ); 2354a49301eSmrg if (writemask & TGSI_WRITEMASK_W) 2364a49301eSmrg CHR( 'w' ); 2374a49301eSmrg } 2384a49301eSmrg} 2394a49301eSmrg 2403464ebd5Sriastradhstatic void 2413464ebd5Sriastradhdump_imm_data(struct tgsi_iterate_context *iter, 2423464ebd5Sriastradh union tgsi_immediate_data *data, 2433464ebd5Sriastradh unsigned num_tokens, 2443464ebd5Sriastradh unsigned data_type) 2453464ebd5Sriastradh{ 2463464ebd5Sriastradh struct dump_ctx *ctx = (struct dump_ctx *)iter; 2473464ebd5Sriastradh unsigned i ; 2483464ebd5Sriastradh 2493464ebd5Sriastradh TXT( " {" ); 2503464ebd5Sriastradh 2513464ebd5Sriastradh assert( num_tokens <= 4 ); 2523464ebd5Sriastradh for (i = 0; i < num_tokens; i++) { 2533464ebd5Sriastradh switch (data_type) { 25401e04c3fSmrg case TGSI_IMM_FLOAT64: { 25501e04c3fSmrg union di d; 25601e04c3fSmrg d.ui = data[i].Uint | (uint64_t)data[i+1].Uint << 32; 25701e04c3fSmrg DBL( d.d ); 25801e04c3fSmrg i++; 25901e04c3fSmrg break; 26001e04c3fSmrg } 26101e04c3fSmrg case TGSI_IMM_INT64: { 26201e04c3fSmrg union di d; 26301e04c3fSmrg d.i = data[i].Uint | (uint64_t)data[i+1].Uint << 32; 26401e04c3fSmrg SI64D( d.i ); 26501e04c3fSmrg i++; 26601e04c3fSmrg break; 26701e04c3fSmrg } 26801e04c3fSmrg case TGSI_IMM_UINT64: { 26901e04c3fSmrg union di d; 27001e04c3fSmrg d.ui = data[i].Uint | (uint64_t)data[i+1].Uint << 32; 27101e04c3fSmrg UI64D( d.ui ); 27201e04c3fSmrg i++; 27301e04c3fSmrg break; 27401e04c3fSmrg } 2753464ebd5Sriastradh case TGSI_IMM_FLOAT32: 27601e04c3fSmrg if (ctx->dump_float_as_hex) 27701e04c3fSmrg HFLT( data[i].Float ); 27801e04c3fSmrg else 27901e04c3fSmrg FLT( data[i].Float ); 2803464ebd5Sriastradh break; 2813464ebd5Sriastradh case TGSI_IMM_UINT32: 2823464ebd5Sriastradh UID(data[i].Uint); 2833464ebd5Sriastradh break; 2843464ebd5Sriastradh case TGSI_IMM_INT32: 2853464ebd5Sriastradh SID(data[i].Int); 2863464ebd5Sriastradh break; 2873464ebd5Sriastradh default: 2883464ebd5Sriastradh assert( 0 ); 2893464ebd5Sriastradh } 2903464ebd5Sriastradh 2913464ebd5Sriastradh if (i < num_tokens - 1) 2923464ebd5Sriastradh TXT( ", " ); 2933464ebd5Sriastradh } 2943464ebd5Sriastradh TXT( "}" ); 2953464ebd5Sriastradh} 2963464ebd5Sriastradh 2974a49301eSmrgstatic boolean 2984a49301eSmrgiter_declaration( 2994a49301eSmrg struct tgsi_iterate_context *iter, 3004a49301eSmrg struct tgsi_full_declaration *decl ) 3014a49301eSmrg{ 3024a49301eSmrg struct dump_ctx *ctx = (struct dump_ctx *)iter; 30301e04c3fSmrg boolean patch = decl->Semantic.Name == TGSI_SEMANTIC_PATCH || 30401e04c3fSmrg decl->Semantic.Name == TGSI_SEMANTIC_TESSINNER || 30501e04c3fSmrg decl->Semantic.Name == TGSI_SEMANTIC_TESSOUTER || 30601e04c3fSmrg decl->Semantic.Name == TGSI_SEMANTIC_PRIMID; 3074a49301eSmrg 3084a49301eSmrg TXT( "DCL " ); 3094a49301eSmrg 310af69d88dSmrg TXT(tgsi_file_name(decl->Declaration.File)); 311cdc920a0Smrg 31201e04c3fSmrg /* all geometry shader inputs and non-patch tessellation shader inputs are 31301e04c3fSmrg * two dimensional 31401e04c3fSmrg */ 315cdc920a0Smrg if (decl->Declaration.File == TGSI_FILE_INPUT && 31601e04c3fSmrg (iter->processor.Processor == PIPE_SHADER_GEOMETRY || 31701e04c3fSmrg (!patch && 31801e04c3fSmrg (iter->processor.Processor == PIPE_SHADER_TESS_CTRL || 31901e04c3fSmrg iter->processor.Processor == PIPE_SHADER_TESS_EVAL)))) { 32001e04c3fSmrg TXT("[]"); 32101e04c3fSmrg } 32201e04c3fSmrg 32301e04c3fSmrg /* all non-patch tess ctrl shader outputs are two dimensional */ 32401e04c3fSmrg if (decl->Declaration.File == TGSI_FILE_OUTPUT && 32501e04c3fSmrg !patch && 32601e04c3fSmrg iter->processor.Processor == PIPE_SHADER_TESS_CTRL) { 327cdc920a0Smrg TXT("[]"); 328cdc920a0Smrg } 329cdc920a0Smrg 330cdc920a0Smrg if (decl->Declaration.Dimension) { 331cdc920a0Smrg CHR('['); 332cdc920a0Smrg SID(decl->Dim.Index2D); 333cdc920a0Smrg CHR(']'); 334cdc920a0Smrg } 335cdc920a0Smrg 336cdc920a0Smrg CHR('['); 337cdc920a0Smrg SID(decl->Range.First); 338cdc920a0Smrg if (decl->Range.First != decl->Range.Last) { 339cdc920a0Smrg TXT(".."); 340cdc920a0Smrg SID(decl->Range.Last); 341cdc920a0Smrg } 342cdc920a0Smrg CHR(']'); 343cdc920a0Smrg 3444a49301eSmrg _dump_writemask( 3454a49301eSmrg ctx, 3464a49301eSmrg decl->Declaration.UsageMask ); 3474a49301eSmrg 348af69d88dSmrg if (decl->Declaration.Array) { 349af69d88dSmrg TXT( ", ARRAY(" ); 350af69d88dSmrg SID(decl->Array.ArrayID); 351af69d88dSmrg CHR(')'); 352af69d88dSmrg } 353af69d88dSmrg 354af69d88dSmrg if (decl->Declaration.Local) 355af69d88dSmrg TXT( ", LOCAL" ); 356af69d88dSmrg 3574a49301eSmrg if (decl->Declaration.Semantic) { 3584a49301eSmrg TXT( ", " ); 359af69d88dSmrg ENM( decl->Semantic.Name, tgsi_semantic_names ); 360cdc920a0Smrg if (decl->Semantic.Index != 0 || 361af69d88dSmrg decl->Semantic.Name == TGSI_SEMANTIC_TEXCOORD || 362cdc920a0Smrg decl->Semantic.Name == TGSI_SEMANTIC_GENERIC) { 3634a49301eSmrg CHR( '[' ); 364cdc920a0Smrg UID( decl->Semantic.Index ); 3654a49301eSmrg CHR( ']' ); 3664a49301eSmrg } 36701e04c3fSmrg 36801e04c3fSmrg if (decl->Semantic.StreamX != 0 || decl->Semantic.StreamY != 0 || 36901e04c3fSmrg decl->Semantic.StreamZ != 0 || decl->Semantic.StreamW != 0) { 37001e04c3fSmrg TXT(", STREAM("); 37101e04c3fSmrg UID(decl->Semantic.StreamX); 37201e04c3fSmrg TXT(", "); 37301e04c3fSmrg UID(decl->Semantic.StreamY); 37401e04c3fSmrg TXT(", "); 37501e04c3fSmrg UID(decl->Semantic.StreamZ); 37601e04c3fSmrg TXT(", "); 37701e04c3fSmrg UID(decl->Semantic.StreamW); 37801e04c3fSmrg CHR(')'); 37901e04c3fSmrg } 3804a49301eSmrg } 3814a49301eSmrg 38201e04c3fSmrg if (decl->Declaration.File == TGSI_FILE_IMAGE) { 38301e04c3fSmrg TXT(", "); 38401e04c3fSmrg ENM(decl->Image.Resource, tgsi_texture_names); 3853464ebd5Sriastradh TXT(", "); 38601e04c3fSmrg TXT(util_format_name(decl->Image.Format)); 38701e04c3fSmrg if (decl->Image.Writable) 388af69d88dSmrg TXT(", WR"); 38901e04c3fSmrg if (decl->Image.Raw) 390af69d88dSmrg TXT(", RAW"); 391af69d88dSmrg } 392af69d88dSmrg 39301e04c3fSmrg if (decl->Declaration.File == TGSI_FILE_BUFFER) { 39401e04c3fSmrg if (decl->Declaration.Atomic) 39501e04c3fSmrg TXT(", ATOMIC"); 39601e04c3fSmrg } 39701e04c3fSmrg 39801e04c3fSmrg if (decl->Declaration.File == TGSI_FILE_MEMORY) { 39901e04c3fSmrg switch (decl->Declaration.MemType) { 40001e04c3fSmrg /* Note: ,GLOBAL is optional / the default */ 40101e04c3fSmrg case TGSI_MEMORY_TYPE_GLOBAL: TXT(", GLOBAL"); break; 40201e04c3fSmrg case TGSI_MEMORY_TYPE_SHARED: TXT(", SHARED"); break; 40301e04c3fSmrg case TGSI_MEMORY_TYPE_PRIVATE: TXT(", PRIVATE"); break; 40401e04c3fSmrg case TGSI_MEMORY_TYPE_INPUT: TXT(", INPUT"); break; 40501e04c3fSmrg } 40601e04c3fSmrg } 40701e04c3fSmrg 408af69d88dSmrg if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) { 409af69d88dSmrg TXT(", "); 410af69d88dSmrg ENM(decl->SamplerView.Resource, tgsi_texture_names); 4113464ebd5Sriastradh TXT(", "); 412af69d88dSmrg if ((decl->SamplerView.ReturnTypeX == decl->SamplerView.ReturnTypeY) && 413af69d88dSmrg (decl->SamplerView.ReturnTypeX == decl->SamplerView.ReturnTypeZ) && 414af69d88dSmrg (decl->SamplerView.ReturnTypeX == decl->SamplerView.ReturnTypeW)) { 41501e04c3fSmrg ENM(decl->SamplerView.ReturnTypeX, tgsi_return_type_names); 4163464ebd5Sriastradh } else { 41701e04c3fSmrg ENM(decl->SamplerView.ReturnTypeX, tgsi_return_type_names); 4183464ebd5Sriastradh TXT(", "); 41901e04c3fSmrg ENM(decl->SamplerView.ReturnTypeY, tgsi_return_type_names); 4203464ebd5Sriastradh TXT(", "); 42101e04c3fSmrg ENM(decl->SamplerView.ReturnTypeZ, tgsi_return_type_names); 4223464ebd5Sriastradh TXT(", "); 42301e04c3fSmrg ENM(decl->SamplerView.ReturnTypeW, tgsi_return_type_names); 4243464ebd5Sriastradh } 4254a49301eSmrg } 4264a49301eSmrg 427af69d88dSmrg if (decl->Declaration.Interpolate) { 42801e04c3fSmrg if (iter->processor.Processor == PIPE_SHADER_FRAGMENT && 429af69d88dSmrg decl->Declaration.File == TGSI_FILE_INPUT) 430af69d88dSmrg { 431af69d88dSmrg TXT( ", " ); 432af69d88dSmrg ENM( decl->Interp.Interpolate, tgsi_interpolate_names ); 433cdc920a0Smrg } 434cdc920a0Smrg 435af69d88dSmrg if (decl->Interp.Location != TGSI_INTERPOLATE_LOC_CENTER) { 436af69d88dSmrg TXT( ", " ); 437af69d88dSmrg ENM( decl->Interp.Location, tgsi_interpolate_locations ); 4383464ebd5Sriastradh } 439af69d88dSmrg } 4403464ebd5Sriastradh 441af69d88dSmrg if (decl->Declaration.Invariant) { 442af69d88dSmrg TXT( ", INVARIANT" ); 4433464ebd5Sriastradh } 4443464ebd5Sriastradh 4454a49301eSmrg EOL(); 4464a49301eSmrg 4474a49301eSmrg return TRUE; 4484a49301eSmrg} 4494a49301eSmrg 4504a49301eSmrgvoid 4514a49301eSmrgtgsi_dump_declaration( 4524a49301eSmrg const struct tgsi_full_declaration *decl ) 4534a49301eSmrg{ 4544a49301eSmrg struct dump_ctx ctx; 45501e04c3fSmrg memset(&ctx, 0, sizeof(ctx)); 4564a49301eSmrg 457af69d88dSmrg ctx.dump_printf = dump_ctx_printf; 4584a49301eSmrg 4594a49301eSmrg iter_declaration( &ctx.iter, (struct tgsi_full_declaration *)decl ); 4604a49301eSmrg} 4614a49301eSmrg 462cdc920a0Smrgstatic boolean 463cdc920a0Smrgiter_property( 464cdc920a0Smrg struct tgsi_iterate_context *iter, 465cdc920a0Smrg struct tgsi_full_property *prop ) 466cdc920a0Smrg{ 46701e04c3fSmrg int i; 468cdc920a0Smrg struct dump_ctx *ctx = (struct dump_ctx *)iter; 469cdc920a0Smrg 470cdc920a0Smrg TXT( "PROPERTY " ); 4713464ebd5Sriastradh ENM(prop->Property.PropertyName, tgsi_property_names); 472cdc920a0Smrg 473cdc920a0Smrg if (prop->Property.NrTokens > 1) 474cdc920a0Smrg TXT(" "); 475cdc920a0Smrg 476cdc920a0Smrg for (i = 0; i < prop->Property.NrTokens - 1; ++i) { 477cdc920a0Smrg switch (prop->Property.PropertyName) { 478cdc920a0Smrg case TGSI_PROPERTY_GS_INPUT_PRIM: 479cdc920a0Smrg case TGSI_PROPERTY_GS_OUTPUT_PRIM: 4803464ebd5Sriastradh ENM(prop->u[i].Data, tgsi_primitive_names); 481cdc920a0Smrg break; 482cdc920a0Smrg case TGSI_PROPERTY_FS_COORD_ORIGIN: 4833464ebd5Sriastradh ENM(prop->u[i].Data, tgsi_fs_coord_origin_names); 484cdc920a0Smrg break; 485cdc920a0Smrg case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER: 4863464ebd5Sriastradh ENM(prop->u[i].Data, tgsi_fs_coord_pixel_center_names); 487cdc920a0Smrg break; 48801e04c3fSmrg case TGSI_PROPERTY_NEXT_SHADER: 48901e04c3fSmrg ENM(prop->u[i].Data, tgsi_processor_type_names); 49001e04c3fSmrg break; 491cdc920a0Smrg default: 492cdc920a0Smrg SID( prop->u[i].Data ); 493cdc920a0Smrg break; 494cdc920a0Smrg } 495cdc920a0Smrg if (i < prop->Property.NrTokens - 2) 496cdc920a0Smrg TXT( ", " ); 497cdc920a0Smrg } 498cdc920a0Smrg EOL(); 499cdc920a0Smrg 500cdc920a0Smrg return TRUE; 501cdc920a0Smrg} 502cdc920a0Smrg 503cdc920a0Smrgvoid tgsi_dump_property( 504cdc920a0Smrg const struct tgsi_full_property *prop ) 505cdc920a0Smrg{ 506cdc920a0Smrg struct dump_ctx ctx; 50701e04c3fSmrg memset(&ctx, 0, sizeof(ctx)); 508cdc920a0Smrg 509af69d88dSmrg ctx.dump_printf = dump_ctx_printf; 510cdc920a0Smrg 511cdc920a0Smrg iter_property( &ctx.iter, (struct tgsi_full_property *)prop ); 512cdc920a0Smrg} 513cdc920a0Smrg 5144a49301eSmrgstatic boolean 5154a49301eSmrgiter_immediate( 5164a49301eSmrg struct tgsi_iterate_context *iter, 5174a49301eSmrg struct tgsi_full_immediate *imm ) 5184a49301eSmrg{ 5194a49301eSmrg struct dump_ctx *ctx = (struct dump_ctx *) iter; 5204a49301eSmrg 521af69d88dSmrg TXT( "IMM[" ); 522af69d88dSmrg SID( ctx->immno++ ); 523af69d88dSmrg TXT( "] " ); 524af69d88dSmrg ENM( imm->Immediate.DataType, tgsi_immediate_type_names ); 5254a49301eSmrg 5263464ebd5Sriastradh dump_imm_data(iter, imm->u, imm->Immediate.NrTokens - 1, 5273464ebd5Sriastradh imm->Immediate.DataType); 5284a49301eSmrg 5294a49301eSmrg EOL(); 5304a49301eSmrg 5314a49301eSmrg return TRUE; 5324a49301eSmrg} 5334a49301eSmrg 5344a49301eSmrgvoid 5354a49301eSmrgtgsi_dump_immediate( 5364a49301eSmrg const struct tgsi_full_immediate *imm ) 5374a49301eSmrg{ 5384a49301eSmrg struct dump_ctx ctx; 53901e04c3fSmrg memset(&ctx, 0, sizeof(ctx)); 5404a49301eSmrg 541af69d88dSmrg ctx.dump_printf = dump_ctx_printf; 5424a49301eSmrg 5434a49301eSmrg iter_immediate( &ctx.iter, (struct tgsi_full_immediate *)imm ); 5444a49301eSmrg} 5454a49301eSmrg 5464a49301eSmrgstatic boolean 5474a49301eSmrgiter_instruction( 5484a49301eSmrg struct tgsi_iterate_context *iter, 5494a49301eSmrg struct tgsi_full_instruction *inst ) 5504a49301eSmrg{ 5514a49301eSmrg struct dump_ctx *ctx = (struct dump_ctx *) iter; 5524a49301eSmrg uint instno = ctx->instno++; 5534a49301eSmrg const struct tgsi_opcode_info *info = tgsi_get_opcode_info( inst->Instruction.Opcode ); 5544a49301eSmrg uint i; 5554a49301eSmrg boolean first_reg = TRUE; 5564a49301eSmrg 5574a49301eSmrg INSTID( instno ); 5584a49301eSmrg TXT( ": " ); 5593464ebd5Sriastradh 5604a49301eSmrg ctx->indent -= info->pre_dedent; 5614a49301eSmrg for(i = 0; (int)i < ctx->indent; ++i) 5624a49301eSmrg TXT( " " ); 5634a49301eSmrg ctx->indent += info->post_indent; 5643464ebd5Sriastradh 56501e04c3fSmrg TXT( tgsi_get_opcode_name(inst->Instruction.Opcode) ); 5663464ebd5Sriastradh 56701e04c3fSmrg if (inst->Instruction.Saturate) { 56801e04c3fSmrg TXT( "_SAT" ); 5693464ebd5Sriastradh } 5703464ebd5Sriastradh 57101e04c3fSmrg if (inst->Instruction.Precise) { 57201e04c3fSmrg TXT( "_PRECISE" ); 5734a49301eSmrg } 5744a49301eSmrg 5754a49301eSmrg for (i = 0; i < inst->Instruction.NumDstRegs; i++) { 576cdc920a0Smrg const struct tgsi_full_dst_register *dst = &inst->Dst[i]; 5774a49301eSmrg 5784a49301eSmrg if (!first_reg) 5794a49301eSmrg CHR( ',' ); 5804a49301eSmrg CHR( ' ' ); 5814a49301eSmrg 5823464ebd5Sriastradh _dump_register_dst( ctx, dst ); 583cdc920a0Smrg _dump_writemask( ctx, dst->Register.WriteMask ); 5844a49301eSmrg 5854a49301eSmrg first_reg = FALSE; 5864a49301eSmrg } 5874a49301eSmrg 5884a49301eSmrg for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { 589cdc920a0Smrg const struct tgsi_full_src_register *src = &inst->Src[i]; 5904a49301eSmrg 5914a49301eSmrg if (!first_reg) 5924a49301eSmrg CHR( ',' ); 5934a49301eSmrg CHR( ' ' ); 5944a49301eSmrg 595cdc920a0Smrg if (src->Register.Negate) 5964a49301eSmrg CHR( '-' ); 597cdc920a0Smrg if (src->Register.Absolute) 598cdc920a0Smrg CHR( '|' ); 5994a49301eSmrg 600cdc920a0Smrg _dump_register_src(ctx, src); 6014a49301eSmrg 602cdc920a0Smrg if (src->Register.SwizzleX != TGSI_SWIZZLE_X || 603cdc920a0Smrg src->Register.SwizzleY != TGSI_SWIZZLE_Y || 604cdc920a0Smrg src->Register.SwizzleZ != TGSI_SWIZZLE_Z || 605cdc920a0Smrg src->Register.SwizzleW != TGSI_SWIZZLE_W) { 6064a49301eSmrg CHR( '.' ); 6073464ebd5Sriastradh ENM( src->Register.SwizzleX, tgsi_swizzle_names ); 6083464ebd5Sriastradh ENM( src->Register.SwizzleY, tgsi_swizzle_names ); 6093464ebd5Sriastradh ENM( src->Register.SwizzleZ, tgsi_swizzle_names ); 6103464ebd5Sriastradh ENM( src->Register.SwizzleW, tgsi_swizzle_names ); 6114a49301eSmrg } 6124a49301eSmrg 613cdc920a0Smrg if (src->Register.Absolute) 6144a49301eSmrg CHR( '|' ); 6154a49301eSmrg 6164a49301eSmrg first_reg = FALSE; 6174a49301eSmrg } 6184a49301eSmrg 619cdc920a0Smrg if (inst->Instruction.Texture) { 62001e04c3fSmrg if (!(inst->Instruction.Opcode >= TGSI_OPCODE_SAMPLE && 62101e04c3fSmrg inst->Instruction.Opcode <= TGSI_OPCODE_GATHER4)) { 62201e04c3fSmrg TXT( ", " ); 62301e04c3fSmrg ENM( inst->Texture.Texture, tgsi_texture_names ); 62401e04c3fSmrg } 625af69d88dSmrg for (i = 0; i < inst->Texture.NumOffsets; i++) { 626af69d88dSmrg TXT( ", " ); 627af69d88dSmrg TXT(tgsi_file_name(inst->TexOffsets[i].File)); 628af69d88dSmrg CHR( '[' ); 629af69d88dSmrg SID( inst->TexOffsets[i].Index ); 630af69d88dSmrg CHR( ']' ); 631af69d88dSmrg CHR( '.' ); 632af69d88dSmrg ENM( inst->TexOffsets[i].SwizzleX, tgsi_swizzle_names); 633af69d88dSmrg ENM( inst->TexOffsets[i].SwizzleY, tgsi_swizzle_names); 634af69d88dSmrg ENM( inst->TexOffsets[i].SwizzleZ, tgsi_swizzle_names); 635af69d88dSmrg } 6364a49301eSmrg } 6374a49301eSmrg 63801e04c3fSmrg if (inst->Instruction.Memory) { 63901e04c3fSmrg uint32_t qualifier = inst->Memory.Qualifier; 64001e04c3fSmrg while (qualifier) { 64101e04c3fSmrg int bit = ffs(qualifier) - 1; 64201e04c3fSmrg qualifier &= ~(1U << bit); 64301e04c3fSmrg TXT(", "); 64401e04c3fSmrg ENM(bit, tgsi_memory_names); 64501e04c3fSmrg } 64601e04c3fSmrg if (inst->Memory.Texture) { 64701e04c3fSmrg TXT( ", " ); 64801e04c3fSmrg ENM( inst->Memory.Texture, tgsi_texture_names ); 64901e04c3fSmrg } 65001e04c3fSmrg if (inst->Memory.Format) { 65101e04c3fSmrg TXT( ", " ); 65201e04c3fSmrg TXT( util_format_name(inst->Memory.Format) ); 65301e04c3fSmrg } 65401e04c3fSmrg } 65501e04c3fSmrg 65601e04c3fSmrg if (inst->Instruction.Label) { 65701e04c3fSmrg switch (inst->Instruction.Opcode) { 65801e04c3fSmrg case TGSI_OPCODE_IF: 65901e04c3fSmrg case TGSI_OPCODE_UIF: 66001e04c3fSmrg case TGSI_OPCODE_ELSE: 66101e04c3fSmrg case TGSI_OPCODE_BGNLOOP: 66201e04c3fSmrg case TGSI_OPCODE_ENDLOOP: 66301e04c3fSmrg case TGSI_OPCODE_CAL: 66401e04c3fSmrg case TGSI_OPCODE_BGNSUB: 66501e04c3fSmrg TXT( " :" ); 66601e04c3fSmrg UID( inst->Label.Label ); 66701e04c3fSmrg break; 66801e04c3fSmrg } 6694a49301eSmrg } 6704a49301eSmrg 6714a49301eSmrg /* update indentation */ 6724a49301eSmrg if (inst->Instruction.Opcode == TGSI_OPCODE_IF || 673af69d88dSmrg inst->Instruction.Opcode == TGSI_OPCODE_UIF || 6744a49301eSmrg inst->Instruction.Opcode == TGSI_OPCODE_ELSE || 6754a49301eSmrg inst->Instruction.Opcode == TGSI_OPCODE_BGNLOOP) { 6764a49301eSmrg ctx->indentation += indent_spaces; 6774a49301eSmrg } 6784a49301eSmrg 6794a49301eSmrg EOL(); 6804a49301eSmrg 6814a49301eSmrg return TRUE; 6824a49301eSmrg} 6834a49301eSmrg 6844a49301eSmrgvoid 6854a49301eSmrgtgsi_dump_instruction( 6864a49301eSmrg const struct tgsi_full_instruction *inst, 6874a49301eSmrg uint instno ) 6884a49301eSmrg{ 6894a49301eSmrg struct dump_ctx ctx; 69001e04c3fSmrg memset(&ctx, 0, sizeof(ctx)); 6914a49301eSmrg 6924a49301eSmrg ctx.instno = instno; 693af69d88dSmrg ctx.immno = instno; 6944a49301eSmrg ctx.indent = 0; 695af69d88dSmrg ctx.dump_printf = dump_ctx_printf; 6964a49301eSmrg ctx.indentation = 0; 69701e04c3fSmrg ctx.file = NULL; 6984a49301eSmrg 6994a49301eSmrg iter_instruction( &ctx.iter, (struct tgsi_full_instruction *)inst ); 7004a49301eSmrg} 7014a49301eSmrg 7024a49301eSmrgstatic boolean 7034a49301eSmrgprolog( 7044a49301eSmrg struct tgsi_iterate_context *iter ) 7054a49301eSmrg{ 7064a49301eSmrg struct dump_ctx *ctx = (struct dump_ctx *) iter; 707af69d88dSmrg ENM( iter->processor.Processor, tgsi_processor_type_names ); 7084a49301eSmrg EOL(); 7094a49301eSmrg return TRUE; 7104a49301eSmrg} 7114a49301eSmrg 71201e04c3fSmrgstatic void 71301e04c3fSmrginit_dump_ctx(struct dump_ctx *ctx, uint flags) 71401e04c3fSmrg{ 71501e04c3fSmrg memset(ctx, 0, sizeof(*ctx)); 71601e04c3fSmrg 71701e04c3fSmrg ctx->iter.prolog = prolog; 71801e04c3fSmrg ctx->iter.iterate_instruction = iter_instruction; 71901e04c3fSmrg ctx->iter.iterate_declaration = iter_declaration; 72001e04c3fSmrg ctx->iter.iterate_immediate = iter_immediate; 72101e04c3fSmrg ctx->iter.iterate_property = iter_property; 72201e04c3fSmrg 72301e04c3fSmrg if (flags & TGSI_DUMP_FLOAT_AS_HEX) 72401e04c3fSmrg ctx->dump_float_as_hex = TRUE; 72501e04c3fSmrg} 72601e04c3fSmrg 7274a49301eSmrgvoid 72801e04c3fSmrgtgsi_dump_to_file(const struct tgsi_token *tokens, uint flags, FILE *file) 7294a49301eSmrg{ 7304a49301eSmrg struct dump_ctx ctx; 73101e04c3fSmrg memset(&ctx, 0, sizeof(ctx)); 7324a49301eSmrg 73301e04c3fSmrg init_dump_ctx(&ctx, flags); 7344a49301eSmrg 735af69d88dSmrg ctx.dump_printf = dump_ctx_printf; 73601e04c3fSmrg ctx.file = file; 7374a49301eSmrg 7384a49301eSmrg tgsi_iterate_shader( tokens, &ctx.iter ); 7394a49301eSmrg} 7404a49301eSmrg 74101e04c3fSmrgvoid 74201e04c3fSmrgtgsi_dump(const struct tgsi_token *tokens, uint flags) 74301e04c3fSmrg{ 74401e04c3fSmrg tgsi_dump_to_file(tokens, flags, NULL); 74501e04c3fSmrg} 74601e04c3fSmrg 7474a49301eSmrgstruct str_dump_ctx 7484a49301eSmrg{ 7494a49301eSmrg struct dump_ctx base; 7504a49301eSmrg char *str; 7514a49301eSmrg char *ptr; 7524a49301eSmrg int left; 75301e04c3fSmrg bool nospace; 7544a49301eSmrg}; 7554a49301eSmrg 7564a49301eSmrgstatic void 7574a49301eSmrgstr_dump_ctx_printf(struct dump_ctx *ctx, const char *format, ...) 7584a49301eSmrg{ 7594a49301eSmrg struct str_dump_ctx *sctx = (struct str_dump_ctx *)ctx; 7604a49301eSmrg 76101e04c3fSmrg if (!sctx->nospace) { 7624a49301eSmrg int written; 7634a49301eSmrg va_list ap; 7644a49301eSmrg va_start(ap, format); 7657ec681f3Smrg written = vsnprintf(sctx->ptr, sctx->left, format, ap); 7664a49301eSmrg va_end(ap); 7674a49301eSmrg 7684a49301eSmrg /* Some complicated logic needed to handle the return value of 7694a49301eSmrg * vsnprintf: 7704a49301eSmrg */ 7714a49301eSmrg if (written > 0) { 77201e04c3fSmrg if (written >= sctx->left) { 77301e04c3fSmrg sctx->nospace = true; 77401e04c3fSmrg written = sctx->left; 77501e04c3fSmrg } 7764a49301eSmrg sctx->ptr += written; 7774a49301eSmrg sctx->left -= written; 7784a49301eSmrg } 7794a49301eSmrg } 7804a49301eSmrg} 7814a49301eSmrg 78201e04c3fSmrgbool 7834a49301eSmrgtgsi_dump_str( 7844a49301eSmrg const struct tgsi_token *tokens, 7854a49301eSmrg uint flags, 7864a49301eSmrg char *str, 7874a49301eSmrg size_t size) 7884a49301eSmrg{ 7894a49301eSmrg struct str_dump_ctx ctx; 79001e04c3fSmrg memset(&ctx, 0, sizeof(ctx)); 7914a49301eSmrg 79201e04c3fSmrg init_dump_ctx(&ctx.base, flags); 7934a49301eSmrg 794af69d88dSmrg ctx.base.dump_printf = &str_dump_ctx_printf; 7954a49301eSmrg 7964a49301eSmrg ctx.str = str; 7974a49301eSmrg ctx.str[0] = 0; 7984a49301eSmrg ctx.ptr = str; 7994a49301eSmrg ctx.left = (int)size; 80001e04c3fSmrg ctx.nospace = false; 8014a49301eSmrg 8024a49301eSmrg tgsi_iterate_shader( tokens, &ctx.base.iter ); 80301e04c3fSmrg 80401e04c3fSmrg return !ctx.nospace; 8054a49301eSmrg} 806af69d88dSmrg 807af69d88dSmrgvoid 808af69d88dSmrgtgsi_dump_instruction_str( 809af69d88dSmrg const struct tgsi_full_instruction *inst, 810af69d88dSmrg uint instno, 811af69d88dSmrg char *str, 812af69d88dSmrg size_t size) 813af69d88dSmrg{ 814af69d88dSmrg struct str_dump_ctx ctx; 81501e04c3fSmrg memset(&ctx, 0, sizeof(ctx)); 816af69d88dSmrg 817af69d88dSmrg ctx.base.instno = instno; 818af69d88dSmrg ctx.base.immno = instno; 819af69d88dSmrg ctx.base.indent = 0; 820af69d88dSmrg ctx.base.dump_printf = &str_dump_ctx_printf; 821af69d88dSmrg ctx.base.indentation = 0; 82201e04c3fSmrg ctx.base.file = NULL; 823af69d88dSmrg 824af69d88dSmrg ctx.str = str; 825af69d88dSmrg ctx.str[0] = 0; 826af69d88dSmrg ctx.ptr = str; 827af69d88dSmrg ctx.left = (int)size; 82801e04c3fSmrg ctx.nospace = false; 829af69d88dSmrg 830af69d88dSmrg iter_instruction( &ctx.base.iter, (struct tgsi_full_instruction *)inst ); 831af69d88dSmrg} 832