From e982f6e2c8a545c8f99fdc8afff11d3d880c29a4 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Mon, 13 Oct 2025 14:57:42 +0200 Subject: [PATCH] radv: fix shaders memleak when importing pipeline binaries with GPL The implementation must use the data in VkPipelineBinaryInfoKHR when provided instead of importing binaries from libraries. This fixes a memleak with shaders found with ASAN. Cc: mesa-stable Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/radv_pipeline_graphics.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/amd/vulkan/radv_pipeline_graphics.c b/src/amd/vulkan/radv_pipeline_graphics.c index 537ec5e18ef..ae8007bd400 100644 --- a/src/amd/vulkan/radv_pipeline_graphics.c +++ b/src/amd/vulkan/radv_pipeline_graphics.c @@ -607,7 +607,7 @@ radv_should_import_lib_binaries(const VkPipelineCreateFlags2 create_flags) static void radv_graphics_pipeline_import_lib(const struct radv_device *device, struct radv_graphics_pipeline *pipeline, - struct radv_graphics_lib_pipeline *lib) + struct radv_graphics_lib_pipeline *lib, bool import_pipeline_binaries) { bool import_binaries = false; @@ -620,7 +620,8 @@ radv_graphics_pipeline_import_lib(const struct radv_device *device, struct radv_ pipeline->active_stages |= lib->base.active_stages; /* Import binaries when LTO is disabled and when the library doesn't retain any shaders. */ - if (lib->base.has_pipeline_binaries || radv_should_import_lib_binaries(pipeline->base.create_flags)) { + if (!import_pipeline_binaries && + (lib->base.has_pipeline_binaries || radv_should_import_lib_binaries(pipeline->base.create_flags))) { import_binaries = true; } @@ -3442,6 +3443,9 @@ radv_graphics_pipeline_init(struct radv_graphics_pipeline *pipeline, struct radv const VkPipelineLibraryCreateInfoKHR *libs_info = vk_find_struct_const(pCreateInfo->pNext, PIPELINE_LIBRARY_CREATE_INFO_KHR); + const VkPipelineBinaryInfoKHR *binary_info = vk_find_struct_const(pCreateInfo->pNext, PIPELINE_BINARY_INFO_KHR); + const bool import_pipeline_binaries = binary_info && binary_info->binaryCount > 0; + /* If we have libraries, import them first. */ if (libs_info) { for (uint32_t i = 0; i < libs_info->libraryCount; i++) { @@ -3450,7 +3454,7 @@ radv_graphics_pipeline_init(struct radv_graphics_pipeline *pipeline, struct radv assert(pipeline_lib->type == RADV_PIPELINE_GRAPHICS_LIB); - radv_graphics_pipeline_import_lib(device, pipeline, gfx_pipeline_lib); + radv_graphics_pipeline_import_lib(device, pipeline, gfx_pipeline_lib, import_pipeline_binaries); } } @@ -3460,9 +3464,7 @@ radv_graphics_pipeline_init(struct radv_graphics_pipeline *pipeline, struct radv if (result != VK_SUCCESS) return result; - const VkPipelineBinaryInfoKHR *binary_info = vk_find_struct_const(pCreateInfo->pNext, PIPELINE_BINARY_INFO_KHR); - - if (binary_info && binary_info->binaryCount > 0) { + if (import_pipeline_binaries) { result = radv_graphics_pipeline_import_binaries(device, pipeline, binary_info); } else { if (gfx_state.compilation_required) { @@ -3564,6 +3566,9 @@ radv_graphics_lib_pipeline_init(struct radv_graphics_lib_pipeline *pipeline, str radv_pipeline_layout_init(device, &pipeline->layout, false); + const VkPipelineBinaryInfoKHR *binary_info = vk_find_struct_const(pCreateInfo->pNext, PIPELINE_BINARY_INFO_KHR); + const bool import_pipeline_binaries = binary_info && binary_info->binaryCount > 0; + /* If we have libraries, import them first. */ if (libs_info) { for (uint32_t i = 0; i < libs_info->libraryCount; i++) { @@ -3574,7 +3579,7 @@ radv_graphics_lib_pipeline_init(struct radv_graphics_lib_pipeline *pipeline, str radv_graphics_pipeline_import_layout(&pipeline->layout, &gfx_pipeline_lib->layout); - radv_graphics_pipeline_import_lib(device, &pipeline->base, gfx_pipeline_lib); + radv_graphics_pipeline_import_lib(device, &pipeline->base, gfx_pipeline_lib, import_pipeline_binaries); pipeline->lib_flags |= gfx_pipeline_lib->lib_flags; } @@ -3590,9 +3595,7 @@ radv_graphics_lib_pipeline_init(struct radv_graphics_lib_pipeline *pipeline, str if (pipeline_layout) radv_graphics_pipeline_import_layout(&pipeline->layout, pipeline_layout); - const VkPipelineBinaryInfoKHR *binary_info = vk_find_struct_const(pCreateInfo->pNext, PIPELINE_BINARY_INFO_KHR); - - if (binary_info && binary_info->binaryCount > 0) { + if (import_pipeline_binaries) { result = radv_graphics_pipeline_import_binaries(device, &pipeline->base, binary_info); } else { struct radv_graphics_pipeline_state gfx_state;