Mesa (main): radv: add a helper function to upload a shader binary

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Dec 2 07:39:17 UTC 2021


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

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Fri Nov  5 13:30:06 2021 +0100

radv: add a helper function to upload a shader binary

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13690>

---

 src/amd/vulkan/radv_shader.c | 151 +++++++++++++++++++++++++++----------------
 1 file changed, 95 insertions(+), 56 deletions(-)

diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c
index 432c70bdd99..68b6497f3e6 100644
--- a/src/amd/vulkan/radv_shader.c
+++ b/src/amd/vulkan/radv_shader.c
@@ -1567,12 +1567,99 @@ radv_postprocess_config(const struct radv_device *device, const struct ac_shader
    }
 }
 
+static bool
+radv_open_rtld_binary(struct radv_device *device, const struct radv_shader *shader,
+                      const struct radv_shader_binary *binary, struct ac_rtld_binary *rtld_binary)
+{
+   const char *elf_data = (const char *)((struct radv_shader_binary_rtld *)binary)->data;
+   size_t elf_size = ((struct radv_shader_binary_rtld *)binary)->elf_size;
+   struct ac_rtld_symbol lds_symbols[2];
+   unsigned num_lds_symbols = 0;
+
+   if (device->physical_device->rad_info.chip_class >= GFX9 &&
+       (binary->stage == MESA_SHADER_GEOMETRY || binary->info.is_ngg) &&
+        !binary->is_gs_copy_shader) {
+      struct ac_rtld_symbol *sym = &lds_symbols[num_lds_symbols++];
+      sym->name = "esgs_ring";
+      sym->size = binary->info.ngg_info.esgs_ring_size;
+      sym->align = 64 * 1024;
+   }
+
+   if (binary->info.is_ngg && binary->stage == MESA_SHADER_GEOMETRY) {
+      struct ac_rtld_symbol *sym = &lds_symbols[num_lds_symbols++];
+      sym->name = "ngg_emit";
+      sym->size = binary->info.ngg_info.ngg_emit_size * 4;
+      sym->align = 4;
+   }
+
+   struct ac_rtld_open_info open_info = {
+      .info = &device->physical_device->rad_info,
+      .shader_type = binary->stage,
+      .wave_size = binary->info.wave_size,
+      .num_parts = 1,
+      .elf_ptrs = &elf_data,
+      .elf_sizes = &elf_size,
+      .num_shared_lds_symbols = num_lds_symbols,
+      .shared_lds_symbols = lds_symbols,
+   };
+
+   return ac_rtld_open(rtld_binary, open_info);
+}
+
+static bool
+radv_shader_binary_upload(struct radv_device *device, const struct radv_shader_binary *binary,
+                          struct radv_shader *shader)
+{
+   void *dest_ptr;
+
+   dest_ptr = radv_alloc_shader_memory(device, shader);
+   if (!dest_ptr) {
+      free(shader);
+      return false;
+   }
+
+   if (binary->type == RADV_BINARY_TYPE_RTLD) {
+      struct ac_rtld_binary rtld_binary = {0};
+
+      if (!radv_open_rtld_binary(device, shader, binary, &rtld_binary)) {
+         free(shader);
+         return false;
+      }
+
+      struct ac_rtld_upload_info info = {
+         .binary = &rtld_binary,
+         .rx_va = radv_shader_get_va(shader),
+         .rx_ptr = dest_ptr,
+      };
+
+      if (!ac_rtld_upload(&info)) {
+         radv_shader_destroy(device, shader);
+         ac_rtld_close(&rtld_binary);
+         return false;
+      }
+
+      shader->code_ptr = dest_ptr;
+      ac_rtld_close(&rtld_binary);
+   } else {
+      struct radv_shader_binary_legacy *bin = (struct radv_shader_binary_legacy *)binary;
+      memcpy(dest_ptr, bin->data + bin->stats_size, bin->code_size);
+
+      /* Add end-of-code markers for the UMR disassembler. */
+      uint32_t *ptr32 = (uint32_t *)dest_ptr + bin->code_size / 4;
+      for (unsigned i = 0; i < DEBUGGER_NUM_MARKERS; i++)
+         ptr32[i] = DEBUGGER_END_OF_CODE_MARKER;
+
+      shader->code_ptr = dest_ptr;
+   }
+
+   return true;
+}
+
 struct radv_shader *
 radv_shader_create(struct radv_device *device, const struct radv_shader_binary *binary,
                    bool keep_shader_info, bool from_cache, const struct radv_shader_args *args)
 {
    struct ac_shader_config config = {0};
-   struct ac_rtld_binary rtld_binary = {0};
    struct radv_shader *shader = calloc(1, sizeof(struct radv_shader));
    if (!shader)
       return NULL;
@@ -1580,39 +1667,9 @@ radv_shader_create(struct radv_device *device, const struct radv_shader_binary *
    shader->ref_count = 1;
 
    if (binary->type == RADV_BINARY_TYPE_RTLD) {
-      struct ac_rtld_symbol lds_symbols[2];
-      unsigned num_lds_symbols = 0;
-      const char *elf_data = (const char *)((struct radv_shader_binary_rtld *)binary)->data;
-      size_t elf_size = ((struct radv_shader_binary_rtld *)binary)->elf_size;
-
-      if (device->physical_device->rad_info.chip_class >= GFX9 &&
-          (binary->stage == MESA_SHADER_GEOMETRY || binary->info.is_ngg) &&
-          !binary->is_gs_copy_shader) {
-         struct ac_rtld_symbol *sym = &lds_symbols[num_lds_symbols++];
-         sym->name = "esgs_ring";
-         sym->size = binary->info.ngg_info.esgs_ring_size;
-         sym->align = 64 * 1024;
-      }
-
-      if (binary->info.is_ngg && binary->stage == MESA_SHADER_GEOMETRY) {
-         struct ac_rtld_symbol *sym = &lds_symbols[num_lds_symbols++];
-         sym->name = "ngg_emit";
-         sym->size = binary->info.ngg_info.ngg_emit_size * 4;
-         sym->align = 4;
-      }
-
-      struct ac_rtld_open_info open_info = {
-         .info = &device->physical_device->rad_info,
-         .shader_type = binary->stage,
-         .wave_size = binary->info.wave_size,
-         .num_parts = 1,
-         .elf_ptrs = &elf_data,
-         .elf_sizes = &elf_size,
-         .num_shared_lds_symbols = num_lds_symbols,
-         .shared_lds_symbols = lds_symbols,
-      };
+      struct ac_rtld_binary rtld_binary = {0};
 
-      if (!ac_rtld_open(&rtld_binary, open_info)) {
+      if (!radv_open_rtld_binary(device, shader, binary, &rtld_binary)) {
          free(shader);
          return NULL;
       }
@@ -1634,6 +1691,7 @@ radv_shader_create(struct radv_device *device, const struct radv_shader_binary *
 
       shader->code_size = rtld_binary.rx_size;
       shader->exec_size = rtld_binary.exec_size;
+      ac_rtld_close(&rtld_binary);
    } else {
       assert(binary->type == RADV_BINARY_TYPE_LEGACY);
       config = ((struct radv_shader_binary_legacy *)binary)->base.config;
@@ -1652,25 +1710,15 @@ radv_shader_create(struct radv_device *device, const struct radv_shader_binary *
       radv_postprocess_config(device, &config, &binary->info, binary->stage, args, &shader->config);
    }
 
-   void *dest_ptr = radv_alloc_shader_memory(device, shader);
-   if (!dest_ptr) {
-      if (binary->type == RADV_BINARY_TYPE_RTLD)
-         ac_rtld_close(&rtld_binary);
-      free(shader);
+   if (!radv_shader_binary_upload(device, binary, shader))
       return NULL;
-   }
 
    if (binary->type == RADV_BINARY_TYPE_RTLD) {
       struct radv_shader_binary_rtld *bin = (struct radv_shader_binary_rtld *)binary;
-      struct ac_rtld_upload_info info = {
-         .binary = &rtld_binary,
-         .rx_va = radv_shader_get_va(shader),
-         .rx_ptr = dest_ptr,
-      };
+      struct ac_rtld_binary rtld_binary = {0};
 
-      if (!ac_rtld_upload(&info)) {
-         radv_shader_destroy(device, shader);
-         ac_rtld_close(&rtld_binary);
+      if (!radv_open_rtld_binary(device, shader, binary, &rtld_binary)) {
+         free(shader);
          return NULL;
       }
 
@@ -1690,19 +1738,10 @@ radv_shader_create(struct radv_device *device, const struct radv_shader_binary *
          memcpy(shader->disasm_string, disasm_data, disasm_size);
          shader->disasm_string[disasm_size] = 0;
       }
-
-      shader->code_ptr = dest_ptr;
       ac_rtld_close(&rtld_binary);
    } else {
       struct radv_shader_binary_legacy *bin = (struct radv_shader_binary_legacy *)binary;
-      memcpy(dest_ptr, bin->data + bin->stats_size, bin->code_size);
 
-      /* Add end-of-code markers for the UMR disassembler. */
-      uint32_t *ptr32 = (uint32_t *)dest_ptr + bin->code_size / 4;
-      for (unsigned i = 0; i < DEBUGGER_NUM_MARKERS; i++)
-         ptr32[i] = DEBUGGER_END_OF_CODE_MARKER;
-
-      shader->code_ptr = dest_ptr;
       shader->ir_string =
          bin->ir_size ? strdup((const char *)(bin->data + bin->stats_size + bin->code_size)) : NULL;
       shader->disasm_string =



More information about the mesa-commit mailing list