Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com --- dlls/winevulkan/make_vulkan | 4 +- dlls/winevulkan/vulkan.c | 96 +++++++++++++++++++++++++++++++++++++++- dlls/winevulkan/vulkan_private.h | 13 ++++++ dlls/winevulkan/vulkan_thunks.c | 5 --- dlls/winevulkan/vulkan_thunks.h | 1 + 5 files changed, 109 insertions(+), 10 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index ddae964457..24160997ec 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 7b0a15f2af..556f6a20ac 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 fam_index, uint32_t queue_count) +{ + unsigned int i; + + struct VkQueue_T *queues = heap_calloc(queue_count, sizeof(struct VkQueue_T)); + if (!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, fam_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,21 @@ 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++) + { + if (device->queues[i]) + heap_free(device->queues[i]); + } + heap_free(device->queues); + device->queues = NULL; + } + + if (device->queue_count) + heap_free(device->queue_count); + if (device->device && device->funcs.p_vkDestroyDevice) { device->funcs.p_vkDestroyDevice(device->device, NULL /* pAllocator */); @@ -328,14 +373,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 +412,45 @@ 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; + } + + object->queue_count = heap_calloc(max_queue_families, sizeof(*object->queue_count)); + if (!object->queue_count) + { + res = VK_ERROR_OUT_OF_HOST_MEMORY; + goto err; + } + + for (i = 0; i < create_info->queueCreateInfoCount; i++) + { + uint32_t fam_index = create_info->pQueueCreateInfos[i].queueFamilyIndex; + uint32_t queue_count = create_info->pQueueCreateInfos[i].queueCount; + + TRACE("queueFamilyIndex %d, queueCount %d\n", fam_index, queue_count); + + object->queues[fam_index] = wine_vk_device_alloc_queues(object, fam_index, queue_count); + if (!object->queues[fam_index]) + { + res = VK_ERROR_OUT_OF_HOST_MEMORY; + ERR("Failed to allocate memory for queues\n"); + goto err; + } + object->queue_count[fam_index] = queue_count; + } + *device = object; return VK_SUCCESS;
@@ -660,6 +744,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 d49366fa5f..d9791cb14d 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -53,6 +53,12 @@ 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; + /* Stores number of queues per queue family */ + uint32_t *queue_count; + VkDevice device; /* native device */ };
@@ -81,4 +87,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 51de005a7f..792f90e764 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 13c1228196..7be86bfa6f 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;