diff --git a/src/amd/compiler/aco_interface.cpp b/src/amd/compiler/aco_interface.cpp index c407e6e4214..d2180fa3750 100644 --- a/src/amd/compiler/aco_interface.cpp +++ b/src/amd/compiler/aco_interface.cpp @@ -73,6 +73,36 @@ validate(aco::Program* program) assert(is_valid); } +static std::string +get_disasm_string(aco::Program* program, std::vector& code, + unsigned exec_size) +{ + std::string disasm; + + if (check_print_asm_support(program)) { + char* data = NULL; + size_t disasm_size = 0; + struct u_memstream mem; + if (u_memstream_open(&mem, &data, &disasm_size)) { + FILE* const memf = u_memstream_get(&mem); + aco::print_asm(program, code, exec_size / 4u, memf); + fputc(0, memf); + u_memstream_close(&mem); + } + + disasm = std::string(data, data + disasm_size); + free(data); + } else { + disasm = "Shader disassembly is not supported in the current configuration" +#ifndef LLVM_AVAILABLE + " (LLVM not available)" +#endif + ".\n"; + } + + return disasm; +} + void aco_compile_shader(const struct radv_nir_compiler_options* options, const struct radv_shader_info* info, @@ -201,28 +231,8 @@ aco_compile_shader(const struct radv_nir_compiler_options* options, std::string disasm; if (get_disasm) { - if (check_print_asm_support(program.get())) { - char* data = NULL; - size_t disasm_size = 0; - struct u_memstream mem; - if (u_memstream_open(&mem, &data, &disasm_size)) { - FILE* const memf = u_memstream_get(&mem); - aco::print_asm(program.get(), code, exec_size / 4u, memf); - fputc(0, memf); - u_memstream_close(&mem); - } - - disasm = std::string(data, data + disasm_size); - size += disasm_size; - free(data); - } else { - disasm = "Shader disassembly is not supported in the current configuration" -#ifndef LLVM_AVAILABLE - " (LLVM not available)" -#endif - ".\n"; - size += disasm.length(); - } + disasm = get_disasm_string(program.get(), code, exec_size); + size += disasm.size(); } size_t stats_size = 0; @@ -297,21 +307,17 @@ aco_compile_vs_prolog(const struct radv_nir_compiler_options* options, code.reserve(align(program->blocks[0].instructions.size() * 2, 16)); unsigned exec_size = aco::emit_program(program.get(), code); - if (options->dump_shader) { - if (check_print_asm_support(program.get())) { - aco::print_asm(program.get(), code, exec_size / 4u, stderr); - fprintf(stderr, "\n"); - } else { - fprintf(stderr, "Shader disassembly is not supported in the current configuration" -#ifndef LLVM_AVAILABLE - " (LLVM not available)" -#endif - ".\n"); - } - } - /* copy into binary */ size_t size = code.size() * sizeof(uint32_t) + sizeof(radv_prolog_binary); + + bool get_disasm = options->dump_shader || options->record_ir; + + std::string disasm; + if (get_disasm) { + disasm = get_disasm_string(program.get(), code, exec_size); + size += disasm.size(); + } + radv_prolog_binary* prolog_binary = (radv_prolog_binary*)calloc(size, 1); prolog_binary->num_sgprs = config.num_sgprs; @@ -320,5 +326,11 @@ aco_compile_vs_prolog(const struct radv_nir_compiler_options* options, prolog_binary->code_size = code.size() * sizeof(uint32_t); memcpy(prolog_binary->data, code.data(), prolog_binary->code_size); + if (get_disasm) { + disasm.copy((char*)prolog_binary->data + prolog_binary->code_size, + disasm.size()); + prolog_binary->disasm_size = disasm.size(); + } + *binary = prolog_binary; } diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c index 374af6ff871..97dd2b1f7d4 100644 --- a/src/amd/vulkan/radv_shader.c +++ b/src/amd/vulkan/radv_shader.c @@ -1991,6 +1991,7 @@ upload_vs_prolog(struct radv_device *device, struct radv_prolog_binary *bin, uns prolog->rsrc1 = S_00B848_VGPRS((bin->num_vgprs - 1) / (wave_size == 32 ? 8 : 4)) | S_00B228_SGPRS((bin->num_sgprs - 1) / 8); prolog->num_preserved_sgprs = bin->num_preserved_sgprs; + prolog->disasm_string = NULL; return prolog; } @@ -2005,6 +2006,7 @@ radv_create_vs_prolog(struct radv_device *device, const struct radv_vs_prolog_ke options.info = &device->physical_device->rad_info; options.address32_hi = device->physical_device->rad_info.address32_hi; options.dump_shader = device->instance->debug_flags & RADV_DEBUG_DUMP_PROLOGS; + options.record_ir = device->instance->debug_flags & RADV_DEBUG_HANG; struct radv_shader_info info = {0}; info.wave_size = key->wave32 ? 32 : 64; @@ -2024,7 +2026,7 @@ radv_create_vs_prolog(struct radv_device *device, const struct radv_vs_prolog_ke info.user_sgprs_locs = args.user_sgprs_locs; #ifdef LLVM_AVAILABLE - if (options.dump_shader) + if (options.dump_shader || options.record_ir) ac_init_llvm_once(); #endif @@ -2033,9 +2035,17 @@ radv_create_vs_prolog(struct radv_device *device, const struct radv_vs_prolog_ke struct radv_shader_prolog *prolog = upload_vs_prolog(device, binary, info.wave_size); if (prolog) { prolog->nontrivial_divisors = key->state->nontrivial_divisors; + prolog->disasm_string = + binary->disasm_size ? strdup((const char *)(binary->data + binary->code_size)) : NULL; } + free(binary); + if (prolog && options.dump_shader) { + fprintf(stderr, "Vertex prolog"); + fprintf(stderr, "\ndisasm:\n%s\n", prolog->disasm_string); + } + return prolog; } @@ -2060,6 +2070,7 @@ radv_prolog_destroy(struct radv_device *device, struct radv_shader_prolog *prolo return; radv_free_shader_memory(device, prolog->alloc); + free(prolog->disasm_string); free(prolog); } diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h index a1814e6208f..0a01b9942b2 100644 --- a/src/amd/vulkan/radv_shader.h +++ b/src/amd/vulkan/radv_shader.h @@ -436,6 +436,7 @@ struct radv_prolog_binary { uint8_t num_vgprs; uint8_t num_preserved_sgprs; unsigned code_size; + unsigned disasm_size; uint8_t data[0]; }; @@ -487,6 +488,9 @@ struct radv_shader_prolog { uint32_t rsrc1; uint8_t num_preserved_sgprs; bool nontrivial_divisors; + + /* debug only */ + char *disasm_string; }; void radv_optimize_nir(const struct radv_device *device, struct nir_shader *shader,