Commit e553be7e authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

winevulkan: Separate PE and Unix VkCommandBuffer structs.

parent 19326ff9
......@@ -501,6 +501,7 @@ VkResult WINAPI vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateIn
if (!(cmd_pool = malloc(sizeof(*cmd_pool))))
return VK_ERROR_OUT_OF_HOST_MEMORY;
cmd_pool->unix_handle = 0;
list_init(&cmd_pool->command_buffers);
params.device = device;
params.pCreateInfo = create_info;
......@@ -517,6 +518,19 @@ void WINAPI vkDestroyCommandPool(VkDevice device, VkCommandPool handle, const Vk
{
struct vk_command_pool *cmd_pool = command_pool_from_handle(handle);
struct vkDestroyCommandPool_params params;
VkCommandBuffer buffer, cursor;
if (!cmd_pool)
return;
/* 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, &cmd_pool->command_buffers, struct VkCommandBuffer_T, pool_link)
{
vkFreeCommandBuffers(device, handle, 1, &buffer);
}
params.device = device;
params.commandPool = handle;
......@@ -525,6 +539,55 @@ void WINAPI vkDestroyCommandPool(VkDevice device, VkCommandPool handle, const Vk
free(cmd_pool);
}
VkResult WINAPI vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *allocate_info,
VkCommandBuffer *buffers)
{
struct vk_command_pool *pool = command_pool_from_handle(allocate_info->commandPool);
struct vkAllocateCommandBuffers_params params;
uint32_t i;
VkResult result;
for (i = 0; i < allocate_info->commandBufferCount; i++)
buffers[i] = alloc_vk_object(sizeof(*buffers[i]));
params.device = device;
params.pAllocateInfo = allocate_info;
params.pCommandBuffers = buffers;
result = vk_unix_call(unix_vkAllocateCommandBuffers, &params);
if (result == VK_SUCCESS)
{
for (i = 0; i < allocate_info->commandBufferCount; i++)
list_add_tail(&pool->command_buffers, &buffers[i]->pool_link);
}
else
{
for (i = 0; i < allocate_info->commandBufferCount; i++)
{
free(buffers[i]);
buffers[i] = NULL;
}
}
return result;
}
void WINAPI vkFreeCommandBuffers(VkDevice device, VkCommandPool cmd_pool, uint32_t count,
const VkCommandBuffer *buffers)
{
struct vkFreeCommandBuffers_params params;
uint32_t i;
params.device = device;
params.commandPool = cmd_pool;
params.commandBufferCount = count;
params.pCommandBuffers = buffers;
vk_unix_call(unix_vkFreeCommandBuffers, &params);
for (i = 0; i < count; i++)
{
list_remove(&buffers[i]->pool_link);
free(buffers[i]);
}
}
static BOOL WINAPI call_vulkan_debug_report_callback( struct wine_vk_debug_report_params *params, ULONG size )
{
return params->user_callback(params->flags, params->object_type, params->object_handle, params->location,
......
......@@ -51,15 +51,6 @@ VkResult WINAPI vkAcquireProfilingLockKHR(VkDevice device, const VkAcquireProfil
return vk_unix_call(unix_vkAcquireProfilingLockKHR, &params);
}
VkResult WINAPI vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers)
{
struct vkAllocateCommandBuffers_params params;
params.device = device;
params.pAllocateInfo = pAllocateInfo;
params.pCommandBuffers = pCommandBuffers;
return vk_unix_call(unix_vkAllocateCommandBuffers, &params);
}
VkResult WINAPI vkAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo, VkDescriptorSet *pDescriptorSets)
{
struct vkAllocateDescriptorSets_params params;
......@@ -2781,16 +2772,6 @@ VkResult WINAPI vkFlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeC
return vk_unix_call(unix_vkFlushMappedMemoryRanges, &params);
}
void WINAPI vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers)
{
struct vkFreeCommandBuffers_params params;
params.device = device;
params.commandPool = commandPool;
params.commandBufferCount = commandBufferCount;
params.pCommandBuffers = pCommandBuffers;
vk_unix_call(unix_vkFreeCommandBuffers, &params);
}
VkResult WINAPI vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets)
{
struct vkFreeDescriptorSets_params params;
......
......@@ -200,13 +200,13 @@ FUNCTION_OVERRIDES = {
"vkGetPhysicalDeviceProperties2KHR" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.PUBLIC, "loader_thunk" : ThunkType.PRIVATE},
# Device functions
"vkAllocateCommandBuffers" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE},
"vkAllocateCommandBuffers" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE},
"vkCreateCommandPool" : {"dispatch": True, "driver" : False, "thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE, "extra_param" : "client_ptr"},
"vkCreateComputePipelines" : {"dispatch": True, "driver" : False, "thunk" : ThunkType.PRIVATE},
"vkCreateGraphicsPipelines" : {"dispatch": True, "driver" : False, "thunk" : ThunkType.PRIVATE},
"vkDestroyCommandPool" : {"dispatch": True, "driver" : False, "thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE},
"vkDestroyDevice" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE},
"vkFreeCommandBuffers" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE},
"vkFreeCommandBuffers" : {"dispatch" : True, "driver" : False, "thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.PRIVATE},
"vkGetDeviceProcAddr" : {"dispatch" : False, "driver" : True, "thunk" : ThunkType.NONE, "loader_thunk" : ThunkType.NONE},
"vkGetDeviceQueue" : {"dispatch": True, "driver" : False, "thunk" : ThunkType.NONE},
"vkGetDeviceQueue2" : {"dispatch": True, "driver" : False, "thunk" : ThunkType.NONE},
......@@ -1061,6 +1061,8 @@ class VkHandle(object):
if self.parent is None:
# Should only happen for VkInstance
return "wine_instance_from_handle({0})->funcs".format(param)
elif self.name == "VkCommandBuffer":
return "wine_cmd_buffer_from_handle({0})->device->funcs".format(param)
elif self.name == "VkDevice":
return "wine_device_from_handle({0})->funcs".format(param)
elif self.name == "VkPhysicalDevice":
......@@ -1098,6 +1100,8 @@ class VkHandle(object):
def native_handle(self, name):
""" Provide access to the native handle of a wrapped object. """
if self.name == "VkCommandBuffer":
return "wine_cmd_buffer_from_handle({0})->command_buffer".format(name)
if self.name == "VkCommandPool":
return "wine_cmd_pool_from_handle({0})->command_pool".format(name)
if self.name == "VkDebugUtilsMessengerEXT":
......@@ -1114,15 +1118,6 @@ class VkHandle(object):
return "wine_queue_from_handle({0})->queue".format(name)
if self.name == "VkSurfaceKHR":
return "wine_surface_from_handle({0})->surface".format(name)
native_handle_name = None
if self.name == "VkCommandBuffer":
native_handle_name = "command_buffer"
if native_handle_name:
return "{0}->{1}".format(name, native_handle_name)
if self.is_dispatchable():
LOGGER.error("Unhandled native handle for: {0}".format(self.name))
return None
......
......@@ -313,13 +313,15 @@ static void wine_vk_free_command_buffers(struct wine_device *device,
for (i = 0; i < count; i++)
{
if (!buffers[i])
struct wine_cmd_buffer *buffer = wine_cmd_buffer_from_handle(buffers[i]);
if (!buffer)
continue;
device->funcs.p_vkFreeCommandBuffers(device->device, pool->command_pool, 1, &buffers[i]->command_buffer);
list_remove(&buffers[i]->pool_link);
WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, buffers[i]);
free(buffers[i]);
device->funcs.p_vkFreeCommandBuffers(device->device, pool->command_pool, 1, &buffer->command_buffer);
WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, buffer);
buffer->handle->base.unix_handle = 0;
free(buffer);
}
}
......@@ -649,6 +651,7 @@ NTSTATUS wine_vkAllocateCommandBuffers(void *args)
struct wine_device *device = wine_device_from_handle(params->device);
const VkCommandBufferAllocateInfo *allocate_info = params->pAllocateInfo;
VkCommandBuffer *buffers = params->pCommandBuffers;
struct wine_cmd_buffer *buffer;
struct wine_cmd_pool *pool;
VkResult res = VK_SUCCESS;
unsigned int i;
......@@ -657,8 +660,6 @@ NTSTATUS wine_vkAllocateCommandBuffers(void *args)
pool = wine_cmd_pool_from_handle(allocate_info->commandPool);
memset(buffers, 0, allocate_info->commandBufferCount * sizeof(*buffers));
for (i = 0; i < allocate_info->commandBufferCount; i++)
{
VkCommandBufferAllocateInfo_host allocate_info_host;
......@@ -673,32 +674,29 @@ NTSTATUS wine_vkAllocateCommandBuffers(void *args)
TRACE("Allocating command buffer %u from pool 0x%s.\n",
i, wine_dbgstr_longlong(allocate_info_host.commandPool));
if (!(buffers[i] = calloc(1, sizeof(**buffers))))
if (!(buffer = calloc(1, sizeof(*buffer))))
{
res = VK_ERROR_OUT_OF_HOST_MEMORY;
break;
}
buffers[i]->base.loader_magic = VULKAN_ICD_MAGIC_VALUE;
buffers[i]->device = device;
list_add_tail(&pool->command_buffers, &buffers[i]->pool_link);
buffer->handle = buffers[i];
buffer->device = device;
res = device->funcs.p_vkAllocateCommandBuffers(device->device,
&allocate_info_host, &buffers[i]->command_buffer);
WINE_VK_ADD_DISPATCHABLE_MAPPING(device->phys_dev->instance, buffers[i],
buffers[i]->command_buffer, buffers[i]);
&allocate_info_host, &buffer->command_buffer);
buffer->handle->base.unix_handle = (uintptr_t)buffer;
WINE_VK_ADD_DISPATCHABLE_MAPPING(device->phys_dev->instance, buffer->handle,
buffer->command_buffer, buffer);
if (res != VK_SUCCESS)
{
ERR("Failed to allocate command buffer, res=%d.\n", res);
buffers[i]->command_buffer = VK_NULL_HANDLE;
buffer->command_buffer = VK_NULL_HANDLE;
break;
}
}
if (res != VK_SUCCESS)
{
wine_vk_free_command_buffers(device, pool, i + 1, buffers);
memset(buffers, 0, allocate_info->commandBufferCount * sizeof(*buffers));
}
return res;
}
......@@ -1160,8 +1158,6 @@ NTSTATUS wine_vkCreateCommandPool(void *args)
if (!(object = calloc(1, 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)
......@@ -1187,26 +1183,12 @@ NTSTATUS wine_vkDestroyCommandPool(void *args)
VkCommandPool handle = params->commandPool;
const VkAllocationCallbacks *allocator = params->pAllocator;
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);
if (!handle)
return STATUS_SUCCESS;
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)
{
WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, buffer);
free(buffer);
}
WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, pool);
device->funcs.p_vkDestroyCommandPool(device->device, pool->command_pool, NULL);
......
......@@ -30,6 +30,7 @@
#include "wine/debug.h"
#include "wine/vulkan.h"
#include "wine/unixlib.h"
#include "wine/list.h"
#include "loader_thunks.h"
......@@ -81,6 +82,7 @@ struct VkDevice_T
struct vk_command_pool
{
UINT64 unix_handle;
struct list command_buffers;
};
static inline struct vk_command_pool *command_pool_from_handle(VkCommandPool handle)
......@@ -88,6 +90,12 @@ static inline struct vk_command_pool *command_pool_from_handle(VkCommandPool han
return (struct vk_command_pool *)(uintptr_t)handle;
}
struct VkCommandBuffer_T
{
struct wine_vk_base base;
struct list pool_link;
};
struct vulkan_func
{
const char *name;
......
......@@ -28,8 +28,6 @@
#include <pthread.h>
#include "wine/list.h"
#include "vulkan_loader.h"
#include "vulkan_thunks.h"
......@@ -43,16 +41,21 @@ struct wine_vk_mapping
uint64_t wine_wrapped_handle;
};
struct VkCommandBuffer_T
struct wine_cmd_buffer
{
struct wine_vk_base base;
struct wine_device *device; /* parent */
VkCommandBuffer handle; /* client command buffer */
VkCommandBuffer command_buffer; /* native command buffer */
struct list pool_link;
struct wine_vk_mapping mapping;
};
static inline struct wine_cmd_buffer *wine_cmd_buffer_from_handle(VkCommandBuffer handle)
{
return (struct wine_cmd_buffer *)(uintptr_t)handle->base.unix_handle;
}
struct wine_device
{
struct vulkan_device_funcs funcs;
......@@ -160,8 +163,6 @@ struct wine_cmd_pool
VkCommandPool handle;
VkCommandPool command_pool;
struct list command_buffers;
struct wine_vk_mapping mapping;
};
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment