From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/vulkan.c | 17 +++++------------ dlls/winemac.drv/vulkan.c | 36 ++++++++++------------------------- dlls/winewayland.drv/vulkan.c | 33 ++++++++++---------------------- dlls/winex11.drv/vulkan.c | 34 +++++++++------------------------ include/wine/vulkan_driver.h | 7 +++---- 5 files changed, 37 insertions(+), 90 deletions(-)
diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index bd039b934ce..5677d02e128 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -52,7 +52,7 @@ static void *(*p_vkGetInstanceProcAddr)(VkInstance, const char *); struct surface { VkSurfaceKHR host_surface; - VkSurfaceKHR driver_surface; + void *driver_private; HWND hwnd; };
@@ -76,14 +76,13 @@ static VkResult win32u_vkCreateWin32SurfaceKHR( VkInstance instance, const VkWin 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->driver_surface ))) + if ((res = driver_funcs->p_vulkan_surface_create( info->hwnd, instance, &surface->host_surface, &surface->driver_private ))) { free( surface ); return res; }
surface->hwnd = info->hwnd; - surface->host_surface = driver_funcs->p_wine_get_host_surface( surface->driver_surface ); *handle = surface_to_handle( surface ); return VK_SUCCESS; } @@ -96,7 +95,7 @@ static void win32u_vkDestroySurfaceKHR( VkInstance instance, VkSurfaceKHR handle if (allocator) FIXME( "Support for allocation callbacks not implemented yet\n" );
p_vkDestroySurfaceKHR( instance, surface->host_surface, NULL /* allocator */ ); - driver_funcs->p_vulkan_surface_destroy( surface->hwnd, surface->driver_surface ); + driver_funcs->p_vulkan_surface_destroy( surface->hwnd, surface->driver_private ); free( surface ); }
@@ -164,13 +163,13 @@ static struct vulkan_funcs vulkan_funcs = .p_wine_get_host_surface = win32u_wine_get_host_surface, };
-static VkResult nulldrv_vulkan_surface_create( HWND hwnd, VkInstance instance, VkSurfaceKHR *surface ) +static VkResult nulldrv_vulkan_surface_create( HWND hwnd, VkInstance instance, VkSurfaceKHR *surface, void **private ) { FIXME( "stub!\n" ); return VK_ERROR_INCOMPATIBLE_DRIVER; }
-static void nulldrv_vulkan_surface_destroy( HWND hwnd, VkSurfaceKHR surface ) +static void nulldrv_vulkan_surface_destroy( HWND hwnd, void *private ) { }
@@ -188,11 +187,6 @@ static const char *nulldrv_get_host_surface_extension(void) return "VK_WINE_nulldrv_surface"; }
-static VkSurfaceKHR nulldrv_wine_get_host_surface( VkSurfaceKHR surface ) -{ - return surface; -} - static const struct vulkan_driver_funcs nulldrv_funcs = { .p_vulkan_surface_create = nulldrv_vulkan_surface_create, @@ -200,7 +194,6 @@ static const struct vulkan_driver_funcs nulldrv_funcs = .p_vulkan_surface_presented = nulldrv_vulkan_surface_presented, .p_vkGetPhysicalDeviceWin32PresentationSupportKHR = nulldrv_vkGetPhysicalDeviceWin32PresentationSupportKHR, .p_get_host_surface_extension = nulldrv_get_host_surface_extension, - .p_wine_get_host_surface = nulldrv_wine_get_host_surface, };
static void vulkan_init(void) diff --git a/dlls/winemac.drv/vulkan.c b/dlls/winemac.drv/vulkan.c index 42e95d91cce..d61e88f60af 100644 --- a/dlls/winemac.drv/vulkan.c +++ b/dlls/winemac.drv/vulkan.c @@ -56,7 +56,6 @@ struct wine_vk_surface { macdrv_metal_device device; macdrv_metal_view view; - VkSurfaceKHR host_surface; /* host surface */ };
typedef struct VkMacOSSurfaceCreateInfoMVK @@ -81,11 +80,6 @@ static VkResult (*pvkGetPhysicalDeviceSurfaceCapabilities2KHR)(VkPhysicalDevice,
static const struct vulkan_driver_funcs macdrv_vulkan_driver_funcs;
-static inline struct wine_vk_surface *surface_from_handle(VkSurfaceKHR handle) -{ - return (struct wine_vk_surface *)(uintptr_t)handle; -} - static void wine_vk_surface_destroy(struct wine_vk_surface *surface) { if (surface->view) @@ -97,13 +91,13 @@ static void wine_vk_surface_destroy(struct wine_vk_surface *surface) free(surface); }
-static VkResult macdrv_vulkan_surface_create(HWND hwnd, VkInstance instance, VkSurfaceKHR *surface) +static VkResult macdrv_vulkan_surface_create(HWND hwnd, VkInstance instance, VkSurfaceKHR *surface, void **private) { VkResult res; struct wine_vk_surface *mac_surface; struct macdrv_win_data *data;
- TRACE("%p %p %p\n", hwnd, instance, surface); + TRACE("%p %p %p %p\n", hwnd, instance, surface, private);
if (!(data = get_win_data(hwnd))) { @@ -144,7 +138,7 @@ static VkResult macdrv_vulkan_surface_create(HWND hwnd, VkInstance instance, VkS create_info_host.flags = 0; /* reserved */ create_info_host.pLayer = macdrv_view_get_metal_layer(mac_surface->view);
- res = pvkCreateMetalSurfaceEXT(instance, &create_info_host, NULL /* allocator */, &mac_surface->host_surface); + res = pvkCreateMetalSurfaceEXT(instance, &create_info_host, NULL /* allocator */, surface); } else { @@ -154,7 +148,7 @@ static VkResult macdrv_vulkan_surface_create(HWND hwnd, VkInstance instance, VkS create_info_host.flags = 0; /* reserved */ create_info_host.pView = macdrv_view_get_metal_layer(mac_surface->view);
- res = pvkCreateMacOSSurfaceMVK(instance, &create_info_host, NULL /* allocator */, &mac_surface->host_surface); + res = pvkCreateMacOSSurfaceMVK(instance, &create_info_host, NULL /* allocator */, surface); } if (res != VK_SUCCESS) { @@ -162,11 +156,11 @@ static VkResult macdrv_vulkan_surface_create(HWND hwnd, VkInstance instance, VkS goto err; }
- *surface = (uintptr_t)mac_surface; - release_win_data(data);
- TRACE("Created surface=0x%s\n", wine_dbgstr_longlong(*surface)); + *private = mac_surface; + + TRACE("Created surface=0x%s, private=%p\n", wine_dbgstr_longlong(*surface), *private); return VK_SUCCESS;
err: @@ -175,11 +169,11 @@ err: return res; }
-static void macdrv_vulkan_surface_destroy(HWND hwnd, VkSurfaceKHR surface) +static void macdrv_vulkan_surface_destroy(HWND hwnd, void *private) { - struct wine_vk_surface *mac_surface = surface_from_handle(surface); + struct wine_vk_surface *mac_surface = private;
- TRACE("%p 0x%s\n", hwnd, wine_dbgstr_longlong(surface)); + TRACE("%p %p\n", hwnd, private);
wine_vk_surface_destroy(mac_surface); } @@ -201,15 +195,6 @@ static const char *macdrv_get_host_surface_extension(void) return pvkCreateMetalSurfaceEXT ? "VK_EXT_metal_surface" : "VK_MVK_macos_surface"; }
-static VkSurfaceKHR macdrv_wine_get_host_surface(VkSurfaceKHR surface) -{ - struct wine_vk_surface *mac_surface = surface_from_handle(surface); - - TRACE("0x%s\n", wine_dbgstr_longlong(surface)); - - return mac_surface->host_surface; -} - static const struct vulkan_driver_funcs macdrv_vulkan_driver_funcs = { .p_vulkan_surface_create = macdrv_vulkan_surface_create, @@ -218,7 +203,6 @@ static const struct vulkan_driver_funcs macdrv_vulkan_driver_funcs =
.p_vkGetPhysicalDeviceWin32PresentationSupportKHR = macdrv_vkGetPhysicalDeviceWin32PresentationSupportKHR, .p_get_host_surface_extension = macdrv_get_host_surface_extension, - .p_wine_get_host_surface = macdrv_wine_get_host_surface, };
UINT macdrv_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs) diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index 403da808fb5..c47277d8e5d 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -61,14 +61,8 @@ static const struct vulkan_driver_funcs wayland_vulkan_driver_funcs; struct wine_vk_surface { struct wayland_client_surface *client; - VkSurfaceKHR host_surface; };
-static struct wine_vk_surface *wine_vk_surface_from_handle(VkSurfaceKHR handle) -{ - return (struct wine_vk_surface *)(uintptr_t)handle; -} - static HWND wine_vk_surface_get_hwnd(struct wine_vk_surface *wine_vk_surface) { return wl_surface_get_user_data(wine_vk_surface->client->wl_surface); @@ -93,21 +87,20 @@ static void wine_vk_surface_destroy(struct wine_vk_surface *wine_vk_surface) free(wine_vk_surface); }
-static VkResult wayland_vulkan_surface_create(HWND hwnd, VkInstance instance, VkSurfaceKHR *vk_surface) +static VkResult wayland_vulkan_surface_create(HWND hwnd, VkInstance instance, VkSurfaceKHR *surface, void **private) { VkResult res; VkWaylandSurfaceCreateInfoKHR create_info_host; struct wine_vk_surface *wine_vk_surface; struct wayland_surface *wayland_surface;
- TRACE("%p %p %p\n", hwnd, instance, vk_surface); + TRACE("%p %p %p %p\n", hwnd, instance, surface, private);
wine_vk_surface = calloc(1, sizeof(*wine_vk_surface)); if (!wine_vk_surface) { ERR("Failed to allocate memory for wayland vulkan surface\n"); - res = VK_ERROR_OUT_OF_HOST_MEMORY; - goto err; + return VK_ERROR_OUT_OF_HOST_MEMORY; }
wayland_surface = wayland_surface_lock_hwnd(hwnd); @@ -138,28 +131,28 @@ static VkResult wayland_vulkan_surface_create(HWND hwnd, VkInstance instance, Vk
res = pvkCreateWaylandSurfaceKHR(instance, &create_info_host, NULL /* allocator */, - &wine_vk_surface->host_surface); + surface); if (res != VK_SUCCESS) { ERR("Failed to create vulkan wayland surface, res=%d\n", res); goto err; }
- *vk_surface = (uintptr_t)wine_vk_surface; + *private = wine_vk_surface;
- TRACE("Created surface=0x%s\n", wine_dbgstr_longlong(*vk_surface)); + TRACE("Created surface=0x%s, private=%p\n", wine_dbgstr_longlong(*surface), *private); return VK_SUCCESS;
err: - if (wine_vk_surface) wine_vk_surface_destroy(wine_vk_surface); + wine_vk_surface_destroy(wine_vk_surface); return res; }
-static void wayland_vulkan_surface_destroy(HWND hwnd, VkSurfaceKHR surface) +static void wayland_vulkan_surface_destroy(HWND hwnd, void *private) { - struct wine_vk_surface *wine_vk_surface = wine_vk_surface_from_handle(surface); + struct wine_vk_surface *wine_vk_surface = private;
- TRACE("%p 0x%s\n", hwnd, wine_dbgstr_longlong(surface)); + TRACE("%p %p\n", hwnd, private);
wine_vk_surface_destroy(wine_vk_surface); } @@ -199,11 +192,6 @@ static const char *wayland_get_host_surface_extension(void) return "VK_KHR_wayland_surface"; }
-static VkSurfaceKHR wayland_wine_get_host_surface(VkSurfaceKHR surface) -{ - return wine_vk_surface_from_handle(surface)->host_surface; -} - static const struct vulkan_driver_funcs wayland_vulkan_driver_funcs = { .p_vulkan_surface_create = wayland_vulkan_surface_create, @@ -212,7 +200,6 @@ static const struct vulkan_driver_funcs wayland_vulkan_driver_funcs =
.p_vkGetPhysicalDeviceWin32PresentationSupportKHR = wayland_vkGetPhysicalDeviceWin32PresentationSupportKHR, .p_get_host_surface_extension = wayland_get_host_surface_extension, - .p_wine_get_host_surface = wayland_wine_get_host_surface, };
/********************************************************************** diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index a49afd32a2c..baf54c28781 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -59,7 +59,6 @@ struct wine_vk_surface LONG ref; struct list entry; Window window; - VkSurfaceKHR host_surface; HWND hwnd; DWORD hwnd_thread_id; }; @@ -78,11 +77,6 @@ static VkBool32 (*pvkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevi
static const struct vulkan_driver_funcs x11drv_vulkan_driver_funcs;
-static inline struct wine_vk_surface *surface_from_handle(VkSurfaceKHR handle) -{ - return (struct wine_vk_surface *)(uintptr_t)handle; -} - static void wine_vk_surface_release( struct wine_vk_surface *surface ) { if (InterlockedDecrement(&surface->ref)) @@ -131,13 +125,13 @@ void vulkan_thread_detach(void) pthread_mutex_unlock(&vulkan_mutex); }
-static VkResult X11DRV_vulkan_surface_create( HWND hwnd, VkInstance instance, VkSurfaceKHR *surface ) +static VkResult X11DRV_vulkan_surface_create( HWND hwnd, VkInstance instance, VkSurfaceKHR *surface, void **private ) { VkResult res; VkXlibSurfaceCreateInfoKHR create_info_host; struct wine_vk_surface *x11_surface;
- TRACE( "%p %p %p\n", hwnd, instance, surface ); + TRACE( "%p %p %p %p\n", hwnd, instance, surface, private );
/* TODO: support child window rendering. */ if (NtUserGetAncestor( hwnd, GA_PARENT ) != NtUserGetDesktopWindow()) @@ -157,7 +151,7 @@ static VkResult X11DRV_vulkan_surface_create( HWND hwnd, VkInstance instance, Vk
if (!x11_surface->window) { - ERR( "Failed to allocate client window for hwnd=%p\n", hwnd ); + ERR("Failed to allocate client window for hwnd=%p\n", hwnd);
/* VK_KHR_win32_surface only allows out of host and device memory as errors. */ free(x11_surface); @@ -170,7 +164,7 @@ static VkResult X11DRV_vulkan_surface_create( HWND hwnd, VkInstance instance, Vk create_info_host.dpy = gdi_display; create_info_host.window = x11_surface->window;
- res = pvkCreateXlibSurfaceKHR( instance, &create_info_host, NULL /* allocator */, &x11_surface->host_surface ); + res = pvkCreateXlibSurfaceKHR( instance, &create_info_host, NULL /* allocator */, surface ); if (res != VK_SUCCESS) { ERR("Failed to create Xlib surface, res=%d\n", res); @@ -183,17 +177,17 @@ static VkResult X11DRV_vulkan_surface_create( HWND hwnd, VkInstance instance, Vk list_add_tail(&surface_list, &x11_surface->entry); pthread_mutex_unlock(&vulkan_mutex);
- *surface = (uintptr_t)x11_surface; + *private = x11_surface;
- TRACE("Created surface=0x%s\n", wine_dbgstr_longlong(*surface)); + TRACE("Created surface 0x%s, private %p\n", wine_dbgstr_longlong(*surface), *private); return VK_SUCCESS; }
-static void X11DRV_vulkan_surface_destroy( HWND hwnd, VkSurfaceKHR surface ) +static void X11DRV_vulkan_surface_destroy( HWND hwnd, void *private ) { - struct wine_vk_surface *x11_surface = surface_from_handle(surface); + struct wine_vk_surface *x11_surface = private;
- TRACE( "%p 0x%s\n", hwnd, wine_dbgstr_longlong(surface) ); + TRACE( "%p %p\n", hwnd, private );
wine_vk_surface_release(x11_surface); } @@ -216,15 +210,6 @@ static const char *X11DRV_get_host_surface_extension(void) return "VK_KHR_xlib_surface"; }
-static VkSurfaceKHR X11DRV_wine_get_host_surface( VkSurfaceKHR surface ) -{ - struct wine_vk_surface *x11_surface = surface_from_handle(surface); - - TRACE("0x%s\n", wine_dbgstr_longlong(surface)); - - return x11_surface->host_surface; -} - static const struct vulkan_driver_funcs x11drv_vulkan_driver_funcs = { .p_vulkan_surface_create = X11DRV_vulkan_surface_create, @@ -233,7 +218,6 @@ static const struct vulkan_driver_funcs x11drv_vulkan_driver_funcs =
.p_vkGetPhysicalDeviceWin32PresentationSupportKHR = X11DRV_vkGetPhysicalDeviceWin32PresentationSupportKHR, .p_get_host_surface_extension = X11DRV_get_host_surface_extension, - .p_wine_get_host_surface = X11DRV_wine_get_host_surface, };
UINT X11DRV_VulkanInit( UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs ) diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h index 20931374ce2..c5b2f82234a 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 32 +#define WINE_VULKAN_DRIVER_VERSION 33
struct vulkan_funcs { @@ -44,13 +44,12 @@ struct vulkan_funcs /* interface between win32u and the user drivers */ struct vulkan_driver_funcs { - VkResult (*p_vulkan_surface_create)(HWND, VkInstance, VkSurfaceKHR *); - void (*p_vulkan_surface_destroy)(HWND, VkSurfaceKHR); + VkResult (*p_vulkan_surface_create)(HWND, VkInstance, VkSurfaceKHR *, void **); + void (*p_vulkan_surface_destroy)(HWND, void *); void (*p_vulkan_surface_presented)(HWND, VkResult);
VkBool32 (*p_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice, uint32_t); const char *(*p_get_host_surface_extension)(void); - VkSurfaceKHR (*p_wine_get_host_surface)(VkSurfaceKHR); };
#endif /* __WINE_VULKAN_DRIVER_H */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/vulkan.c | 65 +++++++++++------------------------ 1 file changed, 20 insertions(+), 45 deletions(-)
diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index c47277d8e5d..4312d9b5e59 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -58,76 +58,54 @@ static VkBool32 (*pvkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalD
static const struct vulkan_driver_funcs wayland_vulkan_driver_funcs;
-struct wine_vk_surface +static HWND wine_vk_surface_get_hwnd(struct wayland_client_surface *client) { - struct wayland_client_surface *client; -}; - -static HWND wine_vk_surface_get_hwnd(struct wine_vk_surface *wine_vk_surface) -{ - return wl_surface_get_user_data(wine_vk_surface->client->wl_surface); + return wl_surface_get_user_data(client->wl_surface); }
-static void wine_vk_surface_destroy(struct wine_vk_surface *wine_vk_surface) +static void wine_vk_surface_destroy(struct wayland_client_surface *client) { - if (wine_vk_surface->client) - { - HWND hwnd = wine_vk_surface_get_hwnd(wine_vk_surface); - struct wayland_surface *wayland_surface = wayland_surface_lock_hwnd(hwnd); + HWND hwnd = wine_vk_surface_get_hwnd(client); + struct wayland_surface *wayland_surface = wayland_surface_lock_hwnd(hwnd);
- if (wayland_client_surface_release(wine_vk_surface->client) && - wayland_surface) - { - wayland_surface->client = NULL; - } - - if (wayland_surface) pthread_mutex_unlock(&wayland_surface->mutex); + if (wayland_client_surface_release(client) && wayland_surface) + { + wayland_surface->client = NULL; }
- free(wine_vk_surface); + if (wayland_surface) pthread_mutex_unlock(&wayland_surface->mutex); }
static VkResult wayland_vulkan_surface_create(HWND hwnd, VkInstance instance, VkSurfaceKHR *surface, void **private) { VkResult res; VkWaylandSurfaceCreateInfoKHR create_info_host; - struct wine_vk_surface *wine_vk_surface; struct wayland_surface *wayland_surface; + struct wayland_client_surface *client;
TRACE("%p %p %p %p\n", hwnd, instance, surface, private);
- wine_vk_surface = calloc(1, sizeof(*wine_vk_surface)); - if (!wine_vk_surface) - { - ERR("Failed to allocate memory for wayland vulkan surface\n"); - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - wayland_surface = wayland_surface_lock_hwnd(hwnd); if (!wayland_surface) { ERR("Failed to find wayland surface for hwnd=%p\n", hwnd); - /* VK_KHR_win32_surface only allows out of host and device memory as errors. */ - res = VK_ERROR_OUT_OF_HOST_MEMORY; - goto err; + return VK_ERROR_OUT_OF_HOST_MEMORY; }
- wine_vk_surface->client = wayland_surface_get_client(wayland_surface); + client = wayland_surface_get_client(wayland_surface); pthread_mutex_unlock(&wayland_surface->mutex);
- if (!wine_vk_surface->client) + if (!client) { ERR("Failed to create client surface for hwnd=%p\n", hwnd); - /* VK_KHR_win32_surface only allows out of host and device memory as errors. */ - res = VK_ERROR_OUT_OF_HOST_MEMORY; - goto err; + return VK_ERROR_OUT_OF_HOST_MEMORY; }
create_info_host.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; create_info_host.pNext = NULL; create_info_host.flags = 0; /* reserved */ create_info_host.display = process_wayland.wl_display; - create_info_host.surface = wine_vk_surface->client->wl_surface; + create_info_host.surface = client->wl_surface;
res = pvkCreateWaylandSurfaceKHR(instance, &create_info_host, NULL /* allocator */, @@ -135,26 +113,23 @@ static VkResult wayland_vulkan_surface_create(HWND hwnd, VkInstance instance, Vk if (res != VK_SUCCESS) { ERR("Failed to create vulkan wayland surface, res=%d\n", res); - goto err; + wine_vk_surface_destroy(client); + return res; }
- *private = wine_vk_surface; + *private = client;
TRACE("Created surface=0x%s, private=%p\n", wine_dbgstr_longlong(*surface), *private); return VK_SUCCESS; - -err: - wine_vk_surface_destroy(wine_vk_surface); - return res; }
static void wayland_vulkan_surface_destroy(HWND hwnd, void *private) { - struct wine_vk_surface *wine_vk_surface = private; + struct wayland_client_surface *client = private;
TRACE("%p %p\n", hwnd, private);
- wine_vk_surface_destroy(wine_vk_surface); + wine_vk_surface_destroy(client); }
static void wayland_vulkan_surface_presented(HWND hwnd, VkResult result)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/ntuser_private.h | 4 ++++ dlls/win32u/vulkan.c | 23 +++++++++++++++++++++++ dlls/win32u/window.c | 3 +++ 3 files changed, 30 insertions(+)
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index bb2169998b6..b41599e34e5 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -77,6 +77,7 @@ typedef struct tagWND UINT dpi; /* window DPI */ DPI_AWARENESS dpi_awareness; /* DPI awareness */ struct window_surface *surface; /* Window surface if any */ + struct list vulkan_surfaces; /* list of vulkan surfaces created for this window */ struct tagDIALOGINFO *dlgInfo; /* Dialog additional info (dialogs only) */ int pixel_format; /* Pixel format set by the graphics driver */ int internal_pixel_format; /* Internal pixel format set via WGL_WINE_pixel_format_passthrough */ @@ -254,6 +255,9 @@ extern BOOL set_keyboard_auto_repeat( BOOL enable ); /* systray.c */ extern LRESULT system_tray_call( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, void *data );
+/* vulkan.c */ +extern void vulkan_window_detach( WND *win ); + /* window.c */ HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type ); void *free_user_handle( HANDLE handle, unsigned int type ); diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index 5677d02e128..5a990d10bfd 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -30,6 +30,7 @@ #include "ntstatus.h" #define WIN32_NO_STATUS #include "win32u_private.h" +#include "ntuser_private.h"
#define VK_NO_PROTOTYPES #define WINE_VK_HOST @@ -51,6 +52,7 @@ static void *(*p_vkGetInstanceProcAddr)(VkInstance, const char *);
struct surface { + struct list entry; VkSurfaceKHR host_surface; void *driver_private; HWND hwnd; @@ -71,6 +73,7 @@ static VkResult win32u_vkCreateWin32SurfaceKHR( VkInstance instance, const VkWin { struct surface *surface; VkResult res; + WND *win;
TRACE( "instance %p, info %p, allocator %p, handle %p\n", instance, info, allocator, handle ); if (allocator) FIXME( "Support for allocation callbacks not implemented yet\n" ); @@ -82,6 +85,14 @@ static VkResult win32u_vkCreateWin32SurfaceKHR( VkInstance instance, const VkWin return res; }
+ if (!(win = get_win_ptr( info->hwnd )) || win == WND_DESKTOP || win == WND_OTHER_PROCESS) + list_init( &surface->entry ); + else + { + list_add_tail( &win->vulkan_surfaces, &surface->entry ); + release_win_ptr( win ); + } + surface->hwnd = info->hwnd; *handle = surface_to_handle( surface ); return VK_SUCCESS; @@ -94,6 +105,7 @@ static void win32u_vkDestroySurfaceKHR( VkInstance instance, VkSurfaceKHR handle TRACE( "instance %p, handle 0x%s, allocator %p\n", instance, wine_dbgstr_longlong(handle), allocator ); if (allocator) FIXME( "Support for allocation callbacks not implemented yet\n" );
+ list_remove( &surface->entry ); p_vkDestroySurfaceKHR( instance, surface->host_surface, NULL /* allocator */ ); driver_funcs->p_vulkan_surface_destroy( surface->hwnd, surface->driver_private ); free( surface ); @@ -239,6 +251,17 @@ static void vulkan_init(void) #undef LOAD_FUNCPTR }
+void vulkan_window_detach( WND *win ) +{ + struct surface *surface; + + LIST_FOR_EACH_ENTRY( surface, &win->vulkan_surfaces, struct surface, entry ) + { + list_remove( &surface->entry ); + list_init( &surface->entry ); + } +} + /*********************************************************************** * __wine_get_vulkan_driver (win32u.so) */ diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 73a0fa9e896..8357be6b43e 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -4763,6 +4763,7 @@ LRESULT destroy_window( HWND hwnd ) window_surface_release( surface ); }
+ vulkan_window_detach( win ); user_driver->pDestroyWindow( hwnd );
free_window_handle( hwnd ); @@ -4864,6 +4865,7 @@ void destroy_thread_windows(void) while ((win = next_process_user_handle_ptr( &handle, NTUSER_OBJ_WINDOW ))) { if (win->tid != GetCurrentThreadId()) continue; + vulkan_window_detach( win ); free_dce( win->dce, win->obj.handle ); set_user_handle_ptr( handle, NULL ); win->obj.handle = free_list; @@ -4987,6 +4989,7 @@ static WND *create_window_handle( HWND parent, HWND owner, UNICODE_STRING *name, win->cbWndExtra = extra_bytes; win->dpi = dpi; win->dpi_awareness = awareness; + list_init( &win->vulkan_surfaces ); set_user_handle_ptr( handle, &win->obj ); if (is_winproc_unicode( win->winproc, !ansi )) win->flags |= WIN_ISUNICODE; return win;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/vulkan.c | 6 +++++ dlls/winemac.drv/vulkan.c | 5 +++++ dlls/winewayland.drv/vulkan.c | 5 +++++ dlls/winex11.drv/vulkan.c | 41 +++++++++++++--------------------- dlls/winex11.drv/window.c | 3 +-- dlls/winex11.drv/x11drv.h | 2 +- dlls/winex11.drv/x11drv_main.c | 1 - include/wine/vulkan_driver.h | 3 ++- 8 files changed, 35 insertions(+), 31 deletions(-)
diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index 5a990d10bfd..fc15515c5e8 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -185,6 +185,10 @@ static void nulldrv_vulkan_surface_destroy( HWND hwnd, void *private ) { }
+static void nulldrv_vulkan_surface_detach( HWND hwnd, void *private ) +{ +} + static void nulldrv_vulkan_surface_presented( HWND hwnd, VkResult result ) { } @@ -203,6 +207,7 @@ static const struct vulkan_driver_funcs nulldrv_funcs = { .p_vulkan_surface_create = nulldrv_vulkan_surface_create, .p_vulkan_surface_destroy = nulldrv_vulkan_surface_destroy, + .p_vulkan_surface_detach = nulldrv_vulkan_surface_detach, .p_vulkan_surface_presented = nulldrv_vulkan_surface_presented, .p_vkGetPhysicalDeviceWin32PresentationSupportKHR = nulldrv_vkGetPhysicalDeviceWin32PresentationSupportKHR, .p_get_host_surface_extension = nulldrv_get_host_surface_extension, @@ -257,6 +262,7 @@ void vulkan_window_detach( WND *win )
LIST_FOR_EACH_ENTRY( surface, &win->vulkan_surfaces, struct surface, entry ) { + driver_funcs->p_vulkan_surface_detach( surface->hwnd, surface->driver_private ); list_remove( &surface->entry ); list_init( &surface->entry ); } diff --git a/dlls/winemac.drv/vulkan.c b/dlls/winemac.drv/vulkan.c index d61e88f60af..d5a3df579d0 100644 --- a/dlls/winemac.drv/vulkan.c +++ b/dlls/winemac.drv/vulkan.c @@ -178,6 +178,10 @@ static void macdrv_vulkan_surface_destroy(HWND hwnd, void *private) wine_vk_surface_destroy(mac_surface); }
+static void macdrv_vulkan_surface_detach(HWND hwnd, void *private) +{ +} + static void macdrv_vulkan_surface_presented(HWND hwnd, VkResult result) { } @@ -199,6 +203,7 @@ static const struct vulkan_driver_funcs macdrv_vulkan_driver_funcs = { .p_vulkan_surface_create = macdrv_vulkan_surface_create, .p_vulkan_surface_destroy = macdrv_vulkan_surface_destroy, + .p_vulkan_surface_detach = macdrv_vulkan_surface_detach, .p_vulkan_surface_presented = macdrv_vulkan_surface_presented,
.p_vkGetPhysicalDeviceWin32PresentationSupportKHR = macdrv_vkGetPhysicalDeviceWin32PresentationSupportKHR, diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index 4312d9b5e59..16084175013 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -132,6 +132,10 @@ static void wayland_vulkan_surface_destroy(HWND hwnd, void *private) wine_vk_surface_destroy(client); }
+static void wayland_vulkan_surface_detach(HWND hwnd, void *private) +{ +} + static void wayland_vulkan_surface_presented(HWND hwnd, VkResult result) { struct wayland_surface *wayland_surface; @@ -171,6 +175,7 @@ static const struct vulkan_driver_funcs wayland_vulkan_driver_funcs = { .p_vulkan_surface_create = wayland_vulkan_surface_create, .p_vulkan_surface_destroy = wayland_vulkan_surface_destroy, + .p_vulkan_surface_detach = wayland_vulkan_surface_detach, .p_vulkan_surface_presented = wayland_vulkan_surface_presented,
.p_vkGetPhysicalDeviceWin32PresentationSupportKHR = wayland_vkGetPhysicalDeviceWin32PresentationSupportKHR, diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index baf54c28781..fbe0f6a87ab 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -107,24 +107,6 @@ void destroy_vk_surface( HWND hwnd ) pthread_mutex_unlock( &vulkan_mutex ); }
-void vulkan_thread_detach(void) -{ - struct wine_vk_surface *surface, *next; - DWORD thread_id = GetCurrentThreadId(); - - pthread_mutex_lock(&vulkan_mutex); - LIST_FOR_EACH_ENTRY_SAFE(surface, next, &surface_list, struct wine_vk_surface, entry) - { - if (surface->hwnd_thread_id != thread_id) - continue; - - TRACE("Detaching surface %p, hwnd %p.\n", surface, surface->hwnd); - XReparentWindow(gdi_display, surface->window, get_dummy_parent(), 0, 0); - XSync(gdi_display, False); - } - pthread_mutex_unlock(&vulkan_mutex); -} - static VkResult X11DRV_vulkan_surface_create( HWND hwnd, VkInstance instance, VkSurfaceKHR *surface, void **private ) { VkResult res; @@ -192,6 +174,20 @@ static void X11DRV_vulkan_surface_destroy( HWND hwnd, void *private ) wine_vk_surface_release(x11_surface); }
+static void X11DRV_vulkan_surface_detach( HWND hwnd, void *private ) +{ + struct wine_vk_surface *x11_surface = private; + struct x11drv_win_data *data; + + TRACE( "%p %p\n", hwnd, private ); + + if ((data = get_win_data( hwnd ))) + { + detach_client_window( data, x11_surface->window ); + release_win_data( data ); + } +} + static void X11DRV_vulkan_surface_presented(HWND hwnd, VkResult result) { } @@ -214,6 +210,7 @@ static const struct vulkan_driver_funcs x11drv_vulkan_driver_funcs = { .p_vulkan_surface_create = X11DRV_vulkan_surface_create, .p_vulkan_surface_destroy = X11DRV_vulkan_surface_destroy, + .p_vulkan_surface_detach = X11DRV_vulkan_surface_detach, .p_vulkan_surface_presented = X11DRV_vulkan_surface_presented,
.p_vkGetPhysicalDeviceWin32PresentationSupportKHR = X11DRV_vkGetPhysicalDeviceWin32PresentationSupportKHR, @@ -247,12 +244,4 @@ UINT X11DRV_VulkanInit( UINT version, void *vulkan_handle, const struct vulkan_d return STATUS_NOT_IMPLEMENTED; }
-void destroy_vk_surface( HWND hwnd ) -{ -} - -void vulkan_thread_detach(void) -{ -} - #endif /* SONAME_LIBVULKAN */ diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 26cfee427ab..921318e81a0 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1604,7 +1604,7 @@ static void client_window_events_disable( struct x11drv_win_data *data, Window c /********************************************************************** * detach_client_window */ -static void detach_client_window( struct x11drv_win_data *data, Window client_window ) +void detach_client_window( struct x11drv_win_data *data, Window client_window ) { if (data->client_window != client_window || !client_window) return;
@@ -1940,7 +1940,6 @@ void X11DRV_DestroyWindow( HWND hwnd ) release_win_data( data ); free( data ); destroy_gl_drawable( hwnd ); - destroy_vk_surface( hwnd ); }
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index c308f54adb3..1e13122076c 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -641,7 +641,6 @@ extern void sync_gl_drawable( HWND hwnd, BOOL known_child ); extern void set_gl_drawable_parent( HWND hwnd, HWND parent ); extern void destroy_gl_drawable( HWND hwnd ); extern void destroy_vk_surface( HWND hwnd ); -extern void vulkan_thread_detach(void);
extern void wait_for_withdrawn_state( HWND hwnd, BOOL set ); extern Window init_clip_window(void); @@ -650,6 +649,7 @@ extern void read_net_wm_states( Display *display, struct x11drv_win_data *data ) extern void update_net_wm_states( struct x11drv_win_data *data ); extern void make_window_embedded( struct x11drv_win_data *data ); extern Window create_client_window( HWND hwnd, const XVisualInfo *visual, Colormap colormap ); +extern void detach_client_window( struct x11drv_win_data *data, Window client_window ); extern void destroy_client_window( HWND hwnd, Window client_window ); extern void set_window_visual( struct x11drv_win_data *data, const XVisualInfo *vis, BOOL use_alpha ); extern void change_systray_owner( Display *display, Window systray_window ); diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 4c8fd943ffd..180573128e7 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -696,7 +696,6 @@ void X11DRV_ThreadDetach(void)
if (data) { - vulkan_thread_detach(); if (data->xim) XCloseIM( data->xim ); if (data->font_set) XFreeFontSet( data->display, data->font_set ); XSync( gdi_display, False ); /* make sure XReparentWindow requests have completed before closing the thread display */ diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h index c5b2f82234a..7ddba4739f4 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 33 +#define WINE_VULKAN_DRIVER_VERSION 34
struct vulkan_funcs { @@ -46,6 +46,7 @@ struct vulkan_driver_funcs { VkResult (*p_vulkan_surface_create)(HWND, VkInstance, VkSurfaceKHR *, void **); void (*p_vulkan_surface_destroy)(HWND, void *); + void (*p_vulkan_surface_detach)(HWND, void *); void (*p_vulkan_surface_presented)(HWND, VkResult);
VkBool32 (*p_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice, uint32_t);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/vulkan.c | 97 ++++++--------------------------------- 1 file changed, 15 insertions(+), 82 deletions(-)
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index fbe0f6a87ab..85993bc517a 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -48,21 +48,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
#ifdef SONAME_LIBVULKAN
-static pthread_mutex_t vulkan_mutex; - #define VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR 1000004000
-static struct list surface_list = LIST_INIT( surface_list ); - -struct wine_vk_surface -{ - LONG ref; - struct list entry; - Window window; - HWND hwnd; - DWORD hwnd_thread_id; -}; - typedef struct VkXlibSurfaceCreateInfoKHR { VkStructureType sType; @@ -77,41 +64,13 @@ static VkBool32 (*pvkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevi
static const struct vulkan_driver_funcs x11drv_vulkan_driver_funcs;
-static void wine_vk_surface_release( struct wine_vk_surface *surface ) -{ - if (InterlockedDecrement(&surface->ref)) - return; - - if (surface->entry.next) - { - pthread_mutex_lock(&vulkan_mutex); - list_remove(&surface->entry); - pthread_mutex_unlock(&vulkan_mutex); - } - - destroy_client_window( surface->hwnd, surface->window ); - free(surface); -} - -void destroy_vk_surface( HWND hwnd ) -{ - struct wine_vk_surface *surface, *next; - - pthread_mutex_lock( &vulkan_mutex ); - LIST_FOR_EACH_ENTRY_SAFE( surface, next, &surface_list, struct wine_vk_surface, entry ) - { - if (surface->hwnd != hwnd) continue; - surface->hwnd_thread_id = 0; - surface->hwnd = NULL; - } - pthread_mutex_unlock( &vulkan_mutex ); -} - static VkResult X11DRV_vulkan_surface_create( HWND hwnd, VkInstance instance, VkSurfaceKHR *surface, void **private ) { - VkResult res; - VkXlibSurfaceCreateInfoKHR create_info_host; - struct wine_vk_surface *x11_surface; + VkXlibSurfaceCreateInfoKHR info = + { + .sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, + .dpy = gdi_display, + };
TRACE( "%p %p %p %p\n", hwnd, instance, surface, private );
@@ -122,44 +81,20 @@ static VkResult X11DRV_vulkan_surface_create( HWND hwnd, VkInstance instance, Vk return VK_ERROR_INCOMPATIBLE_DRIVER; }
- x11_surface = calloc(1, sizeof(*x11_surface)); - if (!x11_surface) - return VK_ERROR_OUT_OF_HOST_MEMORY; - - x11_surface->ref = 1; - x11_surface->hwnd = hwnd; - x11_surface->window = create_client_window( hwnd, &default_visual, default_colormap ); - x11_surface->hwnd_thread_id = NtUserGetWindowThread( x11_surface->hwnd, NULL ); - - if (!x11_surface->window) + if (!(info.window = create_client_window( hwnd, &default_visual, default_colormap ))) { ERR("Failed to allocate client window for hwnd=%p\n", hwnd); - - /* VK_KHR_win32_surface only allows out of host and device memory as errors. */ - free(x11_surface); return VK_ERROR_OUT_OF_HOST_MEMORY; }
- create_info_host.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; - create_info_host.pNext = NULL; - create_info_host.flags = 0; /* reserved */ - create_info_host.dpy = gdi_display; - create_info_host.window = x11_surface->window; - - res = pvkCreateXlibSurfaceKHR( instance, &create_info_host, NULL /* allocator */, surface ); - if (res != VK_SUCCESS) + if (pvkCreateXlibSurfaceKHR( instance, &info, NULL /* allocator */, surface )) { - ERR("Failed to create Xlib surface, res=%d\n", res); - destroy_client_window( x11_surface->hwnd, x11_surface->window ); - free(x11_surface); - return res; + ERR("Failed to create Xlib surface\n"); + destroy_client_window( hwnd, info.window ); + return VK_ERROR_OUT_OF_HOST_MEMORY; }
- pthread_mutex_lock(&vulkan_mutex); - list_add_tail(&surface_list, &x11_surface->entry); - pthread_mutex_unlock(&vulkan_mutex); - - *private = x11_surface; + *private = (void *)info.window;
TRACE("Created surface 0x%s, private %p\n", wine_dbgstr_longlong(*surface), *private); return VK_SUCCESS; @@ -167,23 +102,23 @@ static VkResult X11DRV_vulkan_surface_create( HWND hwnd, VkInstance instance, Vk
static void X11DRV_vulkan_surface_destroy( HWND hwnd, void *private ) { - struct wine_vk_surface *x11_surface = private; + Window client_window = (Window)private;
TRACE( "%p %p\n", hwnd, private );
- wine_vk_surface_release(x11_surface); + destroy_client_window( hwnd, client_window ); }
static void X11DRV_vulkan_surface_detach( HWND hwnd, void *private ) { - struct wine_vk_surface *x11_surface = private; + Window client_window = (Window)private; struct x11drv_win_data *data;
TRACE( "%p %p\n", hwnd, private );
if ((data = get_win_data( hwnd ))) { - detach_client_window( data, x11_surface->window ); + detach_client_window( data, client_window ); release_win_data( data ); } } @@ -225,8 +160,6 @@ UINT X11DRV_VulkanInit( UINT version, void *vulkan_handle, const struct vulkan_d return STATUS_INVALID_PARAMETER; }
- init_recursive_mutex( &vulkan_mutex ); - #define LOAD_FUNCPTR( f ) if (!(p##f = dlsym( vulkan_handle, #f ))) return STATUS_PROCEDURE_NOT_FOUND; LOAD_FUNCPTR( vkCreateXlibSurfaceKHR ); LOAD_FUNCPTR( vkGetPhysicalDeviceXlibPresentationSupportKHR );
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=145256
Your paranoid android.
=== debian11b (64 bit WoW report) ===
vulkan-1: vulkan: Timeout
That, combined with the next patch, will call the driver with user lock hold. Unless I'm missing something, it should be fine to move that to the destructor loop bellow.
On Mon Apr 29 15:26:39 2024 +0000, Jacek Caban wrote:
That, combined with the next patch, will call the driver with user lock hold. Unless I'm missing something, it should be fine to move that to the destructor loop bellow.
Right, I missed that other loop. Will change, thanks.