r300g: Add new debug option for logging vertex/fragment program stats
authorTom Stellard <tstellar@gmail.com>
Mon, 18 Oct 2010 06:17:01 +0000 (23:17 -0700)
committerTom Stellard <tstellar@gmail.com>
Tue, 19 Oct 2010 03:51:05 +0000 (20:51 -0700)
src/gallium/drivers/r300/r300_debug.c
src/gallium/drivers/r300/r300_fs.c
src/gallium/drivers/r300/r300_screen.h
src/gallium/drivers/r300/r300_vs.c
src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
src/mesa/drivers/dri/r300/compiler/radeon_remove_constants.c

index 145a798..f78fe34 100644 (file)
@@ -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" },
index d9d4a93..c91532e 100644 (file)
@@ -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);
     }
index dc2bc7e..8b7f1fa 100644 (file)
@@ -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)
index e2b9af9..6569655 100644 (file)
@@ -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);
     }
index 4793f33..2f13019 100644 (file)
@@ -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}
        };
 
index d7d49e5..bf8341f 100644 (file)
@@ -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}
        };
 
index b410b2d..125d64e 100644 (file)
@@ -26,7 +26,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#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)
index 6d96ac9..31fd469 100644 (file)
 #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;
 
index d6c808a..5f67f53 100644 (file)
@@ -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);
 }