Module: Mesa Branch: main Commit: 5c214117ad131286539904ba7f5600b71a4dbd01 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=5c214117ad131286539904ba7f5600b71a4dbd01
Author: Lionel Landwerlin <[email protected]> Date: Wed Apr 26 11:14:25 2023 +0300 intel/tools: add ability to dump out raw kernels data Useful for debug. Signed-off-by: Lionel Landwerlin <[email protected]> Reviewed-by: Marcin Ĺšlusarz <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22703> --- src/intel/common/intel_batch_decoder.c | 51 +++++++++++++++++++++++--------- src/intel/common/intel_decoder.h | 7 +++++ src/intel/common/intel_disasm.c | 8 ++--- src/intel/common/intel_disasm.h | 3 ++ src/intel/tools/aubinator_error_decode.c | 25 +++++++++++++++- 5 files changed, 75 insertions(+), 19 deletions(-) diff --git a/src/intel/common/intel_batch_decoder.c b/src/intel/common/intel_batch_decoder.c index 8a2b67c577b..4f2a01ec529 100644 --- a/src/intel/common/intel_batch_decoder.c +++ b/src/intel/common/intel_batch_decoder.c @@ -140,15 +140,24 @@ update_count(struct intel_batch_decode_ctx *ctx, static void ctx_disassemble_program(struct intel_batch_decode_ctx *ctx, - uint32_t ksp, const char *type) + uint32_t ksp, + const char *short_name, + const char *name) { uint64_t addr = ctx->instruction_base + ksp; struct intel_batch_decode_bo bo = ctx_get_bo(ctx, true, addr); if (!bo.map) return; - fprintf(ctx->fp, "\nReferenced %s:\n", type); + fprintf(ctx->fp, "\nReferenced %s:\n", name); intel_disassemble(ctx->isa, bo.map, 0, ctx->fp); + + if (ctx->shader_binary) { + int size = intel_disassemble_find_end(ctx->isa, bo.map, 0); + + ctx->shader_binary(ctx->user_data, short_name, addr, + bo.map, size); + } } /* Heuristic to determine whether a uint32_t is probably actually a float @@ -412,7 +421,7 @@ handle_interface_descriptor_data(struct intel_batch_decode_ctx *ctx, } } - ctx_disassemble_program(ctx, ksp, "compute shader"); + ctx_disassemble_program(ctx, ksp, "CS", "compute shader"); fprintf(ctx->fp, "\n"); if (sampler_count) @@ -656,9 +665,19 @@ decode_single_ksp(struct intel_batch_decode_ctx *ctx, const uint32_t *p) strcmp(inst->name, "3DSTATE_VS") == 0 ? (is_simd8 ? "SIMD8 vertex shader" : "vec4 vertex shader") : strcmp(inst->name, "3DSTATE_GS") == 0 ? (is_simd8 ? "SIMD8 geometry shader" : "vec4 geometry shader") : NULL; + const char *short_name = + strcmp(inst->name, "VS_STATE") == 0 ? "VS" : + strcmp(inst->name, "GS_STATE") == 0 ? "GS" : + strcmp(inst->name, "SF_STATE") == 0 ? "SF" : + strcmp(inst->name, "CLIP_STATE") == 0 ? "CL" : + strcmp(inst->name, "3DSTATE_DS") == 0 ? "DS" : + strcmp(inst->name, "3DSTATE_HS") == 0 ? "HS" : + strcmp(inst->name, "3DSTATE_VS") == 0 ? "VS" : + strcmp(inst->name, "3DSTATE_GS") == 0 ? "GS" : + NULL; if (is_enabled) { - ctx_disassemble_program(ctx, ksp, type); + ctx_disassemble_program(ctx, ksp, short_name, type); fprintf(ctx->fp, "\n"); } } @@ -688,9 +707,13 @@ decode_mesh_task_ksp(struct intel_batch_decode_ctx *ctx, const uint32_t *p) strcmp(inst->name, "3DSTATE_MESH_SHADER") == 0 ? "mesh shader" : strcmp(inst->name, "3DSTATE_TASK_SHADER") == 0 ? "task shader" : NULL; + const char *short_name = + strcmp(inst->name, "3DSTATE_MESH_SHADER") == 0 ? "MS" : + strcmp(inst->name, "3DSTATE_TASK_SHADER") == 0 ? "TS" : + NULL; if (threads && local_x_maximum) { - ctx_disassemble_program(ctx, ksp, type); + ctx_disassemble_program(ctx, ksp, short_name, type); fprintf(ctx->fp, "\n"); } } @@ -738,11 +761,11 @@ decode_ps_kern(struct intel_batch_decode_ctx *ctx, } if (enabled[0]) - ctx_disassemble_program(ctx, ksp[0], "SIMD8 fragment shader"); + ctx_disassemble_program(ctx, ksp[0], "FS8", "SIMD8 fragment shader"); if (enabled[1]) - ctx_disassemble_program(ctx, ksp[1], "SIMD16 fragment shader"); + ctx_disassemble_program(ctx, ksp[1], "FS16", "SIMD16 fragment shader"); if (enabled[2]) - ctx_disassemble_program(ctx, ksp[2], "SIMD32 fragment shader"); + ctx_disassemble_program(ctx, ksp[2], "FS32", "SIMD32 fragment shader"); if (enabled[0] || enabled[1] || enabled[2]) fprintf(ctx->fp, "\n"); @@ -1167,7 +1190,7 @@ decode_load_register_imm(struct intel_batch_decode_ctx *ctx, const uint32_t *p) static void disasm_program_from_group(struct intel_batch_decode_ctx *ctx, struct intel_group *strct, const void *map, - const char *type) + const char *short_name, const char *type) { uint64_t ksp = 0; bool is_enabled = true; @@ -1184,7 +1207,7 @@ disasm_program_from_group(struct intel_batch_decode_ctx *ctx, } if (is_enabled) { - ctx_disassemble_program(ctx, ksp, type); + ctx_disassemble_program(ctx, ksp, short_name, type); fprintf(ctx->fp, "\n"); } } @@ -1208,7 +1231,7 @@ decode_vs_state(struct intel_batch_decode_ctx *ctx, uint32_t offset) } ctx_print_group(ctx, strct, offset, bind_bo.map); - disasm_program_from_group(ctx, strct, bind_bo.map, "vertex shader"); + disasm_program_from_group(ctx, strct, bind_bo.map, "VS", "vertex shader"); } static void @@ -1230,7 +1253,7 @@ decode_gs_state(struct intel_batch_decode_ctx *ctx, uint32_t offset) } ctx_print_group(ctx, strct, offset, bind_bo.map); - disasm_program_from_group(ctx, strct, bind_bo.map, "geometry shader"); + disasm_program_from_group(ctx, strct, bind_bo.map, "GS", "geometry shader"); } static void @@ -1252,7 +1275,7 @@ decode_clip_state(struct intel_batch_decode_ctx *ctx, uint32_t offset) } ctx_print_group(ctx, strct, offset, bind_bo.map); - disasm_program_from_group(ctx, strct, bind_bo.map, "clip shader"); + disasm_program_from_group(ctx, strct, bind_bo.map, "CL", "clip shader"); struct intel_group *vp_strct = intel_spec_find_struct(ctx->spec, "CLIP_VIEWPORT"); @@ -1289,7 +1312,7 @@ decode_sf_state(struct intel_batch_decode_ctx *ctx, uint32_t offset) } ctx_print_group(ctx, strct, offset, bind_bo.map); - disasm_program_from_group(ctx, strct, bind_bo.map, "strips and fans shader"); + disasm_program_from_group(ctx, strct, bind_bo.map, "SF", "strips and fans shader"); struct intel_group *vp_strct = intel_spec_find_struct(ctx->spec, "SF_VIEWPORT"); diff --git a/src/intel/common/intel_decoder.h b/src/intel/common/intel_decoder.h index 1e0386d5206..bc87bf06383 100644 --- a/src/intel/common/intel_decoder.h +++ b/src/intel/common/intel_decoder.h @@ -235,6 +235,13 @@ struct intel_batch_decode_ctx { unsigned (*get_state_size)(void *user_data, uint64_t address, uint64_t base_address); + + void (*shader_binary)(void *user_data, + const char *short_name, + uint64_t address, + const void *data, + unsigned data_length); + void *user_data; FILE *fp; diff --git a/src/intel/common/intel_disasm.c b/src/intel/common/intel_disasm.c index 354676ccadf..abf76349c6e 100644 --- a/src/intel/common/intel_disasm.c +++ b/src/intel/common/intel_disasm.c @@ -38,9 +38,9 @@ is_send(uint32_t opcode) opcode == BRW_OPCODE_SENDSC ); } -static int -intel_disasm_find_end(const struct brw_isa_info *isa, - const void *assembly, int start) +int +intel_disassemble_find_end(const struct brw_isa_info *isa, + const void *assembly, int start) { const struct intel_device_info *devinfo = isa->devinfo; int offset = start; @@ -69,7 +69,7 @@ void intel_disassemble(const struct brw_isa_info *isa, const void *assembly, int start, FILE *out) { - int end = intel_disasm_find_end(isa, assembly, start); + int end = intel_disassemble_find_end(isa, assembly, start); /* Make a dummy disasm structure that brw_validate_instructions * can work from. diff --git a/src/intel/common/intel_disasm.h b/src/intel/common/intel_disasm.h index 4d4fd1bcc8f..756fc0380aa 100644 --- a/src/intel/common/intel_disasm.h +++ b/src/intel/common/intel_disasm.h @@ -31,6 +31,9 @@ extern "C" { #endif +int intel_disassemble_find_end(const struct brw_isa_info *isa, + const void *assembly, int start); + void intel_disassemble(const struct brw_isa_info *isa, const void *assembly, int start, FILE *out); diff --git a/src/intel/tools/aubinator_error_decode.c b/src/intel/tools/aubinator_error_decode.c index 2021e9f5acd..58d009ee707 100644 --- a/src/intel/tools/aubinator_error_decode.c +++ b/src/intel/tools/aubinator_error_decode.c @@ -50,6 +50,7 @@ static bool option_full_decode = true; static bool option_print_all_bb = false; static bool option_print_offsets = true; +static bool option_dump_kernels = false; static enum { COLOR_AUTO, COLOR_ALWAYS, COLOR_NEVER } option_color; static char *xml_path = NULL; @@ -406,6 +407,24 @@ get_intel_batch_bo(void *user_data, bool ppgtt, uint64_t address) return (struct intel_batch_decode_bo) { .map = NULL }; } +static void +dump_shader_binary(void *user_data, const char *short_name, + uint64_t address, const void *data, + unsigned data_length) +{ + char filename[128]; + snprintf(filename, sizeof(filename), "%s_0x%016"PRIx64".bin", + short_name, address); + + FILE *f = fopen(filename, "w"); + if (f == NULL) { + fprintf(stderr, "Unable to open %s\n", filename); + return; + } + fwrite(data, data_length, 1, f); + fclose(f); +} + static void read_data_file(FILE *file) { @@ -683,6 +702,8 @@ read_data_file(FILE *file) NULL, NULL); batch_ctx.acthd = acthd; + if (option_dump_kernels) + batch_ctx.shader_binary = dump_shader_binary; for (int s = 0; s < num_sections; s++) { enum intel_engine_class class; @@ -760,7 +781,8 @@ print_help(const char *progname, FILE *file) " --no-pager don't launch pager\n" " --no-offsets don't print instruction offsets\n" " --xml=DIR load hardware xml description from directory DIR\n" - " --all-bb print out all batchbuffers\n", + " --all-bb print out all batchbuffers\n" + " --kernels dump out all kernels (in current directory)\n", progname); } @@ -823,6 +845,7 @@ main(int argc, char *argv[]) { "color", optional_argument, NULL, 'c' }, { "xml", required_argument, NULL, 'x' }, { "all-bb", no_argument, (int *) &option_print_all_bb, true }, + { "kernels", no_argument, (int *) &option_dump_kernels, true }, { NULL, 0, NULL, 0 } };
