From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/vulkan.c | 18 ++++++++++++++++++ dlls/winevulkan/vulkan.c | 14 +++++++++++++- include/wine/vulkan_driver.h | 12 +++++++++++- 3 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index 6866dbcb076..54c0fde841e 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -24,6 +24,7 @@
#include "config.h"
+#include <assert.h> #include <dlfcn.h> #include <pthread.h>
@@ -43,9 +44,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); static void *vulkan_handle; static struct vulkan_funcs vulkan_funcs;
+static VkResult (*p_vkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *); static void *(*p_vkGetDeviceProcAddr)(VkDevice, const char *); static void *(*p_vkGetInstanceProcAddr)(VkInstance, const char *);
+static VkResult win32u_vkQueuePresentKHR( VkQueue queue, const VkPresentInfoKHR *present_info ) +{ + const VkPresentSurfacesInfoWine *surfaces_info = present_info->pNext; + VkPresentInfoKHR host_present_info = *present_info; + + TRACE( "queue %p, present_info %p\n", queue, present_info ); + + assert( surfaces_info && surfaces_info->sType == VK_STRUCTURE_TYPE_PRESENT_SURFACES_INFO_WINE ); + host_present_info.pNext = surfaces_info->pNext; + + return p_vkQueuePresentKHR( queue, &host_present_info ); +} + static void *win32u_vkGetDeviceProcAddr( VkDevice device, const char *name ) { TRACE( "device %p, name %s\n", device, debugstr_a(name) ); @@ -112,6 +127,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/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 972de3cedaf..b915147e927 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -1739,7 +1739,9 @@ void wine_vkDestroySwapchainKHR(VkDevice device_handle, VkSwapchainKHR swapchain
VkResult wine_vkQueuePresentKHR(VkQueue queue_handle, const VkPresentInfoKHR *present_info) { + VkPresentSurfacesInfoWine surfaces_info = {.sType = VK_STRUCTURE_TYPE_PRESENT_SURFACES_INFO_WINE, .pNext = present_info->pNext}; 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; @@ -1747,16 +1749,25 @@ VkResult wine_vkQueuePresentKHR(VkQueue queue_handle, const VkPresentInfoKHR *pr 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; + present_info_host.pNext = &surfaces_info; + surfaces_info.swapchainCount = present_info_host.swapchainCount; + surfaces_info.pSurfaces = surfaces;
res = device->funcs.p_vkQueuePresentKHR(queue->host_queue, &present_info_host);
@@ -1786,6 +1797,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/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h index e707a56269c..d6002d88b80 100644 --- a/include/wine/vulkan_driver.h +++ b/include/wine/vulkan_driver.h @@ -21,7 +21,17 @@ #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 + +#define VK_STRUCTURE_TYPE_PRESENT_SURFACES_INFO_WINE (UINT)VK_STRUCTURE_TYPE_MAX_ENUM + 1 + +typedef struct VkPresentSurfacesInfoWine +{ + VkStructureType sType; + const void *pNext; + uint32_t swapchainCount; + HWND *pSurfaces; +} VkPresentSurfacesInfoWine;
struct vulkan_funcs {