From 96a240e176701f9b305c4bd273da9a8aee78e280 Mon Sep 17 00:00:00 2001 From: Benjamin Cheng Date: Mon, 4 Apr 2022 00:35:19 -0400 Subject: [PATCH] radv: fix memory leak of descriptor set layout We need to be able to track the descriptor sets explicity to unref the descriptor sets, otherwise these descriptor sets will not unref the descriptor set layout it holds. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/6222 Fixes: 66f7289d568 ("radv: add reference counting for descriptor set layouts") Tested-by: Jakob Bornecrantz Reviewed-by: Bas Nieuwenhuizen Part-of: --- src/amd/vulkan/radv_descriptor_set.c | 31 +++++++++++++--------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/amd/vulkan/radv_descriptor_set.c b/src/amd/vulkan/radv_descriptor_set.c index 00156b22ab4..81df56438e7 100644 --- a/src/amd/vulkan/radv_descriptor_set.c +++ b/src/amd/vulkan/radv_descriptor_set.c @@ -694,9 +694,8 @@ radv_descriptor_set_create(struct radv_device *device, struct radv_descriptor_po if (!pool->host_memory_base) { pool->entries[pool->entry_count].offset = pool->current_offset; pool->entries[pool->entry_count].size = layout_size; - pool->entries[pool->entry_count].set = set; - pool->entry_count++; } + pool->entries[pool->entry_count].set = set; pool->current_offset += layout_size; } else if (!pool->host_memory_base) { uint64_t offset = 0; @@ -720,7 +719,6 @@ radv_descriptor_set_create(struct radv_device *device, struct radv_descriptor_po pool->entries[index].offset = offset; pool->entries[index].size = layout_size; pool->entries[index].set = set; - pool->entry_count++; } else return VK_ERROR_OUT_OF_POOL_MEMORY; @@ -743,6 +741,7 @@ radv_descriptor_set_create(struct radv_device *device, struct radv_descriptor_po } } + pool->entry_count++; radv_descriptor_set_layout_ref(layout); *out_set = set; return VK_SUCCESS; @@ -752,10 +751,11 @@ static void radv_descriptor_set_destroy(struct radv_device *device, struct radv_descriptor_pool *pool, struct radv_descriptor_set *set, bool free_bo) { - assert(!pool->host_memory_base); - radv_descriptor_set_layout_unref(device, set->header.layout); + if (pool->host_memory_base) + return; + if (free_bo && !pool->host_memory_base) { for (int i = 0; i < pool->entry_count; ++i) { if (pool->entries[i].set == set) { @@ -774,10 +774,8 @@ static void radv_destroy_descriptor_pool(struct radv_device *device, const VkAllocationCallbacks *pAllocator, struct radv_descriptor_pool *pool) { - if (!pool->host_memory_base) { - for (int i = 0; i < pool->entry_count; ++i) { - radv_descriptor_set_destroy(device, pool, pool->entries[i].set, false); - } + for (int i = 0; i < pool->entry_count; ++i) { + radv_descriptor_set_destroy(device, pool, pool->entries[i].set, false); } if (pool->bo) @@ -871,13 +869,14 @@ radv_CreateDescriptorPool(VkDevice _device, const VkDescriptorPoolCreateInfo *pC } } + uint64_t entries_size = sizeof(struct radv_descriptor_pool_entry) * pCreateInfo->maxSets; + size += entries_size; + if (!(pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT)) { uint64_t host_size = pCreateInfo->maxSets * sizeof(struct radv_descriptor_set); host_size += sizeof(struct radeon_winsys_bo *) * bo_count; host_size += sizeof(struct radv_descriptor_range) * range_count; size += host_size; - } else { - size += sizeof(struct radv_descriptor_pool_entry) * pCreateInfo->maxSets; } pool = vk_alloc2(&device->vk.alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); @@ -889,7 +888,7 @@ radv_CreateDescriptorPool(VkDevice _device, const VkDescriptorPoolCreateInfo *pC vk_object_base_init(&device->vk, &pool->base, VK_OBJECT_TYPE_DESCRIPTOR_POOL); if (!(pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT)) { - pool->host_memory_base = (uint8_t *)pool + sizeof(struct radv_descriptor_pool); + pool->host_memory_base = (uint8_t *)pool + sizeof(struct radv_descriptor_pool) + entries_size; pool->host_memory_ptr = pool->host_memory_base; pool->host_memory_end = (uint8_t *)pool + size; } @@ -951,12 +950,10 @@ radv_ResetDescriptorPool(VkDevice _device, VkDescriptorPool descriptorPool, RADV_FROM_HANDLE(radv_device, device, _device); RADV_FROM_HANDLE(radv_descriptor_pool, pool, descriptorPool); - if (!pool->host_memory_base) { - for (int i = 0; i < pool->entry_count; ++i) { - radv_descriptor_set_destroy(device, pool, pool->entries[i].set, false); - } - pool->entry_count = 0; + for (int i = 0; i < pool->entry_count; ++i) { + radv_descriptor_set_destroy(device, pool, pool->entries[i].set, false); } + pool->entry_count = 0; pool->current_offset = 0; pool->host_memory_ptr = pool->host_memory_base;