-- v3: win32u: Move surface and swapchain wrappers from winevulkan. winevulkan: Keep the host function pointers in devices and instances. winevulkan: Use the vulkan object as the wrapper tree node. winevulkan: Get rid of unnecessary *to_handle helpers. winevulkan: Avoid changing client command buffer pointer. winevulkan: Fix incorrect client queue pointers. winevulkan: Introduce a new vulkan_object_init helper. winevulkan: Use the result to decide if creation failed.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/loader.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/winevulkan/loader.c b/dlls/winevulkan/loader.c index 0f58d17bdd7..644e0982e7a 100644 --- a/dlls/winevulkan/loader.c +++ b/dlls/winevulkan/loader.c @@ -376,7 +376,7 @@ VkResult WINAPI vkCreateInstance(const VkInstanceCreateInfo *create_info, free(instance); }
- if (!instance->obj.unix_handle) + if (params.result) free(instance); return params.result; } @@ -583,7 +583,7 @@ VkResult WINAPI vkCreateDevice(VkPhysicalDevice phys_dev, const VkDeviceCreateIn params.client_ptr = device; status = UNIX_CALL(vkCreateDevice, ¶ms); assert(!status); - if (!device->obj.unix_handle) + if (params.result) free(device); return params.result; } @@ -618,7 +618,7 @@ VkResult WINAPI vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateIn params.client_ptr = cmd_pool; status = UNIX_CALL(vkCreateCommandPool, ¶ms); assert(!status); - if (!cmd_pool->obj.unix_handle) + if (params.result) free(cmd_pool); return params.result; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/vulkan.c | 51 +++++++++++++++++------------------- include/wine/vulkan_driver.h | 6 +++++ 2 files changed, 30 insertions(+), 27 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 44cea07be9c..58edc18d078 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -55,6 +55,13 @@ static struct wine_device *wine_device_from_handle(VkDevice handle) return CONTAINING_RECORD(object, struct wine_device, obj); }
+static void vulkan_object_init_ptr( struct vulkan_object *obj, UINT64 host_handle, struct vulkan_client_object *client ) +{ + obj->host_handle = host_handle; + obj->client_handle = (UINT_PTR)client; + client->unix_handle = (UINT_PTR)obj; +} + static int window_surface_compare(const void *key, const struct rb_entry *entry) { const struct wine_surface *surface = RB_ENTRY_VALUE(entry, struct wine_surface, window_entry); @@ -383,11 +390,8 @@ static VkResult wine_vk_physical_device_init(struct wine_phys_dev *object, VkPhy VkResult res; unsigned int i, j;
+ vulkan_object_init_ptr(&object->obj.obj, (UINT_PTR)host_physical_device, &client_physical_device->obj); object->obj.instance = instance; - object->obj.client.physical_device = client_physical_device; - object->obj.host.physical_device = host_physical_device; - - client_physical_device->obj.unix_handle = (uintptr_t)object;
instance->p_vkGetPhysicalDeviceMemoryProperties(host_physical_device, &object->memory_properties);
@@ -567,14 +571,12 @@ static void wine_vk_device_init_queues(struct wine_device *object, const VkDevic device->p_vkGetDeviceQueue(device->host.device, info->queueFamilyIndex, i, &host_queue); }
- queue->obj.host.queue = host_queue; - queue->obj.client.queue = client_queue; + vulkan_object_init_ptr(&queue->obj.obj, (UINT_PTR)host_queue, &client_queue->obj); queue->obj.device = device; queue->family_index = info->queueFamilyIndex; queue->queue_index = i; queue->flags = info->flags;
- client_queue->obj.unix_handle = (uintptr_t)queue; TRACE("Got device %p queue %p, host_queue %p.\n", device, queue, queue->obj.host.queue); }
@@ -892,10 +894,8 @@ VkResult wine_vkAllocateCommandBuffers(VkDevice client_device, const VkCommandBu break; }
- buffer->host.command_buffer = host_command_buffer; - buffer->client.command_buffer = client_command_buffer; + vulkan_object_init_ptr(&buffer->obj, (UINT_PTR)host_command_buffer, &client_command_buffer->obj); buffer->device = device; - client_command_buffer->obj.unix_handle = (uintptr_t)buffer; add_handle_mapping_ptr(instance, buffer->client.command_buffer, buffer->host.command_buffer, &buffer->wrapper_entry); }
@@ -952,8 +952,8 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice client_physical_device, const VkDe return res; }
+ vulkan_object_init_ptr(&device->obj.obj, (UINT_PTR)host_device, &client_device->obj); device->obj.physical_device = physical_device; - device->obj.host.device = host_device;
/* Just load all function pointers we are aware off. The loader takes care of filtering. * We use vkGetDeviceProcAddr as opposed to vkGetInstanceProcAddr for efficiency reasons @@ -970,7 +970,6 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice client_physical_device, const VkDe wine_vk_device_init_queues(device, create_info_host.pQueueCreateInfos + i, &client_queues);
client_device->quirks = CONTAINING_RECORD(instance, struct wine_instance, obj)->quirks; - client_device->obj.unix_handle = (uintptr_t)device;
TRACE("Created device %p, host_device %p.\n", device, device->obj.host.device); for (i = 0; i < device->queue_count; i++) @@ -988,12 +987,11 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, const VkAllocationCallbacks *allocator, VkInstance *ret, void *client_ptr) { - VkInstance client_instance = client_ptr; VkInstanceCreateInfo create_info_host; const VkApplicationInfo *app_info; struct conversion_context ctx; struct wine_instance *instance; - VkInstance host_instance; + VkInstance host_instance, client_instance = client_ptr; unsigned int i; VkResult res;
@@ -1019,8 +1017,7 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, return res; }
- instance->obj.client.instance = client_instance; - instance->obj.host.instance = host_instance; + vulkan_object_init_ptr(&instance->obj.obj, (UINT_PTR)host_instance, &client_instance->obj);
/* Load all instance functions we are aware of. Note the loader takes care * of any filtering for extensions which were not requested, but which the @@ -1058,8 +1055,6 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, instance->quirks |= WINEVULKAN_QUIRK_GET_DEVICE_PROC_ADDR; }
- client_instance->obj.unix_handle = (uintptr_t)instance; - TRACE("Created instance %p, host_instance %p.\n", instance, instance->obj.host.instance);
rb_init(&instance->wrappers, wrapper_entry_compare); @@ -1331,9 +1326,7 @@ VkResult wine_vkCreateCommandPool(VkDevice client_device, const VkCommandPoolCre return res; }
- object->host.command_pool = host_command_pool; - object->client.command_pool = (uintptr_t)client_command_pool; - client_command_pool->obj.unix_handle = (uintptr_t)object; + vulkan_object_init_ptr(&object->obj, host_command_pool, &client_command_pool->obj);
*command_pool = object->client.command_pool; add_handle_mapping(instance, *command_pool, object->host.command_pool, &object->wrapper_entry); @@ -1706,6 +1699,7 @@ VkResult wine_vkCreateWin32SurfaceKHR(VkInstance client_instance, const VkWin32S struct vulkan_instance *instance = vulkan_instance_from_handle(client_instance); VkWin32SurfaceCreateInfoKHR create_info_host = *create_info; struct wine_surface *surface; + VkSurfaceKHR host_surface; HWND dummy = NULL; VkResult res;
@@ -1733,7 +1727,10 @@ VkResult wine_vkCreateWin32SurfaceKHR(VkInstance client_instance, const VkWin32S return res; }
- surface->obj.host.surface = vk_funcs->p_wine_get_host_surface(surface->driver_surface); + host_surface = vk_funcs->p_wine_get_host_surface(surface->driver_surface); + vulkan_object_init(&surface->obj.obj, host_surface); + surface->obj.instance = instance; + if (dummy) NtUserDestroyWindow(dummy); window_surfaces_insert(surface);
@@ -1852,7 +1849,7 @@ VkResult wine_vkCreateSwapchainKHR(VkDevice client_device, const VkSwapchainCrea return res; }
- object->obj.host.swapchain = host_swapchain; + vulkan_object_init(&object->obj.obj, host_swapchain); object->surface = surface; object->extents = create_info->imageExtent;
@@ -2051,7 +2048,7 @@ VkResult wine_vkAllocateMemory(VkDevice client_device, const VkMemoryAllocateInf return result; }
- memory->host.device_memory = host_device_memory; + vulkan_object_init(&memory->obj, host_device_memory); memory->size = info.allocationSize; memory->vm_map = mapping;
@@ -2435,7 +2432,7 @@ VkResult wine_vkCreateDebugUtilsMessengerEXT(VkInstance client_instance, return res; }
- object->host.debug_messenger = host_debug_messenger; + vulkan_object_init(&object->obj, host_debug_messenger); object->instance = instance; object->user_callback = (UINT_PTR)create_info->pfnUserCallback; object->user_data = (UINT_PTR)create_info->pUserData; @@ -2491,7 +2488,7 @@ VkResult wine_vkCreateDebugReportCallbackEXT(VkInstance client_instance, return res; }
- object->host.debug_callback = host_debug_callback; + vulkan_object_init(&object->obj, host_debug_callback); object->instance = instance; object->user_callback = (UINT_PTR)create_info->pfnCallback; object->user_data = (UINT_PTR)create_info->pUserData; @@ -2541,7 +2538,7 @@ VkResult wine_vkCreateDeferredOperationKHR(VkDevice device_handle, return res; }
- object->host.deferred_operation = host_deferred_operation; + vulkan_object_init(&object->obj, host_deferred_operation); init_conversion_context(&object->ctx);
*operation = wine_deferred_operation_to_handle(object); diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h index cdc44c8d61c..6af3cc0ac13 100644 --- a/include/wine/vulkan_driver.h +++ b/include/wine/vulkan_driver.h @@ -63,6 +63,12 @@ struct vulkan_object }; \ }
+static inline void vulkan_object_init( struct vulkan_object *obj, UINT64 host_handle ) +{ + obj->host_handle = host_handle; + obj->client_handle = (UINT_PTR)obj; +} + struct vulkan_instance { VULKAN_OBJECT_HEADER( VkInstance, instance );
From: Rémi Bernon rbernon@codeweavers.com
Fixes: 32f21f7537fbd913f691d2691b9d4f0c84fad5ca Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57477 --- dlls/winevulkan/vulkan.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 58edc18d078..8102fabbd1c 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -537,11 +537,11 @@ static void wine_vk_free_command_buffers(struct vulkan_device *device, } }
-static void wine_vk_device_init_queues(struct wine_device *object, const VkDeviceQueueCreateInfo *info, - VkQueue *client_queues) +static void wine_vk_device_init_queues(struct wine_device *object, const VkDeviceQueueCreateInfo *info) { struct wine_queue *queues = object->queues + object->queue_count; struct vulkan_device *device = &object->obj; + VkQueue client_queues = device->client.device->queues + object->queue_count; VkDeviceQueueInfo2 queue_info; UINT i;
@@ -550,7 +550,7 @@ static void wine_vk_device_init_queues(struct wine_device *object, const VkDevic for (i = 0; i < info->queueCount; i++) { struct wine_queue *queue = queues + i; - VkQueue host_queue, client_queue = *client_queues++; + VkQueue host_queue, client_queue = client_queues + i;
/* The Vulkan spec says: * @@ -912,7 +912,6 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice client_physical_device, const VkDe struct vulkan_instance *instance = physical_device->instance; VkDevice host_device, client_device = client_ptr; VkDeviceCreateInfo create_info_host; - struct VkQueue_T *client_queues; struct conversion_context ctx; struct wine_device *device; unsigned int queue_count, i; @@ -965,9 +964,8 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice client_physical_device, const VkDe ALL_VK_DEVICE_FUNCS #undef USE_VK_FUNC
- client_queues = client_device->queues; for (i = 0; i < create_info_host.queueCreateInfoCount; i++) - wine_vk_device_init_queues(device, create_info_host.pQueueCreateInfos + i, &client_queues); + wine_vk_device_init_queues(device, create_info_host.pQueueCreateInfos + i);
client_device->quirks = CONTAINING_RECORD(instance, struct wine_instance, obj)->quirks;
From: Rémi Bernon rbernon@codeweavers.com
It is used later for cleanup in case of allocation failure.
Fixes: 32f21f7537fbd913f691d2691b9d4f0c84fad5ca --- dlls/winevulkan/vulkan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 8102fabbd1c..c57bb6f8d16 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -867,7 +867,7 @@ VkResult wine_vkAllocateCommandBuffers(VkDevice client_device, const VkCommandBu for (i = 0; i < allocate_info->commandBufferCount; i++) { VkCommandBufferAllocateInfo allocate_info_host; - VkCommandBuffer host_command_buffer, client_command_buffer = *buffers++; + VkCommandBuffer host_command_buffer, client_command_buffer = buffers[i];
/* TODO: future extensions (none yet) may require pNext conversion. */ allocate_info_host.pNext = allocate_info->pNext;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/vulkan.c | 10 +++++----- dlls/winevulkan/vulkan_private.h | 28 ---------------------------- 2 files changed, 5 insertions(+), 33 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index c57bb6f8d16..8dc8f89709e 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -1732,7 +1732,7 @@ VkResult wine_vkCreateWin32SurfaceKHR(VkInstance client_instance, const VkWin32S if (dummy) NtUserDestroyWindow(dummy); window_surfaces_insert(surface);
- *ret = wine_surface_to_handle(surface); + *ret = surface->obj.client.surface; add_handle_mapping(instance, *ret, surface->obj.host.surface, &surface->wrapper_entry); return VK_SUCCESS; } @@ -1851,7 +1851,7 @@ VkResult wine_vkCreateSwapchainKHR(VkDevice client_device, const VkSwapchainCrea object->surface = surface; object->extents = create_info->imageExtent;
- *ret = wine_swapchain_to_handle(object); + *ret = object->obj.client.swapchain; add_handle_mapping(instance, *ret, object->obj.host.swapchain, &object->wrapper_entry); return VK_SUCCESS; } @@ -2435,7 +2435,7 @@ VkResult wine_vkCreateDebugUtilsMessengerEXT(VkInstance client_instance, object->user_callback = (UINT_PTR)create_info->pfnUserCallback; object->user_data = (UINT_PTR)create_info->pUserData;
- *messenger = wine_debug_utils_messenger_to_handle(object); + *messenger = object->client.debug_messenger; add_handle_mapping(instance, *messenger, object->host.debug_messenger, &object->wrapper_entry); return VK_SUCCESS; } @@ -2491,7 +2491,7 @@ VkResult wine_vkCreateDebugReportCallbackEXT(VkInstance client_instance, object->user_callback = (UINT_PTR)create_info->pfnCallback; object->user_data = (UINT_PTR)create_info->pUserData;
- *callback = wine_debug_report_callback_to_handle(object); + *callback = object->client.debug_callback; add_handle_mapping(instance, *callback, object->host.debug_callback, &object->wrapper_entry); return VK_SUCCESS; } @@ -2539,7 +2539,7 @@ VkResult wine_vkCreateDeferredOperationKHR(VkDevice device_handle, vulkan_object_init(&object->obj, host_deferred_operation); init_conversion_context(&object->ctx);
- *operation = wine_deferred_operation_to_handle(object); + *operation = object->client.deferred_operation; add_handle_mapping(instance, *operation, object->host.deferred_operation, &object->wrapper_entry); return VK_SUCCESS; } diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index d762e51e951..bcf24bdd5ef 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -172,24 +172,12 @@ static inline struct wine_debug_utils_messenger *wine_debug_utils_messenger_from return (struct wine_debug_utils_messenger *)(uintptr_t)handle; }
-static inline VkDebugUtilsMessengerEXT wine_debug_utils_messenger_to_handle( - struct wine_debug_utils_messenger *debug_messenger) -{ - return (VkDebugUtilsMessengerEXT)(uintptr_t)debug_messenger; -} - static inline struct wine_debug_report_callback *wine_debug_report_callback_from_handle( VkDebugReportCallbackEXT handle) { return (struct wine_debug_report_callback *)(uintptr_t)handle; }
-static inline VkDebugReportCallbackEXT wine_debug_report_callback_to_handle( - struct wine_debug_report_callback *debug_messenger) -{ - return (VkDebugReportCallbackEXT)(uintptr_t)debug_messenger; -} - struct wine_surface { struct vulkan_surface obj; @@ -206,11 +194,6 @@ static inline struct wine_surface *wine_surface_from_handle(VkSurfaceKHR handle) return CONTAINING_RECORD(obj, struct wine_surface, obj); }
-static inline VkSurfaceKHR wine_surface_to_handle(struct wine_surface *surface) -{ - return (VkSurfaceKHR)(uintptr_t)&surface->obj; -} - struct wine_swapchain { struct vulkan_swapchain obj; @@ -226,11 +209,6 @@ static inline struct wine_swapchain *wine_swapchain_from_handle(VkSwapchainKHR h return CONTAINING_RECORD(obj, struct wine_swapchain, obj); }
-static inline VkSwapchainKHR wine_swapchain_to_handle(struct wine_swapchain *surface) -{ - return (VkSwapchainKHR)(uintptr_t)&surface->obj; -} - BOOL wine_vk_device_extension_supported(const char *name); BOOL wine_vk_instance_extension_supported(const char *name); BOOL wine_vk_is_host_surface_extension(const char *name); @@ -295,12 +273,6 @@ static inline struct wine_deferred_operation *wine_deferred_operation_from_handl return (struct wine_deferred_operation *)(uintptr_t)handle; }
-static inline VkDeferredOperationKHR wine_deferred_operation_to_handle( - struct wine_deferred_operation *deferred_operation) -{ - return (VkDeferredOperationKHR)(uintptr_t)deferred_operation; -} - typedef UINT32 PTR32;
typedef struct
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/vulkan.c | 112 ++++++++++++++----------------- dlls/winevulkan/vulkan_private.h | 34 +--------- include/wine/vulkan_driver.h | 2 + 3 files changed, 53 insertions(+), 95 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 8dc8f89709e..c5ce0735901 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -130,46 +130,34 @@ static uint32_t wine_vk_count_struct_(void *s, VkStructureType t)
static const struct vulkan_funcs *vk_funcs;
-static int wrapper_entry_compare(const void *key, const struct rb_entry *entry) +static int vulkan_object_compare(const void *key, const struct rb_entry *entry) { - struct wrapper_entry *wrapper = RB_ENTRY_VALUE(entry, struct wrapper_entry, entry); + struct vulkan_object *object = RB_ENTRY_VALUE(entry, struct vulkan_object, entry); const uint64_t *host_handle = key; - if (*host_handle < wrapper->host_handle) return -1; - if (*host_handle > wrapper->host_handle) return 1; + if (*host_handle < object->host_handle) return -1; + if (*host_handle > object->host_handle) return 1; return 0; }
-static void add_handle_mapping(struct vulkan_instance *obj, uint64_t client_handle, - uint64_t host_handle, struct wrapper_entry *entry) +static void vulkan_instance_insert_object( struct vulkan_instance *instance, struct vulkan_object *obj ) { - struct wine_instance *instance = CONTAINING_RECORD(obj, struct wine_instance, obj); - - if (instance->enable_wrapper_list) + struct wine_instance *impl = CONTAINING_RECORD(instance, struct wine_instance, obj); + if (impl->objects.compare) { - entry->host_handle = host_handle; - entry->client_handle = client_handle; - - pthread_rwlock_wrlock(&instance->wrapper_lock); - rb_put(&instance->wrappers, &host_handle, &entry->entry); - pthread_rwlock_unlock(&instance->wrapper_lock); + pthread_rwlock_wrlock( &impl->objects_lock ); + rb_put( &impl->objects, &obj->host_handle, &obj->entry ); + pthread_rwlock_unlock( &impl->objects_lock ); } }
-static void add_handle_mapping_ptr(struct vulkan_instance *obj, void *client_handle, - void *host_handle, struct wrapper_entry *entry) +static void vulkan_instance_remove_object( struct vulkan_instance *instance, struct vulkan_object *obj ) { - add_handle_mapping(obj, (uintptr_t)client_handle, (uintptr_t)host_handle, entry); -} - -static void remove_handle_mapping(struct vulkan_instance *obj, struct wrapper_entry *entry) -{ - struct wine_instance *instance = CONTAINING_RECORD(obj, struct wine_instance, obj); - - if (instance->enable_wrapper_list) + struct wine_instance *impl = CONTAINING_RECORD(instance, struct wine_instance, obj); + if (impl->objects.compare) { - pthread_rwlock_wrlock(&instance->wrapper_lock); - rb_remove(&instance->wrappers, &entry->entry); - pthread_rwlock_unlock(&instance->wrapper_lock); + pthread_rwlock_wrlock( &impl->objects_lock ); + rb_remove( &impl->objects, &obj->entry ); + pthread_rwlock_unlock( &impl->objects_lock ); } }
@@ -179,13 +167,13 @@ static uint64_t client_handle_from_host(struct vulkan_instance *obj, uint64_t ho struct rb_entry *entry; uint64_t result = 0;
- pthread_rwlock_rdlock(&instance->wrapper_lock); - if ((entry = rb_get(&instance->wrappers, &host_handle))) + pthread_rwlock_rdlock(&instance->objects_lock); + if ((entry = rb_get(&instance->objects, &host_handle))) { - struct wrapper_entry *wrapper = RB_ENTRY_VALUE(entry, struct wrapper_entry, entry); - result = wrapper->client_handle; + struct vulkan_object *object = RB_ENTRY_VALUE(entry, struct vulkan_object, entry); + result = object->client_handle; } - pthread_rwlock_unlock(&instance->wrapper_lock); + pthread_rwlock_unlock(&instance->objects_lock); return result; }
@@ -531,7 +519,7 @@ static void wine_vk_free_command_buffers(struct vulkan_device *device,
device->p_vkFreeCommandBuffers(device->host.device, pool->host.command_pool, 1, &buffer->host.command_buffer); - remove_handle_mapping(instance, &buffer->wrapper_entry); + vulkan_instance_remove_object(instance, &buffer->obj); buffer->client.command_buffer->obj.unix_handle = 0; free(buffer); } @@ -759,7 +747,8 @@ static VkResult wine_vk_instance_convert_create_info(struct conversion_context * const char *extension_name = dst->ppEnabledExtensionNames[i]; if (!strcmp(extension_name, "VK_EXT_debug_utils") || !strcmp(extension_name, "VK_EXT_debug_report")) { - instance->enable_wrapper_list = VK_TRUE; + rb_init(&instance->objects, vulkan_object_compare); + pthread_rwlock_init(&instance->objects_lock, NULL); } if (!strcmp(extension_name, "VK_KHR_win32_surface")) { @@ -896,7 +885,7 @@ VkResult wine_vkAllocateCommandBuffers(VkDevice client_device, const VkCommandBu
vulkan_object_init_ptr(&buffer->obj, (UINT_PTR)host_command_buffer, &client_command_buffer->obj); buffer->device = device; - add_handle_mapping_ptr(instance, buffer->client.command_buffer, buffer->host.command_buffer, &buffer->wrapper_entry); + vulkan_instance_insert_object(instance, &buffer->obj); }
if (res != VK_SUCCESS) @@ -973,9 +962,9 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice client_physical_device, const VkDe for (i = 0; i < device->queue_count; i++) { struct wine_queue *queue = device->queues + i; - add_handle_mapping_ptr(instance, queue->obj.client.queue, queue->obj.host.queue, &queue->wrapper_entry); + vulkan_instance_insert_object(instance, &queue->obj.obj); } - add_handle_mapping_ptr(instance, client_device, device->obj.host.device, &device->wrapper_entry); + vulkan_instance_insert_object(instance, &device->obj.obj);
*ret = client_device; return VK_SUCCESS; @@ -1055,17 +1044,14 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info,
TRACE("Created instance %p, host_instance %p.\n", instance, instance->obj.host.instance);
- rb_init(&instance->wrappers, wrapper_entry_compare); - pthread_rwlock_init(&instance->wrapper_lock, NULL); - for (i = 0; i < instance->phys_dev_count; i++) { struct wine_phys_dev *phys_dev = &instance->phys_devs[i]; - add_handle_mapping_ptr(&instance->obj, phys_dev->obj.client.physical_device, phys_dev->obj.host.physical_device, &phys_dev->wrapper_entry); + vulkan_instance_insert_object(&instance->obj, &phys_dev->obj.obj); } + vulkan_instance_insert_object(&instance->obj, &instance->obj.obj);
*ret = client_instance; - add_handle_mapping_ptr(&instance->obj, *ret, instance->obj.host.instance, &instance->wrapper_entry); return VK_SUCCESS; }
@@ -1082,8 +1068,8 @@ void wine_vkDestroyDevice(VkDevice client_device, const VkAllocationCallbacks *a
device->obj.p_vkDestroyDevice(device->obj.host.device, NULL /* pAllocator */); for (i = 0; i < device->queue_count; i++) - remove_handle_mapping(instance, &device->queues[i].wrapper_entry); - remove_handle_mapping(instance, &device->wrapper_entry); + vulkan_instance_remove_object(instance, &device->queues[i].obj.obj); + vulkan_instance_remove_object(instance, &device->obj.obj);
free(device); } @@ -1101,12 +1087,12 @@ void wine_vkDestroyInstance(VkInstance client_instance, const VkAllocationCallba instance->obj.p_vkDestroyInstance(instance->obj.host.instance, NULL /* allocator */); for (i = 0; i < instance->phys_dev_count; i++) { - remove_handle_mapping(&instance->obj, &instance->phys_devs[i].wrapper_entry); + vulkan_instance_remove_object(&instance->obj, &instance->phys_devs[i].obj.obj); wine_phys_dev_cleanup(&instance->phys_devs[i]); } - remove_handle_mapping(&instance->obj, &instance->wrapper_entry); + vulkan_instance_remove_object(&instance->obj, &instance->obj.obj);
- pthread_rwlock_destroy(&instance->wrapper_lock); + if (instance->objects.compare) pthread_rwlock_destroy(&instance->objects_lock); free(instance->utils_messengers); free(instance); } @@ -1325,9 +1311,9 @@ VkResult wine_vkCreateCommandPool(VkDevice client_device, const VkCommandPoolCre }
vulkan_object_init_ptr(&object->obj, host_command_pool, &client_command_pool->obj); + vulkan_instance_insert_object(instance, &object->obj);
*command_pool = object->client.command_pool; - add_handle_mapping(instance, *command_pool, object->host.command_pool, &object->wrapper_entry); return VK_SUCCESS; }
@@ -1342,7 +1328,7 @@ void wine_vkDestroyCommandPool(VkDevice client_device, VkCommandPool handle, FIXME("Support for allocation callbacks not implemented yet\n");
device->p_vkDestroyCommandPool(device->host.device, pool->host.command_pool, NULL); - remove_handle_mapping(instance, &pool->wrapper_entry); + vulkan_instance_remove_object(instance, &pool->obj); free(pool); }
@@ -1728,12 +1714,12 @@ VkResult wine_vkCreateWin32SurfaceKHR(VkInstance client_instance, const VkWin32S host_surface = vk_funcs->p_wine_get_host_surface(surface->driver_surface); vulkan_object_init(&surface->obj.obj, host_surface); surface->obj.instance = instance; + vulkan_instance_insert_object(instance, &surface->obj.obj);
if (dummy) NtUserDestroyWindow(dummy); window_surfaces_insert(surface);
*ret = surface->obj.client.surface; - add_handle_mapping(instance, *ret, surface->obj.host.surface, &surface->wrapper_entry); return VK_SUCCESS; }
@@ -1747,7 +1733,7 @@ void wine_vkDestroySurfaceKHR(VkInstance client_instance, VkSurfaceKHR client_su return;
instance->p_vkDestroySurfaceKHR(instance->host.instance, surface->driver_surface, NULL); - remove_handle_mapping(instance, &surface->wrapper_entry); + vulkan_instance_remove_object(instance, &surface->obj.obj); window_surfaces_remove(surface);
free(surface); @@ -1850,9 +1836,9 @@ VkResult wine_vkCreateSwapchainKHR(VkDevice client_device, const VkSwapchainCrea vulkan_object_init(&object->obj.obj, host_swapchain); object->surface = surface; object->extents = create_info->imageExtent; + vulkan_instance_insert_object(instance, &object->obj.obj);
*ret = object->obj.client.swapchain; - add_handle_mapping(instance, *ret, object->obj.host.swapchain, &object->wrapper_entry); return VK_SUCCESS; }
@@ -1867,7 +1853,7 @@ void wine_vkDestroySwapchainKHR(VkDevice client_device, VkSwapchainKHR client_sw if (!swapchain) return;
device->p_vkDestroySwapchainKHR(device->host.device, swapchain->obj.host.swapchain, NULL); - remove_handle_mapping(instance, &swapchain->wrapper_entry); + vulkan_instance_remove_object(instance, &swapchain->obj.obj);
free(swapchain); } @@ -2049,9 +2035,9 @@ VkResult wine_vkAllocateMemory(VkDevice client_device, const VkMemoryAllocateInf vulkan_object_init(&memory->obj, host_device_memory); memory->size = info.allocationSize; memory->vm_map = mapping; + vulkan_instance_insert_object(instance, &memory->obj);
- *ret = (VkDeviceMemory)(uintptr_t)memory; - add_handle_mapping(instance, *ret, memory->host.device_memory, &memory->wrapper_entry); + *ret = memory->client.device_memory; return VK_SUCCESS; }
@@ -2078,7 +2064,7 @@ void wine_vkFreeMemory(VkDevice client_device, VkDeviceMemory memory_handle, con }
device->p_vkFreeMemory(device->host.device, memory->host.device_memory, NULL); - remove_handle_mapping(instance, &memory->wrapper_entry); + vulkan_instance_remove_object(instance, &memory->obj);
if (memory->vm_map) { @@ -2434,9 +2420,9 @@ VkResult wine_vkCreateDebugUtilsMessengerEXT(VkInstance client_instance, object->instance = instance; object->user_callback = (UINT_PTR)create_info->pfnUserCallback; object->user_data = (UINT_PTR)create_info->pUserData; + vulkan_instance_insert_object(instance, &object->obj);
*messenger = object->client.debug_messenger; - add_handle_mapping(instance, *messenger, object->host.debug_messenger, &object->wrapper_entry); return VK_SUCCESS; }
@@ -2452,7 +2438,7 @@ void wine_vkDestroyDebugUtilsMessengerEXT(VkInstance client_instance, VkDebugUti return;
instance->p_vkDestroyDebugUtilsMessengerEXT(instance->host.instance, object->host.debug_messenger, NULL); - remove_handle_mapping(instance, &object->wrapper_entry); + vulkan_instance_remove_object(instance, &object->obj);
free(object); } @@ -2490,9 +2476,9 @@ VkResult wine_vkCreateDebugReportCallbackEXT(VkInstance client_instance, object->instance = instance; object->user_callback = (UINT_PTR)create_info->pfnCallback; object->user_data = (UINT_PTR)create_info->pUserData; + vulkan_instance_insert_object(instance, &object->obj);
*callback = object->client.debug_callback; - add_handle_mapping(instance, *callback, object->host.debug_callback, &object->wrapper_entry); return VK_SUCCESS; }
@@ -2508,7 +2494,7 @@ void wine_vkDestroyDebugReportCallbackEXT(VkInstance client_instance, VkDebugRep return;
instance->p_vkDestroyDebugReportCallbackEXT(instance->host.instance, object->host.debug_callback, NULL); - remove_handle_mapping(instance, &object->wrapper_entry); + vulkan_instance_remove_object(instance, &object->obj);
free(object); } @@ -2538,9 +2524,9 @@ VkResult wine_vkCreateDeferredOperationKHR(VkDevice device_handle,
vulkan_object_init(&object->obj, host_deferred_operation); init_conversion_context(&object->ctx); + vulkan_instance_insert_object(instance, &object->obj);
*operation = object->client.deferred_operation; - add_handle_mapping(instance, *operation, object->host.deferred_operation, &object->wrapper_entry); return VK_SUCCESS; }
@@ -2558,7 +2544,7 @@ void wine_vkDestroyDeferredOperationKHR(VkDevice device_handle, return;
device->p_vkDestroyDeferredOperationKHR(device->host.device, object->host.deferred_operation, NULL); - remove_handle_mapping(instance, &object->wrapper_entry); + vulkan_instance_remove_object(instance, &object->obj);
free_conversion_context(&object->ctx); free(object); diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index bcf24bdd5ef..e6b983f5112 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -30,21 +30,10 @@
#include "wine/rbtree.h"
-/* Some extensions have callbacks for those we need to be able to - * get the wine wrapper for a host handle - */ -struct wrapper_entry -{ - struct rb_entry entry; - uint64_t host_handle; - uint64_t client_handle; -}; - struct wine_cmd_buffer { VULKAN_OBJECT_HEADER( VkCommandBuffer, command_buffer ); struct vulkan_device *device; - struct wrapper_entry wrapper_entry; };
static inline struct wine_cmd_buffer *wine_cmd_buffer_from_handle(VkCommandBuffer handle) @@ -60,15 +49,11 @@ struct wine_queue uint32_t family_index; uint32_t queue_index; VkDeviceQueueCreateFlags flags; - - struct wrapper_entry wrapper_entry; };
struct wine_device { struct vulkan_device obj; - struct wrapper_entry wrapper_entry; - uint64_t queue_count; struct wine_queue queues[]; }; @@ -84,8 +69,6 @@ struct wine_debug_report_callback
UINT64 user_callback; /* client pointer */ UINT64 user_data; /* client pointer */ - - struct wrapper_entry wrapper_entry; };
struct wine_phys_dev @@ -98,8 +81,6 @@ struct wine_phys_dev
uint32_t external_memory_align; uint32_t map_placed_align; - - struct wrapper_entry wrapper_entry; };
struct wine_debug_report_callback; @@ -109,9 +90,6 @@ struct wine_instance struct vulkan_instance obj;
VkBool32 enable_win32_surface; - VkBool32 enable_wrapper_list; - struct rb_tree wrappers; - pthread_rwlock_t wrapper_lock;
struct wine_debug_utils_messenger *utils_messengers; uint32_t utils_messenger_count; @@ -120,7 +98,8 @@ struct wine_instance
unsigned int quirks;
- struct wrapper_entry wrapper_entry; + struct rb_tree objects; + pthread_rwlock_t objects_lock;
/* We cache devices as we need to wrap them as they are dispatchable objects. */ uint32_t phys_dev_count; @@ -132,7 +111,6 @@ C_ASSERT(sizeof(struct wine_instance) == offsetof(struct wine_instance, phys_dev struct wine_cmd_pool { VULKAN_OBJECT_HEADER( VkCommandPool, command_pool ); - struct wrapper_entry wrapper_entry; };
static inline struct wine_cmd_pool *wine_cmd_pool_from_handle(VkCommandPool handle) @@ -146,8 +124,6 @@ struct wine_device_memory VULKAN_OBJECT_HEADER( VkDeviceMemory, device_memory ); VkDeviceSize size; void *vm_map; - - struct wrapper_entry wrapper_entry; };
static inline struct wine_device_memory *wine_device_memory_from_handle(VkDeviceMemory handle) @@ -162,8 +138,6 @@ struct wine_debug_utils_messenger
UINT64 user_callback; /* client pointer */ UINT64 user_data; /* client pointer */ - - struct wrapper_entry wrapper_entry; };
static inline struct wine_debug_utils_messenger *wine_debug_utils_messenger_from_handle( @@ -185,7 +159,6 @@ struct wine_surface HWND hwnd;
struct rb_entry window_entry; - struct wrapper_entry wrapper_entry; };
static inline struct wine_surface *wine_surface_from_handle(VkSurfaceKHR handle) @@ -199,8 +172,6 @@ struct wine_swapchain struct vulkan_swapchain obj; struct wine_surface *surface; VkExtent2D extents; - - struct wrapper_entry wrapper_entry; };
static inline struct wine_swapchain *wine_swapchain_from_handle(VkSwapchainKHR handle) @@ -264,7 +235,6 @@ struct wine_deferred_operation { VULKAN_OBJECT_HEADER( VkDeferredOperationKHR, deferred_operation ); struct conversion_context ctx; /* to keep params alive. */ - struct wrapper_entry wrapper_entry; };
static inline struct wine_deferred_operation *wine_deferred_operation_from_handle( diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h index 6af3cc0ac13..5a56bfe08f7 100644 --- a/include/wine/vulkan_driver.h +++ b/include/wine/vulkan_driver.h @@ -44,6 +44,7 @@ struct vulkan_client_object
#define WINE_VK_HOST #include "wine/vulkan.h" +#include "wine/rbtree.h"
/* Wine internal vulkan driver version, needs to be bumped upon vulkan_funcs changes. */ #define WINE_VULKAN_DRIVER_VERSION 35 @@ -52,6 +53,7 @@ struct vulkan_object { UINT64 host_handle; UINT64 client_handle; + struct rb_entry entry; };
#define VULKAN_OBJECT_HEADER( type, name ) \
From: Rémi Bernon rbernon@codeweavers.com
And call win32u redirected functions through vk_funcs. --- dlls/win32u/vulkan.c | 51 ++++++++++---------------------- dlls/winevulkan/make_vulkan | 8 +++-- dlls/winevulkan/vulkan.c | 6 ++-- dlls/winevulkan/vulkan_private.h | 2 ++ dlls/winevulkan/vulkan_thunks.c | 4 +-- 5 files changed, 27 insertions(+), 44 deletions(-)
diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index 451a27ac833..4b46a520c63 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -119,6 +119,11 @@ static void win32u_vkDestroySurfaceKHR( VkInstance instance, VkSurfaceKHR handle free( surface ); }
+static VkBool32 win32u_vkGetPhysicalDeviceWin32PresentationSupportKHR( VkPhysicalDevice physical_device, uint32_t queue ) +{ + return driver_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR( physical_device, queue ); +} + static VkResult win32u_vkQueuePresentKHR( VkQueue queue, const VkPresentInfoKHR *present_info, VkSurfaceKHR *surfaces ) { VkResult res; @@ -139,32 +144,9 @@ static VkResult win32u_vkQueuePresentKHR( VkQueue queue, const VkPresentInfoKHR return res; }
-static PFN_vkVoidFunction win32u_vkGetDeviceProcAddr( VkDevice device, const char *name ) -{ - TRACE( "device %p, name %s\n", device, debugstr_a(name) ); - - if (!strcmp( name, "vkGetDeviceProcAddr" )) return (PFN_vkVoidFunction)vulkan_funcs.p_vkGetDeviceProcAddr; - if (!strcmp( name, "vkQueuePresentKHR" )) return (PFN_vkVoidFunction)vulkan_funcs.p_vkQueuePresentKHR; - - return p_vkGetDeviceProcAddr( device, name ); -} - -static PFN_vkVoidFunction win32u_vkGetInstanceProcAddr( VkInstance instance, const char *name ) +static const char *win32u_get_host_surface_extension(void) { - TRACE( "instance %p, name %s\n", instance, debugstr_a(name) ); - - if (!instance) return p_vkGetInstanceProcAddr( instance, name ); - - if (!strcmp( name, "vkCreateWin32SurfaceKHR" )) return (PFN_vkVoidFunction)vulkan_funcs.p_vkCreateWin32SurfaceKHR; - if (!strcmp( name, "vkDestroySurfaceKHR" )) return (PFN_vkVoidFunction)vulkan_funcs.p_vkDestroySurfaceKHR; - if (!strcmp( name, "vkGetInstanceProcAddr" )) return (PFN_vkVoidFunction)vulkan_funcs.p_vkGetInstanceProcAddr; - if (!strcmp( name, "vkGetPhysicalDeviceWin32PresentationSupportKHR" )) return (PFN_vkVoidFunction)vulkan_funcs.p_vkGetPhysicalDeviceWin32PresentationSupportKHR; - - /* vkGetInstanceProcAddr also loads any children of instance, so device functions as well. */ - if (!strcmp( name, "vkGetDeviceProcAddr" )) return (PFN_vkVoidFunction)vulkan_funcs.p_vkGetDeviceProcAddr; - if (!strcmp( name, "vkQueuePresentKHR" )) return (PFN_vkVoidFunction)vulkan_funcs.p_vkQueuePresentKHR; - - return p_vkGetInstanceProcAddr( instance, name ); + return driver_funcs->p_get_host_surface_extension(); }
static VkSurfaceKHR win32u_wine_get_host_surface( VkSurfaceKHR handle ) @@ -184,8 +166,8 @@ static struct vulkan_funcs vulkan_funcs = .p_vkCreateWin32SurfaceKHR = win32u_vkCreateWin32SurfaceKHR, .p_vkDestroySurfaceKHR = win32u_vkDestroySurfaceKHR, .p_vkQueuePresentKHR = win32u_vkQueuePresentKHR, - .p_vkGetDeviceProcAddr = win32u_vkGetDeviceProcAddr, - .p_vkGetInstanceProcAddr = win32u_vkGetInstanceProcAddr, + .p_vkGetPhysicalDeviceWin32PresentationSupportKHR = win32u_vkGetPhysicalDeviceWin32PresentationSupportKHR, + .p_get_host_surface_extension = win32u_get_host_surface_extension, .p_wine_get_host_surface = win32u_wine_get_host_surface, .p_vulkan_surface_update = win32u_vulkan_surface_update, }; @@ -244,13 +226,8 @@ static void vulkan_driver_init(void) return; }
- if (status == STATUS_NOT_IMPLEMENTED) - driver_funcs = &nulldrv_funcs; - else - { - vulkan_funcs.p_vkGetPhysicalDeviceWin32PresentationSupportKHR = driver_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR; - vulkan_funcs.p_get_host_surface_extension = driver_funcs->p_get_host_surface_extension; - } + if (status == STATUS_NOT_IMPLEMENTED) driver_funcs = &nulldrv_funcs; + else vulkan_funcs.p_get_host_surface_extension = driver_funcs->p_get_host_surface_extension; }
static void vulkan_driver_load(void) @@ -308,6 +285,8 @@ static const struct vulkan_driver_funcs lazydrv_funcs = .p_vulkan_surface_detach = lazydrv_vulkan_surface_detach, .p_vulkan_surface_update = lazydrv_vulkan_surface_update, .p_vulkan_surface_presented = lazydrv_vulkan_surface_presented, + .p_vkGetPhysicalDeviceWin32PresentationSupportKHR = lazydrv_vkGetPhysicalDeviceWin32PresentationSupportKHR, + .p_get_host_surface_extension = lazydrv_get_host_surface_extension, };
static void vulkan_init_once(void) @@ -334,8 +313,8 @@ static void vulkan_init_once(void) #undef LOAD_FUNCPTR
driver_funcs = &lazydrv_funcs; - vulkan_funcs.p_vkGetPhysicalDeviceWin32PresentationSupportKHR = lazydrv_vkGetPhysicalDeviceWin32PresentationSupportKHR; - vulkan_funcs.p_get_host_surface_extension = lazydrv_get_host_surface_extension; + vulkan_funcs.p_vkGetInstanceProcAddr = p_vkGetInstanceProcAddr; + vulkan_funcs.p_vkGetDeviceProcAddr = p_vkGetDeviceProcAddr; }
void vulkan_detach_surfaces( struct list *surfaces ) diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 4ecc454b7ef..d6d54e76dd1 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -904,10 +904,12 @@ class VkFunction(object): else: params += ", {0}{1}".format(params_prefix, self.extra_param)
- if self.name not in MANUAL_UNIX_THUNKS: - func_prefix = "{0}->p_".format(self.params[0].dispatch_table(params_prefix, conv)) - else: + if self.name in MANUAL_UNIX_THUNKS: func_prefix = "wine_" + elif self.name in USER_DRIVER_FUNCS: + func_prefix = "vk_funcs->p_" + else: + func_prefix = "{0}->p_".format(self.params[0].dispatch_table(params_prefix, conv))
# Call the host Vulkan function. if self.type == "void": diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index c5ce0735901..628bc477ff8 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -128,7 +128,7 @@ static uint32_t wine_vk_count_struct_(void *s, VkStructureType t) return result; }
-static const struct vulkan_funcs *vk_funcs; +const struct vulkan_funcs *vk_funcs;
static int vulkan_object_compare(const void *key, const struct rb_entry *entry) { @@ -1702,7 +1702,7 @@ VkResult wine_vkCreateWin32SurfaceKHR(VkInstance client_instance, const VkWin32S create_info_host.hwnd = surface->hwnd = dummy; }
- res = instance->p_vkCreateWin32SurfaceKHR(instance->host.instance, &create_info_host, + res = vk_funcs->p_vkCreateWin32SurfaceKHR(instance->host.instance, &create_info_host, NULL /* allocator */, &surface->driver_surface); if (res != VK_SUCCESS) { @@ -1732,7 +1732,7 @@ void wine_vkDestroySurfaceKHR(VkInstance client_instance, VkSurfaceKHR client_su if (!surface) return;
- instance->p_vkDestroySurfaceKHR(instance->host.instance, surface->driver_surface, NULL); + vk_funcs->p_vkDestroySurfaceKHR(instance->host.instance, surface->driver_surface, NULL); vulkan_instance_remove_object(instance, &surface->obj.obj); window_surfaces_remove(surface);
diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index e6b983f5112..23a29bb460f 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -30,6 +30,8 @@
#include "wine/rbtree.h"
+extern const struct vulkan_funcs *vk_funcs; + struct wine_cmd_buffer { VULKAN_OBJECT_HEADER( VkCommandBuffer, command_buffer ); diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c index fd01558550f..d515ad7e0e0 100644 --- a/dlls/winevulkan/vulkan_thunks.c +++ b/dlls/winevulkan/vulkan_thunks.c @@ -51112,7 +51112,7 @@ static NTSTATUS thunk64_vkGetPhysicalDeviceWin32PresentationSupportKHR(void *arg
TRACE("%p, %u\n", params->physicalDevice, params->queueFamilyIndex);
- params->result = vulkan_physical_device_from_handle(params->physicalDevice)->instance->p_vkGetPhysicalDeviceWin32PresentationSupportKHR(vulkan_physical_device_from_handle(params->physicalDevice)->host.physical_device, params->queueFamilyIndex); + params->result = vk_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR(vulkan_physical_device_from_handle(params->physicalDevice)->host.physical_device, params->queueFamilyIndex); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -51128,7 +51128,7 @@ static NTSTATUS thunk32_vkGetPhysicalDeviceWin32PresentationSupportKHR(void *arg
TRACE("%#x, %u\n", params->physicalDevice, params->queueFamilyIndex);
- params->result = vulkan_physical_device_from_handle((VkPhysicalDevice)UlongToPtr(params->physicalDevice))->instance->p_vkGetPhysicalDeviceWin32PresentationSupportKHR(vulkan_physical_device_from_handle((VkPhysicalDevice)UlongToPtr(params->physicalDevice))->host.physical_device, params->queueFamilyIndex); + params->result = vk_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR(vulkan_physical_device_from_handle((VkPhysicalDevice)UlongToPtr(params->physicalDevice))->host.physical_device, params->queueFamilyIndex); return STATUS_SUCCESS; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/vulkan.c | 467 ++++++++++++++++++++++++++++--- dlls/winevulkan/make_vulkan | 43 +-- dlls/winevulkan/vulkan.c | 441 +---------------------------- dlls/winevulkan/vulkan_private.h | 28 -- dlls/winevulkan/vulkan_thunks.c | 52 ++-- dlls/winevulkan/vulkan_thunks.h | 12 - include/wine/vulkan_driver.h | 15 +- 7 files changed, 476 insertions(+), 582 deletions(-)
diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index 4b46a520c63..c3b322bd4bb 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -38,6 +38,7 @@ #include "wine/vulkan_driver.h"
WINE_DEFAULT_DEBUG_CHANNEL(vulkan); +WINE_DECLARE_DEBUG_CHANNEL(fps);
PFN_vkGetDeviceProcAddr p_vkGetDeviceProcAddr = NULL; PFN_vkGetInstanceProcAddr p_vkGetInstanceProcAddr = NULL; @@ -49,45 +50,114 @@ static struct vulkan_funcs vulkan_funcs;
static const struct vulkan_driver_funcs *driver_funcs;
-static void (*p_vkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *); -static VkResult (*p_vkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *); - struct surface { - struct list entry; - VkSurfaceKHR host_surface; + struct vulkan_surface obj; void *driver_private; HWND hwnd; + + struct list entry; + struct rb_entry window_entry; };
-static inline struct surface *surface_from_handle( VkSurfaceKHR handle ) +static struct surface *surface_from_handle( VkSurfaceKHR handle ) { - return (struct surface *)(uintptr_t)handle; + struct vulkan_surface *obj = vulkan_surface_from_handle( handle ); + return CONTAINING_RECORD( obj, struct surface, obj ); }
static inline VkSurfaceKHR surface_to_handle( struct surface *surface ) { - return (VkSurfaceKHR)(uintptr_t)surface; + return (VkSurfaceKHR)(uintptr_t)&surface->obj; +} + +struct swapchain +{ + struct vulkan_swapchain obj; + struct surface *surface; + VkExtent2D extents; +}; + +static struct swapchain *swapchain_from_handle( VkSwapchainKHR handle ) +{ + struct vulkan_swapchain *obj = vulkan_swapchain_from_handle( handle ); + return CONTAINING_RECORD( obj, struct swapchain, obj ); +} + +static int window_surface_compare( const void *key, const struct rb_entry *entry ) +{ + const struct surface *surface = RB_ENTRY_VALUE( entry, struct surface, window_entry ); + HWND key_hwnd = (HWND)key; + + if (key_hwnd < surface->hwnd) return -1; + if (key_hwnd > surface->hwnd) return 1; + return 0; +} + +static pthread_mutex_t window_surfaces_lock = PTHREAD_MUTEX_INITIALIZER; +static struct rb_tree window_surfaces = {.compare = window_surface_compare}; + +static void window_surfaces_insert( struct surface *surface ) +{ + struct surface *previous; + struct rb_entry *ptr; + + pthread_mutex_lock( &window_surfaces_lock ); + + if (!(ptr = rb_get( &window_surfaces, surface->hwnd ))) + rb_put( &window_surfaces, surface->hwnd, &surface->window_entry ); + else + { + previous = RB_ENTRY_VALUE( ptr, struct surface, window_entry ); + rb_replace( &window_surfaces, &previous->window_entry, &surface->window_entry ); + previous->hwnd = 0; /* make sure previous surface becomes invalid */ + } + + pthread_mutex_unlock( &window_surfaces_lock ); +} + +static void window_surfaces_remove( struct surface *surface ) +{ + pthread_mutex_lock( &window_surfaces_lock ); + if (surface->hwnd) rb_remove( &window_surfaces, &surface->window_entry ); + pthread_mutex_unlock( &window_surfaces_lock ); }
-static VkResult win32u_vkCreateWin32SurfaceKHR( VkInstance instance, const VkWin32SurfaceCreateInfoKHR *info, - const VkAllocationCallbacks *allocator, VkSurfaceKHR *handle ) +static VkResult win32u_vkCreateWin32SurfaceKHR( VkInstance client_instance, const VkWin32SurfaceCreateInfoKHR *create_info, + const VkAllocationCallbacks *allocator, VkSurfaceKHR *ret ) { + struct vulkan_instance *instance = vulkan_instance_from_handle( client_instance ); + VkSurfaceKHR host_surface; struct surface *surface; + HWND dummy = NULL; VkResult res; WND *win;
- TRACE( "instance %p, info %p, allocator %p, handle %p\n", instance, info, allocator, handle ); + TRACE( "client_instance %p, create_info %p, allocator %p, ret %p\n", client_instance, create_info, allocator, ret ); if (allocator) FIXME( "Support for allocation callbacks not implemented yet\n" );
if (!(surface = calloc( 1, sizeof(*surface) ))) return VK_ERROR_OUT_OF_HOST_MEMORY; - if ((res = driver_funcs->p_vulkan_surface_create( info->hwnd, instance, &surface->host_surface, &surface->driver_private ))) + + /* Windows allows surfaces to be created with no HWND, they return VK_ERROR_SURFACE_LOST_KHR later */ + if (!(surface->hwnd = create_info->hwnd)) + { + static const WCHAR staticW[] = {'s','t','a','t','i','c',0}; + UNICODE_STRING static_us = RTL_CONSTANT_STRING( staticW ); + dummy = NtUserCreateWindowEx( 0, &static_us, &static_us, &static_us, WS_POPUP, 0, 0, 0, 0, + NULL, NULL, NULL, NULL, 0, NULL, 0, FALSE ); + WARN( "Created dummy window %p for null surface window\n", dummy ); + surface->hwnd = dummy; + } + + if ((res = driver_funcs->p_vulkan_surface_create( surface->hwnd, instance->host.instance, + &host_surface, &surface->driver_private ))) { + if (dummy) NtUserDestroyWindow( dummy ); free( surface ); return res; }
- if (!(win = get_win_ptr( info->hwnd )) || win == WND_DESKTOP || win == WND_OTHER_PROCESS) + if (!(win = get_win_ptr( surface->hwnd )) || win == WND_DESKTOP || win == WND_OTHER_PROCESS) list_init( &surface->entry ); else { @@ -95,17 +165,28 @@ static VkResult win32u_vkCreateWin32SurfaceKHR( VkInstance instance, const VkWin release_win_ptr( win ); }
- surface->hwnd = info->hwnd; - *handle = surface_to_handle( surface ); + surface->hwnd = create_info->hwnd; + vulkan_object_init( &surface->obj.obj, host_surface ); + surface->obj.instance = instance; + instance->p_insert_object( instance, &surface->obj.obj ); + + if (dummy) NtUserDestroyWindow( dummy ); + window_surfaces_insert( surface ); + + *ret = surface->obj.client.surface; return VK_SUCCESS; }
-static void win32u_vkDestroySurfaceKHR( VkInstance instance, VkSurfaceKHR handle, const VkAllocationCallbacks *allocator ) +static void win32u_vkDestroySurfaceKHR( VkInstance client_instance, VkSurfaceKHR client_surface, + const VkAllocationCallbacks *allocator ) { - struct surface *surface = surface_from_handle( handle ); + struct vulkan_instance *instance = vulkan_instance_from_handle( client_instance ); + struct surface *surface = surface_from_handle( client_surface ); WND *win;
- TRACE( "instance %p, handle 0x%s, allocator %p\n", instance, wine_dbgstr_longlong(handle), allocator ); + if (!surface) return; + + TRACE( "instance %p, handle 0x%s, allocator %p\n", instance, wine_dbgstr_longlong( client_surface ), allocator ); if (allocator) FIXME( "Support for allocation callbacks not implemented yet\n" );
if ((win = get_win_ptr( surface->hwnd )) && win != WND_DESKTOP && win != WND_OTHER_PROCESS) @@ -114,31 +195,342 @@ static void win32u_vkDestroySurfaceKHR( VkInstance instance, VkSurfaceKHR handle release_win_ptr( win ); }
- p_vkDestroySurfaceKHR( instance, surface->host_surface, NULL /* allocator */ ); + instance->p_vkDestroySurfaceKHR( instance->host.instance, surface->obj.host.surface, NULL /* allocator */ ); driver_funcs->p_vulkan_surface_destroy( surface->hwnd, surface->driver_private ); + + instance->p_remove_object( instance, &surface->obj.obj ); + window_surfaces_remove( surface ); + free( surface ); }
-static VkBool32 win32u_vkGetPhysicalDeviceWin32PresentationSupportKHR( VkPhysicalDevice physical_device, uint32_t queue ) +static void adjust_surface_capabilities( struct vulkan_instance *instance, struct surface *surface, + VkSurfaceCapabilitiesKHR *capabilities ) +{ + RECT client_rect; + + /* Many Windows games, for example Strange Brigade, No Man's Sky, Path of Exile + * and World War Z, do not expect that maxImageCount can be set to 0. + * A value of 0 means that there is no limit on the number of images. + * Nvidia reports 8 on Windows, AMD 16. + * https://vulkan.gpuinfo.org/displayreport.php?id=9122#surface + * https://vulkan.gpuinfo.org/displayreport.php?id=9121#surface + */ + if (!capabilities->maxImageCount) capabilities->maxImageCount = max( capabilities->minImageCount, 16 ); + + /* Update the image extents to match what the Win32 WSI would provide. */ + /* FIXME: handle DPI scaling, somehow */ + NtUserGetClientRect( surface->hwnd, &client_rect, NtUserGetDpiForWindow( surface->hwnd ) ); + capabilities->minImageExtent.width = client_rect.right - client_rect.left; + capabilities->minImageExtent.height = client_rect.bottom - client_rect.top; + capabilities->maxImageExtent.width = client_rect.right - client_rect.left; + capabilities->maxImageExtent.height = client_rect.bottom - client_rect.top; + capabilities->currentExtent.width = client_rect.right - client_rect.left; + capabilities->currentExtent.height = client_rect.bottom - client_rect.top; +} + +static VkResult win32u_vkGetPhysicalDeviceSurfaceCapabilitiesKHR( VkPhysicalDevice client_physical_device, VkSurfaceKHR client_surface, + VkSurfaceCapabilitiesKHR *capabilities ) +{ + struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle( client_physical_device ); + struct surface *surface = surface_from_handle( client_surface ); + struct vulkan_instance *instance = physical_device->instance; + VkResult res; + + if (!NtUserIsWindow( surface->hwnd )) return VK_ERROR_SURFACE_LOST_KHR; + res = instance->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR( physical_device->host.physical_device, + surface->obj.host.surface, capabilities ); + if (!res) adjust_surface_capabilities( instance, surface, capabilities ); + return res; +} + +static VkResult win32u_vkGetPhysicalDeviceSurfaceCapabilities2KHR( VkPhysicalDevice client_physical_device, const VkPhysicalDeviceSurfaceInfo2KHR *surface_info, + VkSurfaceCapabilities2KHR *capabilities ) +{ + struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle( client_physical_device ); + struct surface *surface = surface_from_handle( surface_info->surface ); + VkPhysicalDeviceSurfaceInfo2KHR surface_info_host = *surface_info; + struct vulkan_instance *instance = physical_device->instance; + VkResult res; + + if (!instance->p_vkGetPhysicalDeviceSurfaceCapabilities2KHR) + { + /* Until the loader version exporting this function is common, emulate it using the older non-2 version. */ + if (surface_info->pNext || capabilities->pNext) FIXME( "Emulating vkGetPhysicalDeviceSurfaceCapabilities2KHR, ignoring pNext.\n" ); + return win32u_vkGetPhysicalDeviceSurfaceCapabilitiesKHR( client_physical_device, surface_info->surface, + &capabilities->surfaceCapabilities ); + } + + surface_info_host.surface = surface->obj.host.surface; + + if (!NtUserIsWindow( surface->hwnd )) return VK_ERROR_SURFACE_LOST_KHR; + res = instance->p_vkGetPhysicalDeviceSurfaceCapabilities2KHR( physical_device->host.physical_device, + &surface_info_host, capabilities ); + if (!res) adjust_surface_capabilities( instance, surface, &capabilities->surfaceCapabilities ); + return res; +} + +static VkResult win32u_vkGetPhysicalDevicePresentRectanglesKHR( VkPhysicalDevice client_physical_device, VkSurfaceKHR client_surface, + uint32_t *rect_count, VkRect2D *rects ) +{ + struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle( client_physical_device ); + struct surface *surface = surface_from_handle( client_surface ); + struct vulkan_instance *instance = physical_device->instance; + + if (!NtUserIsWindow( surface->hwnd )) + { + if (rects && !*rect_count) return VK_INCOMPLETE; + if (rects) memset( rects, 0, sizeof(VkRect2D) ); + *rect_count = 1; + return VK_SUCCESS; + } + + return instance->p_vkGetPhysicalDevicePresentRectanglesKHR( physical_device->host.physical_device, + surface->obj.host.surface, rect_count, rects ); +} + +static VkResult win32u_vkGetPhysicalDeviceSurfaceFormatsKHR( VkPhysicalDevice client_physical_device, VkSurfaceKHR client_surface, + uint32_t *format_count, VkSurfaceFormatKHR *formats ) +{ + struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle( client_physical_device ); + struct surface *surface = surface_from_handle( client_surface ); + struct vulkan_instance *instance = physical_device->instance; + + return instance->p_vkGetPhysicalDeviceSurfaceFormatsKHR( physical_device->host.physical_device, + surface->obj.host.surface, format_count, formats ); +} + +static VkResult win32u_vkGetPhysicalDeviceSurfaceFormats2KHR( VkPhysicalDevice client_physical_device, const VkPhysicalDeviceSurfaceInfo2KHR *surface_info, + uint32_t *format_count, VkSurfaceFormat2KHR *formats ) +{ + struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle( client_physical_device ); + struct surface *surface = surface_from_handle( surface_info->surface ); + VkPhysicalDeviceSurfaceInfo2KHR surface_info_host = *surface_info; + struct vulkan_instance *instance = physical_device->instance; + VkResult res; + + if (!instance->p_vkGetPhysicalDeviceSurfaceFormats2KHR) + { + VkSurfaceFormatKHR *surface_formats; + UINT i; + + /* Until the loader version exporting this function is common, emulate it using the older non-2 version. */ + if (surface_info->pNext) FIXME( "Emulating vkGetPhysicalDeviceSurfaceFormats2KHR, ignoring pNext.\n" ); + if (!formats) return win32u_vkGetPhysicalDeviceSurfaceFormatsKHR( client_physical_device, surface_info->surface, format_count, NULL ); + + surface_formats = calloc( *format_count, sizeof(*surface_formats) ); + if (!surface_formats) return VK_ERROR_OUT_OF_HOST_MEMORY; + + res = win32u_vkGetPhysicalDeviceSurfaceFormatsKHR( client_physical_device, surface_info->surface, format_count, surface_formats ); + if (!res || res == VK_INCOMPLETE) for (i = 0; i < *format_count; i++) formats[i].surfaceFormat = surface_formats[i]; + + free( surface_formats ); + return res; + } + + surface_info_host.surface = surface->obj.host.surface; + + return instance->p_vkGetPhysicalDeviceSurfaceFormats2KHR( physical_device->host.physical_device, + &surface_info_host, format_count, formats ); +} + +static VkBool32 win32u_vkGetPhysicalDeviceWin32PresentationSupportKHR( VkPhysicalDevice client_physical_device, uint32_t queue ) +{ + struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle( client_physical_device ); + return driver_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR( physical_device->host.physical_device, queue ); +} + +static VkResult win32u_vkCreateSwapchainKHR( VkDevice client_device, const VkSwapchainCreateInfoKHR *create_info, + const VkAllocationCallbacks *allocator, VkSwapchainKHR *ret ) +{ + struct swapchain *swapchain, *old_swapchain = swapchain_from_handle( create_info->oldSwapchain ); + struct surface *surface = surface_from_handle( create_info->surface ); + struct vulkan_device *device = vulkan_device_from_handle( client_device ); + struct vulkan_physical_device *physical_device = device->physical_device; + struct vulkan_instance *instance = physical_device->instance; + VkSwapchainCreateInfoKHR create_info_host = *create_info; + VkSurfaceCapabilitiesKHR capabilities; + VkSwapchainKHR host_swapchain; + VkResult res; + + if (!NtUserIsWindow( surface->hwnd )) + { + ERR( "surface %p, hwnd %p is invalid!\n", surface, surface->hwnd ); + return VK_ERROR_INITIALIZATION_FAILED; + } + + if (surface) create_info_host.surface = surface->obj.host.surface; + if (old_swapchain) create_info_host.oldSwapchain = old_swapchain->obj.host.swapchain; + + /* update the host surface to commit any pending size change */ + driver_funcs->p_vulkan_surface_update( surface->hwnd, surface->driver_private ); + + /* Windows allows client rect to be empty, but host Vulkan often doesn't, adjust extents back to the host capabilities */ + res = instance->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR( physical_device->host.physical_device, surface->obj.host.surface, &capabilities ); + if (res) return res; + + create_info_host.imageExtent.width = max( create_info_host.imageExtent.width, capabilities.minImageExtent.width ); + create_info_host.imageExtent.height = max( create_info_host.imageExtent.height, capabilities.minImageExtent.height ); + + if (!(swapchain = calloc( 1, sizeof(*swapchain) ))) return VK_ERROR_OUT_OF_HOST_MEMORY; + + if ((res = device->p_vkCreateSwapchainKHR( device->host.device, &create_info_host, NULL, &host_swapchain ))) + { + free( swapchain ); + return res; + } + + vulkan_object_init( &swapchain->obj.obj, host_swapchain ); + swapchain->surface = surface; + swapchain->extents = create_info->imageExtent; + instance->p_insert_object( instance, &swapchain->obj.obj ); + + *ret = swapchain->obj.client.swapchain; + return VK_SUCCESS; +} + +void win32u_vkDestroySwapchainKHR( VkDevice client_device, VkSwapchainKHR client_swapchain, + const VkAllocationCallbacks *allocator ) +{ + struct vulkan_device *device = vulkan_device_from_handle( client_device ); + struct vulkan_instance *instance = device->physical_device->instance; + struct swapchain *swapchain = swapchain_from_handle( client_swapchain ); + + if (allocator) FIXME( "Support for allocation callbacks not implemented yet\n" ); + if (!swapchain) return; + + device->p_vkDestroySwapchainKHR( device->host.device, swapchain->obj.host.swapchain, NULL ); + instance->p_remove_object( instance, &swapchain->obj.obj ); + + free( swapchain ); +} + +static BOOL extents_equals( const VkExtent2D *extents, const RECT *rect ) +{ + return extents->width == rect->right - rect->left && extents->height == rect->bottom - rect->top; +} + +static VkResult win32u_vkAcquireNextImage2KHR( VkDevice client_device, const VkAcquireNextImageInfoKHR *acquire_info, + uint32_t *image_index ) { - return driver_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR( physical_device, queue ); + struct swapchain *swapchain = swapchain_from_handle( acquire_info->swapchain ); + struct vulkan_device *device = vulkan_device_from_handle( client_device ); + VkAcquireNextImageInfoKHR acquire_info_host = *acquire_info; + struct surface *surface = swapchain->surface; + RECT client_rect; + VkResult res; + + acquire_info_host.swapchain = swapchain->obj.host.swapchain; + + res = device->p_vkAcquireNextImage2KHR( device->host.device, &acquire_info_host, image_index ); + + if (!res && NtUserGetClientRect( surface->hwnd, &client_rect, NtUserGetDpiForWindow( surface->hwnd ) ) && + !extents_equals( &swapchain->extents, &client_rect )) + { + WARN( "Swapchain size %dx%d does not match client rect %s, returning VK_SUBOPTIMAL_KHR\n", + swapchain->extents.width, swapchain->extents.height, wine_dbgstr_rect( &client_rect ) ); + return VK_SUBOPTIMAL_KHR; + } + + return res; }
-static VkResult win32u_vkQueuePresentKHR( VkQueue queue, const VkPresentInfoKHR *present_info, VkSurfaceKHR *surfaces ) +static VkResult win32u_vkAcquireNextImageKHR( VkDevice client_device, VkSwapchainKHR client_swapchain, uint64_t timeout, + VkSemaphore semaphore, VkFence fence, uint32_t *image_index ) { + struct swapchain *swapchain = swapchain_from_handle( client_swapchain ); + struct vulkan_device *device = vulkan_device_from_handle( client_device ); + struct surface *surface = swapchain->surface; + RECT client_rect; + VkResult res; + + res = device->p_vkAcquireNextImageKHR( device->host.device, swapchain->obj.host.swapchain, timeout, + semaphore, fence, image_index ); + + if (!res && NtUserGetClientRect( surface->hwnd, &client_rect, NtUserGetDpiForWindow( surface->hwnd ) ) && + !extents_equals( &swapchain->extents, &client_rect )) + { + WARN( "Swapchain size %dx%d does not match client rect %s, returning VK_SUBOPTIMAL_KHR\n", + swapchain->extents.width, swapchain->extents.height, wine_dbgstr_rect( &client_rect ) ); + return VK_SUBOPTIMAL_KHR; + } + + return res; +} + +static VkResult win32u_vkQueuePresentKHR( VkQueue client_queue, const VkPresentInfoKHR *present_info ) +{ + struct vulkan_queue *queue = vulkan_queue_from_handle( client_queue ); + VkSwapchainKHR swapchains_buffer[16], *swapchains = swapchains_buffer; + VkPresentInfoKHR present_info_host = *present_info; + struct vulkan_device *device = queue->device; VkResult res; UINT i;
TRACE( "queue %p, present_info %p\n", queue, present_info );
- res = p_vkQueuePresentKHR( queue, present_info ); + if (present_info->swapchainCount > ARRAY_SIZE(swapchains_buffer) && + !(swapchains = malloc( present_info->swapchainCount * sizeof(*swapchains) ))) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + for (i = 0; i < present_info->swapchainCount; i++) + { + struct swapchain *swapchain = swapchain_from_handle( present_info->pSwapchains[i] ); + swapchains[i] = swapchain->obj.host.swapchain; + } + + present_info_host.pSwapchains = swapchains; + + res = device->p_vkQueuePresentKHR( queue->host.queue, &present_info_host );
for (i = 0; i < present_info->swapchainCount; i++) { + struct swapchain *swapchain = swapchain_from_handle( present_info->pSwapchains[i] ); VkResult swapchain_res = present_info->pResults ? present_info->pResults[i] : res; - struct surface *surface = surface_from_handle( surfaces[i] ); + struct surface *surface = swapchain->surface; + RECT client_rect;
driver_funcs->p_vulkan_surface_presented( surface->hwnd, surface->driver_private, swapchain_res ); + + if (swapchain_res < VK_SUCCESS) continue; + if (!NtUserGetClientRect( surface->hwnd, &client_rect, NtUserGetDpiForWindow( surface->hwnd ) )) + { + WARN( "Swapchain window %p is invalid, returning VK_ERROR_OUT_OF_DATE_KHR\n", surface->hwnd ); + if (present_info->pResults) present_info->pResults[i] = VK_ERROR_OUT_OF_DATE_KHR; + if (res >= VK_SUCCESS) res = VK_ERROR_OUT_OF_DATE_KHR; + } + else if (swapchain_res) + WARN( "Present returned status %d for swapchain %p\n", swapchain_res, swapchain ); + else if (!extents_equals( &swapchain->extents, &client_rect )) + { + WARN( "Swapchain size %dx%d does not match client rect %s, returning VK_SUBOPTIMAL_KHR\n", + swapchain->extents.width, swapchain->extents.height, wine_dbgstr_rect( &client_rect ) ); + if (present_info->pResults) present_info->pResults[i] = VK_SUBOPTIMAL_KHR; + if (!res) res = VK_SUBOPTIMAL_KHR; + } + } + + if (swapchains != swapchains_buffer) free( swapchains ); + + if (TRACE_ON( fps )) + { + static unsigned long frames, frames_total; + static long prev_time, start_time; + DWORD time; + + time = NtGetTickCount(); + frames++; + frames_total++; + + if (time - prev_time > 1500) + { + TRACE_(fps)( "%p @ approx %.2ffps, total %.2ffps\n", queue, 1000.0 * frames / (time - prev_time), + 1000.0 * frames_total / (time - start_time) ); + prev_time = time; + frames = 0; + + if (!start_time) start_time = time; + } }
return res; @@ -149,27 +541,22 @@ static const char *win32u_get_host_surface_extension(void) return driver_funcs->p_get_host_surface_extension(); }
-static VkSurfaceKHR win32u_wine_get_host_surface( VkSurfaceKHR handle ) -{ - struct surface *surface = surface_from_handle( handle ); - return surface->host_surface; -} - -static void win32u_vulkan_surface_update( VkSurfaceKHR handle ) -{ - struct surface *surface = surface_from_handle( handle ); - driver_funcs->p_vulkan_surface_update( surface->hwnd, surface->driver_private ); -} - static struct vulkan_funcs vulkan_funcs = { .p_vkCreateWin32SurfaceKHR = win32u_vkCreateWin32SurfaceKHR, .p_vkDestroySurfaceKHR = win32u_vkDestroySurfaceKHR, - .p_vkQueuePresentKHR = win32u_vkQueuePresentKHR, + .p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = win32u_vkGetPhysicalDeviceSurfaceCapabilitiesKHR, + .p_vkGetPhysicalDeviceSurfaceCapabilities2KHR = win32u_vkGetPhysicalDeviceSurfaceCapabilities2KHR, + .p_vkGetPhysicalDevicePresentRectanglesKHR = win32u_vkGetPhysicalDevicePresentRectanglesKHR, + .p_vkGetPhysicalDeviceSurfaceFormatsKHR = win32u_vkGetPhysicalDeviceSurfaceFormatsKHR, + .p_vkGetPhysicalDeviceSurfaceFormats2KHR = win32u_vkGetPhysicalDeviceSurfaceFormats2KHR, .p_vkGetPhysicalDeviceWin32PresentationSupportKHR = win32u_vkGetPhysicalDeviceWin32PresentationSupportKHR, + .p_vkCreateSwapchainKHR = win32u_vkCreateSwapchainKHR, + .p_vkDestroySwapchainKHR = win32u_vkDestroySwapchainKHR, + .p_vkAcquireNextImage2KHR = win32u_vkAcquireNextImage2KHR, + .p_vkAcquireNextImageKHR = win32u_vkAcquireNextImageKHR, + .p_vkQueuePresentKHR = win32u_vkQueuePresentKHR, .p_get_host_surface_extension = win32u_get_host_surface_extension, - .p_wine_get_host_surface = win32u_wine_get_host_surface, - .p_vulkan_surface_update = win32u_vulkan_surface_update, };
static VkResult nulldrv_vulkan_surface_create( HWND hwnd, VkInstance instance, VkSurfaceKHR *surface, void **private ) @@ -306,8 +693,6 @@ static void vulkan_init_once(void) return; \ }
- LOAD_FUNCPTR( vkDestroySurfaceKHR ); - LOAD_FUNCPTR( vkQueuePresentKHR ); LOAD_FUNCPTR( vkGetDeviceProcAddr ); LOAD_FUNCPTR( vkGetInstanceProcAddr ); #undef LOAD_FUNCPTR diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index d6d54e76dd1..95f7b31586c 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -194,18 +194,25 @@ FUNCTION_OVERRIDES = {
# functions for which a user driver entry must be generated USER_DRIVER_FUNCS = { + "vkAcquireNextImage2KHR", + "vkAcquireNextImageKHR", + "vkCreateSwapchainKHR", "vkCreateWin32SurfaceKHR", "vkDestroySurfaceKHR", + "vkDestroySwapchainKHR", "vkGetDeviceProcAddr", "vkGetInstanceProcAddr", + "vkGetPhysicalDevicePresentRectanglesKHR", + "vkGetPhysicalDeviceSurfaceCapabilities2KHR", + "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", + "vkGetPhysicalDeviceSurfaceFormats2KHR", + "vkGetPhysicalDeviceSurfaceFormatsKHR", "vkGetPhysicalDeviceWin32PresentationSupportKHR", "vkQueuePresentKHR", }
# functions for which the unix thunk is manually implemented MANUAL_UNIX_THUNKS = { - "vkAcquireNextImage2KHR", - "vkAcquireNextImageKHR", "vkAllocateCommandBuffers", "vkAllocateMemory", "vkCreateBuffer", @@ -216,16 +223,12 @@ MANUAL_UNIX_THUNKS = { "vkCreateDevice", "vkCreateImage", "vkCreateInstance", - "vkCreateSwapchainKHR", - "vkCreateWin32SurfaceKHR", "vkDestroyCommandPool", "vkDestroyDebugReportCallbackEXT", "vkDestroyDebugUtilsMessengerEXT", "vkDestroyDeferredOperationKHR", "vkDestroyDevice", "vkDestroyInstance", - "vkDestroySurfaceKHR", - "vkDestroySwapchainKHR", "vkEnumerateDeviceExtensionProperties", "vkEnumerateDeviceLayerProperties", "vkEnumerateInstanceExtensionProperties", @@ -252,14 +255,8 @@ MANUAL_UNIX_THUNKS = { "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR", "vkGetPhysicalDeviceImageFormatProperties2", "vkGetPhysicalDeviceImageFormatProperties2KHR", - "vkGetPhysicalDevicePresentRectanglesKHR", - "vkGetPhysicalDeviceSurfaceCapabilities2KHR", - "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", - "vkGetPhysicalDeviceSurfaceFormats2KHR", - "vkGetPhysicalDeviceSurfaceFormatsKHR", "vkMapMemory", "vkMapMemory2KHR", - "vkQueuePresentKHR", "vkUnmapMemory", "vkUnmapMemory2KHR", } @@ -335,16 +332,12 @@ def convert_suffix(direction, win_type, unwrap, is_wrapped): return "host_to_{0}".format(win_type) if unwrap == Unwrap.NONE: return "unwrapped_host_to_{0}".format(win_type) - if unwrap == Unwrap.DRIVER: - return "driver_to_{0}".format(win_type) return "host_to_{0}".format(win_type) else: if not is_wrapped: return "{0}_to_host".format(win_type) if unwrap == Unwrap.NONE: return "{0}_to_unwrapped_host".format(win_type) - if unwrap == Unwrap.DRIVER: - return "{0}_to_driver".format(win_type) return "{0}_to_host".format(win_type)
@@ -645,10 +638,8 @@ class VkFunction(object): # and is used by the code generation. self.required = True if func_info else False
- if self.name in MANUAL_UNIX_THUNKS: + if self.name in MANUAL_UNIX_THUNKS | USER_DRIVER_FUNCS: self.unwrap = Unwrap.NONE - elif self.name in USER_DRIVER_FUNCS: - self.unwrap = Unwrap.DRIVER else: self.unwrap = Unwrap.HOST
@@ -1210,17 +1201,7 @@ class VkHandle(object): LOGGER.error("Unhandled host handle for: {0}".format(self.name)) return None
- def driver_handle(self, name): - """ Provide access to the handle that should be passed to the wine driver """ - - if self.name == "VkSurfaceKHR": - return "wine_surface_from_handle({0})->driver_surface".format(name) - - return self.host_handle(name) - def unwrap_handle(self, name, unwrap): - if unwrap == Unwrap.DRIVER: - return self.driver_handle(name) if unwrap == Unwrap.HOST: return self.host_handle(name) assert unwrap != Unwrap.NONE @@ -1590,8 +1571,6 @@ class VkMember(VkVariable): elif self.is_generic_handle(): if direction == Direction.OUTPUT: LOGGER.error("OUTPUT parameter {0}.{1} cannot be unwrapped".format(self.type, self.name)) - if unwrap == Unwrap.DRIVER and self.is_wrapped(Unwrap.DRIVER): - LOGGER.error("DRIVER unwrapping of {0}.{1} not implemented".format(self.type, self.name)) return "{0}{1} = wine_vk_unwrap_handle({2}{3}, {2}{1});\n".format(output, self.name, input, self.object_type) else: selector_part = ", {0}{1}".format(input, self.selector) if self.selector else "" @@ -1994,8 +1973,6 @@ class VkParam(VkVariable): if unwrap != Unwrap.NONE: unwrap_handle = None if self.object_type != None and self.type == "uint64_t": - if unwrap == Unwrap.DRIVER and self.is_wrapped(Unwrap.DRIVER): - LOGGER.error("DRIVER unwrapping of {0}.{1} not implemented".format(self.type, self.name)) unwrap_handle = "wine_vk_unwrap_handle({0}{1}, {0}{2})".format( params_prefix, self.object_type, self.name)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 628bc477ff8..f6de197f720 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -31,7 +31,6 @@ #include "ntuser.h"
WINE_DEFAULT_DEBUG_CHANNEL(vulkan); -WINE_DECLARE_DEBUG_CHANNEL(fps);
static PFN_vkCreateInstance p_vkCreateInstance; static PFN_vkEnumerateInstanceVersion p_vkEnumerateInstanceVersion; @@ -62,45 +61,6 @@ static void vulkan_object_init_ptr( struct vulkan_object *obj, UINT64 host_handl client->unix_handle = (UINT_PTR)obj; }
-static int window_surface_compare(const void *key, const struct rb_entry *entry) -{ - const struct wine_surface *surface = RB_ENTRY_VALUE(entry, struct wine_surface, window_entry); - HWND key_hwnd = (HWND)key; - - if (key_hwnd < surface->hwnd) return -1; - if (key_hwnd > surface->hwnd) return 1; - return 0; -} - -static pthread_mutex_t window_surfaces_lock = PTHREAD_MUTEX_INITIALIZER; -static struct rb_tree window_surfaces = {.compare = window_surface_compare}; - -static void window_surfaces_insert(struct wine_surface *surface) -{ - struct wine_surface *previous; - struct rb_entry *ptr; - - pthread_mutex_lock(&window_surfaces_lock); - - if (!(ptr = rb_get(&window_surfaces, surface->hwnd))) - rb_put(&window_surfaces, surface->hwnd, &surface->window_entry); - else - { - previous = RB_ENTRY_VALUE(ptr, struct wine_surface, window_entry); - rb_replace(&window_surfaces, &previous->window_entry, &surface->window_entry); - previous->hwnd = 0; /* make sure previous surface becomes invalid */ - } - - pthread_mutex_unlock(&window_surfaces_lock); -} - -static void window_surfaces_remove(struct wine_surface *surface) -{ - pthread_mutex_lock(&window_surfaces_lock); - if (surface->hwnd) rb_remove(&window_surfaces, &surface->window_entry); - pthread_mutex_unlock(&window_surfaces_lock); -} - static BOOL is_wow64(void) { return sizeof(void *) == sizeof(UINT64) && NtCurrentTeb()->WowTebOffset; @@ -1005,6 +965,8 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, }
vulkan_object_init_ptr(&instance->obj.obj, (UINT_PTR)host_instance, &client_instance->obj); + instance->obj.p_insert_object = vulkan_instance_insert_object; + instance->obj.p_remove_object = vulkan_instance_remove_object;
/* Load all instance functions we are aware of. Note the loader takes care * of any filtering for extensions which were not requested, but which the @@ -1677,269 +1639,6 @@ void wine_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(VkPhysicalDevice cli properties->externalSemaphoreFeatures = 0; }
-VkResult wine_vkCreateWin32SurfaceKHR(VkInstance client_instance, const VkWin32SurfaceCreateInfoKHR *create_info, - const VkAllocationCallbacks *allocator, VkSurfaceKHR *ret) -{ - struct vulkan_instance *instance = vulkan_instance_from_handle(client_instance); - VkWin32SurfaceCreateInfoKHR create_info_host = *create_info; - struct wine_surface *surface; - VkSurfaceKHR host_surface; - HWND dummy = NULL; - VkResult res; - - if (allocator) FIXME("Support for allocation callbacks not implemented yet\n"); - - if (!(surface = calloc(1, sizeof(*surface)))) return VK_ERROR_OUT_OF_HOST_MEMORY; - - /* Windows allows surfaces to be created with no HWND, they return VK_ERROR_SURFACE_LOST_KHR later */ - if (!(surface->hwnd = create_info->hwnd)) - { - static const WCHAR staticW[] = {'s','t','a','t','i','c',0}; - UNICODE_STRING static_us = RTL_CONSTANT_STRING(staticW); - dummy = NtUserCreateWindowEx(0, &static_us, &static_us, &static_us, WS_POPUP, - 0, 0, 0, 0, NULL, NULL, NULL, NULL, 0, NULL, 0, FALSE); - WARN("Created dummy window %p for null surface window\n", dummy); - create_info_host.hwnd = surface->hwnd = dummy; - } - - res = vk_funcs->p_vkCreateWin32SurfaceKHR(instance->host.instance, &create_info_host, - NULL /* allocator */, &surface->driver_surface); - if (res != VK_SUCCESS) - { - if (dummy) NtUserDestroyWindow(dummy); - free(surface); - return res; - } - - host_surface = vk_funcs->p_wine_get_host_surface(surface->driver_surface); - vulkan_object_init(&surface->obj.obj, host_surface); - surface->obj.instance = instance; - vulkan_instance_insert_object(instance, &surface->obj.obj); - - if (dummy) NtUserDestroyWindow(dummy); - window_surfaces_insert(surface); - - *ret = surface->obj.client.surface; - return VK_SUCCESS; -} - -void wine_vkDestroySurfaceKHR(VkInstance client_instance, VkSurfaceKHR client_surface, - const VkAllocationCallbacks *allocator) -{ - struct vulkan_instance *instance = vulkan_instance_from_handle(client_instance); - struct wine_surface *surface = wine_surface_from_handle(client_surface); - - if (!surface) - return; - - vk_funcs->p_vkDestroySurfaceKHR(instance->host.instance, surface->driver_surface, NULL); - vulkan_instance_remove_object(instance, &surface->obj.obj); - window_surfaces_remove(surface); - - free(surface); -} - -static BOOL extents_equals(const VkExtent2D *extents, const RECT *rect) -{ - return extents->width == rect->right - rect->left && - extents->height == rect->bottom - rect->top; -} - -VkResult wine_vkAcquireNextImage2KHR(VkDevice client_device, const VkAcquireNextImageInfoKHR *acquire_info, - uint32_t *image_index) -{ - struct wine_swapchain *swapchain = wine_swapchain_from_handle(acquire_info->swapchain); - struct vulkan_device *device = vulkan_device_from_handle(client_device); - VkAcquireNextImageInfoKHR acquire_info_host = *acquire_info; - struct wine_surface *surface = swapchain->surface; - RECT client_rect; - VkResult res; - - acquire_info_host.swapchain = swapchain->obj.host.swapchain; - res = device->p_vkAcquireNextImage2KHR(device->host.device, &acquire_info_host, image_index); - - if (res == VK_SUCCESS && NtUserGetClientRect(surface->hwnd, &client_rect, NtUserGetDpiForWindow(surface->hwnd)) && - !extents_equals(&swapchain->extents, &client_rect)) - { - WARN("Swapchain size %dx%d does not match client rect %s, returning VK_SUBOPTIMAL_KHR\n", - swapchain->extents.width, swapchain->extents.height, wine_dbgstr_rect(&client_rect)); - return VK_SUBOPTIMAL_KHR; - } - - return res; -} - -VkResult wine_vkAcquireNextImageKHR(VkDevice client_device, VkSwapchainKHR client_swapchain, uint64_t timeout, - VkSemaphore semaphore, VkFence fence, uint32_t *image_index) -{ - struct wine_swapchain *swapchain = wine_swapchain_from_handle(client_swapchain); - struct vulkan_device *device = vulkan_device_from_handle(client_device); - struct wine_surface *surface = swapchain->surface; - RECT client_rect; - VkResult res; - - res = device->p_vkAcquireNextImageKHR(device->host.device, swapchain->obj.host.swapchain, timeout, - semaphore, fence, image_index); - - if (res == VK_SUCCESS && NtUserGetClientRect(surface->hwnd, &client_rect, NtUserGetDpiForWindow(surface->hwnd)) && - !extents_equals(&swapchain->extents, &client_rect)) - { - WARN("Swapchain size %dx%d does not match client rect %s, returning VK_SUBOPTIMAL_KHR\n", - swapchain->extents.width, swapchain->extents.height, wine_dbgstr_rect(&client_rect)); - return VK_SUBOPTIMAL_KHR; - } - - return res; -} - -VkResult wine_vkCreateSwapchainKHR(VkDevice client_device, const VkSwapchainCreateInfoKHR *create_info, - const VkAllocationCallbacks *allocator, VkSwapchainKHR *ret) -{ - struct wine_swapchain *object, *old_swapchain = wine_swapchain_from_handle(create_info->oldSwapchain); - struct wine_surface *surface = wine_surface_from_handle(create_info->surface); - struct vulkan_device *device = vulkan_device_from_handle(client_device); - struct vulkan_physical_device *physical_device = device->physical_device; - struct vulkan_instance *instance = physical_device->instance; - VkSwapchainCreateInfoKHR create_info_host = *create_info; - VkSurfaceCapabilitiesKHR capabilities; - VkSwapchainKHR host_swapchain; - VkResult res; - - if (!NtUserIsWindow(surface->hwnd)) - { - ERR("surface %p, hwnd %p is invalid!\n", surface, surface->hwnd); - return VK_ERROR_INITIALIZATION_FAILED; - } - - if (surface) create_info_host.surface = surface->obj.host.surface; - if (old_swapchain) create_info_host.oldSwapchain = old_swapchain->obj.host.swapchain; - - /* update the host surface to commit any pending size change */ - vk_funcs->p_vulkan_surface_update( surface->driver_surface ); - - /* Windows allows client rect to be empty, but host Vulkan often doesn't, adjust extents back to the host capabilities */ - res = instance->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device->host.physical_device, - surface->obj.host.surface, &capabilities); - if (res != VK_SUCCESS) return res; - - create_info_host.imageExtent.width = max(create_info_host.imageExtent.width, capabilities.minImageExtent.width); - create_info_host.imageExtent.height = max(create_info_host.imageExtent.height, capabilities.minImageExtent.height); - - if (!(object = calloc(1, sizeof(*object)))) return VK_ERROR_OUT_OF_HOST_MEMORY; - res = device->p_vkCreateSwapchainKHR(device->host.device, &create_info_host, NULL, &host_swapchain); - if (res != VK_SUCCESS) - { - free(object); - return res; - } - - vulkan_object_init(&object->obj.obj, host_swapchain); - object->surface = surface; - object->extents = create_info->imageExtent; - vulkan_instance_insert_object(instance, &object->obj.obj); - - *ret = object->obj.client.swapchain; - return VK_SUCCESS; -} - -void wine_vkDestroySwapchainKHR(VkDevice client_device, VkSwapchainKHR client_swapchain, - const VkAllocationCallbacks *allocator) -{ - struct vulkan_device *device = vulkan_device_from_handle(client_device); - struct vulkan_instance *instance = device->physical_device->instance; - struct wine_swapchain *swapchain = wine_swapchain_from_handle(client_swapchain); - - if (allocator) FIXME("Support for allocation callbacks not implemented yet\n"); - if (!swapchain) return; - - device->p_vkDestroySwapchainKHR(device->host.device, swapchain->obj.host.swapchain, NULL); - vulkan_instance_remove_object(instance, &swapchain->obj.obj); - - free(swapchain); -} - -VkResult wine_vkQueuePresentKHR(VkQueue client_queue, const VkPresentInfoKHR *present_info) -{ - VkSwapchainKHR swapchains_buffer[16], *swapchains = swapchains_buffer; - VkSurfaceKHR surfaces_buffer[ARRAY_SIZE(swapchains_buffer)], *surfaces = surfaces_buffer; - struct vulkan_queue *queue = vulkan_queue_from_handle(client_queue); - VkPresentInfoKHR present_info_host = *present_info; - VkResult res; - UINT i; - - if (present_info->swapchainCount > ARRAY_SIZE(swapchains_buffer) && - (!(swapchains = malloc(present_info->swapchainCount * sizeof(*swapchains))) || - !(surfaces = malloc(present_info->swapchainCount * sizeof(*surfaces))))) - { - free(swapchains); - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - - for (i = 0; i < present_info->swapchainCount; i++) - { - struct wine_swapchain *swapchain = wine_swapchain_from_handle(present_info->pSwapchains[i]); - struct wine_surface *surface = swapchain->surface; - swapchains[i] = swapchain->obj.host.swapchain; - surfaces[i] = surface->driver_surface; - } - - present_info_host.pSwapchains = swapchains; - - res = vk_funcs->p_vkQueuePresentKHR(queue->host.queue, &present_info_host, surfaces); - - for (i = 0; i < present_info->swapchainCount; i++) - { - struct wine_swapchain *swapchain = wine_swapchain_from_handle(present_info->pSwapchains[i]); - VkResult swapchain_res = present_info->pResults ? present_info->pResults[i] : res; - struct wine_surface *surface = swapchain->surface; - RECT client_rect; - - if (swapchain_res < VK_SUCCESS) continue; - if (!NtUserGetClientRect(surface->hwnd, &client_rect, NtUserGetDpiForWindow(surface->hwnd))) - { - WARN("Swapchain window %p is invalid, returning VK_ERROR_OUT_OF_DATE_KHR\n", surface->hwnd); - if (present_info->pResults) present_info->pResults[i] = VK_ERROR_OUT_OF_DATE_KHR; - if (res >= VK_SUCCESS) res = VK_ERROR_OUT_OF_DATE_KHR; - } - else if (swapchain_res != VK_SUCCESS) - WARN("Present returned status %d for swapchain %p\n", swapchain_res, swapchain); - else if (!extents_equals(&swapchain->extents, &client_rect)) - { - WARN("Swapchain size %dx%d does not match client rect %s, returning VK_SUBOPTIMAL_KHR\n", - swapchain->extents.width, swapchain->extents.height, wine_dbgstr_rect(&client_rect)); - if (present_info->pResults) present_info->pResults[i] = VK_SUBOPTIMAL_KHR; - if (res == VK_SUCCESS) res = VK_SUBOPTIMAL_KHR; - } - } - - if (swapchains != swapchains_buffer) free(swapchains); - if (surfaces != surfaces_buffer) free(surfaces); - - if (TRACE_ON(fps)) - { - static unsigned long frames, frames_total; - static long prev_time, start_time; - DWORD time; - - time = NtGetTickCount(); - frames++; - frames_total++; - - if (time - prev_time > 1500) - { - TRACE_(fps)("%p @ approx %.2ffps, total %.2ffps\n", queue, - 1000.0 * frames / (time - prev_time), - 1000.0 * frames_total / (time - start_time)); - prev_time = time; - frames = 0; - - if (!start_time) start_time = time; - } - } - - return res; -} - VkResult wine_vkAllocateMemory(VkDevice client_device, const VkMemoryAllocateInfo *alloc_info, const VkAllocationCallbacks *allocator, VkDeviceMemory *ret) { @@ -2251,142 +1950,6 @@ VkResult wine_vkCreateImage(VkDevice client_device, const VkImageCreateInfo *cre return device->p_vkCreateImage(device->host.device, &info, NULL, image); }
-static void adjust_surface_capabilities(struct vulkan_instance *instance, struct wine_surface *surface, - VkSurfaceCapabilitiesKHR *capabilities) -{ - RECT client_rect; - - /* Many Windows games, for example Strange Brigade, No Man's Sky, Path of Exile - * and World War Z, do not expect that maxImageCount can be set to 0. - * A value of 0 means that there is no limit on the number of images. - * Nvidia reports 8 on Windows, AMD 16. - * https://vulkan.gpuinfo.org/displayreport.php?id=9122#surface - * https://vulkan.gpuinfo.org/displayreport.php?id=9121#surface - */ - if (!capabilities->maxImageCount) - capabilities->maxImageCount = max(capabilities->minImageCount, 16); - - /* Update the image extents to match what the Win32 WSI would provide. */ - /* FIXME: handle DPI scaling, somehow */ - NtUserGetClientRect(surface->hwnd, &client_rect, NtUserGetDpiForWindow(surface->hwnd)); - capabilities->minImageExtent.width = client_rect.right - client_rect.left; - capabilities->minImageExtent.height = client_rect.bottom - client_rect.top; - capabilities->maxImageExtent.width = client_rect.right - client_rect.left; - capabilities->maxImageExtent.height = client_rect.bottom - client_rect.top; - capabilities->currentExtent.width = client_rect.right - client_rect.left; - capabilities->currentExtent.height = client_rect.bottom - client_rect.top; -} - -VkResult wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice client_physical_device, VkSurfaceKHR client_surface, - VkSurfaceCapabilitiesKHR *capabilities) -{ - struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle(client_physical_device); - struct wine_surface *surface = wine_surface_from_handle(client_surface); - struct vulkan_instance *instance = physical_device->instance; - VkResult res; - - if (!NtUserIsWindow(surface->hwnd)) return VK_ERROR_SURFACE_LOST_KHR; - res = instance->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device->host.physical_device, - surface->obj.host.surface, capabilities); - if (res == VK_SUCCESS) adjust_surface_capabilities(instance, surface, capabilities); - return res; -} - -VkResult wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice client_physical_device, const VkPhysicalDeviceSurfaceInfo2KHR *surface_info, - VkSurfaceCapabilities2KHR *capabilities) -{ - struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle(client_physical_device); - struct wine_surface *surface = wine_surface_from_handle(surface_info->surface); - VkPhysicalDeviceSurfaceInfo2KHR surface_info_host = *surface_info; - struct vulkan_instance *instance = physical_device->instance; - VkResult res; - - if (!instance->p_vkGetPhysicalDeviceSurfaceCapabilities2KHR) - { - /* Until the loader version exporting this function is common, emulate it using the older non-2 version. */ - if (surface_info->pNext || capabilities->pNext) FIXME("Emulating vkGetPhysicalDeviceSurfaceCapabilities2KHR, ignoring pNext.\n"); - return wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(client_physical_device, surface_info->surface, - &capabilities->surfaceCapabilities); - } - - surface_info_host.surface = surface->obj.host.surface; - - if (!NtUserIsWindow(surface->hwnd)) return VK_ERROR_SURFACE_LOST_KHR; - res = instance->p_vkGetPhysicalDeviceSurfaceCapabilities2KHR(physical_device->host.physical_device, - &surface_info_host, capabilities); - if (res == VK_SUCCESS) adjust_surface_capabilities(instance, surface, &capabilities->surfaceCapabilities); - return res; -} - -VkResult wine_vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice client_physical_device, VkSurfaceKHR client_surface, - uint32_t *rect_count, VkRect2D *rects) -{ - struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle(client_physical_device); - struct wine_surface *surface = wine_surface_from_handle(client_surface); - struct vulkan_instance *instance = physical_device->instance; - - if (!NtUserIsWindow(surface->hwnd)) - { - if (rects && !*rect_count) return VK_INCOMPLETE; - if (rects) memset(rects, 0, sizeof(VkRect2D)); - *rect_count = 1; - return VK_SUCCESS; - } - - return instance->p_vkGetPhysicalDevicePresentRectanglesKHR(physical_device->host.physical_device, - surface->obj.host.surface, rect_count, rects); -} - -VkResult wine_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice client_physical_device, VkSurfaceKHR client_surface, - uint32_t *format_count, VkSurfaceFormatKHR *formats) -{ - struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle(client_physical_device); - struct wine_surface *surface = wine_surface_from_handle(client_surface); - struct vulkan_instance *instance = physical_device->instance; - - return instance->p_vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device->host.physical_device, surface->obj.host.surface, - format_count, formats); -} - -VkResult wine_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice client_physical_device, const VkPhysicalDeviceSurfaceInfo2KHR *surface_info, - uint32_t *format_count, VkSurfaceFormat2KHR *formats) -{ - struct vulkan_physical_device *physical_device = vulkan_physical_device_from_handle(client_physical_device); - struct wine_surface *surface = wine_surface_from_handle(surface_info->surface); - VkPhysicalDeviceSurfaceInfo2KHR surface_info_host = *surface_info; - struct vulkan_instance *instance = physical_device->instance; - VkResult res; - - if (!instance->p_vkGetPhysicalDeviceSurfaceFormats2KHR) - { - VkSurfaceFormatKHR *surface_formats; - UINT i; - - /* Until the loader version exporting this function is common, emulate it using the older non-2 version. */ - if (surface_info->pNext) FIXME("Emulating vkGetPhysicalDeviceSurfaceFormats2KHR, ignoring pNext.\n"); - - if (!formats) return wine_vkGetPhysicalDeviceSurfaceFormatsKHR(client_physical_device, surface_info->surface, format_count, NULL); - - surface_formats = calloc(*format_count, sizeof(*surface_formats)); - if (!surface_formats) return VK_ERROR_OUT_OF_HOST_MEMORY; - - res = wine_vkGetPhysicalDeviceSurfaceFormatsKHR(client_physical_device, surface_info->surface, format_count, surface_formats); - if (res == VK_SUCCESS || res == VK_INCOMPLETE) - { - for (i = 0; i < *format_count; i++) - formats[i].surfaceFormat = surface_formats[i]; - } - - free(surface_formats); - return res; - } - - surface_info_host.surface = surface->obj.host.surface; - - return instance->p_vkGetPhysicalDeviceSurfaceFormats2KHR(physical_device->host.physical_device, - &surface_info_host, format_count, formats); -} - VkResult wine_vkCreateDebugUtilsMessengerEXT(VkInstance client_instance, const VkDebugUtilsMessengerCreateInfoEXT *create_info, const VkAllocationCallbacks *allocator, diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index 23a29bb460f..87e12c63b2b 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -154,34 +154,6 @@ static inline struct wine_debug_report_callback *wine_debug_report_callback_from return (struct wine_debug_report_callback *)(uintptr_t)handle; }
-struct wine_surface -{ - struct vulkan_surface obj; - VkSurfaceKHR driver_surface; - HWND hwnd; - - struct rb_entry window_entry; -}; - -static inline struct wine_surface *wine_surface_from_handle(VkSurfaceKHR handle) -{ - struct vulkan_surface *obj = vulkan_surface_from_handle(handle); - return CONTAINING_RECORD(obj, struct wine_surface, obj); -} - -struct wine_swapchain -{ - struct vulkan_swapchain obj; - struct wine_surface *surface; - VkExtent2D extents; -}; - -static inline struct wine_swapchain *wine_swapchain_from_handle(VkSwapchainKHR handle) -{ - struct vulkan_swapchain *obj = vulkan_swapchain_from_handle(handle); - return CONTAINING_RECORD(obj, struct wine_swapchain, obj); -} - BOOL wine_vk_device_extension_supported(const char *name); BOOL wine_vk_instance_extension_supported(const char *name); BOOL wine_vk_is_host_surface_extension(const char *name); diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c index d515ad7e0e0..f3b06622208 100644 --- a/dlls/winevulkan/vulkan_thunks.c +++ b/dlls/winevulkan/vulkan_thunks.c @@ -36616,7 +36616,7 @@ static NTSTATUS thunk64_vkAcquireNextImage2KHR(void *args)
TRACE("%p, %p, %p\n", params->device, params->pAcquireInfo, params->pImageIndex);
- params->result = wine_vkAcquireNextImage2KHR(params->device, params->pAcquireInfo, params->pImageIndex); + params->result = vk_funcs->p_vkAcquireNextImage2KHR(params->device, params->pAcquireInfo, params->pImageIndex); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -36635,7 +36635,7 @@ static NTSTATUS thunk32_vkAcquireNextImage2KHR(void *args) TRACE("%#x, %#x, %#x\n", params->device, params->pAcquireInfo, params->pImageIndex);
convert_VkAcquireNextImageInfoKHR_win32_to_unwrapped_host((const VkAcquireNextImageInfoKHR32 *)UlongToPtr(params->pAcquireInfo), &pAcquireInfo_host); - params->result = wine_vkAcquireNextImage2KHR((VkDevice)UlongToPtr(params->device), &pAcquireInfo_host, (uint32_t *)UlongToPtr(params->pImageIndex)); + params->result = vk_funcs->p_vkAcquireNextImage2KHR((VkDevice)UlongToPtr(params->device), &pAcquireInfo_host, (uint32_t *)UlongToPtr(params->pImageIndex)); return STATUS_SUCCESS; }
@@ -36646,7 +36646,7 @@ static NTSTATUS thunk64_vkAcquireNextImageKHR(void *args)
TRACE("%p, 0x%s, 0x%s, 0x%s, 0x%s, %p\n", params->device, wine_dbgstr_longlong(params->swapchain), wine_dbgstr_longlong(params->timeout), wine_dbgstr_longlong(params->semaphore), wine_dbgstr_longlong(params->fence), params->pImageIndex);
- params->result = wine_vkAcquireNextImageKHR(params->device, params->swapchain, params->timeout, params->semaphore, params->fence, params->pImageIndex); + params->result = vk_funcs->p_vkAcquireNextImageKHR(params->device, params->swapchain, params->timeout, params->semaphore, params->fence, params->pImageIndex); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -36666,7 +36666,7 @@ static NTSTATUS thunk32_vkAcquireNextImageKHR(void *args)
TRACE("%#x, 0x%s, 0x%s, 0x%s, 0x%s, %#x\n", params->device, wine_dbgstr_longlong(params->swapchain), wine_dbgstr_longlong(params->timeout), wine_dbgstr_longlong(params->semaphore), wine_dbgstr_longlong(params->fence), params->pImageIndex);
- params->result = wine_vkAcquireNextImageKHR((VkDevice)UlongToPtr(params->device), params->swapchain, params->timeout, params->semaphore, params->fence, (uint32_t *)UlongToPtr(params->pImageIndex)); + params->result = vk_funcs->p_vkAcquireNextImageKHR((VkDevice)UlongToPtr(params->device), params->swapchain, params->timeout, params->semaphore, params->fence, (uint32_t *)UlongToPtr(params->pImageIndex)); return STATUS_SUCCESS; }
@@ -45155,7 +45155,7 @@ static NTSTATUS thunk64_vkCreateSwapchainKHR(void *args)
TRACE("%p, %p, %p, %p\n", params->device, params->pCreateInfo, params->pAllocator, params->pSwapchain);
- params->result = wine_vkCreateSwapchainKHR(params->device, params->pCreateInfo, params->pAllocator, params->pSwapchain); + params->result = vk_funcs->p_vkCreateSwapchainKHR(params->device, params->pCreateInfo, params->pAllocator, params->pSwapchain); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -45178,7 +45178,7 @@ static NTSTATUS thunk32_vkCreateSwapchainKHR(void *args)
init_conversion_context(ctx); convert_VkSwapchainCreateInfoKHR_win32_to_unwrapped_host(ctx, (const VkSwapchainCreateInfoKHR32 *)UlongToPtr(params->pCreateInfo), &pCreateInfo_host); - params->result = wine_vkCreateSwapchainKHR((VkDevice)UlongToPtr(params->device), &pCreateInfo_host, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator), (VkSwapchainKHR *)UlongToPtr(params->pSwapchain)); + params->result = vk_funcs->p_vkCreateSwapchainKHR((VkDevice)UlongToPtr(params->device), &pCreateInfo_host, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator), (VkSwapchainKHR *)UlongToPtr(params->pSwapchain)); free_conversion_context(ctx); return STATUS_SUCCESS; } @@ -45291,7 +45291,7 @@ static NTSTATUS thunk64_vkCreateWin32SurfaceKHR(void *args)
TRACE("%p, %p, %p, %p\n", params->instance, params->pCreateInfo, params->pAllocator, params->pSurface);
- params->result = wine_vkCreateWin32SurfaceKHR(params->instance, params->pCreateInfo, params->pAllocator, params->pSurface); + params->result = vk_funcs->p_vkCreateWin32SurfaceKHR(params->instance, params->pCreateInfo, params->pAllocator, params->pSurface); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -45311,7 +45311,7 @@ static NTSTATUS thunk32_vkCreateWin32SurfaceKHR(void *args) TRACE("%#x, %#x, %#x, %#x\n", params->instance, params->pCreateInfo, params->pAllocator, params->pSurface);
convert_VkWin32SurfaceCreateInfoKHR_win32_to_host((const VkWin32SurfaceCreateInfoKHR32 *)UlongToPtr(params->pCreateInfo), &pCreateInfo_host); - params->result = wine_vkCreateWin32SurfaceKHR((VkInstance)UlongToPtr(params->instance), &pCreateInfo_host, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator), (VkSurfaceKHR *)UlongToPtr(params->pSurface)); + params->result = vk_funcs->p_vkCreateWin32SurfaceKHR((VkInstance)UlongToPtr(params->instance), &pCreateInfo_host, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator), (VkSurfaceKHR *)UlongToPtr(params->pSurface)); return STATUS_SUCCESS; }
@@ -46587,7 +46587,7 @@ static NTSTATUS thunk64_vkDestroySurfaceKHR(void *args)
TRACE("%p, 0x%s, %p\n", params->instance, wine_dbgstr_longlong(params->surface), params->pAllocator);
- wine_vkDestroySurfaceKHR(params->instance, params->surface, params->pAllocator); + vk_funcs->p_vkDestroySurfaceKHR(params->instance, params->surface, params->pAllocator); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -46603,7 +46603,7 @@ static NTSTATUS thunk32_vkDestroySurfaceKHR(void *args)
TRACE("%#x, 0x%s, %#x\n", params->instance, wine_dbgstr_longlong(params->surface), params->pAllocator);
- wine_vkDestroySurfaceKHR((VkInstance)UlongToPtr(params->instance), params->surface, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator)); + vk_funcs->p_vkDestroySurfaceKHR((VkInstance)UlongToPtr(params->instance), params->surface, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator)); return STATUS_SUCCESS; }
@@ -46614,7 +46614,7 @@ static NTSTATUS thunk64_vkDestroySwapchainKHR(void *args)
TRACE("%p, 0x%s, %p\n", params->device, wine_dbgstr_longlong(params->swapchain), params->pAllocator);
- wine_vkDestroySwapchainKHR(params->device, params->swapchain, params->pAllocator); + vk_funcs->p_vkDestroySwapchainKHR(params->device, params->swapchain, params->pAllocator); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -46630,7 +46630,7 @@ static NTSTATUS thunk32_vkDestroySwapchainKHR(void *args)
TRACE("%#x, 0x%s, %#x\n", params->device, wine_dbgstr_longlong(params->swapchain), params->pAllocator);
- wine_vkDestroySwapchainKHR((VkDevice)UlongToPtr(params->device), params->swapchain, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator)); + vk_funcs->p_vkDestroySwapchainKHR((VkDevice)UlongToPtr(params->device), params->swapchain, (const VkAllocationCallbacks *)UlongToPtr(params->pAllocator)); return STATUS_SUCCESS; }
@@ -50352,7 +50352,7 @@ static NTSTATUS thunk64_vkGetPhysicalDevicePresentRectanglesKHR(void *args)
TRACE("%p, 0x%s, %p, %p\n", params->physicalDevice, wine_dbgstr_longlong(params->surface), params->pRectCount, params->pRects);
- params->result = wine_vkGetPhysicalDevicePresentRectanglesKHR(params->physicalDevice, params->surface, params->pRectCount, params->pRects); + params->result = vk_funcs->p_vkGetPhysicalDevicePresentRectanglesKHR(params->physicalDevice, params->surface, params->pRectCount, params->pRects); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -50370,7 +50370,7 @@ static NTSTATUS thunk32_vkGetPhysicalDevicePresentRectanglesKHR(void *args)
TRACE("%#x, 0x%s, %#x, %#x\n", params->physicalDevice, wine_dbgstr_longlong(params->surface), params->pRectCount, params->pRects);
- params->result = wine_vkGetPhysicalDevicePresentRectanglesKHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), params->surface, (uint32_t *)UlongToPtr(params->pRectCount), (VkRect2D *)UlongToPtr(params->pRects)); + params->result = vk_funcs->p_vkGetPhysicalDevicePresentRectanglesKHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), params->surface, (uint32_t *)UlongToPtr(params->pRectCount), (VkRect2D *)UlongToPtr(params->pRects)); return STATUS_SUCCESS; }
@@ -50740,7 +50740,7 @@ static NTSTATUS thunk64_vkGetPhysicalDeviceSurfaceCapabilities2KHR(void *args)
TRACE("%p, %p, %p\n", params->physicalDevice, params->pSurfaceInfo, params->pSurfaceCapabilities);
- params->result = wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(params->physicalDevice, params->pSurfaceInfo, params->pSurfaceCapabilities); + params->result = vk_funcs->p_vkGetPhysicalDeviceSurfaceCapabilities2KHR(params->physicalDevice, params->pSurfaceInfo, params->pSurfaceCapabilities); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -50764,7 +50764,7 @@ static NTSTATUS thunk32_vkGetPhysicalDeviceSurfaceCapabilities2KHR(void *args) init_conversion_context(ctx); convert_VkPhysicalDeviceSurfaceInfo2KHR_win32_to_unwrapped_host(ctx, (const VkPhysicalDeviceSurfaceInfo2KHR32 *)UlongToPtr(params->pSurfaceInfo), &pSurfaceInfo_host); convert_VkSurfaceCapabilities2KHR_win32_to_host(ctx, (VkSurfaceCapabilities2KHR32 *)UlongToPtr(params->pSurfaceCapabilities), &pSurfaceCapabilities_host); - params->result = wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), &pSurfaceInfo_host, &pSurfaceCapabilities_host); + params->result = vk_funcs->p_vkGetPhysicalDeviceSurfaceCapabilities2KHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), &pSurfaceInfo_host, &pSurfaceCapabilities_host); convert_VkSurfaceCapabilities2KHR_host_to_win32(&pSurfaceCapabilities_host, (VkSurfaceCapabilities2KHR32 *)UlongToPtr(params->pSurfaceCapabilities)); free_conversion_context(ctx); return STATUS_SUCCESS; @@ -50777,7 +50777,7 @@ static NTSTATUS thunk64_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(void *args)
TRACE("%p, 0x%s, %p\n", params->physicalDevice, wine_dbgstr_longlong(params->surface), params->pSurfaceCapabilities);
- params->result = wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(params->physicalDevice, params->surface, params->pSurfaceCapabilities); + params->result = vk_funcs->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(params->physicalDevice, params->surface, params->pSurfaceCapabilities); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -50794,7 +50794,7 @@ static NTSTATUS thunk32_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(void *args)
TRACE("%#x, 0x%s, %#x\n", params->physicalDevice, wine_dbgstr_longlong(params->surface), params->pSurfaceCapabilities);
- params->result = wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), params->surface, (VkSurfaceCapabilitiesKHR *)UlongToPtr(params->pSurfaceCapabilities)); + params->result = vk_funcs->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), params->surface, (VkSurfaceCapabilitiesKHR *)UlongToPtr(params->pSurfaceCapabilities)); return STATUS_SUCCESS; }
@@ -50805,7 +50805,7 @@ static NTSTATUS thunk64_vkGetPhysicalDeviceSurfaceFormats2KHR(void *args)
TRACE("%p, %p, %p, %p\n", params->physicalDevice, params->pSurfaceInfo, params->pSurfaceFormatCount, params->pSurfaceFormats);
- params->result = wine_vkGetPhysicalDeviceSurfaceFormats2KHR(params->physicalDevice, params->pSurfaceInfo, params->pSurfaceFormatCount, params->pSurfaceFormats); + params->result = vk_funcs->p_vkGetPhysicalDeviceSurfaceFormats2KHR(params->physicalDevice, params->pSurfaceInfo, params->pSurfaceFormatCount, params->pSurfaceFormats); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -50830,7 +50830,7 @@ static NTSTATUS thunk32_vkGetPhysicalDeviceSurfaceFormats2KHR(void *args) init_conversion_context(ctx); convert_VkPhysicalDeviceSurfaceInfo2KHR_win32_to_unwrapped_host(ctx, (const VkPhysicalDeviceSurfaceInfo2KHR32 *)UlongToPtr(params->pSurfaceInfo), &pSurfaceInfo_host); pSurfaceFormats_host = convert_VkSurfaceFormat2KHR_array_win32_to_host(ctx, (VkSurfaceFormat2KHR32 *)UlongToPtr(params->pSurfaceFormats), *(uint32_t *)UlongToPtr(params->pSurfaceFormatCount)); - params->result = wine_vkGetPhysicalDeviceSurfaceFormats2KHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), &pSurfaceInfo_host, (uint32_t *)UlongToPtr(params->pSurfaceFormatCount), pSurfaceFormats_host); + params->result = vk_funcs->p_vkGetPhysicalDeviceSurfaceFormats2KHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), &pSurfaceInfo_host, (uint32_t *)UlongToPtr(params->pSurfaceFormatCount), pSurfaceFormats_host); convert_VkSurfaceFormat2KHR_array_host_to_win32(pSurfaceFormats_host, (VkSurfaceFormat2KHR32 *)UlongToPtr(params->pSurfaceFormats), *(uint32_t *)UlongToPtr(params->pSurfaceFormatCount)); free_conversion_context(ctx); return STATUS_SUCCESS; @@ -50843,7 +50843,7 @@ static NTSTATUS thunk64_vkGetPhysicalDeviceSurfaceFormatsKHR(void *args)
TRACE("%p, 0x%s, %p, %p\n", params->physicalDevice, wine_dbgstr_longlong(params->surface), params->pSurfaceFormatCount, params->pSurfaceFormats);
- params->result = wine_vkGetPhysicalDeviceSurfaceFormatsKHR(params->physicalDevice, params->surface, params->pSurfaceFormatCount, params->pSurfaceFormats); + params->result = vk_funcs->p_vkGetPhysicalDeviceSurfaceFormatsKHR(params->physicalDevice, params->surface, params->pSurfaceFormatCount, params->pSurfaceFormats); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -50861,7 +50861,7 @@ static NTSTATUS thunk32_vkGetPhysicalDeviceSurfaceFormatsKHR(void *args)
TRACE("%#x, 0x%s, %#x, %#x\n", params->physicalDevice, wine_dbgstr_longlong(params->surface), params->pSurfaceFormatCount, params->pSurfaceFormats);
- params->result = wine_vkGetPhysicalDeviceSurfaceFormatsKHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), params->surface, (uint32_t *)UlongToPtr(params->pSurfaceFormatCount), (VkSurfaceFormatKHR *)UlongToPtr(params->pSurfaceFormats)); + params->result = vk_funcs->p_vkGetPhysicalDeviceSurfaceFormatsKHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), params->surface, (uint32_t *)UlongToPtr(params->pSurfaceFormatCount), (VkSurfaceFormatKHR *)UlongToPtr(params->pSurfaceFormats)); return STATUS_SUCCESS; }
@@ -51112,7 +51112,7 @@ static NTSTATUS thunk64_vkGetPhysicalDeviceWin32PresentationSupportKHR(void *arg
TRACE("%p, %u\n", params->physicalDevice, params->queueFamilyIndex);
- params->result = vk_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR(vulkan_physical_device_from_handle(params->physicalDevice)->host.physical_device, params->queueFamilyIndex); + params->result = vk_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR(params->physicalDevice, params->queueFamilyIndex); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -51128,7 +51128,7 @@ static NTSTATUS thunk32_vkGetPhysicalDeviceWin32PresentationSupportKHR(void *arg
TRACE("%#x, %u\n", params->physicalDevice, params->queueFamilyIndex);
- params->result = vk_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR(vulkan_physical_device_from_handle((VkPhysicalDevice)UlongToPtr(params->physicalDevice))->host.physical_device, params->queueFamilyIndex); + params->result = vk_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), params->queueFamilyIndex); return STATUS_SUCCESS; }
@@ -52496,7 +52496,7 @@ static NTSTATUS thunk64_vkQueuePresentKHR(void *args)
TRACE("%p, %p\n", params->queue, params->pPresentInfo);
- params->result = wine_vkQueuePresentKHR(params->queue, params->pPresentInfo); + params->result = vk_funcs->p_vkQueuePresentKHR(params->queue, params->pPresentInfo); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -52517,7 +52517,7 @@ static NTSTATUS thunk32_vkQueuePresentKHR(void *args)
init_conversion_context(ctx); convert_VkPresentInfoKHR_win32_to_unwrapped_host(ctx, (const VkPresentInfoKHR32 *)UlongToPtr(params->pPresentInfo), &pPresentInfo_host); - params->result = wine_vkQueuePresentKHR((VkQueue)UlongToPtr(params->queue), &pPresentInfo_host); + params->result = vk_funcs->p_vkQueuePresentKHR((VkQueue)UlongToPtr(params->queue), &pPresentInfo_host); free_conversion_context(ctx); return STATUS_SUCCESS; } diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h index 88ce00f7a08..9fd02d744d0 100644 --- a/dlls/winevulkan/vulkan_thunks.h +++ b/dlls/winevulkan/vulkan_thunks.h @@ -21,8 +21,6 @@ #define WINE_VK_VERSION VK_API_VERSION_1_3
/* Functions for which we have custom implementations outside of the thunks. */ -VkResult wine_vkAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo, uint32_t *pImageIndex); -VkResult wine_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex); VkResult wine_vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers); VkResult wine_vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory); VkResult wine_vkCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer); @@ -33,16 +31,12 @@ VkResult wine_vkCreateDeferredOperationKHR(VkDevice device, const VkAllocationCa VkResult wine_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, void *client_ptr); VkResult wine_vkCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkImage *pImage); VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance, void *client_ptr); -VkResult wine_vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain); -VkResult wine_vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface); void wine_vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator); void wine_vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks *pAllocator); void wine_vkDestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger, const VkAllocationCallbacks *pAllocator); void wine_vkDestroyDeferredOperationKHR(VkDevice device, VkDeferredOperationKHR operation, const VkAllocationCallbacks *pAllocator); void wine_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator); void wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator); -void wine_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator); -void wine_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator); VkResult wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties); VkResult wine_vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkLayerProperties *pProperties); VkResult wine_vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties); @@ -66,14 +60,8 @@ void wine_vkGetPhysicalDeviceExternalSemaphoreProperties(VkPhysicalDevice physic void wine_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo, VkExternalSemaphoreProperties *pExternalSemaphoreProperties); VkResult wine_vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties); VkResult wine_vkGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties); -VkResult wine_vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pRectCount, VkRect2D *pRects); -VkResult wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, VkSurfaceCapabilities2KHR *pSurfaceCapabilities); -VkResult wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities); -VkResult wine_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, uint32_t *pSurfaceFormatCount, VkSurfaceFormat2KHR *pSurfaceFormats); -VkResult wine_vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats); VkResult wine_vkMapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void **ppData); VkResult wine_vkMapMemory2KHR(VkDevice device, const VkMemoryMapInfoKHR *pMemoryMapInfo, void **ppData); -VkResult wine_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo); void wine_vkUnmapMemory(VkDevice device, VkDeviceMemory memory); VkResult wine_vkUnmapMemory2KHR(VkDevice device, const VkMemoryUnmapInfoKHR *pMemoryUnmapInfo);
diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h index 5a56bfe08f7..4bd60218943 100644 --- a/include/wine/vulkan_driver.h +++ b/include/wine/vulkan_driver.h @@ -77,6 +77,8 @@ struct vulkan_instance #define USE_VK_FUNC(x) PFN_ ## x p_ ## x; ALL_VK_INSTANCE_FUNCS #undef USE_VK_FUNC + void (*p_insert_object)( struct vulkan_instance *instance, struct vulkan_object *obj ); + void (*p_remove_object)( struct vulkan_instance *instance, struct vulkan_object *obj ); };
static inline struct vulkan_instance *vulkan_instance_from_handle( VkInstance handle ) @@ -151,17 +153,24 @@ struct vulkan_funcs * needs to provide. Other function calls will be provided indirectly by dispatch * tables part of dispatchable Vulkan objects such as VkInstance or vkDevice. */ + PFN_vkAcquireNextImage2KHR p_vkAcquireNextImage2KHR; + PFN_vkAcquireNextImageKHR p_vkAcquireNextImageKHR; + PFN_vkCreateSwapchainKHR p_vkCreateSwapchainKHR; PFN_vkCreateWin32SurfaceKHR p_vkCreateWin32SurfaceKHR; PFN_vkDestroySurfaceKHR p_vkDestroySurfaceKHR; + PFN_vkDestroySwapchainKHR p_vkDestroySwapchainKHR; PFN_vkGetDeviceProcAddr p_vkGetDeviceProcAddr; PFN_vkGetInstanceProcAddr p_vkGetInstanceProcAddr; + PFN_vkGetPhysicalDevicePresentRectanglesKHR p_vkGetPhysicalDevicePresentRectanglesKHR; + PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR p_vkGetPhysicalDeviceSurfaceCapabilities2KHR; + PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR; + PFN_vkGetPhysicalDeviceSurfaceFormats2KHR p_vkGetPhysicalDeviceSurfaceFormats2KHR; + PFN_vkGetPhysicalDeviceSurfaceFormatsKHR p_vkGetPhysicalDeviceSurfaceFormatsKHR; PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR p_vkGetPhysicalDeviceWin32PresentationSupportKHR; - VkResult (*p_vkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *, VkSurfaceKHR *surfaces); + PFN_vkQueuePresentKHR p_vkQueuePresentKHR;
/* winevulkan specific functions */ const char *(*p_get_host_surface_extension)(void); - VkSurfaceKHR (*p_wine_get_host_surface)(VkSurfaceKHR); - void (*p_vulkan_surface_update)(VkSurfaceKHR); };
/* interface between win32u and the user drivers */
On Mon Dec 2 16:01:50 2024 +0000, Rémi Bernon wrote:
changed this line in [version 3 of the diff](/wine/wine/-/merge_requests/6931/diffs?diff_id=146594&start_sha=7983944438f5cc903f1354113cfc9018d8e75fea#dcb06a041ed868c4edf96285c55f6258da0c3321_72_70)
Hmm, yeah though the command_pool wrapping gets a little bit in the way. I made `vulkan_object_init_ptr` separate (and local to winevulkan), but I also changed it to take a `UINT64 host_handle` for this specific case. All other callers will have to cast their pointer to `UINT_PTR` which hopefully isn't too ugly.
v3: Use vk_funcs for win32u wrapped functions, only keep host vulkan function pointers in devices and instances. Split `vulkan_object_init` helpers, fix incorrect cast.
This merge request was approved by Jacek Caban.