From 519651ebb45cd3d35de4b797cd473cd29564243c Mon Sep 17 00:00:00 2001 From: Andrew Eikum Date: Tue, 12 Jan 2021 11:34:40 -0600 Subject: wineopenxr: HACK: Don't try to call OpenXR functions if OpenVR is not working --- wineopenxr/openxr.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) 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 = { -- cgit v1.2.3