[vr] Load OpenVR API DLL if necessary

Some games initialize the DXGI factory and D3D11 device even before
loading the OpenVR DLL, so we have to be even more invasive.
This commit is contained in:
Philip Rebohle 2018-07-11 15:31:35 +02:00
parent 67fe452580
commit 22bb4391ba
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 35 additions and 11 deletions

View File

@ -67,10 +67,8 @@ namespace dxvk {
instance->enumAdapters(i)->handle()));
}
if (m_initializedOpenVr)
g_vrFunctions.shutdownInternal();
m_initializedDevExt = true;
this->shutdown();
}
@ -104,18 +102,29 @@ namespace dxvk {
vr::IVRCompositor* VrInstance::getCompositor() {
// Locate the OpenVR DLL if loaded by the process
HMODULE ovrApi = ::GetModuleHandle("openvr_api.dll");
// Skip OpenVR initialization if requested
if (env::getEnvVar(L"DXVK_NO_VR") == "1")
return nullptr;
if (ovrApi == nullptr) {
// Locate the OpenVR DLL if loaded by the process. Some
// applications may not have OpenVR loaded at the time
// they create the DXGI instance, so we try our own DLL.
m_ovrApi = ::GetModuleHandle("openvr_api.dll");
if (m_ovrApi == nullptr) {
m_ovrApi = ::LoadLibrary("openvr_api_dxvk.dll");
m_loadedOvrApi = m_ovrApi != nullptr;
}
if (m_ovrApi == nullptr) {
Logger::warn("OpenVR: Failed to locate module");
return nullptr;
}
// Load method used to retrieve the IVRCompositor interface
g_vrFunctions.initInternal = reinterpret_cast<VR_InitInternalProc> (::GetProcAddress(ovrApi, "VR_InitInternal"));
g_vrFunctions.shutdownInternal = reinterpret_cast<VR_ShutdownInternalProc> (::GetProcAddress(ovrApi, "VR_ShutdownInternal"));
g_vrFunctions.getGenericInterface = reinterpret_cast<VR_GetGenericInterfaceProc>(::GetProcAddress(ovrApi, "VR_GetGenericInterface"));
g_vrFunctions.initInternal = reinterpret_cast<VR_InitInternalProc> (::GetProcAddress(m_ovrApi, "VR_InitInternal"));
g_vrFunctions.shutdownInternal = reinterpret_cast<VR_ShutdownInternalProc> (::GetProcAddress(m_ovrApi, "VR_ShutdownInternal"));
g_vrFunctions.getGenericInterface = reinterpret_cast<VR_GetGenericInterfaceProc>(::GetProcAddress(m_ovrApi, "VR_GetGenericInterface"));
if (g_vrFunctions.getGenericInterface == nullptr) {
Logger::warn("OpenVR: VR_GetGenericInterface not found");
@ -150,8 +159,7 @@ namespace dxvk {
if (error != vr::VRInitError_None || compositor == nullptr) {
Logger::warn("OpenVR: Failed to query compositor interface");
g_vrFunctions.shutdownInternal();
m_initializedOpenVr = false;
this->shutdown();
return nullptr;
}
}
@ -159,5 +167,17 @@ namespace dxvk {
Logger::info("OpenVR: Compositor interface found");
return compositor;
}
void VrInstance::shutdown() {
if (m_initializedOpenVr)
g_vrFunctions.shutdownInternal();
if (m_loadedOvrApi)
::FreeLibrary(m_ovrApi);
m_initializedOpenVr = false;
m_loadedOvrApi = false;
}
}

View File

@ -66,7 +66,9 @@ namespace dxvk {
std::mutex m_mutex;
vr::IVRCompositor* m_compositor = nullptr;
HMODULE m_ovrApi = nullptr;
bool m_loadedOvrApi = false;
bool m_initializedOpenVr = false;
bool m_initializedInsExt = false;
bool m_initializedDevExt = false;
@ -83,6 +85,8 @@ namespace dxvk {
const std::string& str) const;
vr::IVRCompositor* getCompositor();
void shutdown();
};