mirror of
https://github.com/ValveSoftware/Proton.git
synced 2024-12-27 23:25:50 +03:00
vrclient: Move vulkan wrapper / unwrapper loading to the unix side.
CW-Bug-Id: #22729
This commit is contained in:
parent
c6a9e4ce99
commit
03366c4d33
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 );
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user