Roderick Colenbrander : winevulkan: Implement vkGetDeviceQueue.

Alexandre Julliard julliard at winehq.org
Wed Mar 14 17:37:18 CDT 2018


Module: wine
Branch: master
Commit: 9721ec92b9b7a764ce140e26560d7254ed3065b3
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=9721ec92b9b7a764ce140e26560d7254ed3065b3

Author: Roderick Colenbrander <thunderbird2k at gmail.com>
Date:   Wed Mar 14 13:11:52 2018 +0100

winevulkan: Implement vkGetDeviceQueue.

Signed-off-by: Roderick Colenbrander <thunderbird2k at gmail.com>
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winevulkan/make_vulkan      |  4 +-
 dlls/winevulkan/vulkan.c         | 84 +++++++++++++++++++++++++++++++++++++++-
 dlls/winevulkan/vulkan_private.h | 11 ++++++
 dlls/winevulkan/vulkan_thunks.c  |  5 ---
 dlls/winevulkan/vulkan_thunks.h  |  1 +
 5 files changed, 95 insertions(+), 10 deletions(-)

diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index b53203b..abcd425 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -113,6 +113,7 @@ FUNCTION_OVERRIDES = {
     # Device functions
     "vkDestroyDevice" : {"dispatch" : True, "driver" : False, "thunk" : False},
     "vkGetDeviceProcAddr" : {"dispatch" : True, "driver" : True, "thunk" : False},
+    "vkGetDeviceQueue" : {"dispatch": True, "driver" : False, "thunk" : False},
 
     # VK_KHR_surface
     "vkDestroySurfaceKHR" : {"dispatch" : True, "driver" : True, "thunk" : False},
@@ -396,9 +397,6 @@ class VkFunction(object):
         if self.name == "vkCreateSwapchainKHR":
             return False
 
-        if self.params[0].type != "VkPhysicalDevice":
-            return True
-
         if self.is_device_func():
             return True
 
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index 7b0fb37..e6873e8 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -52,6 +52,36 @@ static void wine_vk_physical_device_free(struct VkPhysicalDevice_T *phys_dev);
 
 static const struct vulkan_funcs *vk_funcs = NULL;
 
+/* 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)
+{
+    struct VkQueue_T *queues;
+    unsigned int i;
+
+    if (!(queues = heap_calloc(queue_count, sizeof(*queues))))
+    {
+        ERR("Failed to allocate memory for queues\n");
+        return NULL;
+    }
+
+    for (i = 0; i < queue_count; i++)
+    {
+        struct VkQueue_T *queue = &queues[i];
+        queue->device = device;
+
+        /* The native device was already allocated with the required number of queues,
+         * so just fetch them from there.
+         */
+        device->funcs.p_vkGetDeviceQueue(device->device, family_index, i, &queue->queue);
+
+        /* Set special header for ICD loader. */
+        ((struct wine_vk_base *)queue)->loader_magic = VULKAN_ICD_MAGIC_VALUE;
+    }
+
+    return queues;
+}
+
 /* Helper function used for freeing a device structure. This function supports full
  * and partial object cleanups and can thus be used for vkCreateDevice failures.
  */
@@ -60,6 +90,17 @@ static void wine_vk_device_free(struct VkDevice_T *device)
     if (!device)
         return;
 
