From 98f96bd076f3c8228279e2234768d740128c6d85 Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Mon, 23 Mar 2026 12:01:52 +0000 Subject: [PATCH] radv: add radv_parse_binary_debug_info Signed-off-by: Rhys Perry Reviewed-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/radv_pipeline_compute.c | 1 + src/amd/vulkan/radv_pipeline_graphics.c | 2 + src/amd/vulkan/radv_pipeline_rt.c | 1 + src/amd/vulkan/radv_shader.c | 76 ++++++++++++++++--------- src/amd/vulkan/radv_shader.h | 3 + 5 files changed, 55 insertions(+), 28 deletions(-) diff --git a/src/amd/vulkan/radv_pipeline_compute.c b/src/amd/vulkan/radv_pipeline_compute.c index 14c728f6fd0..0d704504ef1 100644 --- a/src/amd/vulkan/radv_pipeline_compute.c +++ b/src/amd/vulkan/radv_pipeline_compute.c @@ -137,6 +137,7 @@ radv_compile_cs(struct radv_device *device, struct vk_pipeline_cache *cache, str nir_string = radv_dump_nir_shaders(instance, &cs_stage->nir, 1); cs_shader = radv_shader_create(device, cache, *cs_binary, skip_shaders_cache || dump_shader); + radv_parse_binary_debug_info(device, *cs_binary, &cs_shader->dbg); cs_shader->dbg.nir_string = nir_string; cs_shader->dbg.stages = 1 << MESA_SHADER_COMPUTE; diff --git a/src/amd/vulkan/radv_pipeline_graphics.c b/src/amd/vulkan/radv_pipeline_graphics.c index 4354b02feaa..d79e3ac8283 100644 --- a/src/amd/vulkan/radv_pipeline_graphics.c +++ b/src/amd/vulkan/radv_pipeline_graphics.c @@ -2427,6 +2427,7 @@ radv_create_gs_copy_shader(struct radv_device *device, struct vk_pipeline_cache radv_shader_create(device, cache, *gs_copy_binary, skip_shaders_cache || dump_shader); if (copy_shader) { + radv_parse_binary_debug_info(device, *gs_copy_binary, ©_shader->dbg); copy_shader->dbg.nir_string = nir_string; copy_shader->dbg.stages = 1 << MESA_SHADER_VERTEX; copy_shader->dbg.dump_shader = dump_shader; @@ -2502,6 +2503,7 @@ radv_graphics_shaders_nir_to_asm(struct radv_device *device, struct vk_pipeline_ shaders[s] = radv_shader_create(device, cache, binaries[s], skip_shaders_cache || dump_shader); + radv_parse_binary_debug_info(device, binaries[s], &shaders[s]->dbg); shaders[s]->dbg.nir_string = nir_string; for (uint32_t i = 0; i < shader_count; i++) shaders[s]->dbg.stages |= 1 << nir_shaders[i]->info.stage; diff --git a/src/amd/vulkan/radv_pipeline_rt.c b/src/amd/vulkan/radv_pipeline_rt.c index 42bebd0ecc1..f0b0a08fd34 100644 --- a/src/amd/vulkan/radv_pipeline_rt.c +++ b/src/amd/vulkan/radv_pipeline_rt.c @@ -526,6 +526,7 @@ radv_rt_nir_to_asm(struct radv_device *device, struct vk_pipeline_cache *cache, shader = radv_shader_create(device, cache, binary, skip_shaders_cache || dump_shader); if (shader) { + radv_parse_binary_debug_info(device, binary, &shader->dbg); shader->dbg.nir_string = nir_string; shader->dbg.stages = 1 << shaders[0]->info.stage; shader->dbg.dump_shader = dump_shader; diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c index bb15993ad79..bcbea97e8ae 100644 --- a/src/amd/vulkan/radv_shader.c +++ b/src/amd/vulkan/radv_shader.c @@ -2866,6 +2866,52 @@ radv_get_max_scratch_waves(const struct radv_device *device, struct radv_shader return MIN2(device->scratch_waves, 4 * num_cu * shader->max_waves); } +VkResult +radv_parse_binary_debug_info(struct radv_device *device, const struct radv_shader_binary *binary, + struct radv_shader_debug_info *dbg) +{ + if (binary->type == RADV_BINARY_TYPE_RTLD) { +#if !defined(USE_LIBELF) + return VK_SUCCESS; +#else + const struct radv_physical_device *pdev = radv_device_physical(device); + struct radv_shader_binary_rtld *bin = (struct radv_shader_binary_rtld *)binary; + struct ac_rtld_binary rtld_binary = {0}; + + if (!radv_open_rtld_binary(pdev->info.gfx_level, binary, &rtld_binary)) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + const char *disasm_data; + size_t disasm_size; + if (!ac_rtld_get_section_by_name(&rtld_binary, ".AMDGPU.disasm", &disasm_data, &disasm_size)) { + ac_rtld_close(&rtld_binary); + return VK_ERROR_UNKNOWN; + } + + dbg->ir_string = bin->llvm_ir_size ? strdup((const char *)(bin->data + bin->elf_size)) : NULL; + dbg->disasm_string = malloc(disasm_size + 1); + memcpy(dbg->disasm_string, disasm_data, disasm_size); + dbg->disasm_string[disasm_size] = 0; + + ac_rtld_close(&rtld_binary); +#endif + } else { + struct radv_shader_binary_legacy *bin = (struct radv_shader_binary_legacy *)binary; + struct radv_shader_binary_layout layout = radv_shader_binary_get_layout(bin); + + dbg->ir_string = bin->ir_size ? strdup(layout.ir) : NULL; + dbg->disasm_string = bin->disasm_size ? strdup(layout.disasm) : NULL; + + if (bin->debug_info_size) { + dbg->debug_info = malloc(bin->debug_info_size); + memcpy(dbg->debug_info, layout.debug_info, bin->debug_info_size); + dbg->debug_info_count = bin->debug_info_size / sizeof(struct ac_shader_debug_info); + } + } + + return VK_SUCCESS; +} + VkResult radv_shader_create_uncached(struct radv_device *device, const struct radv_shader_binary *binary, bool replayable, struct radv_serialized_shader_arena_block *replay_block, struct radv_shader **out_shader) @@ -2891,51 +2937,24 @@ radv_shader_create_uncached(struct radv_device *device, const struct radv_shader goto out; #else const struct radv_physical_device *pdev = radv_device_physical(device); - struct radv_shader_binary_rtld *bin = (struct radv_shader_binary_rtld *)binary; struct ac_rtld_binary rtld_binary = {0}; - if (!radv_open_rtld_binary(pdev->info.gfx_level, binary, &rtld_binary)) { result = VK_ERROR_OUT_OF_HOST_MEMORY; goto out; } - shader->code_size = rtld_binary.rx_size; shader->exec_size = rtld_binary.exec_size; - - const char *disasm_data; - size_t disasm_size; - if (!ac_rtld_get_section_by_name(&rtld_binary, ".AMDGPU.disasm", &disasm_data, &disasm_size)) { - result = VK_ERROR_UNKNOWN; - goto out; - } - - shader->dbg.ir_string = bin->llvm_ir_size ? strdup((const char *)(bin->data + bin->elf_size)) : NULL; - shader->dbg.disasm_string = malloc(disasm_size + 1); - memcpy(shader->dbg.disasm_string, disasm_data, disasm_size); - shader->dbg.disasm_string[disasm_size] = 0; - ac_rtld_close(&rtld_binary); #endif } else { struct radv_shader_binary_legacy *bin = (struct radv_shader_binary_legacy *)binary; struct radv_shader_binary_layout layout = radv_shader_binary_get_layout(bin); - shader->code_size = bin->code_size; shader->exec_size = bin->exec_size; - if (bin->stats_size) { shader->dbg.statistics = calloc(bin->stats_size, 1); memcpy(shader->dbg.statistics, layout.stats, bin->stats_size); } - - shader->dbg.ir_string = bin->ir_size ? strdup(layout.ir) : NULL; - shader->dbg.disasm_string = bin->disasm_size ? strdup(layout.disasm) : NULL; - - if (bin->debug_info_size) { - shader->dbg.debug_info = malloc(bin->debug_info_size); - memcpy(shader->dbg.debug_info, layout.debug_info, bin->debug_info_size); - shader->dbg.debug_info_count = bin->debug_info_size / sizeof(struct ac_shader_debug_info); - } } if (radv_device_physical(device)->info.family_overridden) { @@ -3412,6 +3431,7 @@ radv_create_trap_handler_shader(struct radv_device *device) struct radv_shader *shader; radv_shader_create_uncached(device, binary, false, NULL, &shader); + radv_parse_binary_debug_info(device, binary, &shader->dbg); if (options.dump_shader) { fprintf(stderr, "Trap handler"); @@ -3494,7 +3514,7 @@ radv_create_rt_prolog(struct radv_device *device, unsigned raygen_param_count, n radv_postprocess_binary_config(device, binary, &in_args); radv_shader_create_uncached(device, binary, false, NULL, &prolog); - if (!prolog) + if (!prolog || radv_parse_binary_debug_info(device, binary, &prolog->dbg) != VK_SUCCESS) goto done; if (options.dump_shader) { diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h index 4916e97ec2e..83a9d161271 100644 --- a/src/amd/vulkan/radv_shader.h +++ b/src/amd/vulkan/radv_shader.h @@ -521,6 +521,9 @@ void radv_destroy_shader_upload_queue(struct radv_device *device); struct radv_shader_args; +VkResult radv_parse_binary_debug_info(struct radv_device *device, const struct radv_shader_binary *binary, + struct radv_shader_debug_info *dbg); + VkResult radv_shader_create_uncached(struct radv_device *device, const struct radv_shader_binary *binary, bool replayable, struct radv_serialized_shader_arena_block *replay_block, struct radv_shader **out_shader);