From ff61b36ba2b03107a98fb708926d607760f29301 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Fri, 5 Nov 2021 13:30:06 +0100 Subject: [PATCH] radv: add a helper function to upload a shader binary Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen Part-of: --- 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 432c70b..68b6497 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 = -- 2.7.4