Józef Kucia : winevulkan: Fix potential memory leaks when a command pool is destroyed.
Module: wine Branch: master Commit: 079d2ec40d0587a886390585408a172c0a8a7b4a URL: https://source.winehq.org/git/wine.git/?a=commit;h=079d2ec40d0587a8863905854... Author: Józef Kucia <jkucia(a)codeweavers.com> Date: Thu Aug 30 12:22:32 2018 +0200 winevulkan: Fix potential memory leaks when a command pool is destroyed. Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/winevulkan/vulkan.c | 22 ++++++++++++++++++---- dlls/winevulkan/vulkan_private.h | 5 +++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 886ef0b..f500602 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -165,6 +165,7 @@ static void wine_vk_free_command_buffers(struct VkDevice_T *device, continue; device->funcs.p_vkFreeCommandBuffers(device->device, pool->command_pool, 1, &buffers[i]->command_buffer); + list_remove(&buffers[i]->pool_link); heap_free(buffers[i]); } } @@ -528,9 +529,8 @@ VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device, allocate_info_host.level = allocate_info->level; allocate_info_host.commandBufferCount = 1; - TRACE("Creating command buffer %u, pool 0x%s, level %#x\n", i, - wine_dbgstr_longlong(allocate_info_host.commandPool), - allocate_info_host.level); + TRACE("Allocating command buffer %u from pool 0x%s.\n", + i, wine_dbgstr_longlong(allocate_info_host.commandPool)); if (!(buffers[i] = heap_alloc_zero(sizeof(**buffers)))) { @@ -544,9 +544,11 @@ VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device, &allocate_info_host, &buffers[i]->command_buffer); if (res != VK_SUCCESS) { - ERR("Failed to allocate command buffer, res=%d\n", res); + ERR("Failed to allocate command buffer, res=%d.\n", res); break; } + + list_add_tail(&pool->command_buffers, &buffers[i]->pool_link); } if (res != VK_SUCCESS) @@ -1132,6 +1134,8 @@ VkResult WINAPI wine_vkCreateCommandPool(VkDevice device, const VkCommandPoolCre if (!(object = heap_alloc_zero(sizeof(*object)))) return VK_ERROR_OUT_OF_HOST_MEMORY; + list_init(&object->command_buffers); + res = device->funcs.p_vkCreateCommandPool(device->device, info, NULL, &object->command_pool); if (res == VK_SUCCESS) @@ -1146,6 +1150,7 @@ void WINAPI wine_vkDestroyCommandPool(VkDevice device, VkCommandPool handle, const VkAllocationCallbacks *allocator) { struct wine_cmd_pool *pool = wine_cmd_pool_from_handle(handle); + struct VkCommandBuffer_T *buffer, *cursor; TRACE("%p, 0x%s, %p\n", device, wine_dbgstr_longlong(handle), allocator); @@ -1155,6 +1160,15 @@ void WINAPI wine_vkDestroyCommandPool(VkDevice device, VkCommandPool handle, if (allocator) FIXME("Support for allocation callbacks not implemented yet\n"); + /* The Vulkan spec says: + * + * "When a pool is destroyed, all command buffers allocated from the pool are freed." + */ + LIST_FOR_EACH_ENTRY_SAFE(buffer, cursor, &pool->command_buffers, struct VkCommandBuffer_T, pool_link) + { + heap_free(buffer); + } + device->funcs.p_vkDestroyCommandPool(device->device, pool->command_pool, NULL); heap_free(pool); } diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index f31d4d5..17072d2 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -27,6 +27,7 @@ #include "wine/debug.h" #include "wine/heap.h" +#include "wine/list.h" #define VK_NO_PROTOTYPES #include "wine/vulkan.h" #include "wine/vulkan_driver.h" @@ -62,6 +63,8 @@ struct VkCommandBuffer_T struct wine_vk_base base; struct VkDevice_T *device; /* parent */ VkCommandBuffer command_buffer; /* native command buffer */ + + struct list pool_link; }; struct VkDevice_T @@ -113,6 +116,8 @@ struct VkQueue_T struct wine_cmd_pool { VkCommandPool command_pool; + + struct list command_buffers; }; static inline struct wine_cmd_pool *wine_cmd_pool_from_handle(VkCommandPool handle)
participants (1)
-
Alexandre Julliard