diff --git a/src/amd/compiler/aco_interface.cpp b/src/amd/compiler/aco_interface.cpp index f33e12f86b9..03a3a3cc27d 100644 --- a/src/amd/compiler/aco_interface.cpp +++ b/src/amd/compiler/aco_interface.cpp @@ -198,19 +198,27 @@ aco_compile_shader(unsigned shader_count, struct nir_shader* const* shaders, std::string disasm; if (get_disasm) { - 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); - } + 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); + disasm = std::string(data, data + disasm_size); + size += disasm_size; + free(data); + } else { + fprintf(stderr, "Shader disassembly is not supported in the current configuration" +#ifndef LLVM_AVAILABLE + " (LLVM not available)" +#endif + ".\n"); + } } size_t stats_size = 0; diff --git a/src/amd/compiler/aco_ir.h b/src/amd/compiler/aco_ir.h index b1ead30b53b..f271fb4fb46 100644 --- a/src/amd/compiler/aco_ir.h +++ b/src/amd/compiler/aco_ir.h @@ -2168,6 +2168,11 @@ void insert_wait_states(Program* program); void insert_NOPs(Program* program); void form_hard_clauses(Program* program); unsigned emit_program(Program* program, std::vector& code); +/** + * Returns true if print_asm can disassemble the given program for the current build/runtime + * configuration + */ +bool check_print_asm_support(Program* program); bool print_asm(Program* program, std::vector& binary, unsigned exec_size, FILE* output); bool validate_ir(Program* program); bool validate_ra(Program* program); diff --git a/src/amd/compiler/aco_print_asm.cpp b/src/amd/compiler/aco_print_asm.cpp index b37cccca2bc..9f15de5aacd 100644 --- a/src/amd/compiler/aco_print_asm.cpp +++ b/src/amd/compiler/aco_print_asm.cpp @@ -24,11 +24,13 @@ #include "aco_ir.h" +#ifdef LLVM_AVAILABLE #include "llvm/ac_llvm_util.h" #include "llvm-c/Disassembler.h" #include #include +#endif #include #include @@ -142,6 +144,7 @@ fail: #endif } +#ifdef LLVM_AVAILABLE std::pair disasm_instr(chip_class chip, LLVMDisasmContextRef disasm, uint32_t* binary, unsigned exec_size, size_t pos, char* outline, unsigned outline_size) @@ -284,15 +287,38 @@ print_asm_llvm(Program* program, std::vector& binary, unsigned exec_si return invalid; } +#endif /* LLVM_AVAILABLE */ + } /* end namespace */ +bool +check_print_asm_support(Program* program) +{ +#ifdef LLVM_AVAILABLE + if (program->chip_class >= GFX8) { + /* LLVM disassembler only supports GFX8+ */ + return true; + } +#endif + +#ifndef _WIN32 + /* Check if CLRX disassembler binary is available and can disassemble the program */ + return to_clrx_device_name(program->chip_class, program->family) && + system("clrxdisasm --version") == 0; +#else + return false; +#endif +} + /* Returns true on failure */ bool print_asm(Program* program, std::vector& binary, unsigned exec_size, FILE* output) { +#ifdef LLVM_AVAILABLE if (program->chip_class >= GFX8) { return print_asm_llvm(program, binary, exec_size, output); } +#endif return print_asm_clrx(program, binary, output); } diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index e01c9c493f7..899b0e9ce7e 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -6095,7 +6095,7 @@ radv_GetPipelineExecutableInternalRepresentationsKHR( ++p; /* Disassembler */ - if (p < end) { + if (p < end && shader->disasm_string) { p->isText = true; desc_copy(p->name, "Assembly"); desc_copy(p->description, "Final Assembly"); diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c index f98154108b0..7319c4f59aa 100644 --- a/src/amd/vulkan/radv_shader.c +++ b/src/amd/vulkan/radv_shader.c @@ -1876,7 +1876,9 @@ radv_GetShaderInfoAMD(VkDevice _device, VkPipeline _pipeline, VkShaderStageFlagB fprintf(memf, "%s:\n", radv_get_shader_name(&variant->info, stage)); fprintf(memf, "%s\n\n", variant->ir_string); - fprintf(memf, "%s\n\n", variant->disasm_string); + if (variant->disasm_string) { + fprintf(memf, "%s\n\n", variant->disasm_string); + } radv_dump_shader_stats(device, pipeline, stage, memf); u_memstream_close(&mem);