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
}
}
- ctx_disassemble_program(ctx, ksp, "compute shader");
+ ctx_disassemble_program(ctx, ksp, "CS", "compute shader");
fprintf(ctx->fp, "\n");
if (sampler_count)
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");
}
}
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");
}
}
}
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");
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;
}
if (is_enabled) {
- ctx_disassemble_program(ctx, ksp, type);
+ ctx_disassemble_program(ctx, ksp, short_name, type);
fprintf(ctx->fp, "\n");
}
}
}
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
}
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
}
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");
}
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");
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;
}
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;
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;
" --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);
}
{ "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 }
};