winevulkan: Wrap VkCommandPools.

We need to wrap VkCommandPools to track allocated VkCommandBuffers.

Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Józef Kucia 2018-08-30 12:22:31 +02:00 committed by Alexandre Julliard
parent 6f3e83f7fc
commit 6f8d02b0f3
5 changed files with 103 additions and 50 deletions

View File

@ -157,6 +157,8 @@ FUNCTION_OVERRIDES = {
# Device functions
"vkAllocateCommandBuffers" : {"dispatch" : True, "driver" : False, "thunk" : False},
"vkCmdExecuteCommands" : {"dispatch" : True, "driver" : False, "thunk" : False},
"vkCreateCommandPool" : {"dispatch": True, "driver" : False, "thunk" : False},
"vkDestroyCommandPool" : {"dispatch": True, "driver" : False, "thunk" : False},
"vkDestroyDevice" : {"dispatch" : True, "driver" : False, "thunk" : False},
"vkFreeCommandBuffers" : {"dispatch" : True, "driver" : False, "thunk" : False},
"vkGetDeviceProcAddr" : {"dispatch" : False, "driver" : True, "thunk" : False},
@ -838,27 +840,31 @@ class VkHandle(object):
def is_required(self):
return self.required
def native_handle(self):
""" Provide access to the native handle of a dispatchable object.
def native_handle(self, name):
""" Provide access to the native handle of a wrapped object. """
Dispatchable objects wrap an underlying 'native' object.
This method provides access to the native object.
"""
if not self.is_dispatchable():
return None
if self.name == "VkCommandPool":
return "wine_cmd_pool_from_handle({0})->command_pool".format(name)
native_handle_name = None
if self.name == "VkCommandBuffer":
return "command_buffer"
elif self.name == "VkDevice":
return "device"
elif self.name == "VkInstance":
return "instance"
elif self.name == "VkPhysicalDevice":
return "phys_dev"
elif self.name == "VkQueue":
return "queue"
else:
native_handle_name = "command_buffer"
if self.name == "VkDevice":
native_handle_name = "device"
if self.name == "VkInstance":
native_handle_name = "instance"
if self.name == "VkPhysicalDevice":
native_handle_name = "phys_dev"
if self.name == "VkQueue":
native_handle_name = "queue"
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
class VkMember(object):
@ -1471,17 +1477,15 @@ class VkParam(object):
LOGGER.debug("TODO: setting NULL VkAllocationCallbacks for {0}".format(self.name))
return "NULL"
# Dispatchable objects wrap the native handle. For thunk generation we
# need to pass the native handle to the native Vulkan calls.
if self.is_dispatchable():
return "{0}->{1}".format(self.name, self.handle.native_handle())
elif conv and self.needs_conversion():
if conv and self.needs_conversion():
if self.is_dynamic_array():
return "{0}_host".format(self.name)
else:
return "&{0}_host".format(self.name)
else:
return self.name
# We need to pass the native handle to the native Vulkan calls.
native_handle = self.handle.native_handle(self.name) if self.is_handle() else None
return native_handle if native_handle else self.name
class VkStruct(Sequence):

View File

@ -154,9 +154,8 @@ err:
return NULL;
}
/* Helper function to release command buffers. */
static void wine_vk_command_buffers_free(struct VkDevice_T *device, VkCommandPool pool,
uint32_t count, const VkCommandBuffer *buffers)
static void wine_vk_free_command_buffers(struct VkDevice_T *device,
struct wine_cmd_pool *pool, uint32_t count, const VkCommandBuffer *buffers)
{
unsigned int i;
@ -165,12 +164,11 @@ static void wine_vk_command_buffers_free(struct VkDevice_T *device, VkCommandPoo
if (!buffers[i])
continue;
device->funcs.p_vkFreeCommandBuffers(device->device, pool, 1, &buffers[i]->command_buffer);
device->funcs.p_vkFreeCommandBuffers(device->device, pool->command_pool, 1, &buffers[i]->command_buffer);
heap_free(buffers[i]);
}
}
/* Helper function to create queues for a given family index. */
static struct VkQueue_T *wine_vk_device_alloc_queues(struct VkDevice_T *device,
uint32_t family_index, uint32_t queue_count, VkDeviceQueueCreateFlags flags)
{
@ -506,10 +504,13 @@ static void wine_vk_instance_free(struct VkInstance_T *instance)
VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device,
const VkCommandBufferAllocateInfo *allocate_info, VkCommandBuffer *buffers)
{
struct wine_cmd_pool *pool;
VkResult res = VK_SUCCESS;
unsigned int i;
TRACE("%p %p %p\n", device, allocate_info, buffers);
TRACE("%p, %p, %p\n", device, allocate_info, buffers);
pool = wine_cmd_pool_from_handle(allocate_info->commandPool);
memset(buffers, 0, allocate_info->commandBufferCount * sizeof(*buffers));
@ -523,7 +524,7 @@ VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device,
/* TODO: future extensions (none yet) may require pNext conversion. */
allocate_info_host.pNext = allocate_info->pNext;
allocate_info_host.sType = allocate_info->sType;
allocate_info_host.commandPool = allocate_info->commandPool;
allocate_info_host.commandPool = pool->command_pool;
allocate_info_host.level = allocate_info->level;
allocate_info_host.commandBufferCount = 1;
@ -550,7 +551,7 @@ VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device,
if (res != VK_SUCCESS)
{
wine_vk_command_buffers_free(device, allocate_info->commandPool, i, buffers);
wine_vk_free_command_buffers(device, pool, i, buffers);
memset(buffers, 0, allocate_info->commandBufferCount * sizeof(*buffers));
return res;
}
@ -920,12 +921,14 @@ VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *c
return *count < instance->phys_dev_count ? VK_INCOMPLETE : VK_SUCCESS;
}
void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool pool, uint32_t count,
const VkCommandBuffer *buffers)
void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool pool_handle,
uint32_t count, const VkCommandBuffer *buffers)
{
TRACE("%p 0x%s %u %p\n", device, wine_dbgstr_longlong(pool), count, buffers);
struct wine_cmd_pool *pool = wine_cmd_pool_from_handle(pool_handle);
wine_vk_command_buffers_free(device, pool, count, buffers);
TRACE("%p, 0x%s, %u, %p\n", device, wine_dbgstr_longlong(pool_handle), count, buffers);
wine_vk_free_command_buffers(device, pool, count, buffers);
}
PFN_vkVoidFunction WINAPI wine_vkGetDeviceProcAddr(VkDevice device, const char *name)
@ -1115,6 +1118,47 @@ err:
return res;
}
VkResult WINAPI wine_vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *info,
const VkAllocationCallbacks *allocator, VkCommandPool *command_pool)
{
struct wine_cmd_pool *object;
VkResult res;
TRACE("%p, %p, %p, %p\n", device, info, allocator, command_pool);
if (allocator)
FIXME("Support for allocation callbacks not implemented yet\n");
if (!(object = heap_alloc_zero(sizeof(*object))))
return VK_ERROR_OUT_OF_HOST_MEMORY;
res = device->funcs.p_vkCreateCommandPool(device->device, info, NULL, &object->command_pool);
if (res == VK_SUCCESS)
*command_pool = wine_cmd_pool_to_handle(object);
else
heap_free(object);
return res;
}
void WINAPI wine_vkDestroyCommandPool(VkDevice device, VkCommandPool handle,
const VkAllocationCallbacks *allocator)
{
struct wine_cmd_pool *pool = wine_cmd_pool_from_handle(handle);
TRACE("%p, 0x%s, %p\n", device, wine_dbgstr_longlong(handle), allocator);
if (!handle)
return;
if (allocator)
FIXME("Support for allocation callbacks not implemented yet\n");
device->funcs.p_vkDestroyCommandPool(device->device, pool->command_pool, NULL);
heap_free(pool);
}
static VkResult wine_vk_enumerate_physical_device_groups(struct VkInstance_T *instance,
VkResult (*p_vkEnumeratePhysicalDeviceGroups)(VkInstance, uint32_t *, VkPhysicalDeviceGroupProperties *),
uint32_t *count, VkPhysicalDeviceGroupProperties *properties)

