From 39a2da738d85adca0fef6ee8fa7363836be3401a Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Fri, 8 Jan 2021 15:09:30 +0200 Subject: [PATCH] ir3: add debug option to override shader assembly IR3_SHADER_DEBUG=vs,tcs,tes... now also prints shader's sha1. When there is a file named %sha1%.asm in IR3_SHADER_OVERRIDE_PATH directory - ir3 assembly from file would be parsed, assembled, and will override the shader with corresponding sha1 hash. Parsing failure is considered unrecoverable error. Upon successful override shader's assembly is printed with: "Native code (overridden) for unnamed ..." This debug option allows easier testing of small changes in assembly without modifying the compiler or using computerator. Signed-off-by: Danylo Piliaiev Part-of: --- src/freedreno/ir3/ir3_compiler.c | 8 ++++++ src/freedreno/ir3/ir3_compiler.h | 1 + src/freedreno/ir3/ir3_shader.c | 62 ++++++++++++++++++++++++++++++++++++---- 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/src/freedreno/ir3/ir3_compiler.c b/src/freedreno/ir3/ir3_compiler.c index 09167e9..c27e8bc 100644 --- a/src/freedreno/ir3/ir3_compiler.c +++ b/src/freedreno/ir3/ir3_compiler.c @@ -50,8 +50,10 @@ static const struct debug_named_value shader_debug_options[] = { }; DEBUG_GET_ONCE_FLAGS_OPTION(ir3_shader_debug, "IR3_SHADER_DEBUG", shader_debug_options, 0) +DEBUG_GET_ONCE_OPTION(ir3_shader_override_path, "IR3_SHADER_OVERRIDE_PATH", NULL) enum ir3_shader_debug ir3_shader_debug = 0; +const char *ir3_shader_override_path = NULL; void ir3_compiler_destroy(struct ir3_compiler *compiler) @@ -66,6 +68,12 @@ ir3_compiler_create(struct fd_device *dev, uint32_t gpu_id) struct ir3_compiler *compiler = rzalloc(NULL, struct ir3_compiler); ir3_shader_debug = debug_get_option_ir3_shader_debug(); + ir3_shader_override_path = + !__check_suid() ? debug_get_option_ir3_shader_override_path() : NULL; + + if (ir3_shader_override_path) { + ir3_shader_debug |= IR3_DBG_NOCACHE; + } compiler->dev = dev; compiler->gpu_id = gpu_id; diff --git a/src/freedreno/ir3/ir3_compiler.h b/src/freedreno/ir3/ir3_compiler.h index 9924140..54a78f3 100644 --- a/src/freedreno/ir3/ir3_compiler.h +++ b/src/freedreno/ir3/ir3_compiler.h @@ -155,6 +155,7 @@ enum ir3_shader_debug { }; extern enum ir3_shader_debug ir3_shader_debug; +extern const char *ir3_shader_override_path; static inline bool shader_debug_enabled(gl_shader_stage type) diff --git a/src/freedreno/ir3/ir3_shader.c b/src/freedreno/ir3/ir3_shader.c index a4feb9b..835b67c 100644 --- a/src/freedreno/ir3/ir3_shader.c +++ b/src/freedreno/ir3/ir3_shader.c @@ -35,6 +35,8 @@ #include "ir3_shader.h" #include "ir3_compiler.h" #include "ir3_nir.h" +#include "ir3_assembler.h" +#include "ir3_parser.h" #include "isa/isa.h" @@ -181,17 +183,65 @@ void * ir3_shader_assemble(struct ir3_shader_variant *v) return bin; } +static bool +try_override_shader_variant(struct ir3_shader_variant *v, const char *identifier) +{ + assert(ir3_shader_override_path); + + char *name = ralloc_asprintf(NULL, "%s/%s.asm", ir3_shader_override_path, identifier); + + FILE* f = fopen(name, "r"); + + if (!f) { + ralloc_free(name); + return false; + } + + struct ir3_kernel_info info; + info.numwg = INVALID_REG; + v->ir = ir3_parse(v, &info, f); + + fclose(f); + + if (!v->ir) { + fprintf(stderr, "Failed to parse %s\n", name); + exit(1); + } + + v->bin = ir3_shader_assemble(v); + if (!v->bin) { + fprintf(stderr, "Failed to assemble %s\n", name); + exit(1); + } + + ralloc_free(name); + return true; +} + static void assemble_variant(struct ir3_shader_variant *v) { v->bin = ir3_shader_assemble(v); - if (shader_debug_enabled(v->shader->type)) { - fprintf(stdout, "Native code for unnamed %s shader %s:\n", - ir3_shader_stage(v), v->shader->nir->info.name); - if (v->shader->type == MESA_SHADER_FRAGMENT) - fprintf(stdout, "SIMD0\n"); - ir3_shader_disasm(v, v->bin, stdout); + bool dbg_enabled = shader_debug_enabled(v->shader->type); + if (dbg_enabled || ir3_shader_override_path) { + unsigned char sha1[21]; + char sha1buf[41]; + + _mesa_sha1_compute(v->bin, v->info.size, sha1); + _mesa_sha1_format(sha1buf, sha1); + + bool shader_overridden = + ir3_shader_override_path && try_override_shader_variant(v, sha1buf); + + if (dbg_enabled || shader_overridden) { + fprintf(stdout, "Native code%s for unnamed %s shader %s with sha1 %s:\n", + shader_overridden ? " (overridden)" : "", + ir3_shader_stage(v), v->shader->nir->info.name, sha1buf); + if (v->shader->type == MESA_SHADER_FRAGMENT) + fprintf(stdout, "SIMD0\n"); + ir3_shader_disasm(v, v->bin, stdout); + } } /* no need to keep the ir around beyond this point: */ -- 2.7.4