From f822cc22f223a0a4f9cf1cdd5871780e5df11d67 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Sun, 17 Oct 2010 23:17:01 -0700 Subject: [PATCH] r300g: Add new debug option for logging vertex/fragment program stats --- src/gallium/drivers/r300/r300_debug.c | 1 + src/gallium/drivers/r300/r300_fs.c | 5 +- src/gallium/drivers/r300/r300_screen.h | 1 + src/gallium/drivers/r300/r300_vs.c | 5 +- .../drivers/dri/r300/compiler/r3xx_fragprog.c | 4 +- .../drivers/dri/r300/compiler/r3xx_vertprog.c | 2 +- .../dri/r300/compiler/radeon_compiler.c | 66 +++++++++++++++++-- .../dri/r300/compiler/radeon_compiler.h | 5 +- .../r300/compiler/radeon_remove_constants.c | 2 +- 9 files changed, 78 insertions(+), 13 deletions(-) diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c index 145a7985da3..f78fe34790c 100644 --- a/src/gallium/drivers/r300/r300_debug.c +++ b/src/gallium/drivers/r300/r300_debug.c @@ -29,6 +29,7 @@ static const struct debug_named_value debug_options[] = { { "fp", DBG_FP, "Log fragment program compilation" }, { "vp", DBG_VP, "Log vertex program compilation" }, + { "pstat", DBG_P_STAT, "Log vertex/fragment program stats" }, { "draw", DBG_DRAW, "Log draw calls" }, { "swtcl", DBG_SWTCL, "Log SWTCL-specific info" }, { "rsblock", DBG_RS_BLOCK, "Log rasterizer registers" }, diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index d9d4a9304df..c91532eb7b3 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -378,7 +378,8 @@ static void r300_translate_fragment_shader( /* Setup the compiler. */ memset(&compiler, 0, sizeof(compiler)); rc_init(&compiler.Base); - compiler.Base.Debug = DBG_ON(r300, DBG_FP); + DBG_ON(r300, DBG_FP) ? compiler.Base.Debug |= RC_DBG_LOG : 0; + DBG_ON(r300, DBG_P_STAT) ? compiler.Base.Debug |= RC_DBG_STATS : 0; compiler.code = &shader->code; compiler.state = shader->compare_state; @@ -395,7 +396,7 @@ static void r300_translate_fragment_shader( find_output_registers(&compiler, shader); - if (compiler.Base.Debug) { + if (compiler.Base.Debug & RC_DBG_LOG) { DBG(r300, DBG_FP, "r300: Initial fragment program\n"); tgsi_dump(tokens, 0); } diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h index dc2bc7e8279..8b7f1fab61b 100644 --- a/src/gallium/drivers/r300/r300_screen.h +++ b/src/gallium/drivers/r300/r300_screen.h @@ -102,6 +102,7 @@ r300_winsys_screen(struct pipe_screen *screen) { #define DBG_NO_CBZB (1 << 21) /* Statistics. */ #define DBG_STATS (1 << 24) +#define DBG_P_STAT (1 << 25) /*@}*/ static INLINE boolean SCREEN_DBG_ON(struct r300_screen * screen, unsigned flags) diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c index e2b9af9d018..65696555ac3 100644 --- a/src/gallium/drivers/r300/r300_vs.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -202,7 +202,8 @@ void r300_translate_vertex_shader(struct r300_context *r300, memset(&compiler, 0, sizeof(compiler)); rc_init(&compiler.Base); - compiler.Base.Debug = DBG_ON(r300, DBG_VP); + DBG_ON(r300, DBG_VP) ? compiler.Base.Debug |= RC_DBG_LOG : 0; + DBG_ON(r300, DBG_P_STAT) ? compiler.Base.Debug |= RC_DBG_STATS : 0; compiler.code = &vs->code; compiler.UserData = vs; compiler.Base.is_r500 = r300->screen->caps.is_r500; @@ -214,7 +215,7 @@ void r300_translate_vertex_shader(struct r300_context *r300, compiler.Base.max_alu_insts = r300->screen->caps.is_r500 ? 1024 : 256; compiler.Base.remove_unused_constants = TRUE; - if (compiler.Base.Debug) { + if (compiler.Base.Debug & RC_DBG_LOG) { DBG(r300, DBG_VP, "r300: Initial vertex program\n"); tgsi_dump(vs->state.tokens, 0); } diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c index 4793f335770..2f130198d35 100644 --- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c @@ -145,8 +145,8 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c) {"final code validation", 0, 1, rc_validate_final_shader, NULL}, {"machine code generation", 0, is_r500, r500BuildFragmentProgramHwCode, NULL}, {"machine code generation", 0, !is_r500, r300BuildFragmentProgramHwCode, NULL}, - {"dump machine code", 0, is_r500 && c->Base.Debug, r500FragmentProgramDump, NULL}, - {"dump machine code", 0, !is_r500 && c->Base.Debug, r300FragmentProgramDump, NULL}, + {"dump machine code", 0, is_r500 && (c->Base.Debug & RC_DBG_LOG), r500FragmentProgramDump, NULL}, + {"dump machine code", 0, !is_r500 && (c->Base.Debug & RC_DBG_LOG), r300FragmentProgramDump, NULL}, {NULL, 0, 0, NULL, NULL} }; diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c index d7d49e514b9..bf8341f0173 100644 --- a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c @@ -1067,7 +1067,7 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler *c) {"dead constants", 1, kill_consts, rc_remove_unused_constants, &c->code->constants_remap_table}, {"final code validation", 0, 1, rc_validate_final_shader, NULL}, {"machine code generation", 0, 1, translate_vertex_program, NULL}, - {"dump machine code", 0,c->Base.Debug,r300_vertex_program_dump, NULL}, + {"dump machine code", 0, c->Base.Debug & RC_DBG_LOG, r300_vertex_program_dump, NULL}, {NULL, 0, 0, NULL, NULL} }; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c index b410b2daf42..125d64e6497 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c @@ -26,7 +26,9 @@ #include #include +#include "radeon_dataflow.h" #include "radeon_program.h" +#include "radeon_program_pair.h" void rc_init(struct radeon_compiler * c) @@ -50,7 +52,7 @@ void rc_debug(struct radeon_compiler * c, const char * fmt, ...) { va_list ap; - if (!c->Debug) + if (!(c->Debug & RC_DBG_LOG)) return; va_start(ap, fmt); @@ -84,7 +86,7 @@ void rc_error(struct radeon_compiler * c, const char * fmt, ...) } } - if (c->Debug) { + if (c->Debug & RC_DBG_LOG) { fprintf(stderr, "r300compiler error: "); va_start(ap, fmt); @@ -351,11 +353,65 @@ void rc_transform_fragment_face(struct radeon_compiler *c, unsigned face) } } +static void reg_count_callback(void * userdata, struct rc_instruction * inst, + rc_register_file file, unsigned int index, unsigned int mask) +{ + unsigned int * max_reg = userdata; + if (file == RC_FILE_TEMPORARY) + index > *max_reg ? *max_reg = index : 0; +} + +static void print_stats(struct radeon_compiler * c) +{ + struct rc_instruction * tmp; + unsigned i, max_reg, insts, fc, tex, alpha, rgb, presub; + max_reg = insts = fc = tex = alpha = rgb = presub = 0; + for(tmp = c->Program.Instructions.Next; tmp != &c->Program.Instructions; + tmp = tmp->Next){ + const struct rc_opcode_info * info; + rc_for_all_reads_mask(tmp, reg_count_callback, &max_reg); + if (tmp->Type == RC_INSTRUCTION_NORMAL) { + if (tmp->U.I.PreSub.Opcode != RC_PRESUB_NONE) + presub++; + info = rc_get_opcode_info(tmp->U.I.Opcode); + } else { + if (tmp->U.P.RGB.Src[RC_PAIR_PRESUB_SRC].Used) + presub++; + if (tmp->U.P.Alpha.Src[RC_PAIR_PRESUB_SRC].Used) + presub++; + /* Assuming alpha will never be a flow control or + * a tex instruction. */ + if (tmp->U.P.Alpha.Opcode != RC_OPCODE_NOP) + alpha++; + if (tmp->U.P.RGB.Opcode != RC_OPCODE_NOP) + rgb++; + info = rc_get_opcode_info(tmp->U.P.RGB.Opcode); + } + if (info->IsFlowControl) + fc++; + if (info->HasTexture) + tex++; + insts++; + } + if (insts < 4) + return; + fprintf(stderr,"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + "~%4u Instructions\n" + "~%4u Vector Instructions (RGB)\n" + "~%4u Scalar Instructions (Alpha)\n" + "~%4u Flow Control Instructions\n" + "~%4u Texture Instructions\n" + "~%4u Presub Operations\n" + "~%4u Temporary Registers\n" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", + insts, rgb, alpha, fc, tex, presub, max_reg + 1); +} + /* Executes a list of compiler passes given in the parameter 'list'. */ void rc_run_compiler(struct radeon_compiler *c, struct radeon_compiler_pass *list, const char *shader_name) { - if (c->Debug) { + if (c->Debug & RC_DBG_LOG) { fprintf(stderr, "%s: before compilation\n", shader_name); rc_print_program(&c->Program); } @@ -367,12 +423,14 @@ void rc_run_compiler(struct radeon_compiler *c, struct radeon_compiler_pass *lis if (c->Error) return; - if (c->Debug && list[i].dump) { + if ((c->Debug & RC_DBG_LOG) && list[i].dump) { fprintf(stderr, "%s: after '%s'\n", shader_name, list[i].name); rc_print_program(&c->Program); } } } + if (c->Debug & RC_DBG_STATS) + print_stats(c); } void rc_validate_final_shader(struct radeon_compiler *c, void *user) diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h index 6d96ac9fdd9..31fd469a04f 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h @@ -30,12 +30,15 @@ #include "radeon_program.h" #include "radeon_emulate_loops.h" +#define RC_DBG_LOG (1 << 0) +#define RC_DBG_STATS (1 << 1) + struct rc_swizzle_caps; struct radeon_compiler { struct memory_pool Pool; struct rc_program Program; - unsigned Debug:1; + unsigned Debug:2; unsigned Error:1; char * ErrorMsg; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_remove_constants.c b/src/mesa/drivers/dri/r300/compiler/radeon_remove_constants.c index d6c808ad815..5f67f536f61 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_remove_constants.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_remove_constants.c @@ -145,6 +145,6 @@ void rc_remove_unused_constants(struct radeon_compiler *c, void *user) free(const_used); free(inv_remap_table); - if (c->Debug) + if (c->Debug & RC_DBG_LOG) rc_constants_print(&c->Program.Constants); } -- 2.30.2