+    if (device->queues)
+    {
+        unsigned int i;
+        for (i = 0; i < device->max_queue_families; i++)
+        {
+            heap_free(device->queues[i]);
+        }
+        heap_free(device->queues);
+        device->queues = NULL;
+    }
+
     if (device->device && device->funcs.p_vkDestroyDevice)
     {
         device->funcs.p_vkDestroyDevice(device->device, NULL /* pAllocator */);
@@ -328,14 +369,14 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
         const VkAllocationCallbacks *allocator, VkDevice *device)
 {
     struct VkDevice_T *object = NULL;
+    uint32_t max_queue_families;
     VkResult res;
+    unsigned int i;
 
     TRACE("%p %p %p %p\n", phys_dev, create_info, allocator, device);
 
     if (allocator)
-    {
         FIXME("Support for allocation callbacks not implemented yet\n");
-    }
 
     object = heap_alloc_zero(sizeof(*object));
     if (!object)
@@ -367,6 +408,37 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
     ALL_VK_DEVICE_FUNCS()
 #undef USE_VK_FUNC
 
+    /* We need to cache all queues within the device as each requires wrapping since queues are
+     * dispatchable objects.
+     */
+    phys_dev->instance->funcs.p_vkGetPhysicalDeviceQueueFamilyProperties(phys_dev->phys_dev,
+            &max_queue_families, NULL);
+    object->max_queue_families = max_queue_families;
+    TRACE("Max queue families: %d\n", object->max_queue_families);
+
+    object->queues = heap_calloc(max_queue_families, sizeof(*object->queues));
+    if (!object->queues)
+    {
+        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto err;
+    }
+
+    for (i = 0; i < create_info->queueCreateInfoCount; i++)
+    {
+        uint32_t family_index = create_info->pQueueCreateInfos[i].queueFamilyIndex;
+        uint32_t queue_count = create_info->pQueueCreateInfos[i].queueCount;
+
+        TRACE("queueFamilyIndex %u, queueCount %u\n", family_index, queue_count);
+
+        object->queues[family_index] = wine_vk_device_alloc_queues(object, family_index, queue_count);
+        if (!object->queues[family_index])
+        {
+            res = VK_ERROR_OUT_OF_HOST_MEMORY;
+            ERR("Failed to allocate memory for queues\n");
+            goto err;
+        }
+    }
+
     *device = object;
     return VK_SUCCESS;
 
@@ -660,6 +732,14 @@ PFN_vkVoidFunction WINAPI wine_vkGetDeviceProcAddr(VkDevice device, const char *
     return NULL;
 }
 
+void WINAPI wine_vkGetDeviceQueue(VkDevice device, uint32_t family_index,
+        uint32_t queue_index, VkQueue *queue)
+{
+    TRACE("%p %u %u %p\n", device, family_index, queue_index, queue);
+
+    *queue = &device->queues[family_index][queue_index];
+}
+
 static PFN_vkVoidFunction WINAPI wine_vkGetInstanceProcAddr(VkInstance instance, const char *name)
 {
     void *func;
diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
index d49366f..203ad12 100644
--- a/dlls/winevulkan/vulkan_private.h
+++ b/dlls/winevulkan/vulkan_private.h
@@ -53,6 +53,10 @@ struct VkDevice_T
     struct wine_vk_base base;
     struct vulkan_device_funcs funcs;
     struct VkPhysicalDevice_T *phys_dev; /* parent */
+
+    uint32_t max_queue_families;
+    struct VkQueue_T **queues;
+
     VkDevice device; /* native device */
 };
 
@@ -81,4 +85,11 @@ struct VkPhysicalDevice_T
     VkPhysicalDevice phys_dev; /* native physical device */
 };
 
+struct VkQueue_T
+{
+    struct wine_vk_base base;
+    VkDevice device; /* parent */
+    VkQueue queue; /* native queue */
+};
+
 #endif /* __WINE_VULKAN_PRIVATE_H */
diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c
index dfda842..ba8b689 100644
--- a/dlls/winevulkan/vulkan_thunks.c
+++ b/dlls/winevulkan/vulkan_thunks.c
@@ -685,11 +685,6 @@ static void WINAPI wine_vkGetDeviceMemoryCommitment(VkDevice device, VkDeviceMem
     FIXME("stub: %p, 0x%s, %p\n", device, wine_dbgstr_longlong(memory), pCommittedMemoryInBytes);
 }
 
-static void WINAPI wine_vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue)
-{
-    FIXME("stub: %p, %u, %u, %p\n", device, queueFamilyIndex, queueIndex, pQueue);
-}
-
 static VkResult WINAPI wine_vkGetEventStatus(VkDevice device, VkEvent event)
 {
     FIXME("stub: %p, 0x%s\n", device, wine_dbgstr_longlong(event));
diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h
index 13c1228..7be86bf 100644
--- a/dlls/winevulkan/vulkan_thunks.h
+++ b/dlls/winevulkan/vulkan_thunks.h
@@ -26,6 +26,7 @@ void WINAPI wine_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain
 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;
 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;
 VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats) DECLSPEC_HIDDEN;
 VkResult WINAPI wine_vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list