Module: wine Branch: master Commit: 9721ec92b9b7a764ce140e26560d7254ed3065b3 URL: https://source.winehq.org/git/wine.git/?a=commit;h=9721ec92b9b7a764ce140e265...
Author: Roderick Colenbrander thunderbird2k@gmail.com Date: Wed Mar 14 13:11:52 2018 +0100
winevulkan: Implement vkGetDeviceQueue.
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com Signed-off-by: Józef Kucia jkucia@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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;