From be8b0530f2caa62ece2acbe772c45224ec543ebd Mon Sep 17 00:00:00 2001 From: FakeMichau <49685661+FakeMichau@users.noreply.github.com> Date: Sun, 1 Mar 2026 02:39:25 +0100 Subject: [PATCH] Add dxvk and vkd3d-proton checks --- OptiScaler/State.h | 1 - OptiScaler/dllmain.cpp | 44 +++-------------- OptiScaler/fsr4/FSR4Upgrade.h | 1 + OptiScaler/hooks/DxgiFactory_Hooks.cpp | 34 ------------- OptiScaler/hooks/DxgiFactory_Hooks.h | 2 - OptiScaler/hooks/DxgiFactory_WrappedCalls.cpp | 34 ------------- OptiScaler/hooks/DxgiFactory_WrappedCalls.h | 2 - OptiScaler/hooks/Vulkan_Hooks.cpp | 5 +- OptiScaler/menu/menu_common.cpp | 13 +++-- OptiScaler/misc/IdentifyGpu.cpp | 49 ++++++++++++------- OptiScaler/misc/IdentifyGpu.h | 22 +++++++-- OptiScaler/proxies/Dxgi_Proxy.h | 43 +++++++++++++++- OptiScaler/wrapped/wrapped_swapchain.cpp | 3 +- 13 files changed, 114 insertions(+), 139 deletions(-) diff --git a/OptiScaler/State.h b/OptiScaler/State.h index 0f523037..317a7d11 100644 --- a/OptiScaler/State.h +++ b/OptiScaler/State.h @@ -194,7 +194,6 @@ class State // Linux checks bool isRunningOnLinux = false; - bool isRunningOnDXVK = false; // Other checks bool isRunningOnNvidia = false; diff --git a/OptiScaler/dllmain.cpp b/OptiScaler/dllmain.cpp index 3c99fbe4..e00d2f61 100644 --- a/OptiScaler/dllmain.cpp +++ b/OptiScaler/dllmain.cpp @@ -587,45 +587,17 @@ static void CheckWorkingMode() // dxgi.dll if (lCaseFilename == "dxgi.dll") { - do - { - auto pluginFilePath = pluginPath / L"dxgi.dll"; - originalModule = NtdllProxy::LoadLibraryExW_Ldr(pluginFilePath.wstring().c_str(), NULL, 0); + // Init will try to load the specifc path itself + // It's to allow dxgi usage before this point + DxgiProxy::Init(nullptr, _passThruMode); - if (originalModule != nullptr) - { - if (!_passThruMode) - LOG_INFO("OptiScaler working as dxgi.dll, original dll loaded from plugin folder"); - - break; - } - - originalModule = NtdllProxy::LoadLibraryExW_Ldr(L"dxgi-original.dll", NULL, 0); - - if (originalModule != nullptr) - { - if (!_passThruMode) - LOG_INFO("OptiScaler working as dxgi.dll, dxgi-original.dll loaded"); - - break; - } - - auto sysFilePath = sysPath / L"dxgi.dll"; - originalModule = NtdllProxy::LoadLibraryExW_Ldr(sysFilePath.wstring().c_str(), NULL, 0); - - if (originalModule != nullptr && !_passThruMode) - LOG_INFO("OptiScaler working as dxgi.dll, system dll loaded"); - - } while (false); - - if (originalModule != nullptr) + if (DxgiProxy::Module() != nullptr) { dllNames.push_back("dxgi.dll"); dllNames.push_back("dxgi"); dllNamesW.push_back(L"dxgi.dll"); dllNamesW.push_back(L"dxgi"); - DxgiProxy::Init(originalModule); dxgi.LoadOriginalLibrary(originalModule); State::Instance().isDxgiMode = true; @@ -839,7 +811,7 @@ static void CheckWorkingMode() } // Vulkan - if (State::Instance().isRunningOnDXVK || State::Instance().isRunningOnLinux || + if (IdentifyGpu::getPrimaryGpu().usesDxvk || State::Instance().isRunningOnLinux || (State::Instance().gameQuirks & GameQuirk::LoadVulkanManually)) { vulkanModule = NtdllProxy::LoadLibraryExW_Ldr(L"vulkan-1.dll", NULL, 0); @@ -1770,7 +1742,8 @@ DWORD WINAPI InitThread(LPVOID hModuleVoid) // Check for Wine spdlog::info(""); State::Instance().isRunningOnLinux = IsRunningOnWine(); - State::Instance().isRunningOnDXVK = State::Instance().isRunningOnLinux; + + auto primaryGpu = IdentifyGpu::getPrimaryGpu(); // Check if real DLSS available if (Config::Instance()->DLSSEnabled.value_or_default()) @@ -1827,10 +1800,7 @@ DWORD WINAPI InitThread(LPVOID hModuleVoid) spdlog::info(""); CheckWorkingMode(); - auto d = IdentifyGpu::getGpuInfo(); - // OptiFG & Overlay Checks - // TODO: Either FGInput == FGInput::Upscaler or FGOutput == FGOutput::FSRFG if ((Config::Instance()->FGInput.value_or_default() == FGInput::Upscaler) && !Config::Instance()->DisableOverlays.has_value()) Config::Instance()->DisableOverlays.set_volatile_value(true); diff --git a/OptiScaler/fsr4/FSR4Upgrade.h b/OptiScaler/fsr4/FSR4Upgrade.h index 11b67e5f..fecb2fcf 100644 --- a/OptiScaler/fsr4/FSR4Upgrade.h +++ b/OptiScaler/fsr4/FSR4Upgrade.h @@ -27,6 +27,7 @@ void CheckForGPU(); std::vector GetDriverStore(); HMODULE GetFSR4Module(); +// Based on the PDBs provided with FFX 2.1.0 enum AmdExtWaveMatrixPropertiesType : int32_t { float16 = 0x0, diff --git a/OptiScaler/hooks/DxgiFactory_Hooks.cpp b/OptiScaler/hooks/DxgiFactory_Hooks.cpp index d06316ab..9a532259 100644 --- a/OptiScaler/hooks/DxgiFactory_Hooks.cpp +++ b/OptiScaler/hooks/DxgiFactory_Hooks.cpp @@ -20,28 +20,6 @@ #include #endif -void DxgiFactoryHooks::CheckAdapter(IUnknown* unkAdapter) -{ - if (State::Instance().isRunningOnDXVK) - return; - - // DXVK VkInterface GUID - const GUID guid = { 0x907bf281, 0xea3c, 0x43b4, { 0xa8, 0xe4, 0x9f, 0x23, 0x11, 0x07, 0xb4, 0xff } }; - - IDXGIAdapter* adapter = nullptr; - bool adapterOk = unkAdapter->QueryInterface(IID_PPV_ARGS(&adapter)) == S_OK; - - void* dxvkAdapter = nullptr; - if (adapterOk && adapter->QueryInterface(guid, &dxvkAdapter) == S_OK) - { - State::Instance().isRunningOnDXVK = dxvkAdapter != nullptr; - ((IDXGIAdapter*) dxvkAdapter)->Release(); - } - - if (adapterOk) - adapter->Release(); -} - void DxgiFactoryHooks::HookToFactory(IDXGIFactory* pFactory) { if (pFactory == nullptr) @@ -920,10 +898,7 @@ HRESULT DxgiFactoryHooks::EnumAdapters(IDXGIFactory* realFactory, UINT Adapter, } if (result == S_OK) - { - CheckAdapter(*ppAdapter); DxgiSpoofing::AttachToAdapter(*ppAdapter); - } #if _DEBUG LOG_TRACE("result: {:X}, Adapter: {}, pAdapter: {:X}", (UINT) result, Adapter, (uintptr_t) *ppAdapter); @@ -997,10 +972,7 @@ HRESULT DxgiFactoryHooks::EnumAdapters1(IDXGIFactory1* realFactory, UINT Adapter } if (result == S_OK) - { - CheckAdapter(*ppAdapter); DxgiSpoofing::AttachToAdapter(*ppAdapter); - } #if _DEBUG LOG_TRACE("result: {:X}, Adapter: {}, pAdapter: {:X}", (UINT) result, Adapter, (uintptr_t) *ppAdapter); @@ -1019,10 +991,7 @@ HRESULT DxgiFactoryHooks::EnumAdapterByLuid(IDXGIFactory4* realFactory, LUID Ada } if (result == S_OK) - { - CheckAdapter((IUnknown*) *ppvAdapter); DxgiSpoofing::AttachToAdapter((IUnknown*) *ppvAdapter); - } #if _DEBUG LOG_TRACE("result: {:X}, pAdapter: {:X}", (UINT) result, (uintptr_t) *ppvAdapter); @@ -1042,10 +1011,7 @@ HRESULT DxgiFactoryHooks::EnumAdapterByGpuPreference(IDXGIFactory6* realFactory, } if (result == S_OK) - { - CheckAdapter((IUnknown*) *ppvAdapter); DxgiSpoofing::AttachToAdapter((IUnknown*) *ppvAdapter); - } #if _DEBUG LOG_TRACE("result: {:X}, Adapter: {}, pAdapter: {:X}", (UINT) result, Adapter, (uintptr_t) *ppvAdapter); diff --git a/OptiScaler/hooks/DxgiFactory_Hooks.h b/OptiScaler/hooks/DxgiFactory_Hooks.h index 54e52f98..54a41ee1 100644 --- a/OptiScaler/hooks/DxgiFactory_Hooks.h +++ b/OptiScaler/hooks/DxgiFactory_Hooks.h @@ -53,8 +53,6 @@ class DxgiFactoryHooks inline static bool _skipFGSwapChainCreation = false; inline static bool _skipHighPerfCheck = false; - static void CheckAdapter(IUnknown* unkAdapter); - class ScopedSkipFGSCCreation { private: diff --git a/OptiScaler/hooks/DxgiFactory_WrappedCalls.cpp b/OptiScaler/hooks/DxgiFactory_WrappedCalls.cpp index bbec3dd1..6bada7e2 100644 --- a/OptiScaler/hooks/DxgiFactory_WrappedCalls.cpp +++ b/OptiScaler/hooks/DxgiFactory_WrappedCalls.cpp @@ -18,28 +18,6 @@ #include #endif -void DxgiFactoryWrappedCalls::CheckAdapter(IUnknown* unkAdapter) -{ - if (State::Instance().isRunningOnDXVK) - return; - - // DXVK VkInterface GUID - const GUID guid = { 0x907bf281, 0xea3c, 0x43b4, { 0xa8, 0xe4, 0x9f, 0x23, 0x11, 0x07, 0xb4, 0xff } }; - - IDXGIAdapter* adapter = nullptr; - bool adapterOk = unkAdapter->QueryInterface(IID_PPV_ARGS(&adapter)) == S_OK; - - void* dxvkAdapter = nullptr; - if (adapterOk && adapter->QueryInterface(guid, &dxvkAdapter) == S_OK) - { - State::Instance().isRunningOnDXVK = dxvkAdapter != nullptr; - ((IDXGIAdapter*) dxvkAdapter)->Release(); - } - - if (adapterOk) - adapter->Release(); -} - HRESULT DxgiFactoryWrappedCalls::CreateSwapChain(IDXGIFactory* realFactory, WrappedIDXGIFactory7* wrappedFactory, IUnknown* pDevice, const DXGI_SWAP_CHAIN_DESC* pDesc, IDXGISwapChain** ppSwapChain) @@ -810,10 +788,7 @@ HRESULT DxgiFactoryWrappedCalls::EnumAdapters(IDXGIFactory* realFactory, UINT Ad } if (result == S_OK) - { - CheckAdapter(*ppAdapter); DxgiSpoofing::AttachToAdapter(*ppAdapter); - } #if _DEBUG LOG_TRACE("result: {:X}, Adapter: {}, pAdapter: {:X}", (UINT) result, Adapter, (uintptr_t) *ppAdapter); @@ -886,10 +861,7 @@ HRESULT DxgiFactoryWrappedCalls::EnumAdapters1(IDXGIFactory1* realFactory, UINT } if (result == S_OK) - { - CheckAdapter(*ppAdapter); DxgiSpoofing::AttachToAdapter(*ppAdapter); - } #if _DEBUG LOG_TRACE("result: {:X}, Adapter: {}, pAdapter: {:X}", (UINT) result, Adapter, (uintptr_t) *ppAdapter); @@ -909,10 +881,7 @@ HRESULT DxgiFactoryWrappedCalls::EnumAdapterByLuid(IDXGIFactory4* realFactory, L } if (result == S_OK) - { - CheckAdapter((IUnknown*) *ppvAdapter); DxgiSpoofing::AttachToAdapter((IUnknown*) *ppvAdapter); - } #if _DEBUG LOG_TRACE("result: {:X}, pAdapter: {:X}", (UINT) result, (uintptr_t) *ppvAdapter); @@ -933,10 +902,7 @@ HRESULT DxgiFactoryWrappedCalls::EnumAdapterByGpuPreference(IDXGIFactory6* realF } if (result == S_OK) - { - CheckAdapter((IUnknown*) *ppvAdapter); DxgiSpoofing::AttachToAdapter((IUnknown*) *ppvAdapter); - } #if _DEBUG LOG_TRACE("result: {:X}, Adapter: {}, pAdapter: {:X}", (UINT) result, Adapter, (uintptr_t) *ppvAdapter); diff --git a/OptiScaler/hooks/DxgiFactory_WrappedCalls.h b/OptiScaler/hooks/DxgiFactory_WrappedCalls.h index 21adf6d6..fee56e3d 100644 --- a/OptiScaler/hooks/DxgiFactory_WrappedCalls.h +++ b/OptiScaler/hooks/DxgiFactory_WrappedCalls.h @@ -29,8 +29,6 @@ class DxgiFactoryWrappedCalls inline static bool _skipFGSwapChainCreation = false; inline static bool _skipHighPerfCheck = false; - static void CheckAdapter(IUnknown* unkAdapter); - class ScopedSkipFGSCCreation { private: diff --git a/OptiScaler/hooks/Vulkan_Hooks.cpp b/OptiScaler/hooks/Vulkan_Hooks.cpp index 644c9ff8..a7e906ac 100644 --- a/OptiScaler/hooks/Vulkan_Hooks.cpp +++ b/OptiScaler/hooks/Vulkan_Hooks.cpp @@ -18,6 +18,7 @@ #include #include +#include // for menu rendering static VkDevice _device = VK_NULL_HANDLE; @@ -183,7 +184,9 @@ static VkResult hkvkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* pPres // get upscaler time UpscalerTimeVk::ReadUpscalingTime(_device); - if (!State::Instance().isRunningOnDXVK) + // ??? TODO: if we are hooking dxvk's vulkan calls then this present call could be either coming from dxvk or from a + // native vk game + if (!IdentifyGpu::getPrimaryGpu().usesDxvk) State::Instance().swapchainApi = Vulkan; // Tick feature to let it know if it's frozen diff --git a/OptiScaler/menu/menu_common.cpp b/OptiScaler/menu/menu_common.cpp index 0ea8682e..83f32cae 100644 --- a/OptiScaler/menu/menu_common.cpp +++ b/OptiScaler/menu/menu_common.cpp @@ -23,6 +23,7 @@ #include #include +#include #define MARK_ALL_BACKENDS_CHANGED() \ for (auto& singleChangeBackend : State::Instance().changeBackend) \ @@ -1872,7 +1873,11 @@ bool MenuCommon::RenderMenu() ImGuiWindowFlags_NoNav)) { std::string api; - if (state.isRunningOnDXVK || state.isRunningOnLinux) + if (IdentifyGpu::getPrimaryGpu().usesDxvk && state.api == DX11) + { + api = "DXVK"; + } + else if (IdentifyGpu::getPrimaryGpu().usesVkd3dProton && state.api == DX12) { api = "VKD3D"; } @@ -2390,7 +2395,7 @@ bool MenuCommon::RenderMenu() else if (state.DeviceAdapterNames.contains(state.currentD3D12Device)) ImGui::Text(state.DeviceAdapterNames[state.currentD3D12Device].c_str()); - ImGui::Text("D3D11 %s| %s %d.%d.%d", state.isRunningOnDXVK ? "(DXVK) " : "", + ImGui::Text("D3D11 %s| %s %d.%d.%d", IdentifyGpu::getPrimaryGpu().usesDxvk ? "(DXVK) " : "", currentFeature->Name().c_str(), currentFeature->Version().major, currentFeature->Version().minor, currentFeature->Version().patch); ImGui::SameLine(0.0f, 6.0f); @@ -2409,7 +2414,7 @@ bool MenuCommon::RenderMenu() if (state.DeviceAdapterNames.contains(state.currentD3D12Device)) ImGui::Text(state.DeviceAdapterNames[state.currentD3D12Device].c_str()); - ImGui::Text("D3D12 %s| %s %d.%d.%d", state.isRunningOnDXVK ? "(DXVK) " : "", + ImGui::Text("D3D12 %s| %s %d.%d.%d", IdentifyGpu::getPrimaryGpu().usesDxvk ? "(DXVK) " : "", currentFeature->Name().c_str(), currentFeature->Version().major, currentFeature->Version().minor, currentFeature->Version().patch); ImGui::SameLine(0.0f, 6.0f); @@ -2428,7 +2433,7 @@ bool MenuCommon::RenderMenu() if (state.DeviceAdapterNames.contains(state.currentVkDevice)) ImGui::Text(state.DeviceAdapterNames[state.currentVkDevice].c_str()); - ImGui::Text("Vulkan %s| %s %d.%d.%d", state.isRunningOnDXVK ? "(DXVK) " : "", + ImGui::Text("Vulkan %s| %s %d.%d.%d", IdentifyGpu::getPrimaryGpu().usesDxvk ? "(DXVK) " : "", currentFeature->Name().c_str(), currentFeature->Version().major, currentFeature->Version().minor, currentFeature->Version().patch); ImGui::SameLine(0.0f, 6.0f); diff --git a/OptiScaler/misc/IdentifyGpu.cpp b/OptiScaler/misc/IdentifyGpu.cpp index ffd4fda7..080a403e 100644 --- a/OptiScaler/misc/IdentifyGpu.cpp +++ b/OptiScaler/misc/IdentifyGpu.cpp @@ -10,7 +10,7 @@ std::optional> IdentifyGpu::cachedInfo; using Microsoft::WRL::ComPtr; -// Maybe take into account some other GPU ordering, DxgiFactoryWrappedCalls::EnumAdapters? +// TODO: Maybe take into account some other GPU ordering, DxgiFactoryWrappedCalls::EnumAdapters? constexpr int vendorPriority(VendorId::Value v) { switch (v) @@ -75,7 +75,13 @@ void IdentifyGpu::checkGpuInfo() std::wstring szName(adapterDesc.Description); gpuInfo.name = wstring_to_string(szName); - if (gpuInfo.vendorId == VendorId::AMD) + // TODO: check if an invalid guid still return S_OK but nullptr + ComPtr dxgiInterop; + if (SUCCEEDED(adapter->QueryInterface(IID_PPV_ARGS(&dxgiInterop)))) + gpuInfo.usesDxvk = true; + + // Needed to be able to query amdxc and check for vkd3d-proton + if (gpuInfo.vendorId == VendorId::AMD || gpuInfo.usesDxvk) { auto result = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_12_0, IID_PPV_ARGS(&gpuInfo.d3d12device)); @@ -96,6 +102,10 @@ void IdentifyGpu::checkGpuInfo() for (auto& gpuInfo : localCachedInfo) { + ComPtr vkd3dInterop; + if (gpuInfo.usesDxvk && SUCCEEDED(gpuInfo.d3d12device->QueryInterface(IID_PPV_ARGS(&vkd3dInterop)))) + gpuInfo.usesVkd3dProton = true; + if (gpuInfo.vendorId == VendorId::AMD && gpuInfo.d3d12device) { auto moduleAmdxc64 = KernelBaseProxy::GetModuleHandleW_()(L"amdxc64.dll"); @@ -119,32 +129,27 @@ void IdentifyGpu::checkGpuInfo() { HRESULT float8support = amdExtD3DShaderIntrinsics->CheckSupport(AmdExtD3DShaderIntrinsicsSupport_Float8Conversion); - gpuInfo.fsr4capable = float8support == S_OK; + gpuInfo.fsr4Capable = float8support == S_OK; } } - if (!gpuInfo.fsr4capable /*&& State::Instance().isRunningOnLinux*/) + if (!gpuInfo.fsr4Capable && gpuInfo.usesVkd3dProton) { - ComPtr interop; + UINT extensionCount = 0; - if (SUCCEEDED(gpuInfo.d3d12device->QueryInterface(IID_PPV_ARGS(&interop)))) + if (SUCCEEDED(vkd3dInterop->GetDeviceExtensions(&extensionCount, nullptr)) && extensionCount > 0) { - UINT extensionCount = 0; + std::vector exts(extensionCount); - if (SUCCEEDED(interop->GetDeviceExtensions(&extensionCount, nullptr)) && extensionCount > 0) + if (SUCCEEDED(vkd3dInterop->GetDeviceExtensions(&extensionCount, exts.data()))) { - std::vector exts(extensionCount); - - if (SUCCEEDED(interop->GetDeviceExtensions(&extensionCount, exts.data()))) + for (UINT i = 0; i < extensionCount; i++) { - for (UINT i = 0; i < extensionCount; i++) + // Only RDNA4+ + if (!strcmp("VK_EXT_shader_float8", exts[i])) { - // Only RDNA4+ - if (!strcmp("VK_EXT_shader_float8", exts[i])) - { - gpuInfo.fsr4capable = true; - break; - } + gpuInfo.fsr4Capable = true; + break; } } } @@ -236,10 +241,16 @@ void IdentifyGpu::checkGpuInfo() } } -std::vector IdentifyGpu::getGpuInfo() +std::vector IdentifyGpu::getAllGpus() { if (!cachedInfo.has_value()) checkGpuInfo(); return cachedInfo.value(); } + +GpuInformation IdentifyGpu::getPrimaryGpu() +{ + auto allGpus = getAllGpus(); + return allGpus.size() > 0 ? allGpus[0] : GpuInformation {}; +} \ No newline at end of file diff --git a/OptiScaler/misc/IdentifyGpu.h b/OptiScaler/misc/IdentifyGpu.h index c931f054..112180fc 100644 --- a/OptiScaler/misc/IdentifyGpu.h +++ b/OptiScaler/misc/IdentifyGpu.h @@ -1,6 +1,7 @@ #pragma once #include +// vkd3d-proton MIDL_INTERFACE("39da4e09-bd1c-4198-9fae-86bbe3be41fd") ID3D12DXVKInteropDevice : public IUnknown { @@ -29,14 +30,24 @@ ID3D12DXVKInteropDevice : public IUnknown virtual HRESULT STDMETHODCALLTYPE UnlockCommandQueue(ID3D12CommandQueue * pCommandQueue) = 0; }; +// dxvk +MIDL_INTERFACE("e2ef5fa5-dc21-4af7-90c4-f67ef6a09323") +IDXGIVkInteropDevice : public IUnknown +{ + virtual void STDMETHODCALLTYPE GetVulkanHandles(VkInstance * pInstance, VkPhysicalDevice * pPhysDev, + VkDevice * pDevice) = 0; +}; + struct GpuInformation { LUID luid {}; // Unique id to be able to reference the exact GPU, VkPhysicalDeviceIDProperties std::string name {}; VendorId::Value vendorId = VendorId::Invalid; size_t dedicatedVramInBytes = 0; + bool usesDxvk = false; + bool usesVkd3dProton = false; - bool fsr4capable = false; + bool fsr4Capable = false; ID3D12Device* d3d12device = nullptr; bool dlssCapable = false; @@ -47,11 +58,15 @@ struct GpuInformation // vulkan caps // - Check Nvidia Arch, watch out for fakenvapi // - Check vram amount +// - Check if dxgi uses dxvk, some dxvk specific call? // // - Check hags support? watch out for linux -// - Check if dxgi uses dxvk, some dxvk specific call? // - Check if vkd3d-proton is being used? Could be helpful to display in menu // - Check vulkan driver? radv vs amdvlk etc +// - Opti in many spots assumes a single GPU and that all handles are coming from that gpu, +// might need to always check if LUID of the held device matches the one provided by this class +// before trying to use any info from here. Could also create a method to query GpuInformation based on LUID +// - Look at removing state.DeviceAdapterNames class IdentifyGpu { @@ -61,5 +76,6 @@ class IdentifyGpu public: // Sorted by priority, the first one should be treated as the primary one - static std::vector getGpuInfo(); + static std::vector getAllGpus(); + static GpuInformation getPrimaryGpu(); }; diff --git a/OptiScaler/proxies/Dxgi_Proxy.h b/OptiScaler/proxies/Dxgi_Proxy.h index 25e81a03..52921ebe 100644 --- a/OptiScaler/proxies/Dxgi_Proxy.h +++ b/OptiScaler/proxies/Dxgi_Proxy.h @@ -20,7 +20,7 @@ class DxgiProxy typedef HRESULT (*PFN_DeclareAdepterRemovalSupport)(); typedef HRESULT (*PFN_GetDebugInterface)(UINT Flags, REFIID riid, void** ppDebug); - static void Init(HMODULE module = nullptr) + static void Init(HMODULE module = nullptr, bool passThruMode = false) { if (_dll != nullptr) return; @@ -29,6 +29,47 @@ class DxgiProxy { _dll = GetModuleHandle(L"dxgi.dll"); + if (_dll == dllModule) + { + wchar_t sysFolder[MAX_PATH]; + GetSystemDirectory(sysFolder, MAX_PATH); + std::filesystem::path sysPath(sysFolder); + std::filesystem::path pluginPath(Config::Instance()->PluginPath.value_or_default()); + + do + { + auto pluginFilePath = pluginPath / L"dxgi.dll"; + originalModule = NtdllProxy::LoadLibraryExW_Ldr(pluginFilePath.wstring().c_str(), NULL, 0); + + if (originalModule != nullptr) + { + if (!passThruMode) + LOG_INFO("OptiScaler working as dxgi.dll, original dll loaded from plugin folder"); + + break; + } + + originalModule = NtdllProxy::LoadLibraryExW_Ldr(L"dxgi-original.dll", NULL, 0); + + if (originalModule != nullptr) + { + if (!passThruMode) + LOG_INFO("OptiScaler working as dxgi.dll, dxgi-original.dll loaded"); + + break; + } + + auto sysFilePath = sysPath / L"dxgi.dll"; + originalModule = NtdllProxy::LoadLibraryExW_Ldr(sysFilePath.wstring().c_str(), NULL, 0); + + if (originalModule != nullptr && !passThruMode) + LOG_INFO("OptiScaler working as dxgi.dll, system dll loaded"); + + _dll = originalModule; + + } while (false); + } + if (_dll == nullptr) _dll = NtdllProxy::LoadLibraryExW_Ldr(L"dxgi.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); } diff --git a/OptiScaler/wrapped/wrapped_swapchain.cpp b/OptiScaler/wrapped/wrapped_swapchain.cpp index b37947b2..e9b40c39 100644 --- a/OptiScaler/wrapped/wrapped_swapchain.cpp +++ b/OptiScaler/wrapped/wrapped_swapchain.cpp @@ -16,6 +16,7 @@ #include #include +#include #pragma intrinsic(_ReturnAddress) @@ -214,7 +215,7 @@ static HRESULT LocalPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT } // DXVK check, it's here because of upscaler time calculations - if (State::Instance().isRunningOnDXVK) + if (IdentifyGpu::getPrimaryGpu().usesDxvk) { if (pPresentParameters == nullptr) presentResult = pSwapChain->Present(SyncInterval, Flags);