[PATCH 5/7] winevulkan: Implement vkAllocate/FreeCommandBuffers.

Roderick Colenbrander thunderbird2k at gmail.com
Wed Mar 14 02:56:13 CDT 2018


Signed-off-by: Roderick Colenbrander <thunderbird2k at gmail.com>
---
 dlls/winevulkan/make_vulkan      |  9 +----
 dlls/winevulkan/vulkan.c         | 80 ++++++++++++++++++++++++++++++++++++++++
 dlls/winevulkan/vulkan_private.h |  7 ++++
 dlls/winevulkan/vulkan_thunks.c  | 22 +++++------
 dlls/winevulkan/vulkan_thunks.h  | 15 ++++++++
 5 files changed, 115 insertions(+), 18 deletions(-)

diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index 81d0e55c6b..a158d88dc8 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -111,7 +111,9 @@ FUNCTION_OVERRIDES = {
     "vkEnumeratePhysicalDevices" : {"dispatch" : True, "driver" : False, "thunk" : False},
 
     # Device functions
+    "vkAllocateCommandBuffers" : {"dispatch" : True, "driver" : False, "thunk" : False},
     "vkDestroyDevice" : {"dispatch" : True, "driver" : False, "thunk" : False},
+    "vkFreeCommandBuffers" : {"dispatch" : True, "driver" : False, "thunk" : False},
     "vkGetDeviceProcAddr" : {"dispatch" : True, "driver" : True, "thunk" : False},
     "vkGetDeviceQueue" : {"dispatch": True, "driver" : False, "thunk" : False},
 
@@ -393,13 +395,6 @@ class VkFunction(object):
     def needs_stub(self):
         """ Temporary function to limit script hacks until more code is implemented. """
 
-        # Temporary hack to pull in VkSwapChainCreateInfoKHR.
-        if self.name == "vkCreateSwapchainKHR":
-            return False
-
-        if self.name in ["vkAllocateCommandBuffers", "vkFreeCommandBuffers"]:
-            return True
-
         if self.params[0].type in ["VkCommandBuffer", "VkQueue"]:
             return True
 
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index 556f6a20ac..579968d5c8 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -52,6 +52,22 @@ static void wine_vk_physical_device_free(struct VkPhysicalDevice_T *phys_dev);
 
 static const struct vulkan_funcs *vk_funcs = NULL;
 
+/* Helper function for release command buffers. */
+static void wine_vk_command_buffers_free(struct VkDevice_T *device, VkCommandPool pool,
+        uint32_t count, const VkCommandBuffer *buffers)
+{
+    unsigned int i;
+
+    for (i = 0; i < count; i++)
+    {
+        if (buffers[i]->command_buffer)
+            device->funcs.p_vkFreeCommandBuffers(device->device, 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 fam_index, uint32_t queue_count)
@@ -368,6 +384,62 @@ VkResult WINAPI wine_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapc
             semaphore, fence, image_index);
 }
 
+VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device,
+        const VkCommandBufferAllocateInfo *allocate_info, VkCommandBuffer *buffers)
+{
+    VkResult res = VK_SUCCESS;
+    unsigned int i;
+
+    TRACE("%p %p %p\n", device, allocate_info, buffers);
+
+    /* The application provides an array of buffers, we just clear it for error handling reasons. */
+    memset(buffers, 0, allocate_info->commandBufferCount * sizeof(*buffers));
+
+    for (i = 0; i < allocate_info->commandBufferCount; i++)
+    {
+#if defined(USE_STRUCT_CONVERSION)
+        VkCommandBufferAllocateInfo_host allocate_info_host;
+#else
+        VkCommandBufferAllocateInfo allocate_info_host;
+#endif
+        /* 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.level = allocate_info->level;
+        allocate_info_host.commandBufferCount = 1;
+
+        TRACE("Creating command buffer %d, pool 0x%s, level %d\n", i,
+                wine_dbgstr_longlong(allocate_info_host.commandPool),
+                allocate_info_host.level);
+
+        buffers[i] = heap_alloc_zero(sizeof(struct VkCommandBuffer_T));
+        if (!buffers[i])
+        {
+            res = VK_ERROR_OUT_OF_HOST_MEMORY;
+            break;
+        }
+
+        buffers[i]->base.loader_magic = VULKAN_ICD_MAGIC_VALUE;
+        buffers[i]->device = device;
+        res = device->funcs.p_vkAllocateCommandBuffers(device->device,
+                &allocate_info_host, &buffers[i]->command_buffer);
+        if (res != VK_SUCCESS)
+        {
+            ERR("Failed to allocate command buffer, res=%d\n", res);
+            break;
+        }
+    }
+
+    if (res != VK_SUCCESS)
+    {
+        wine_vk_command_buffers_free(device, allocate_info->commandPool, i, buffers);
+        return res;
+    }
+
+    return VK_SUCCESS;
+}
+
 VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
         const VkDeviceCreateInfo *create_info,
         const VkAllocationCallbacks *allocator, VkDevice *device)
@@ -722,6 +794,14 @@ VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *d
     return res;
 }
 
+void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool pool, uint32_t count,
+        const VkCommandBuffer *buffers)
+{
+    TRACE("%p 0x%s %d %p\n", device, wine_dbgstr_longlong(pool), count, buffers);
+
+    wine_vk_command_buffers_free(device, pool, count, buffers);
+}
+
 PFN_vkVoidFunction WINAPI wine_vkGetDeviceProcAddr(VkDevice device, const char *name)
 {
     void *func;
diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
index d9791cb14d..92df159cb5 100644
--- a/dlls/winevulkan/vulkan_private.h
+++ b/dlls/winevulkan/vulkan_private.h
@@ -48,6 +48,13 @@ struct wine_vk_base
     UINT_PTR loader_magic;
 };
 
+struct VkCommandBuffer_T
+{
+    struct wine_vk_base base;
+    VkDevice device; /* parent */
+    VkCommandBuffer command_buffer; /* native command buffer */
+};
+
 struct VkDevice_T
 {
     struct wine_vk_base base;
diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c
index 130d91f321..8397a223fe 100644
--- a/dlls/winevulkan/vulkan_thunks.c
+++ b/dlls/winevulkan/vulkan_thunks.c
@@ -12,6 +12,17 @@
 WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
 
 #if defined(USE_STRUCT_CONVERSION)
+static inline void convert_VkCommandBufferAllocateInfo_win_to_host(const VkCommandBufferAllocateInfo *in, VkCommandBufferAllocateInfo_host *out)
+{
+    if (!in) return;
+
+    out->sType = in->sType;
+    out->pNext = in->pNext;
+    out->commandPool = in->commandPool;
+    out->level = in->level;
+    out->commandBufferCount = in->commandBufferCount;
+}
+
 static inline void convert_VkDescriptorSetAllocateInfo_win_to_host(const VkDescriptorSetAllocateInfo *in, VkDescriptorSetAllocateInfo_host *out)
 {
     if (!in) return;
@@ -537,12 +548,6 @@ static inline void free_VkCopyDescriptorSet_array(VkCopyDescriptorSet_host *in,
 
 #endif /* USE_STRUCT_CONVERSION */
 
-static VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers)
-{
-    FIXME("stub: %p, %p, %p\n", device, pAllocateInfo, pCommandBuffers);
-    return VK_ERROR_OUT_OF_HOST_MEMORY;
-}
-
 static VkResult WINAPI wine_vkAllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo, VkDescriptorSet *pDescriptorSets)
 {
 #if defined(USE_STRUCT_CONVERSION)
@@ -1141,11 +1146,6 @@ static VkResult WINAPI wine_vkFlushMappedMemoryRanges(VkDevice device, uint32_t
 #endif
 }
 
-static void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers)
-{
-    FIXME("stub: %p, 0x%s, %u, %p\n", device, wine_dbgstr_longlong(commandPool), commandBufferCount, pCommandBuffers);
-}
-
 static VkResult WINAPI wine_vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets)
 {
     TRACE("%p, 0x%s, %u, %p\n", device, wine_dbgstr_longlong(descriptorPool), descriptorSetCount, pDescriptorSets);
diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h
index 20f68dc90e..188598b101 100644
--- a/dlls/winevulkan/vulkan_thunks.h
+++ b/dlls/winevulkan/vulkan_thunks.h
@@ -16,6 +16,7 @@ BOOL wine_vk_device_extension_supported(const char *name) DECLSPEC_HIDDEN;
 
 /* Functions for which we have custom implementations outside of the thunks. */
 VkResult WINAPI wine_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) DECLSPEC_HIDDEN;
+VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers) DECLSPEC_HIDDEN;
 VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) DECLSPEC_HIDDEN;
 VkResult WINAPI wine_vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) DECLSPEC_HIDDEN;
 VkResult WINAPI wine_vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) DECLSPEC_HIDDEN;
