intel/tools: add ability to dump out raw kernels data
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Wed, 26 Apr 2023 08:14:25 +0000 (11:14 +0300)
committerMarge Bot <emma+marge@anholt.net>
Wed, 26 Apr 2023 10:00:54 +0000 (10:00 +0000)
Useful for debug.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Marcin Ĺšlusarz <marcin.slusarz@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22703>

src/intel/common/intel_batch_decoder.c
src/intel/common/intel_decoder.h
src/intel/common/intel_disasm.c
src/intel/common/intel_disasm.h
src/intel/tools/aubinator_error_decode.c

index 8a2b67c..4f2a01e 100644 (file)
@@ -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");
index 1e0386d..bc87bf0 100644 (file)
@@ -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;
index 354676c..abf7634 100644 (file)
@@ -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.
index 4d4fd1b..756fc03 100644 (file)
@@ -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);
 
index 2021e9f..58d009e 100644 (file)
@@ -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;
 
@@ -407,6 +408,24 @@ get_intel_batch_bo(void *user_data, bool ppgtt, uint64_t address)
 }
 
 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)
 {
    struct intel_spec *spec = NULL;
@@ -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 }
    };