We need to wrap VkCommandPools to track allocated VkCommandBuffers.
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/winevulkan/make_vulkan | 50 +++++++++++++++--------------
dlls/winevulkan/vulkan.c | 68 +++++++++++++++++++++++++++++++++-------
dlls/winevulkan/vulkan_private.h | 15 +++++++++
dlls/winevulkan/vulkan_thunks.c | 18 ++---------
dlls/winevulkan/vulkan_thunks.h | 2 ++
5 files changed, 103 insertions(+), 50 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index 5b0f82ce355a..8e7d88ad7dec 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -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):
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index 89df838f0499..886ef0b47344 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -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)
diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
index 2e071a524b1c..f31d4d5d8f52 100644
--- a/dlls/winevulkan/vulkan_private.h
+++ b/dlls/winevulkan/vulkan_private.h
@@ -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;
diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c
index 9d637bf9eb92..f5cadd8c72b6 100644
--- a/dlls/winevulkan/vulkan_thunks.c
+++ b/dlls/winevulkan/vulkan_thunks.c
@@ -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)
diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h
index 94e56bb97300..21f9b4817800 100644
--- a/dlls/winevulkan/vulkan_thunks.h
+++ b/dlls/winevulkan/vulkan_thunks.h
@@ -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);
--
2.16.4