From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/win32u/vulkan.c | 10 +++++++++- include/wine/gdi_driver.h | 11 +++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index 1bb4735587f..707cd82772a 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -1835,7 +1835,12 @@ static VkResult win32u_vkCreateSwapchainKHR( VkDevice client_device, const VkSwa return VK_ERROR_INITIALIZATION_FAILED; } - if (surface) create_info_host.surface = surface->obj.host.surface; + if (surface) + { + create_info_host.surface = surface->obj.host.surface; + if (surface->client && client_surface_grab( surface->client )) + return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR; + } if (old_swapchain) create_info_host.oldSwapchain = old_swapchain->obj.host.swapchain; /* Windows allows client rect to be empty, but host Vulkan often doesn't, adjust extents back to the host capabilities */ @@ -1882,6 +1887,7 @@ void win32u_vkDestroySwapchainKHR( VkDevice client_device, VkSwapchainKHR client 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 ); + struct surface *surface = swapchain->surface; if (allocator) FIXME( "Support for allocation callbacks not implemented yet\n" ); if (!swapchain) return; @@ -1889,6 +1895,8 @@ void win32u_vkDestroySwapchainKHR( VkDevice client_device, VkSwapchainKHR client device->p_vkDestroySwapchainKHR( device->host.device, swapchain->obj.host.swapchain, NULL ); instance->p_remove_object( instance, &swapchain->obj.obj ); + if (surface && surface->client) client_surface_drop( surface->client ); + free( swapchain ); } diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 384fdcac18e..38c61d0a80a 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -263,6 +263,7 @@ struct client_surface const struct client_surface_funcs *funcs; struct list entry; /* entry in win32u managed list */ LONG ref; /* reference count */ + LONG grab_ref; /* underlying WSI is using the surface */ HWND hwnd; /* window the surface was created for */ LONG updated; /* has been moved / resized / reparented */ HWND toplevel; /* toplevel window of the surface */ @@ -279,6 +280,16 @@ W32KAPI void client_surface_update( struct client_surface *surface ); W32KAPI void update_client_surfaces( HWND hwnd ); W32KAPI void detach_client_surfaces( HWND hwnd ); +static inline LONG client_surface_grab( struct client_surface *surface ) +{ + return InterlockedCompareExchange( &surface->grab_ref, 1, 0 ); +} + +static inline LONG client_surface_drop( struct client_surface *surface ) +{ + return InterlockedCompareExchange( &surface->grab_ref, 0, 1 ); +} + static inline const char *debugstr_client_surface( struct client_surface *surface ) { if (!surface) return "(null)"; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11342