win32u: Introduce a distinct vulkan interface between win32u and the user drivers.

This commit is contained in:
Rémi Bernon 2024-02-24 12:54:14 +01:00 committed by Alexandre Julliard
parent 798f158a60
commit 46713b03a7
10 changed files with 140 additions and 78 deletions

View file

@ -897,7 +897,7 @@ static BOOL nulldrv_SystemParametersInfo( UINT action, UINT int_param, void *ptr
return FALSE;
}
static UINT nulldrv_VulkanInit( UINT version, void *vulkan_handle, struct vulkan_funcs *vulkan_funcs )
static UINT nulldrv_VulkanInit( UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs )
{
return STATUS_NOT_IMPLEMENTED;
}
@ -1213,9 +1213,9 @@ static BOOL loaderdrv_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWI
return load_driver()->pUpdateLayeredWindow( hwnd, info, window_rect );
}
static UINT loaderdrv_VulkanInit( UINT version, void *vulkan_handle, struct vulkan_funcs *vulkan_funcs )
static UINT loaderdrv_VulkanInit( UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs )
{
return load_driver()->pVulkanInit( version, vulkan_handle, vulkan_funcs );
return load_driver()->pVulkanInit( version, vulkan_handle, driver_funcs );
}
static const struct user_driver_funcs lazy_load_driver =

View file

