diff --git a/build-wine32.txt b/build-wine32.txt index 0ca8f90c..5c5e9f3e 100644 --- a/build-wine32.txt +++ b/build-wine32.txt @@ -10,7 +10,7 @@ winelib = true c_args=['-m32', '-msse', '-msse2'] cpp_args=['-m32', '--no-gnu-unique', '-Wno-attributes', '-msse', '-msse2'] -cpp_link_args=['-m32', '-mwindows'] +cpp_link_args=['-m32', '-mwindows', '-ldl'] [host_machine] system = 'linux' diff --git a/build-wine64.txt b/build-wine64.txt index f4a69cd9..26baf206 100644 --- a/build-wine64.txt +++ b/build-wine64.txt @@ -10,7 +10,7 @@ winelib = true c_args=['-m64'] cpp_args=['-m64', '--no-gnu-unique', '-Wno-attributes'] -cpp_link_args=['-m64', '-mwindows'] +cpp_link_args=['-m64', '-mwindows', '-ldl'] [host_machine] system = 'linux' diff --git a/src/dxvk/dxvk_openvr.cpp b/src/dxvk/dxvk_openvr.cpp index 99878732..3e4fbe20 100644 --- a/src/dxvk/dxvk_openvr.cpp +++ b/src/dxvk/dxvk_openvr.cpp @@ -5,8 +5,20 @@ #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" #endif +#ifdef __WINE__ +#include + +#pragma push_macro("_WIN32") +//request UNIX ABI from openvr.hpp +#undef _WIN32 +#endif + #include +#ifdef __WINE__ +#pragma pop_macro("_WIN32") +#endif + using VR_InitInternalProc = vr::IVRSystem* (VR_CALLTYPE *)(vr::EVRInitError*, vr::EVRApplicationType); using VR_ShutdownInternalProc = void (VR_CALLTYPE *)(); using VR_GetGenericInterfaceProc = void* (VR_CALLTYPE *)(const char*, vr::EVRInitError*); @@ -109,12 +121,22 @@ namespace dxvk { // 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. +#ifdef __WINE__ + // on winelib, load native openvr_api directly + m_ovrApi = ::dlopen("libopenvr_api.so", RTLD_LAZY | RTLD_NOLOAD); + + if (m_ovrApi == nullptr) { + m_ovrApi = ::dlopen("libopenvr_api_dxvk.so", RTLD_LAZY | RTLD_LOCAL); + m_loadedOvrApi = m_ovrApi != nullptr; + } +#else m_ovrApi = ::GetModuleHandle("openvr_api.dll"); if (m_ovrApi == nullptr) { m_ovrApi = ::LoadLibrary("openvr_api_dxvk.dll"); m_loadedOvrApi = m_ovrApi != nullptr; } +#endif if (m_ovrApi == nullptr) { Logger::warn("OpenVR: Failed to locate module"); @@ -122,9 +144,15 @@ namespace dxvk { } // Load method used to retrieve the IVRCompositor interface +#ifdef __WINE__ + g_vrFunctions.initInternal = reinterpret_cast (::dlsym(m_ovrApi, "VR_InitInternal")); + g_vrFunctions.shutdownInternal = reinterpret_cast (::dlsym(m_ovrApi, "VR_ShutdownInternal")); + g_vrFunctions.getGenericInterface = reinterpret_cast(::dlsym(m_ovrApi, "VR_GetGenericInterface")); +#else g_vrFunctions.initInternal = reinterpret_cast (::GetProcAddress(m_ovrApi, "VR_InitInternal")); g_vrFunctions.shutdownInternal = reinterpret_cast (::GetProcAddress(m_ovrApi, "VR_ShutdownInternal")); g_vrFunctions.getGenericInterface = reinterpret_cast(::GetProcAddress(m_ovrApi, "VR_GetGenericInterface")); +#endif if (g_vrFunctions.getGenericInterface == nullptr) { Logger::warn("OpenVR: VR_GetGenericInterface not found"); @@ -173,8 +201,13 @@ namespace dxvk { if (m_initializedOpenVr) g_vrFunctions.shutdownInternal(); +#if __WINE__ + if (m_loadedOvrApi) + ::dlclose(m_ovrApi); +#else if (m_loadedOvrApi) ::FreeLibrary(m_ovrApi); +#endif m_initializedOpenVr = false; m_loadedOvrApi = false; diff --git a/src/dxvk/dxvk_openvr.h b/src/dxvk/dxvk_openvr.h index be21744e..858f57c3 100644 --- a/src/dxvk/dxvk_openvr.h +++ b/src/dxvk/dxvk_openvr.h @@ -66,7 +66,11 @@ namespace dxvk { std::mutex m_mutex; vr::IVRCompositor* m_compositor = nullptr; +#ifdef __WINE__ + void* m_ovrApi = nullptr; +#else HMODULE m_ovrApi = nullptr; +#endif bool m_loadedOvrApi = false; bool m_initializedOpenVr = false;