radeonsi: pre-generate shader logs for ddebug
authorMarek Olšák <marek.olsak@amd.com>
Fri, 22 Jul 2016 21:40:45 +0000 (23:40 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Tue, 26 Jul 2016 21:06:46 +0000 (23:06 +0200)
This cuts down the overhead of si_dump_shader when ddebug is capturing
shader logs, which is done for every draw call unconditionally (that's
quite a lot of work for a draw call).

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeonsi/si_debug.c
src/gallium/drivers/radeonsi/si_shader.c
src/gallium/drivers/radeonsi/si_shader.h
src/gallium/drivers/radeonsi/si_state_shaders.c

index d9d4890b90e3f0a99debe5a773c7b6116d4db0a5..e030f4875425dcc800e9a41bb96a31bb9f96a2e7 100644 (file)
@@ -37,11 +37,16 @@ DEBUG_GET_ONCE_OPTION(replace_shaders, "RADEON_REPLACE_SHADERS", NULL)
 static void si_dump_shader(struct si_screen *sscreen,
                           struct si_shader_ctx_state *state, FILE *f)
 {
-       if (!state->cso || !state->current)
+       struct si_shader *current = state->current;
+
+       if (!state->cso || !current)
                return;
 
-       si_shader_dump(sscreen, state->current, NULL,
-                      state->cso->info.processor, f);
+       if (current->shader_log)
+               fwrite(current->shader_log, current->shader_log_size, 1, f);
+       else
+               si_shader_dump(sscreen, state->current, NULL,
+                              state->cso->info.processor, f);
 }
 
 /**
index 47947371fc3c89193e653bf137a478ab6a729b9c..62a1486fbe24651a6ab1cc26f18338fd53ef3d76 100644 (file)
@@ -7951,4 +7951,6 @@ void si_shader_destroy(struct si_shader *shader)
 
        if (!shader->is_binary_shared)
                radeon_shader_binary_clean(&shader->binary);
+
+       free(shader->shader_log);
 }
index 6073296ac9f0b8a82589ec254e80226fbc2130c4..e8560498988ca82bfd5f8f0138f78da84ebe380b 100644 (file)
@@ -240,6 +240,7 @@ struct si_shader_selector {
         * if thread_index == -1 (non-threaded). */
        LLVMTargetMachineRef    tm;
        struct pipe_debug_callback debug;
+       bool                    is_debug_context;
 
        pipe_mutex              mutex;
        struct si_shader        *first_variant; /* immutable after the first variant */
@@ -438,6 +439,12 @@ struct si_shader {
        struct radeon_shader_binary     binary;
        struct si_shader_config         config;
        struct si_shader_info           info;
+
+       /* Shader key + LLVM IR + disassembly + statistics.
+        * Generated for debug contexts only.
+        */
+       char                            *shader_log;
+       size_t                          shader_log_size;
 };
 
 struct si_shader_part {
index fd3ba9d897209698b44918e13e88188d3b25da44..47cf496ae41d6dfdb230a789542bee64dd19f5a8 100644 (file)
@@ -992,7 +992,8 @@ static int si_shader_select_with_key(struct si_screen *sscreen,
                                     union si_shader_key *key,
                                     LLVMTargetMachineRef tm,
                                     struct pipe_debug_callback *debug,
-                                    bool wait)
+                                    bool wait,
+                                    bool is_debug_context)
 {
        struct si_shader_selector *sel = state->cso;
        struct si_shader *current = state->current;
@@ -1043,6 +1044,16 @@ static int si_shader_select_with_key(struct si_screen *sscreen,
                pipe_mutex_unlock(sel->mutex);
                return r;
        }
+
+       if (is_debug_context) {
+               FILE *f = open_memstream(&shader->shader_log,
+                                        &shader->shader_log_size);
+               if (f) {
+                       si_shader_dump(sscreen, shader, NULL, sel->type, f);
+                       fclose(f);
+               }
+       }
+
        si_shader_init_pm4_state(sscreen, shader);
 
        if (!sel->last_variant) {
@@ -1065,7 +1076,8 @@ static int si_shader_select(struct pipe_context *ctx,
 
        si_shader_selector_key(ctx, state->cso, &key);
        return si_shader_select_with_key(sctx->screen, state, &key,
-                                        sctx->tm, &sctx->b.debug, true);
+                                        sctx->tm, &sctx->b.debug, true,
+                                        sctx->is_debug);
 }
 
 static void si_parse_next_shader_property(const struct tgsi_shader_info *info,
@@ -1190,7 +1202,7 @@ void si_init_shader_selector_async(void *job, int thread_index)
                }
 
                if (si_shader_select_with_key(sscreen, &state, &key, tm, debug,
-                                             false))
+                                             false, sel->is_debug_context))
                        fprintf(stderr, "radeonsi: can't create a monolithic shader\n");
        }
 }
@@ -1209,6 +1221,7 @@ static void *si_create_shader_selector(struct pipe_context *ctx,
        sel->screen = sscreen;
        sel->tm = sctx->tm;
        sel->debug = sctx->b.debug;
+       sel->is_debug_context = sctx->is_debug;
        sel->tokens = tgsi_dup_tokens(state->tokens);
        if (!sel->tokens) {
                FREE(sel);
@@ -1325,6 +1338,7 @@ static void *si_create_shader_selector(struct pipe_context *ctx,
        util_queue_fence_init(&sel->ready);
 
        if ((sctx->b.debug.debug_message && !sctx->b.debug.async) ||
+           sctx->is_debug ||
            r600_can_dump_shader(&sscreen->b, sel->info.processor) ||
            !util_queue_is_initialized(&sscreen->shader_compiler_queue))
                si_init_shader_selector_async(sel, -1);