@@ -25,6 +26,7 @@ void WINAPI wine_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
 void WINAPI wine_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) DECLSPEC_HIDDEN;
 VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) DECLSPEC_HIDDEN;
 VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices) DECLSPEC_HIDDEN;
+void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers) DECLSPEC_HIDDEN;
 PFN_vkVoidFunction WINAPI wine_vkGetDeviceProcAddr(VkDevice device, const char *pName) DECLSPEC_HIDDEN;
 void WINAPI wine_vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) DECLSPEC_HIDDEN;
 VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) DECLSPEC_HIDDEN;
@@ -35,6 +37,15 @@ VkBool32 WINAPI wine_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDe
 VkResult WINAPI wine_vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) DECLSPEC_HIDDEN;
 VkResult WINAPI wine_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) DECLSPEC_HIDDEN;
 
+typedef struct VkCommandBufferAllocateInfo_host
+{
+    VkStructureType sType;
+    const void *pNext;
+    VkCommandPool commandPool;
+    VkCommandBufferLevel level;
+    uint32_t commandBufferCount;
+} VkCommandBufferAllocateInfo_host;
+
 typedef struct VkDescriptorSetAllocateInfo_host
 {
     VkStructureType sType;
@@ -383,7 +394,11 @@ typedef struct VkCopyDescriptorSet_host
 /* For use by vkDevice and children */
 struct vulkan_device_funcs
 {
+#if defined(USE_STRUCT_CONVERSION)
+    VkResult (*p_vkAllocateCommandBuffers)(VkDevice, const VkCommandBufferAllocateInfo_host *, VkCommandBuffer *);
+#else
     VkResult (*p_vkAllocateCommandBuffers)(VkDevice, const VkCommandBufferAllocateInfo *, VkCommandBuffer *);
+#endif
 #if defined(USE_STRUCT_CONVERSION)
     VkResult (*p_vkAllocateDescriptorSets)(VkDevice, const VkDescriptorSetAllocateInfo_host *, VkDescriptorSet *);
 #else
-- 
2.14.3




More information about the wine-devel mailing list