ir3: add debug option to override shader assembly
authorDanylo Piliaiev <dpiliaiev@igalia.com>
Fri, 8 Jan 2021 13:09:30 +0000 (15:09 +0200)
committerMarge Bot <eric+marge@anholt.net>
Thu, 14 Jan 2021 21:51:16 +0000 (21:51 +0000)
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 <dpiliaiev@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8388>

src/freedreno/ir3/ir3_compiler.c
src/freedreno/ir3/ir3_compiler.h
src/freedreno/ir3/ir3_shader.c

index 09167e9..c27e8bc 100644 (file)
@@ -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;
index 9924140..54a78f3 100644 (file)
@@ -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)
index a4feb9b..835b67c 100644 (file)
@@ -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: */