From 04a995158084acbd1917b4c7e0f8d381e1c9222d Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Thu, 23 May 2019 19:05:23 +0300 Subject: [PATCH] intel/compiler: add ability to override shader's assembly When dumping shader's assembly with INTEL_DEBUG=vs,tcs,... sha1 of the resulting assembly is also printed, having environment variable INTEL_SHADER_ASM_READ_PATH present driver will try to load a "%sha1%.bin" file from the path and substitute current assembly with the one from the file. Signed-off-by: Danylo Piliaiev Reviewed-by: Sagar Ghuge Reviewed-by: Matt Turner --- src/intel/compiler/brw_eu.c | 43 +++++++++++++++++++++++ src/intel/compiler/brw_eu.h | 3 ++ src/intel/compiler/brw_fs_generator.cpp | 20 +++++++++-- src/intel/compiler/brw_vec4_generator.cpp | 31 +++++++++++----- 4 files changed, 85 insertions(+), 12 deletions(-) diff --git a/src/intel/compiler/brw_eu.c b/src/intel/compiler/brw_eu.c index ec30579446b..882293e981b 100644 --- a/src/intel/compiler/brw_eu.c +++ b/src/intel/compiler/brw_eu.c @@ -29,6 +29,8 @@ * Keith Whitwell */ +#include +#include #include "brw_eu_defines.h" #include "brw_eu.h" @@ -349,6 +351,47 @@ const unsigned *brw_get_program( struct brw_codegen *p, return (const unsigned *)p->store; } +bool brw_try_override_assembly(struct brw_codegen *p, int start_offset, + const char *identifier) +{ + const char *read_path = getenv("INTEL_SHADER_ASM_READ_PATH"); + if (!read_path) { + return false; + } + + char *name = ralloc_asprintf(NULL, "%s/%s.bin", read_path, identifier); + + int fd = open(name, O_RDONLY); + ralloc_free(name); + + if (fd == -1) { + return false; + } + + struct stat sb; + if (fstat(fd, &sb) != 0 || (!S_ISREG(sb.st_mode))) { + return false; + } + + p->nr_insn -= (p->next_insn_offset - start_offset) / sizeof(brw_inst); + p->nr_insn += sb.st_size / sizeof(brw_inst); + + p->next_insn_offset = start_offset + sb.st_size; + p->store_size = (start_offset + sb.st_size) / sizeof(brw_inst); + p->store = reralloc_size(p->mem_ctx, p->store, p->next_insn_offset); + assert(p->store); + + read(fd, p->store + start_offset, sb.st_size); + close(fd); + + bool valid = brw_validate_instructions(p->devinfo, p->store, + start_offset, p->next_insn_offset, + 0); + assert(valid); + + return true; +} + void brw_disassemble(const struct gen_device_info *devinfo, const void *assembly, int start, int end, FILE *out) diff --git a/src/intel/compiler/brw_eu.h b/src/intel/compiler/brw_eu.h index e4b5ffdc64a..cb23c9ff51a 100644 --- a/src/intel/compiler/brw_eu.h +++ b/src/intel/compiler/brw_eu.h @@ -163,6 +163,9 @@ void brw_disassemble(const struct gen_device_info *devinfo, const void *assembly, int start, int end, FILE *out); const unsigned *brw_get_program( struct brw_codegen *p, unsigned *sz ); +bool brw_try_override_assembly(struct brw_codegen *p, int start_offset, + const char *identifier); + brw_inst *brw_next_insn(struct brw_codegen *p, unsigned opcode); void brw_set_dest(struct brw_codegen *p, brw_inst *insn, struct brw_reg dest); void brw_set_src0(struct brw_codegen *p, brw_inst *insn, struct brw_reg reg); diff --git a/src/intel/compiler/brw_fs_generator.cpp b/src/intel/compiler/brw_fs_generator.cpp index 62d19719c39..cd83a1fac70 100644 --- a/src/intel/compiler/brw_fs_generator.cpp +++ b/src/intel/compiler/brw_fs_generator.cpp @@ -30,6 +30,7 @@ #include "brw_eu.h" #include "brw_fs.h" #include "brw_cfg.h" +#include "util/mesa-sha1.h" static enum brw_reg_file brw_file_from_reg(fs_reg *reg) @@ -2290,13 +2291,21 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width) int after_size = p->next_insn_offset - start_offset; if (unlikely(debug_flag)) { - fprintf(stderr, "Native code for %s\n" + unsigned char sha1[21]; + char sha1buf[41]; + + _mesa_sha1_compute(p->store + start_offset / sizeof(brw_inst), + after_size, sha1); + _mesa_sha1_format(sha1buf, sha1); + + fprintf(stderr, "Native code for %s (sha1 %s)\n" "SIMD%d shader: %d instructions. %d loops. %u cycles. " "%d:%d spills:fills. " "scheduled with mode %s. " "Promoted %u constants. " "Compacted %d to %d bytes (%.0f%%)\n", - shader_name, dispatch_width, before_size / 16, + shader_name, sha1buf, + dispatch_width, before_size / 16, loop_count, cfg->cycle_count, spill_count, fill_count, shader_stats.scheduler_mode, @@ -2304,7 +2313,12 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width) before_size, after_size, 100.0f * (before_size - after_size) / before_size); - dump_assembly(p->store, disasm_info); + /* overriding the shader makes disasm_info invalid */ + if (!brw_try_override_assembly(p, start_offset, sha1buf)) { + dump_assembly(p->store, disasm_info); + } else { + fprintf(stderr, "Successfully overrode shader with sha1 %s\n\n", sha1buf); + } } ralloc_free(disasm_info); assert(validated); diff --git a/src/intel/compiler/brw_vec4_generator.cpp b/src/intel/compiler/brw_vec4_generator.cpp index d85e3c43241..338c638aeb5 100644 --- a/src/intel/compiler/brw_vec4_generator.cpp +++ b/src/intel/compiler/brw_vec4_generator.cpp @@ -24,6 +24,7 @@ #include "brw_cfg.h" #include "brw_eu.h" #include "dev/gen_debug.h" +#include "util/mesa-sha1.h" using namespace brw; @@ -2174,17 +2175,29 @@ generate_code(struct brw_codegen *p, int after_size = p->next_insn_offset; if (unlikely(debug_flag)) { - fprintf(stderr, "Native code for %s %s shader %s:\n", - nir->info.label ? nir->info.label : "unnamed", - _mesa_shader_stage_to_string(nir->info.stage), nir->info.name); + unsigned char sha1[21]; + char sha1buf[41]; - fprintf(stderr, "%s vec4 shader: %d instructions. %d loops. %u cycles. %d:%d " - "spills:fills. Compacted %d to %d bytes (%.0f%%)\n", - stage_abbrev, before_size / 16, loop_count, cfg->cycle_count, - spill_count, fill_count, before_size, after_size, - 100.0f * (before_size - after_size) / before_size); + _mesa_sha1_compute(p->store, p->next_insn_offset, sha1); + _mesa_sha1_format(sha1buf, sha1); + + fprintf(stderr, "Native code for %s %s shader %s (sha1 %s):\n", + nir->info.label ? nir->info.label : "unnamed", + _mesa_shader_stage_to_string(nir->info.stage), nir->info.name, + sha1buf); - dump_assembly(p->store, disasm_info); + fprintf(stderr, "%s vec4 shader: %d instructions. %d loops. %u cycles. %d:%d " + "spills:fills. Compacted %d to %d bytes (%.0f%%)\n", + stage_abbrev, before_size / 16, loop_count, cfg->cycle_count, + spill_count, fill_count, before_size, after_size, + 100.0f * (before_size - after_size) / before_size); + + /* overriding the shader makes disasm_info invalid */ + if (!brw_try_override_assembly(p, 0, sha1buf)) { + dump_assembly(p->store, disasm_info); + } else { + fprintf(stderr, "Successfully overrode shader with sha1 %s\n\n", sha1buf); + } } ralloc_free(disasm_info); assert(validated); -- 2.30.2