vrclient: Move vulkan wrapper / unwrapper loading to the unix side.

CW-Bug-Id: #22729
This commit is contained in:
Rémi Bernon 2023-10-02 19:57:26 +02:00 committed by Arkadiusz Hiler
parent c6a9e4ce99
commit 03366c4d33
3 changed files with 77 additions and 75 deletions

View File

@ -1,5 +1,6 @@
#include "unix_private.h"
#include <winternl.h>
#include <dlfcn.h>
WINE_DEFAULT_DEBUG_CHANNEL(vrclient);
@ -7,6 +8,65 @@ WINE_DEFAULT_DEBUG_CHANNEL(vrclient);
static void *(*p_HmdSystemFactory)( const char *name, int *return_code );
static void *(*p_VRClientCoreFactory)( const char *name, int *return_code );
VkDevice_T *(WINAPI *p_get_native_VkDevice)( VkDevice_T * );
VkInstance_T *(WINAPI *p_get_native_VkInstance)( VkInstance_T * );
VkPhysicalDevice_T *(WINAPI *p_get_native_VkPhysicalDevice)( VkPhysicalDevice_T * );
VkPhysicalDevice_T *(WINAPI *p_get_wrapped_VkPhysicalDevice)( VkInstance_T *, VkPhysicalDevice_T * );
VkQueue_T *(WINAPI *p_get_native_VkQueue)( VkQueue_T * );
static void *get_winevulkan_unixlib( HMODULE winevulkan )
{
UINT64 unix_funcs;
NTSTATUS status;
Dl_info info;
status = NtQueryVirtualMemory( GetCurrentProcess(), winevulkan, (MEMORY_INFORMATION_CLASS)1000 /*MemoryWineUnixFuncs*/,
&unix_funcs, sizeof(unix_funcs), NULL );
if (status)
{
WINE_ERR("NtQueryVirtualMemory status %#x.\n", (int)status);
return NULL;
}
if (!dladdr( (void *)(ULONG_PTR)unix_funcs, &info ))
{
WINE_ERR("dladdr failed.\n");
return NULL;
}
WINE_TRACE( "path %s.\n", info.dli_fname );
return dlopen( info.dli_fname, RTLD_NOW );
}
static void load_vk_unwrappers( HMODULE winevulkan )
{
static HMODULE h = NULL;
void *unix_handle;
if (!(unix_handle = get_winevulkan_unixlib( winevulkan )))
{
ERR("Unable to open winevulkan.so.\n");
return;
}
#define LOAD_FUNC( name ) \
if (!(p_##name = (decltype(p_##name))dlsym( unix_handle, "__wine_" #name ))) \
{ \
ERR( "%s not found.\n", #name ); \
return; \
}
LOAD_FUNC( get_native_VkDevice )
LOAD_FUNC( get_native_VkInstance )
LOAD_FUNC( get_native_VkPhysicalDevice )
LOAD_FUNC( get_wrapped_VkPhysicalDevice )
LOAD_FUNC( get_native_VkQueue )
#undef LOAD_FUNC
dlclose(unix_handle);
}
bool unix_vrclient_init( struct vrclient_init_params *params )
{
static void *vrclient;
@ -29,6 +89,9 @@ bool unix_vrclient_init( struct vrclient_init_params *params )
LOAD_FUNC( HmdSystemFactory );
LOAD_FUNC( VRClientCoreFactory );
#undef LOAD_FUNC
load_vk_unwrappers( params->winevulkan );
return true;
}

View File

@ -39,9 +39,16 @@ struct render_model_texture_map
struct vrclient_init_params
{
HMODULE winevulkan;
char *unix_path;
};
extern VkDevice_T *(WINAPI *p_get_native_VkDevice)( VkDevice_T * );
extern VkInstance_T *(WINAPI *p_get_native_VkInstance)( VkInstance_T * );
extern VkPhysicalDevice_T *(WINAPI *p_get_native_VkPhysicalDevice)( VkPhysicalDevice_T * );
extern VkPhysicalDevice_T *(WINAPI *p_get_wrapped_VkPhysicalDevice)( VkInstance_T *, VkPhysicalDevice_T * );
extern VkQueue_T *(WINAPI *p_get_native_VkQueue)( VkQueue_T * );
extern bool unix_vrclient_init( struct vrclient_init_params *params );
extern void *unix_HmdSystemFactory( const char *name, int *return_code );
extern void *unix_VRClientCoreFactory( const char *name, int *return_code );

View File

@ -1,8 +1,6 @@
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#define __USE_GNU
#include <dlfcn.h>
#include <limits.h>
#include <stdint.h>
@ -197,9 +195,10 @@ struct w_steam_iface *create_win_interface(const char *name, void *linux_side)
static int load_vrclient(void)
{
static const WCHAR PROTON_VR_RUNTIME_W[] = {'P','R','O','T','O','N','_','V','R','_','R','U','N','T','I','M','E',0};
static const WCHAR winevulkanW[] = {'w','i','n','e','v','u','l','k','a','n','.','d','l','l',0};
static BOOL loaded;
struct vrclient_init_params params = {0};
struct vrclient_init_params params = {.winevulkan = LoadLibraryW( winevulkanW )};
WCHAR pathW[PATH_MAX];
DWORD sz;
@ -281,100 +280,33 @@ void *CDECL VRClientCoreFactory(const char *name, int *return_code)
return create_win_interface( name, unix_VRClientCoreFactory( name, return_code ) );
}
static VkDevice_T *(WINAPI *p_get_native_VkDevice)( VkDevice_T * );
static VkInstance_T *(WINAPI *p_get_native_VkInstance)( VkInstance_T * );
static VkPhysicalDevice_T *(WINAPI *p_get_native_VkPhysicalDevice)( VkPhysicalDevice_T * );
static VkPhysicalDevice_T *(WINAPI *p_get_wrapped_VkPhysicalDevice)( VkInstance_T *, VkPhysicalDevice_T * );
static VkQueue_T *(WINAPI *p_get_native_VkQueue)( VkQueue_T * );
static void *get_winevulkan_unix_lib_handle(HMODULE hvulkan)
{
unixlib_handle_t unix_funcs;
NTSTATUS status;
Dl_info info;
status = NtQueryVirtualMemory(GetCurrentProcess(), hvulkan, (MEMORY_INFORMATION_CLASS)1000 /*MemoryWineUnixFuncs*/,
&unix_funcs, sizeof(unix_funcs), NULL);
if (status)
{
WINE_ERR("NtQueryVirtualMemory status %#x.\n", (int)status);
return NULL;
}
if (!dladdr((void *)(ULONG_PTR)unix_funcs, &info))
{
WINE_ERR("dladdr failed.\n");
return NULL;
}
WINE_TRACE("path %s.\n", info.dli_fname);
return dlopen(info.dli_fname, RTLD_NOW);
}
static void load_vk_unwrappers(void)
{
static HMODULE h = NULL;
void *unix_handle;
if(h)
/* already loaded */
return;
h = LoadLibraryA("winevulkan");
if(!h){
ERR("unable to load winevulkan\n");
return;
}
if (!(unix_handle = get_winevulkan_unix_lib_handle(h)))
{
ERR("Unable to open winevulkan.so.\n");
return;
}
#define L( name ) \
if (!(p_##name = dlsym( unix_handle, "__wine_" #name ))) \
{ \
ERR( "%s not found.\n", #name ); \
dlclose( unix_handle ); \
return; \
}
L(get_native_VkDevice);
L(get_native_VkInstance);
L(get_native_VkPhysicalDevice);
L(get_wrapped_VkPhysicalDevice);
L(get_native_VkQueue);
#undef L
dlclose(unix_handle);
}
VkDevice_T *get_native_VkDevice( VkDevice_T *device )
{
load_vk_unwrappers();
load_vrclient();
return p_get_native_VkDevice( device );
}
VkInstance_T *get_native_VkInstance( VkInstance_T *instance )
{
load_vk_unwrappers();
load_vrclient();
return p_get_native_VkInstance( instance );
}
VkPhysicalDevice_T *get_native_VkPhysicalDevice( VkPhysicalDevice_T *device )
{
load_vk_unwrappers();
load_vrclient();
return p_get_native_VkPhysicalDevice( device );
}
VkPhysicalDevice_T *get_wrapped_VkPhysicalDevice( VkInstance_T *instance, VkPhysicalDevice_T *device )
{
load_vk_unwrappers();
load_vrclient();
return p_get_wrapped_VkPhysicalDevice( instance, device );
}
VkQueue_T *get_native_VkQueue( VkQueue_T *queue )
{
load_vk_unwrappers();
load_vrclient();
return p_get_native_VkQueue( queue );
}