Mesa (main): radv,aco: keep track of the prolog disassembly if necessary

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jan 4 08:10:46 UTC 2022


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

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Fri Oct 15 10:03:21 2021 +0200

radv,aco: keep track of the prolog disassembly if necessary

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Rhys Perry <pendingchaos02 at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13376>

---

 src/amd/compiler/aco_interface.cpp | 82 ++++++++++++++++++++++----------------
 src/amd/vulkan/radv_shader.c       | 13 +++++-
 src/amd/vulkan/radv_shader.h       |  4 ++
 3 files changed, 63 insertions(+), 36 deletions(-)

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<uint32_t>& 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,



More information about the mesa-commit mailing list