diff --git a/vrclient_x64/vrclient_x64/unixlib.cpp b/vrclient_x64/vrclient_x64/unixlib.cpp index af465597..ef2f1aa7 100644 --- a/vrclient_x64/vrclient_x64/unixlib.cpp +++ b/vrclient_x64/vrclient_x64/unixlib.cpp @@ -1,5 +1,6 @@ #include "unix_private.h" +#include #include 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; } diff --git a/vrclient_x64/vrclient_x64/unixlib.h b/vrclient_x64/vrclient_x64/unixlib.h index fc8e8cd3..48de79f7 100644 --- a/vrclient_x64/vrclient_x64/unixlib.h +++ b/vrclient_x64/vrclient_x64/unixlib.h @@ -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 ); diff --git a/vrclient_x64/vrclient_x64/vrclient_main.c b/vrclient_x64/vrclient_x64/vrclient_main.c index 06841240..c2a8b6c0 100644 --- a/vrclient_x64/vrclient_x64/vrclient_main.c +++ b/vrclient_x64/vrclient_x64/vrclient_main.c @@ -1,8 +1,6 @@ #include #include #include -#define __USE_GNU -#include #include #include @@ -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 ); }