winevulkan: Fix potential memory leaks when a command pool is destroyed.
Signed-off-by: Józef Kucia <jkucia@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
6f8d02b0f3
commit
079d2ec40d
|
@ -165,6 +165,7 @@ static void wine_vk_free_command_buffers(struct VkDevice_T *device,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
device->funcs.p_vkFreeCommandBuffers(device->device, pool->command_pool, 1, &buffers[i]->command_buffer);
|
device->funcs.p_vkFreeCommandBuffers(device->device, pool->command_pool, 1, &buffers[i]->command_buffer);
|
||||||
|
list_remove(&buffers[i]->pool_link);
|
||||||
heap_free(buffers[i]);
|
heap_free(buffers[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -528,9 +529,8 @@ VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device,
|
||||||
allocate_info_host.level = allocate_info->level;
|
allocate_info_host.level = allocate_info->level;
|
||||||
allocate_info_host.commandBufferCount = 1;
|
allocate_info_host.commandBufferCount = 1;
|
||||||
|
|
||||||
TRACE("Creating command buffer %u, pool 0x%s, level %#x\n", i,
|
TRACE("Allocating command buffer %u from pool 0x%s.\n",
|
||||||
wine_dbgstr_longlong(allocate_info_host.commandPool),
|
i, wine_dbgstr_longlong(allocate_info_host.commandPool));
|
||||||
allocate_info_host.level);
|
|
||||||
|
|
||||||
if (!(buffers[i] = heap_alloc_zero(sizeof(**buffers))))
|
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);
|
&allocate_info_host, &buffers[i]->command_buffer);
|
||||||
if (res != VK_SUCCESS)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_add_tail(&pool->command_buffers, &buffers[i]->pool_link);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res != VK_SUCCESS)
|
if (res != VK_SUCCESS)
|
||||||
|
@ -1132,6 +1134,8 @@ VkResult WINAPI wine_vkCreateCommandPool(VkDevice device, const VkCommandPoolCre
|
||||||
if (!(object = heap_alloc_zero(sizeof(*object))))
|
if (!(object = heap_alloc_zero(sizeof(*object))))
|
||||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
|
|
||||||
|
list_init(&object->command_buffers);
|
||||||
|
|
||||||
res = device->funcs.p_vkCreateCommandPool(device->device, info, NULL, &object->command_pool);
|
res = device->funcs.p_vkCreateCommandPool(device->device, info, NULL, &object->command_pool);
|
||||||
|
|
||||||
if (res == VK_SUCCESS)
|
if (res == VK_SUCCESS)
|
||||||
|
@ -1146,6 +1150,7 @@ void WINAPI wine_vkDestroyCommandPool(VkDevice device, VkCommandPool handle,
|
||||||
const VkAllocationCallbacks *allocator)
|
const VkAllocationCallbacks *allocator)
|
||||||
{
|
{
|
||||||
struct wine_cmd_pool *pool = wine_cmd_pool_from_handle(handle);
|
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);
|
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)
|
if (allocator)
|
||||||
FIXME("Support for allocation callbacks not implemented yet\n");
|
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);
|
device->funcs.p_vkDestroyCommandPool(device->device, pool->command_pool, NULL);
|
||||||
heap_free(pool);
|
heap_free(pool);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "wine/heap.h"
|
#include "wine/heap.h"
|
||||||
|
#include "wine/list.h"
|
||||||
#define VK_NO_PROTOTYPES
|
#define VK_NO_PROTOTYPES
|
||||||
#include "wine/vulkan.h"
|
#include "wine/vulkan.h"
|
||||||
#include "wine/vulkan_driver.h"
|
#include "wine/vulkan_driver.h"
|
||||||
|
@ -62,6 +63,8 @@ struct VkCommandBuffer_T
|
||||||
struct wine_vk_base base;
|
struct wine_vk_base base;
|
||||||
struct VkDevice_T *device; /* parent */
|
struct VkDevice_T *device; /* parent */
|
||||||
VkCommandBuffer command_buffer; /* native command buffer */
|
VkCommandBuffer command_buffer; /* native command buffer */
|
||||||
|
|
||||||
|
struct list pool_link;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VkDevice_T
|
struct VkDevice_T
|
||||||
|
@ -113,6 +116,8 @@ struct VkQueue_T
|
||||||
struct wine_cmd_pool
|
struct wine_cmd_pool
|
||||||
{
|
{
|
||||||
VkCommandPool command_pool;
|
VkCommandPool command_pool;
|
||||||
|
|
||||||
|
struct list command_buffers;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct wine_cmd_pool *wine_cmd_pool_from_handle(VkCommandPool handle)
|
static inline struct wine_cmd_pool *wine_cmd_pool_from_handle(VkCommandPool handle)
|
||||||
|
|
Loading…
Reference in New Issue