View File

@ -110,6 +110,21 @@ struct VkQueue_T
VkDeviceQueueCreateFlags flags;
};
struct wine_cmd_pool
{
VkCommandPool command_pool;
};
static inline struct wine_cmd_pool *wine_cmd_pool_from_handle(VkCommandPool handle)
{
return (struct wine_cmd_pool *)(uintptr_t)handle;
}
static inline VkCommandPool wine_cmd_pool_to_handle(struct wine_cmd_pool *cmd_pool)
{
return (VkCommandPool)(uintptr_t)cmd_pool;
}
void *wine_vk_get_device_proc_addr(const char *name) DECLSPEC_HIDDEN;
void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN;

View File

@ -1744,12 +1744,6 @@ VkResult WINAPI wine_vkCreateBufferView(VkDevice device, const VkBufferViewCreat
#endif
}
VkResult WINAPI wine_vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool)
{
TRACE("%p, %p, %p, %p\n", device, pCreateInfo, pAllocator, pCommandPool);
return device->funcs.p_vkCreateCommandPool(device->device, pCreateInfo, NULL, pCommandPool);
}
VkResult WINAPI wine_vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines)
{
#if defined(USE_STRUCT_CONVERSION)
@ -1979,12 +1973,6 @@ void WINAPI wine_vkDestroyBufferView(VkDevice device, VkBufferView bufferView, c
device->funcs.p_vkDestroyBufferView(device->device, bufferView, NULL);
}
void WINAPI wine_vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator)
{
TRACE("%p, 0x%s, %p\n", device, wine_dbgstr_longlong(commandPool), pAllocator);
device->funcs.p_vkDestroyCommandPool(device->device, commandPool, NULL);
}
void WINAPI wine_vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks *pAllocator)
{
TRACE("%p, 0x%s, %p\n", device, wine_dbgstr_longlong(descriptorPool), pAllocator);
@ -2744,7 +2732,7 @@ VkResult WINAPI wine_vkResetCommandBuffer(VkCommandBuffer commandBuffer, VkComma
VkResult WINAPI wine_vkResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags)
{
TRACE("%p, 0x%s, %#x\n", device, wine_dbgstr_longlong(commandPool), flags);
return device->funcs.p_vkResetCommandPool(device->device, commandPool, flags);
return device->funcs.p_vkResetCommandPool(device->device, wine_cmd_pool_from_handle(commandPool)->command_pool, flags);
}
VkResult WINAPI wine_vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags)
@ -2774,13 +2762,13 @@ VkResult WINAPI wine_vkSetEvent(VkDevice device, VkEvent event)
void WINAPI wine_vkTrimCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags)
{
TRACE("%p, 0x%s, %#x\n", device, wine_dbgstr_longlong(commandPool), flags);
device->funcs.p_vkTrimCommandPool(device->device, commandPool, flags);
device->funcs.p_vkTrimCommandPool(device->device, wine_cmd_pool_from_handle(commandPool)->command_pool, flags);
}
static void WINAPI wine_vkTrimCommandPoolKHR(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags)
{
TRACE("%p, 0x%s, %#x\n", device, wine_dbgstr_longlong(commandPool), flags);
device->funcs.p_vkTrimCommandPoolKHR(device->device, commandPool, flags);
device->funcs.p_vkTrimCommandPoolKHR(device->device, wine_cmd_pool_from_handle(commandPool)->command_pool, flags);
}
void WINAPI wine_vkUnmapMemory(VkDevice device, VkDeviceMemory memory)

View File

@ -43,7 +43,9 @@
/* Functions for which we have custom implementations outside of the thunks. */
VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers);
void WINAPI wine_vkCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers);
VkResult WINAPI wine_vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool);
VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice);
void WINAPI wine_vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator);
void WINAPI wine_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator);
void WINAPI wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator);
VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties);