Mesa (main): radv: Disable shader disassembly when no disassembler is available

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Oct 1 09:05:43 UTC 2021


Module: Mesa
Branch: main
Commit: 3c1802accd7367d8c6c7ff8ebbe6c8c5f9111a3c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3c1802accd7367d8c6c7ff8ebbe6c8c5f9111a3c

Author: Tony Wasserka <tony.wasserka at gmx.de>
Date:   Fri Jun 11 12:37:50 2021 +0200

radv: Disable shader disassembly when no disassembler is available

ACO relies on LLVM to disassemble AMD shaders for ISAs newer than GFX7,
so disassembly needs to be skipped when LLVM is not enabled.

For vkGetPipelineExecutableInternalRepresentationsKHR and vkGetShaderInfoAMD,
the disassembly will not be reported anymore if it can't be generated.

Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11319>

---

 src/amd/compiler/aco_interface.cpp | 32 ++++++++++++++++++++------------
 src/amd/compiler/aco_ir.h          |  5 +++++
 src/amd/compiler/aco_print_asm.cpp | 26 ++++++++++++++++++++++++++
 src/amd/vulkan/radv_pipeline.c     |  2 +-
 src/amd/vulkan/radv_shader.c       |  4 +++-
 5 files changed, 55 insertions(+), 14 deletions(-)

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);
+      } else {
+         fprintf(stderr, "Shader disassembly is not supported in the current configuration"
+#ifndef LLVM_AVAILABLE
+                         " (LLVM not available)"
+#endif
+                         ".\n");
       }
-
-      disasm = std::string(data, data + disasm_size);
-      size += disasm_size;
-      free(data);
    }
 
    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<uint32_t>& 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<uint32_t>& 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 <llvm/ADT/StringRef.h>
 #include <llvm/MC/MCDisassembler/MCDisassembler.h>
+#endif
 
 #include <array>
 #include <iomanip>
@@ -142,6 +144,7 @@ fail:
 #endif
 }
 
+#ifdef LLVM_AVAILABLE
 std::pair<bool, size_t>
 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<uint32_t>& 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<uint32_t>& 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);
 



More information about the mesa-commit mailing list