diff options
author | Andrew Eikum <aeikum@codeweavers.com> | 2021-01-12 20:34:40 +0300 |
---|---|---|
committer | Andrew Eikum <aeikum@codeweavers.com> | 2021-01-13 19:16:39 +0300 |
commit | 519651ebb45cd3d35de4b797cd473cd29564243c (patch) | |
tree | 5102081a09c422d1261999c6dd4e768772ea3c42 | |
parent | 21bbd755d2d54f86d19de3f28a4e1fe4e3430229 (diff) |
wineopenxr: HACK: Don't try to call OpenXR functions if OpenVR is not workingproton-5.13-5-rc6
-rw-r--r-- | wineopenxr/openxr.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/wineopenxr/openxr.c b/wineopenxr/openxr.c index 00468d1f..2e2e88d1 100644 --- a/wineopenxr/openxr.c +++ b/wineopenxr/openxr.c @@ -224,6 +224,65 @@ static void parse_extensions(const char *in, uint32_t *out_count, *out_strs = list; } +static BOOL HACK_does_openvr_work(void) +{ + /* Linux SteamVR's xrCreateInstance will hang forever if SteamVR hasn't + * already been launched by the user. Since that's the only way to tell if + * OpenXR is functioning, let's use OpenVR to tell whether SteamVR is + * functioning before calling xrCreateInstance. + * + * This should be removed when SteamVR's bug is fixed. */ + + static void *(CDECL *InitInternal)(int *err, int type); + static void (CDECL *ShutdownInternal)(void); + static void *(CDECL *GetGenericInterface)(const char *, int *err); + + int error; + HANDLE openvr_api; + void *compositor; + BOOL need_unload = FALSE; + + openvr_api = GetModuleHandleW(L"openvr_api.dll"); + if(!openvr_api){ + openvr_api = LoadLibraryW(L"openvr_api_dxvk.dll"); + if(!openvr_api){ + WINE_TRACE("no openvr_api_dxvk\n"); + return FALSE; + } + need_unload = TRUE; + } + + InitInternal = (void *)GetProcAddress(openvr_api, "VR_InitInternal"); + ShutdownInternal = (void *)GetProcAddress(openvr_api, "VR_ShutdownInternal"); + GetGenericInterface = (void *)GetProcAddress(openvr_api, "VR_GetGenericInterface"); + + if(!InitInternal || !ShutdownInternal || !GetGenericInterface){ + WINE_TRACE("missing openvr function\n"); + if(need_unload) + FreeLibrary(openvr_api); + return FALSE; + } + + error = 1; + compositor = GetGenericInterface("IVRCompositor_022", &error); + if(!compositor || error != 0){ + InitInternal(&error, 3 /* VRApplication_Background */); + + if(error == 0 /* VRInitError_None */){ + WINE_TRACE("openvr init succeeded\n"); + ShutdownInternal(); + }else + WINE_TRACE("openvr init failed\n"); + }else{ + WINE_TRACE("got openvr compositor\n"); + } + + if(need_unload) + FreeLibrary(openvr_api); + + return error == 0 /* VRInitError_None */; +} + XrResult load_host_openxr_loader(void) { PFN_xrGetVulkanInstanceExtensionsKHR pxrGetVulkanInstanceExtensionsKHR; @@ -250,6 +309,10 @@ XrResult load_host_openxr_loader(void) /* already done */ return XR_SUCCESS; + if(!HACK_does_openvr_work()){ + return XR_ERROR_INITIALIZATION_FAILED; + } + load_vk_unwrappers(); XrInstanceCreateInfo xrCreateInfo = { |