@ -41,6 +41,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
#ifdef SONAME_LIBVULKAN
static void *vulkan_handle;
static const struct vulkan_driver_funcs *driver_funcs;
static struct vulkan_funcs vulkan_funcs;
static VkResult (*p_vkQueuePresentKHR)(VkQueue, const VkPresentInfoKHR *);
@ -60,7 +61,7 @@ static VkResult win32u_vkQueuePresentKHR( VkQueue queue, const VkPresentInfoKHR
for (i = 0; i < present_info->swapchainCount; i++)
{
VkResult swapchain_res = present_info->pResults ? present_info->pResults[i] : res;
vulkan_funcs.p_vulkan_surface_presented( surfaces[i], swapchain_res );
driver_funcs->p_vulkan_surface_presented( surfaces[i], swapchain_res );
}
return res;
@ -70,7 +71,7 @@ static void *win32u_vkGetDeviceProcAddr( VkDevice device, const char *name )
{
TRACE( "device %p, name %s\n", device, debugstr_a(name) );
if (!strcmp( name, "vkGetDeviceProcAddr" )) return win32u_vkGetDeviceProcAddr;
if (!strcmp( name, "vkGetDeviceProcAddr" )) return vulkan_funcs.p_vkGetDeviceProcAddr;
if (!strcmp( name, "vkQueuePresentKHR" )) return vulkan_funcs.p_vkQueuePresentKHR;
return p_vkGetDeviceProcAddr( device, name );
@ -84,16 +85,63 @@ static void *win32u_vkGetInstanceProcAddr( VkInstance instance, const char *name
if (!strcmp( name, "vkCreateWin32SurfaceKHR" )) return vulkan_funcs.p_vkCreateWin32SurfaceKHR;
if (!strcmp( name, "vkDestroySurfaceKHR" )) return vulkan_funcs.p_vkDestroySurfaceKHR;
if (!strcmp( name, "vkGetInstanceProcAddr" )) return win32u_vkGetInstanceProcAddr;
if (!strcmp( name, "vkGetInstanceProcAddr" )) return vulkan_funcs.p_vkGetInstanceProcAddr;
if (!strcmp( name, "vkGetPhysicalDeviceWin32PresentationSupportKHR" )) return vulkan_funcs.p_vkGetPhysicalDeviceWin32PresentationSupportKHR;
/* vkGetInstanceProcAddr also loads any children of instance, so device functions as well. */
if (!strcmp( name, "vkGetDeviceProcAddr" )) return win32u_vkGetDeviceProcAddr;
if (!strcmp( name, "vkGetDeviceProcAddr" )) return vulkan_funcs.p_vkGetDeviceProcAddr;
if (!strcmp( name, "vkQueuePresentKHR" )) return vulkan_funcs.p_vkQueuePresentKHR;
return p_vkGetInstanceProcAddr( instance, name );
}
static struct vulkan_funcs vulkan_funcs =
{
.p_vkQueuePresentKHR = win32u_vkQueuePresentKHR,
.p_vkGetDeviceProcAddr = win32u_vkGetDeviceProcAddr,
.p_vkGetInstanceProcAddr = win32u_vkGetInstanceProcAddr,
};
static VkResult nulldrv_vkCreateWin32SurfaceKHR( VkInstance instance, const VkWin32SurfaceCreateInfoKHR *info,
const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface )
{
FIXME( "stub!\n" );
return VK_ERROR_INCOMPATIBLE_DRIVER;
}
static void nulldrv_vkDestroySurfaceKHR( VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *allocator )
{
}
static void nulldrv_vulkan_surface_presented( HWND hwnd, VkResult result )
{
}
static VkBool32 nulldrv_vkGetPhysicalDeviceWin32PresentationSupportKHR( VkPhysicalDevice device, uint32_t queue )
{
return VK_TRUE;
}
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_vkCreateWin32SurfaceKHR = nulldrv_vkCreateWin32SurfaceKHR,
.p_vkDestroySurfaceKHR = nulldrv_vkDestroySurfaceKHR,
.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)
{
UINT status;
@ -104,7 +152,7 @@ static void vulkan_init(void)
return;
}
if ((status = user_driver->pVulkanInit( WINE_VULKAN_DRIVER_VERSION, vulkan_handle, &vulkan_funcs )) &&
if ((status = user_driver->pVulkanInit( WINE_VULKAN_DRIVER_VERSION, vulkan_handle, &driver_funcs )) &&
status != STATUS_NOT_IMPLEMENTED)
{
ERR( "Failed to initialize the driver vulkan functions, status %#x\n", status );
@ -113,6 +161,17 @@ static void vulkan_init(void)
return;
}
if (status == STATUS_NOT_IMPLEMENTED)
driver_funcs = &nulldrv_funcs;
else
{
vulkan_funcs.p_vkCreateWin32SurfaceKHR = driver_funcs->p_vkCreateWin32SurfaceKHR;
vulkan_funcs.p_vkDestroySurfaceKHR = driver_funcs->p_vkDestroySurfaceKHR;
vulkan_funcs.p_vkGetPhysicalDeviceWin32PresentationSupportKHR = driver_funcs->p_vkGetPhysicalDeviceWin32PresentationSupportKHR;
vulkan_funcs.p_get_host_surface_extension = driver_funcs->p_get_host_surface_extension;
vulkan_funcs.p_wine_get_host_surface = driver_funcs->p_wine_get_host_surface;
}
#define LOAD_FUNCPTR( f ) \
if (!(p_##f = dlsym( vulkan_handle, #f ))) \
{ \
@ -126,10 +185,6 @@ static void vulkan_init(void)
LOAD_FUNCPTR( vkGetInstanceProcAddr );
LOAD_FUNCPTR( vkQueuePresentKHR );
#undef LOAD_FUNCPTR
vulkan_funcs.p_vkGetDeviceProcAddr = win32u_vkGetDeviceProcAddr;
vulkan_funcs.p_vkGetInstanceProcAddr = win32u_vkGetInstanceProcAddr;
vulkan_funcs.p_vkQueuePresentKHR = win32u_vkQueuePresentKHR;
}
/***********************************************************************

View file

@ -257,7 +257,7 @@ extern BOOL macdrv_SystemParametersInfo(UINT action, UINT int_param, void *ptr_p
extern void macdrv_lost_pasteboard_ownership(HWND hwnd);
extern struct opengl_funcs *macdrv_wine_get_wgl_driver(UINT version);
extern UINT macdrv_VulkanInit(UINT version, void *vulkan_handle, struct vulkan_funcs *vulkan_funcs);
extern UINT macdrv_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs);
extern void sync_gl_view(struct macdrv_win_data* data, const RECT* old_whole_rect, const RECT* old_client_rect);
extern CGImageRef create_cgimage_from_icon_bitmaps(HDC hdc, HANDLE icon, HBITMAP hbmColor,

View file

@ -80,7 +80,7 @@ static VkResult (*pvkCreateMetalSurfaceEXT)(VkInstance, const VkMetalSurfaceCrea
static void (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *);
static VkResult (*pvkGetPhysicalDeviceSurfaceCapabilities2KHR)(VkPhysicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *, VkSurfaceCapabilities2KHR *);
static const struct vulkan_funcs vulkan_funcs;
static const struct vulkan_driver_funcs macdrv_vulkan_driver_funcs;
static inline struct wine_vk_surface *surface_from_handle(VkSurfaceKHR handle)
{
@ -196,6 +196,10 @@ static void macdrv_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface
wine_vk_surface_destroy(instance, mac_surface);
}
static void macdrv_vulkan_surface_presented(HWND hwnd, VkResult result)
{
}
static VkBool32 macdrv_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev,
uint32_t index)
{
@ -218,25 +222,18 @@ static VkSurfaceKHR macdrv_wine_get_host_surface(VkSurfaceKHR surface)
return mac_surface->host_surface;
}
static void macdrv_vulkan_surface_presented(HWND hwnd, VkResult result)
static const struct vulkan_driver_funcs macdrv_vulkan_driver_funcs =
{
}
.p_vkCreateWin32SurfaceKHR = macdrv_vkCreateWin32SurfaceKHR,
.p_vkDestroySurfaceKHR = macdrv_vkDestroySurfaceKHR,
.p_vulkan_surface_presented = macdrv_vulkan_surface_presented,
static const struct vulkan_funcs vulkan_funcs =
{
macdrv_vkCreateWin32SurfaceKHR,
macdrv_vkDestroySurfaceKHR,
NULL,
NULL,
macdrv_vkGetPhysicalDeviceWin32PresentationSupportKHR,
NULL,
macdrv_get_host_surface_extension,
macdrv_wine_get_host_surface,
macdrv_vulkan_surface_presented,
.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, struct vulkan_funcs *driver_funcs)
UINT macdrv_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs)
{
if (version != WINE_VULKAN_DRIVER_VERSION)
{
@ -250,13 +247,13 @@ UINT macdrv_VulkanInit(UINT version, void *vulkan_handle, struct vulkan_funcs *d
LOAD_FUNCPTR(vkDestroySurfaceKHR)
#undef LOAD_FUNCPTR
*driver_funcs = vulkan_funcs;
*driver_funcs = &macdrv_vulkan_driver_funcs;
return STATUS_SUCCESS;
}
#else /* No vulkan */
UINT macdrv_VulkanInit(UINT version, void *vulkan_handle, struct vulkan_funcs *driver_funcs)
UINT macdrv_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs)
{
ERR("Wine was built without Vulkan support.\n");
return STATUS_NOT_IMPLEMENTED;

View file

@ -57,7 +57,7 @@ static VkResult (*pvkCreateWaylandSurfaceKHR)(VkInstance, const VkWaylandSurface
static void (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *);
static VkBool32 (*pvkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice, uint32_t, struct wl_display *);
static const struct vulkan_funcs vulkan_funcs;
static const struct vulkan_driver_funcs wayland_vulkan_driver_funcs;
struct wine_vk_surface
{
@ -176,25 +176,6 @@ static void wayland_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surfac
wine_vk_surface_destroy(wine_vk_surface);
}
static VkBool32 wayland_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev,
uint32_t index)
{
TRACE("%p %u\n", phys_dev, index);
return pvkGetPhysicalDeviceWaylandPresentationSupportKHR(phys_dev, index,
process_wayland.wl_display);
}
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 void wayland_vulkan_surface_presented(HWND hwnd, VkResult result)
{
struct wayland_surface *wayland_surface;
@ -216,20 +197,40 @@ static void wayland_vulkan_surface_presented(HWND hwnd, VkResult result)
}
}
static const struct vulkan_funcs vulkan_funcs =
static VkBool32 wayland_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev,
uint32_t index)
{
TRACE("%p %u\n", phys_dev, index);
return pvkGetPhysicalDeviceWaylandPresentationSupportKHR(phys_dev, index,
process_wayland.wl_display);
}
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_vkCreateWin32SurfaceKHR = wayland_vkCreateWin32SurfaceKHR,
.p_vkDestroySurfaceKHR = wayland_vkDestroySurfaceKHR,
.p_vulkan_surface_presented = wayland_vulkan_surface_presented,
.p_vkGetPhysicalDeviceWin32PresentationSupportKHR = wayland_vkGetPhysicalDeviceWin32PresentationSupportKHR,
.p_get_host_surface_extension = wayland_get_host_surface_extension,
.p_wine_get_host_surface = wayland_wine_get_host_surface,
.p_vulkan_surface_presented = wayland_vulkan_surface_presented,
};
/**********************************************************************
* WAYLAND_VulkanInit
*/
UINT WAYLAND_VulkanInit(UINT version, void *vulkan_handle, struct vulkan_funcs *driver_funcs)
UINT WAYLAND_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs)
{
if (version != WINE_VULKAN_DRIVER_VERSION)
{
@ -243,13 +244,13 @@ UINT WAYLAND_VulkanInit(UINT version, void *vulkan_handle, struct vulkan_funcs *
LOAD_FUNCPTR(vkGetPhysicalDeviceWaylandPresentationSupportKHR);
#undef LOAD_FUNCPTR
*driver_funcs = vulkan_funcs;
*driver_funcs = &wayland_vulkan_driver_funcs;
return STATUS_SUCCESS;
}
#else /* No vulkan */
UINT WAYLAND_VulkanInit(UINT version, void *vulkan_handle, struct vulkan_funcs *driver_funcs)
UINT WAYLAND_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs)
{
ERR( "Wine was built without Vulkan support.\n" );
return STATUS_NOT_IMPLEMENTED;

View file

@ -342,7 +342,7 @@ void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags,
BOOL WAYLAND_WindowPosChanging(HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *window_rect, const RECT *client_rect,
RECT *visible_rect, struct window_surface **surface);
UINT WAYLAND_VulkanInit(UINT version, void *vulkan_handle, struct vulkan_funcs *driver_funcs);
UINT WAYLAND_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs);
struct opengl_funcs *WAYLAND_wine_get_wgl_driver(UINT version);
#endif /* __WINE_WAYLANDDRV_H */

View file

@ -77,7 +77,7 @@ static VkResult (*pvkCreateXlibSurfaceKHR)(VkInstance, const VkXlibSurfaceCreate
static void (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *);
static VkBool32 (*pvkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice, uint32_t, Display *, VisualID);
static const struct vulkan_funcs vulkan_funcs;
static const struct vulkan_driver_funcs x11drv_vulkan_driver_funcs;
static inline struct wine_vk_surface *surface_from_handle(VkSurfaceKHR handle)
{
@ -209,6 +209,10 @@ static void X11DRV_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface
wine_vk_surface_release(x11_surface);
}
static void X11DRV_vulkan_surface_presented(HWND hwnd, VkResult result)
{
}
static VkBool32 X11DRV_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev,
uint32_t index)
{
@ -232,25 +236,18 @@ static VkSurfaceKHR X11DRV_wine_get_host_surface( VkSurfaceKHR surface )
return x11_surface->host_surface;
}
static void X11DRV_vulkan_surface_presented(HWND hwnd, VkResult result)
static const struct vulkan_driver_funcs x11drv_vulkan_driver_funcs =
{
}
.p_vkCreateWin32SurfaceKHR = X11DRV_vkCreateWin32SurfaceKHR,
.p_vkDestroySurfaceKHR = X11DRV_vkDestroySurfaceKHR,
.p_vulkan_surface_presented = X11DRV_vulkan_surface_presented,
static const struct vulkan_funcs vulkan_funcs =
{
X11DRV_vkCreateWin32SurfaceKHR,
X11DRV_vkDestroySurfaceKHR,
NULL,
NULL,
X11DRV_vkGetPhysicalDeviceWin32PresentationSupportKHR,
NULL,
X11DRV_get_host_surface_extension,
X11DRV_wine_get_host_surface,
X11DRV_vulkan_surface_presented,
.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, struct vulkan_funcs *driver_funcs )
UINT X11DRV_VulkanInit( UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs )
{
if (version != WINE_VULKAN_DRIVER_VERSION)
{
@ -266,13 +263,13 @@ UINT X11DRV_VulkanInit( UINT version, void *vulkan_handle, struct vulkan_funcs *
LOAD_FUNCPTR( vkGetPhysicalDeviceXlibPresentationSupportKHR );
#undef LOAD_FUNCPTR
*driver_funcs = vulkan_funcs;
*driver_funcs = &x11drv_vulkan_driver_funcs;
return STATUS_SUCCESS;
}
#else /* No vulkan */
UINT X11DRV_VulkanInit( UINT version, void *vulkan_handle, struct vulkan_funcs *driver_funcs )
UINT X11DRV_VulkanInit( UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs )
{
ERR( "Wine was built without Vulkan support.\n" );
return STATUS_NOT_IMPLEMENTED;

View file

@ -289,7 +289,7 @@ extern BOOL shape_layered_windows;
extern const struct gdi_dc_funcs *X11DRV_XRender_Init(void);
extern struct opengl_funcs *get_glx_driver(UINT);
extern UINT X11DRV_VulkanInit( UINT, void *, struct vulkan_funcs * );
extern UINT X11DRV_VulkanInit( UINT, void *, const struct vulkan_driver_funcs ** );
extern struct format_entry *import_xdnd_selection( Display *display, Window win, Atom selection,
Atom *targets, UINT count,

View file

@ -269,6 +269,8 @@ struct gdi_device_manager
struct tagUPDATELAYEREDWINDOWINFO;
struct vulkan_driver_funcs;
struct user_driver_funcs
{
struct gdi_dc_funcs dc_funcs;
@ -339,7 +341,7 @@ struct user_driver_funcs
/* system parameters */
BOOL (*pSystemParametersInfo)(UINT,UINT,void*,UINT);
/* vulkan support */
UINT (*pVulkanInit)(UINT,void *,struct vulkan_funcs *);
UINT (*pVulkanInit)(UINT,void *,const struct vulkan_driver_funcs **);
/* opengl support */
struct opengl_funcs * (*pwine_get_wgl_driver)(UINT);
/* thread management */

View file

@ -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 27
#define WINE_VULKAN_DRIVER_VERSION 28
struct vulkan_funcs
{
@ -39,8 +39,18 @@ struct vulkan_funcs
/* winevulkan specific functions */
const char *(*p_get_host_surface_extension)(void);
VkSurfaceKHR (*p_wine_get_host_surface)(VkSurfaceKHR);
};
/* interface between win32u and the user drivers */
struct vulkan_driver_funcs
{
VkResult (*p_vkCreateWin32SurfaceKHR)(VkInstance, const VkWin32SurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *);
void (*p_vkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *);
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 */