For the series: Reviewed-by: Marek Olšák <marek.ol...@amd.com>
On Mon, Dec 21, 2015 at 10:18 PM, Nicolai Hähnle <nhaeh...@gmail.com> wrote: > From: Nicolai Hähnle <nicolai.haeh...@amd.com> > > This option allows replacing a single shader by a pre-compiled ELF object > as generated by LLVM's llc, for example. This can be useful for debugging a > deterministically occuring error in shaders (and has in fact helped find > the causes of https://bugs.freedesktop.org/show_bug.cgi?id=93264). > > v2: drop the debug flag, use DEBUG_GET_ONCE_OPTION instead > --- > src/gallium/drivers/radeonsi/si_debug.c | 95 > ++++++++++++++++++++++++++++++++ > src/gallium/drivers/radeonsi/si_pipe.h | 1 + > src/gallium/drivers/radeonsi/si_shader.c | 14 +++-- > 3 files changed, 105 insertions(+), 5 deletions(-) > > diff --git a/src/gallium/drivers/radeonsi/si_debug.c > b/src/gallium/drivers/radeonsi/si_debug.c > index c45f8c0..a07b1c5 100644 > --- a/src/gallium/drivers/radeonsi/si_debug.c > +++ b/src/gallium/drivers/radeonsi/si_debug.c > @@ -28,8 +28,11 @@ > #include "si_shader.h" > #include "sid.h" > #include "sid_tables.h" > +#include "radeon/radeon_elf_util.h" > #include "ddebug/dd_util.h" > +#include "util/u_memory.h" > > +DEBUG_GET_ONCE_OPTION(replace_shaders, "RADEON_REPLACE_SHADERS", NULL) > > static void si_dump_shader(struct si_shader_ctx_state *state, const char > *name, > FILE *f) > @@ -42,6 +45,98 @@ static void si_dump_shader(struct si_shader_ctx_state > *state, const char *name, > fprintf(f, "%s\n\n", state->current->binary.disasm_string); > } > > +/** > + * Shader compiles can be overridden with arbitrary ELF objects by setting > + * the environment variable > RADEON_REPLACE_SHADERS=num1:filename1[;num2:filename2] > + */ > +bool si_replace_shader(unsigned num, struct radeon_shader_binary *binary) > +{ > + const char *p = debug_get_option_replace_shaders(); > + const char *semicolon; > + char *copy = NULL; > + FILE *f; > + long filesize, nread; > + char *buf = NULL; > + bool replaced = false; > + > + if (!p) > + return false; > + > + while (*p) { > + unsigned long i; > + char *endp; > + i = strtoul(p, &endp, 0); > + > + p = endp; > + if (*p != ':') { > + fprintf(stderr, "RADEON_REPLACE_SHADERS formatted > badly.\n"); > + exit(1); > + } > + ++p; > + > + if (i == num) > + break; > + > + p = strchr(p, ';'); > + if (!p) > + return false; > + ++p; > + } > + if (!*p) > + return false; > + > + semicolon = strchr(p, ';'); > + if (semicolon) { > + p = copy = strndup(p, semicolon - p); > + if (!copy) { > + fprintf(stderr, "out of memory\n"); > + return false; > + } > + } > + > + fprintf(stderr, "radeonsi: replace shader %u by %s\n", num, p); > + > + f = fopen(p, "r"); > + if (!f) { > + perror("radeonsi: failed to open file"); > + goto out_free; > + } > + > + if (fseek(f, 0, SEEK_END) != 0) > + goto file_error; > + > + filesize = ftell(f); > + if (filesize < 0) > + goto file_error; > + > + if (fseek(f, 0, SEEK_SET) != 0) > + goto file_error; > + > + buf = MALLOC(filesize); > + if (!buf) { > + fprintf(stderr, "out of memory\n"); > + goto out_close; > + } > + > + nread = fread(buf, 1, filesize, f); > + if (nread != filesize) > + goto file_error; > + > + radeon_elf_read(buf, filesize, binary); > + replaced = true; > + > +out_close: > + fclose(f); > +out_free: > + FREE(buf); > + free(copy); > + return replaced; > + > +file_error: > + perror("radeonsi: reading shader"); > + goto out_close; > +} > + > /* Parsed IBs are difficult to read without colors. Use "less -R file" to > * read them, or use "aha -b -f file" to convert them to html. > */ > diff --git a/src/gallium/drivers/radeonsi/si_pipe.h > b/src/gallium/drivers/radeonsi/si_pipe.h > index 65c7e19..f83cb02 100644 > --- a/src/gallium/drivers/radeonsi/si_pipe.h > +++ b/src/gallium/drivers/radeonsi/si_pipe.h > @@ -329,6 +329,7 @@ void si_init_cp_dma_functions(struct si_context *sctx); > /* si_debug.c */ > void si_init_debug_functions(struct si_context *sctx); > void si_check_vm_faults(struct si_context *sctx); > +bool si_replace_shader(unsigned num, struct radeon_shader_binary *binary); > > /* si_dma.c */ > void si_dma_copy(struct pipe_context *ctx, > diff --git a/src/gallium/drivers/radeonsi/si_shader.c > b/src/gallium/drivers/radeonsi/si_shader.c > index 511ed88..0e98784 100644 > --- a/src/gallium/drivers/radeonsi/si_shader.c > +++ b/src/gallium/drivers/radeonsi/si_shader.c > @@ -3884,13 +3884,17 @@ int si_compile_llvm(struct si_screen *sscreen, struct > si_shader *shader, > bool dump_asm = r600_can_dump_shader(&sscreen->b, > shader->selector ? shader->selector->tokens : > NULL); > bool dump_ir = dump_asm && !(sscreen->b.debug_flags & DBG_NO_IR); > + unsigned count = p_atomic_inc_return(&sscreen->b.num_compilations); > > - p_atomic_inc(&sscreen->b.num_compilations); > + if (dump_ir || dump_asm) > + fprintf(stderr, "radeonsi: Compiling shader %d\n", count); > > - r = radeon_llvm_compile(mod, &shader->binary, > - r600_get_llvm_processor_name(sscreen->b.family), dump_ir, > dump_asm, tm); > - if (r) > - return r; > + if (!si_replace_shader(count, &shader->binary)) { > + r = radeon_llvm_compile(mod, &shader->binary, > + r600_get_llvm_processor_name(sscreen->b.family), > dump_ir, dump_asm, tm); > + if (r) > + return r; > + } > > r = si_shader_binary_read(sscreen, shader); > > -- > 2.5.0 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev