From 8b749ee0eaf935481ee37697e5a28b278d616885 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Sat, 11 Nov 2017 23:26:19 -0800 Subject: [PATCH] intel/tools/error: Decode shaders while decoding batch commands. This makes aubinator_error_decode's shader dumping work like aubinator. Instead of printing them after the fact, it prints them right inside the 3DSTATE_VS/HS/DS/GS/PS packet that references them. This saves you the effort of cross-referencing things and jumping back and forth. It also reduces a bunch of book-keeping, and eliminates the limitation that we could only handle 4096 programs. That code was also broken and failed to print any shaders if there were under 4096 programs. Reviewed-by: Lionel Landwerlin --- src/intel/tools/aubinator_error_decode.c | 134 +++++++++-------------- 1 file changed, 49 insertions(+), 85 deletions(-) diff --git a/src/intel/tools/aubinator_error_decode.c b/src/intel/tools/aubinator_error_decode.c index cea68523ae2..96b4989936e 100644 --- a/src/intel/tools/aubinator_error_decode.c +++ b/src/intel/tools/aubinator_error_decode.c @@ -221,35 +221,28 @@ struct section { #define MAX_SECTIONS 30 static struct section sections[MAX_SECTIONS]; -struct program { - const char *type; - const char *command; - uint64_t command_offset; - uint64_t instruction_base_address; - uint64_t ksp; -}; - -#define MAX_NUM_PROGRAMS 4096 -static struct program programs[MAX_NUM_PROGRAMS]; -static int idx_program = 0, num_programs = 0; - -static int next_program(void) +static void +disassemble_program(struct gen_disasm *disasm, const char *type, + const struct section *instruction_section, + uint64_t ksp) { - int ret = idx_program; - idx_program = (idx_program + 1) % MAX_NUM_PROGRAMS; - num_programs = MIN(num_programs + 1, MAX_NUM_PROGRAMS); - return ret; + if (!instruction_section) + return; + + printf("\nReferenced %s:\n", type); + gen_disasm_disassemble(disasm, instruction_section->data, ksp, stdout); } static void -decode(struct gen_spec *spec, const struct section *section) +decode(struct gen_spec *spec, struct gen_disasm *disasm, + const struct section *section) { uint64_t gtt_offset = section->gtt_offset; uint32_t *data = section->data; uint32_t *p, *end = (data + section->count); int length; struct gen_group *inst; - uint64_t current_instruction_base_address = 0; + const struct section *current_instruction_buffer = NULL; for (p = data; p < end; p += length) { const char *color = option_full_decode ? BLUE_HEADER : NORMAL, @@ -284,7 +277,13 @@ decode(struct gen_spec *spec, const struct section *section) while (gen_field_iterator_next(&iter)) { if (strcmp(iter.name, "Instruction Base Address") == 0) { - current_instruction_base_address = strtol(iter.value, NULL, 16); + uint64_t instr_base_address = strtol(iter.value, NULL, 16); + current_instruction_buffer = NULL; + for (int s = 0; s < MAX_SECTIONS; s++) { + if (sections[s].gtt_offset == instr_base_address) { + current_instruction_buffer = §ions[s]; + } + } } } } else if (strcmp(inst->name, "WM_STATE") == 0 || @@ -309,50 +308,37 @@ decode(struct gen_spec *spec, const struct section *section) } } + /* Reorder KSPs to be [8, 16, 32] instead of the hardware order. */ + if (enabled[0] + enabled[1] + enabled[2] == 1) { + if (enabled[1]) { + ksp[1] = ksp[0]; + ksp[0] = 0; + } else if (enabled[2]) { + ksp[2] = ksp[0]; + ksp[0] = 0; + } + } else { + uint64_t tmp = ksp[1]; + ksp[1] = ksp[2]; + ksp[2] = tmp; + } + /* FINISHME: Broken for multi-program WM_STATE, * which Mesa does not use */ - if (enabled[0] + enabled[1] + enabled[2] == 1) { - const char *type = enabled[0] ? "SIMD8 fragment shader" : - enabled[1] ? "SIMD16 fragment shader" : - enabled[2] ? "SIMD32 fragment shader" : NULL; - - programs[next_program()] = (struct program) { - .type = type, - .command = inst->name, - .command_offset = offset, - .instruction_base_address = current_instruction_base_address, - .ksp = ksp[0], - }; - } else { - if (enabled[0]) /* SIMD8 */ { - programs[next_program()] = (struct program) { - .type = "SIMD8 fragment shader", - .command = inst->name, - .command_offset = offset, - .instruction_base_address = current_instruction_base_address, - .ksp = ksp[0], /* SIMD8 shader is specified by ksp[0] */ - }; - } - if (enabled[1]) /* SIMD16 */ { - programs[next_program()] = (struct program) { - .type = "SIMD16 fragment shader", - .command = inst->name, - .command_offset = offset, - .instruction_base_address = current_instruction_base_address, - .ksp = ksp[2], /* SIMD16 shader is specified by ksp[2] */ - }; - } - if (enabled[2]) /* SIMD32 */ { - programs[next_program()] = (struct program) { - .type = "SIMD32 fragment shader", - .command = inst->name, - .command_offset = offset, - .instruction_base_address = current_instruction_base_address, - .ksp = ksp[1], /* SIMD32 shader is specified by ksp[1] */ - }; - } + if (enabled[0]) { + disassemble_program(disasm, "SIMD8 fragment shader", + current_instruction_buffer, ksp[0]); + } + if (enabled[1]) { + disassemble_program(disasm, "SIMD16 fragment shader", + current_instruction_buffer, ksp[1]); + } + if (enabled[2]) { + disassemble_program(disasm, "SIMD32 fragment shader", + current_instruction_buffer, ksp[2]); } + printf("\n"); } else if (strcmp(inst->name, "VS_STATE") == 0 || strcmp(inst->name, "GS_STATE") == 0 || strcmp(inst->name, "SF_STATE") == 0 || @@ -391,13 +377,8 @@ decode(struct gen_spec *spec, const struct section *section) NULL; if (is_enabled) { - programs[next_program()] = (struct program) { - .type = type, - .command = inst->name, - .command_offset = offset, - .instruction_base_address = current_instruction_base_address, - .ksp = ksp, - }; + disassemble_program(disasm, type, current_instruction_buffer, ksp); + printf("\n"); } } } @@ -671,24 +652,7 @@ read_data_file(FILE *file) if (strcmp(sections[s].buffer_name, "batch buffer") == 0 || strcmp(sections[s].buffer_name, "ring buffer") == 0 || strcmp(sections[s].buffer_name, "HW Context") == 0) { - decode(spec, §ions[s]); - } else if (strcmp(sections[s].buffer_name, "user") == 0) { - printf("Disassembly of programs in instruction buffer at " - "0x%08"PRIx64":\n", sections[s].gtt_offset); - for (int i = 0; i < num_programs; i++) { - int idx = (idx_program + i) % MAX_NUM_PROGRAMS; - if (programs[idx].instruction_base_address == - sections[s].gtt_offset) { - printf("\n%s (specified by %s at batch offset " - "0x%08"PRIx64") at offset 0x%08"PRIx64"\n", - programs[idx].type, - programs[idx].command, - programs[idx].command_offset, - programs[idx].ksp); - gen_disasm_disassemble(disasm, sections[s].data, - programs[idx].ksp, stdout); - } - } + decode(spec, disasm, §ions[s]); } free(sections[s].ring_name); -- 2.30.2