[PATCH 1/4] winevulkan: Wrap VkCommandPools.

Józef Kucia jkucia at codeweavers.com
Thu Aug 30 05:22:31 CDT 2018


We need to wrap VkCommandPools to track allocated VkCommandBuffers.

Signed-off-by: Józef Kucia <jkucia at 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




More information about the wine-devel mailing list