[Mesa-dev] [PATCH v2 3/3] radeonsi: add RADEON_REPLACE_SHADERS debug option

Marek Olšák maraeo at gmail.com
Tue Dec 22 12:26:39 PST 2015


For the series:

Reviewed-by: Marek Olšák <marek.olsak at amd.com>

On Mon, Dec 21, 2015 at 10:18 PM, Nicolai Hähnle <nhaehnle at gmail.com> wrote:
> From: Nicolai Hähnle <nicolai.haehnle at 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list