From d2892d352d544027d449734b8f2924f0ed620a9e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Wed, 10 Apr 2024 14:17:07 +0200
Subject: [PATCH] winevulkan: Pass surface info for each vkQueuePresent
 swapchain to win32u.

---
 dlls/win32u/vulkan.c          | 13 +++++++++++++
 dlls/winemac.drv/vulkan.c     |  2 +-
 dlls/winevulkan/vulkan.c      | 13 ++++++++++---
 dlls/winewayland.drv/vulkan.c |  2 +-
 dlls/winex11.drv/vulkan.c     |  2 +-
 include/wine/vulkan_driver.h  |  4 ++--
 6 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c
index 6866dbcb076..73e0b276bbe 100644
--- a/dlls/win32u/vulkan.c
+++ b/dlls/win32u/vulkan.c
@@ -43,9 +43,19 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
 static void *vulkan_handle;
 static struct vulkan_funcs vulkan_funcs;
 
+static VkResult (*p_vkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *, HWND *);
 static void *(*p_vkGetDeviceProcAddr)(VkDevice, const char *);
 static void *(*p_vkGetInstanceProcAddr)(VkInstance, const char *);
 
+static VkResult win32u_vkQueuePresentKHR( VkQueue queue, const VkPresentInfoKHR *present_info, HWND *surfaces )
+{
+    VkPresentInfoKHR host_present_info = *present_info;
+
+    TRACE( "queue %p, present_info %p\n", queue, present_info );
+
+    return p_vkQueuePresentKHR( queue, &host_present_info, surfaces );
+}
+
 static void *win32u_vkGetDeviceProcAddr( VkDevice device, const char *name )
 {
     TRACE( "device %p, name %s\n", device, debugstr_a(name) );
@@ -112,6 +122,9 @@ static void vulkan_init(void)
 
     vulkan_funcs.p_vkGetDeviceProcAddr = win32u_vkGetDeviceProcAddr;
     vulkan_funcs.p_vkGetInstanceProcAddr = win32u_vkGetInstanceProcAddr;
+
+    p_vkQueuePresentKHR = vulkan_funcs.p_vkQueuePresentKHR;
+    vulkan_funcs.p_vkQueuePresentKHR = win32u_vkQueuePresentKHR;
 }
 
 /***********************************************************************
diff --git a/dlls/winemac.drv/vulkan.c b/dlls/winemac.drv/vulkan.c
index f32269c7237..fd25b862ac9 100644
--- a/dlls/winemac.drv/vulkan.c
+++ b/dlls/winemac.drv/vulkan.c
@@ -235,7 +235,7 @@ static VkBool32 macdrv_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysical
     return VK_TRUE;
 }
 
-static VkResult macdrv_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *present_info)
+static VkResult macdrv_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *present_info, HWND *surfaces)
 {
     TRACE("%p, %p\n", queue, present_info);
     return pvkQueuePresentKHR(queue, present_info);
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index 972de3cedaf..ab757e19a61 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -1740,25 +1740,31 @@ void wine_vkDestroySwapchainKHR(VkDevice device_handle, VkSwapchainKHR swapchain
 VkResult wine_vkQueuePresentKHR(VkQueue queue_handle, const VkPresentInfoKHR *present_info)
 {
     VkSwapchainKHR swapchains_buffer[16], *swapchains = swapchains_buffer;
+    HWND surfaces_buffer[ARRAY_SIZE(swapchains_buffer)], *surfaces = surfaces_buffer;
     struct wine_queue *queue = wine_queue_from_handle(queue_handle);
     VkPresentInfoKHR present_info_host = *present_info;
-    struct wine_device *device = queue->device;
     VkResult res;
     UINT i;
 
     if (present_info->swapchainCount > ARRAY_SIZE(swapchains_buffer) &&
-        !(swapchains = malloc(present_info->swapchainCount * sizeof(*swapchains))))
+        (!(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->host_swapchain;
+        surfaces[i] = surface->hwnd;
     }
 
     present_info_host.pSwapchains = swapchains;
 
-    res = device->funcs.p_vkQueuePresentKHR(queue->host_queue, &present_info_host);
+    res = vk_funcs->p_vkQueuePresentKHR(queue->host_queue, &present_info_host, surfaces);
 
     for (i = 0; i < present_info->swapchainCount; i++)
     {
@@ -1786,6 +1792,7 @@ VkResult wine_vkQueuePresentKHR(VkQueue queue_handle, const VkPresentInfoKHR *pr
     }
 
     if (swapchains != swapchains_buffer) free(swapchains);
+    if (surfaces != surfaces_buffer) free(surfaces);
 
     if (TRACE_ON(fps))
     {
diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c
index 8fd13fa7761..9246e70439c 100644
--- a/dlls/winewayland.drv/vulkan.c
+++ b/dlls/winewayland.drv/vulkan.c
@@ -365,7 +365,7 @@ static VkBool32 wayland_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysica
                                                              process_wayland.wl_display);
 }
 
-static VkResult wayland_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *present_info)
+static VkResult wayland_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *present_info, HWND *surfaces)
 {
     VkResult res;
 
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c
index 36edcffa997..4aa76103995 100644
--- a/dlls/winex11.drv/vulkan.c
+++ b/dlls/winex11.drv/vulkan.c
@@ -252,7 +252,7 @@ static VkBool32 X11DRV_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysical
             default_visual.visual->visualid);
 }
 
-static VkResult X11DRV_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *present_info)
+static VkResult X11DRV_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *present_info, HWND *surfaces)
 {
     TRACE("%p, %p\n", queue, present_info);
     return pvkQueuePresentKHR(queue, present_info);
diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h
index e707a56269c..cd08f525f40 100644
--- a/include/wine/vulkan_driver.h
+++ b/include/wine/vulkan_driver.h
@@ -21,7 +21,7 @@
 #define __WINE_VULKAN_DRIVER_H
 
 /* Wine internal vulkan driver version, needs to be bumped upon vulkan_funcs changes. */
-#define WINE_VULKAN_DRIVER_VERSION 23
+#define WINE_VULKAN_DRIVER_VERSION 24
 
 struct vulkan_funcs
 {
@@ -36,7 +36,7 @@ struct vulkan_funcs
     void * (*p_vkGetDeviceProcAddr)(VkDevice, const char *);
     void * (*p_vkGetInstanceProcAddr)(VkInstance, const char *);
     VkBool32 (*p_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice, uint32_t);
-    VkResult (*p_vkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *);
+    VkResult (*p_vkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *, HWND *surfaces);
 
     /* winevulkan specific functions */
     const char *(*p_get_host_surface_extension)(void);
-- 
GitLab