From 113013017366b80f7d3e2c76f7b8a6d661f6bc1d Mon Sep 17 00:00:00 2001 From: cdozdil Date: Thu, 19 Sep 2024 01:41:15 +0300 Subject: [PATCH] added missing d3d11 hook --- OptiScaler/NVNGX_DLSS_Dx11.cpp | 5 +- OptiScaler/NVNGX_DLSS_Dx12.cpp | 2 + OptiScaler/NVNGX_DLSS_Vk.cpp | 2 + OptiScaler/OptiScaler.vcxproj | 2 +- OptiScaler/dllmain.h | 5 +- OptiScaler/imgui/imgui_overlay_dx.cpp | 84 +++++++++++++++++++++----- OptiScaler/imgui/wrapped_swapchain.cpp | 33 ++++++++-- OptiScaler/imgui/wrapped_swapchain.h | 2 + OptiScaler/pch.h | 3 +- OptiScaler/resource.h | 2 +- 10 files changed, 113 insertions(+), 27 deletions(-) diff --git a/OptiScaler/NVNGX_DLSS_Dx11.cpp b/OptiScaler/NVNGX_DLSS_Dx11.cpp index 248f5586..240b67fc 100644 --- a/OptiScaler/NVNGX_DLSS_Dx11.cpp +++ b/OptiScaler/NVNGX_DLSS_Dx11.cpp @@ -194,9 +194,6 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D11_Shutdown() DLSSFeatureDx11::Shutdown(D3D11Device); - //if (Config::Instance()->OverlayMenu.value_or(true) && ImGuiOverlayDx11::IsInitedDx11()) - // ImGuiOverlayDx11::ShutdownDx11(); - if (Config::Instance()->DLSSEnabled.value_or(true) && NVNGXProxy::IsDx11Inited() && NVNGXProxy::D3D11_Shutdown() != nullptr) { auto result = NVNGXProxy::D3D11_Shutdown()(); @@ -204,6 +201,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D11_Shutdown() LOG_INFO("D3D11_Shutdown result: {0:X}", (UINT)result); } + ImGuiOverlayDx::UnHookDx(); + return NVSDK_NGX_Result_Success; } diff --git a/OptiScaler/NVNGX_DLSS_Dx12.cpp b/OptiScaler/NVNGX_DLSS_Dx12.cpp index 59e9595f..95fe90ce 100644 --- a/OptiScaler/NVNGX_DLSS_Dx12.cpp +++ b/OptiScaler/NVNGX_DLSS_Dx12.cpp @@ -394,6 +394,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Shutdown(void) LOG_INFO("D3D12_Shutdown result: {0:X}", (UINT)result); } + ImGuiOverlayDx::UnHookDx(); + return NVSDK_NGX_Result_Success; } diff --git a/OptiScaler/NVNGX_DLSS_Vk.cpp b/OptiScaler/NVNGX_DLSS_Vk.cpp index ba3a25ef..b7539a60 100644 --- a/OptiScaler/NVNGX_DLSS_Vk.cpp +++ b/OptiScaler/NVNGX_DLSS_Vk.cpp @@ -979,6 +979,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Shutdown(void) LOG_INFO("VULKAN_Shutdown result: {0:X}", (UINT)result); } + ImGuiOverlayVk::UnHookVk(); + return NVSDK_NGX_Result_Success; } diff --git a/OptiScaler/OptiScaler.vcxproj b/OptiScaler/OptiScaler.vcxproj index 80ca5794..068b654e 100644 --- a/OptiScaler/OptiScaler.vcxproj +++ b/OptiScaler/OptiScaler.vcxproj @@ -82,7 +82,7 @@ $(SolutionDir)external\vulkan\include;$(SolutionDir)external\nvngx_dlss_sdk;$(SolutionDir)external\xess\inc\xess;$(SolutionDir)external\FidelityFX-SDK\ffx-api\include\ffx_api;$(SolutionDir)external\simpleini;$(SolutionDir)external\unordered_dense\include;$(SolutionDir)external\spdlog\include;$(IncludePath) $(ProjectDir)fsr2\lib;$(ProjectDir)fsr2_212\lib;$(ProjectDir)vulkan;$(ProjectDir)d3dx;$(ProjectDir)detours;$(SolutionDir)external\xess\lib;$(LibraryPath) dxgi - D:\Folders\Games\God of War\ + D:\Folders\Games\Cyberpunk 2077\bin\x64\ .\x64\Debug diff --git a/OptiScaler/dllmain.h b/OptiScaler/dllmain.h index 4a169d2f..ef30b20a 100644 --- a/OptiScaler/dllmain.h +++ b/OptiScaler/dllmain.h @@ -1708,6 +1708,8 @@ void AttachToAdapter(IUnknown* unkAdapter) PVOID* pVTable = *(PVOID**)unkAdapter; + bool dxvkStatus = Config::Instance()->IsRunningOnDXVK; + IDXGIAdapter* adapter = nullptr; bool adapterOk = unkAdapter->QueryInterface(__uuidof(IDXGIAdapter), (void**)&adapter) == S_OK; @@ -1718,7 +1720,8 @@ void AttachToAdapter(IUnknown* unkAdapter) ((IDXGIAdapter*)dxvkAdapter)->Release(); } - LOG_INFO("IDXGIVkInteropDevice interface {0}", Config::Instance()->IsRunningOnDXVK ? "found" : "not found"); + if(Config::Instance()->IsRunningOnDXVK != dxvkStatus) + LOG_INFO("IDXGIVkInteropDevice interface {0}", Config::Instance()->IsRunningOnDXVK ? "found" : "not found"); if (ptrGetDesc == nullptr && adapterOk) { diff --git a/OptiScaler/imgui/imgui_overlay_dx.cpp b/OptiScaler/imgui/imgui_overlay_dx.cpp index 3d9030a4..ee9fbd75 100644 --- a/OptiScaler/imgui/imgui_overlay_dx.cpp +++ b/OptiScaler/imgui/imgui_overlay_dx.cpp @@ -49,6 +49,7 @@ static PFN_D3D12_CREATE_DEVICE o_D3D12CreateDevice = nullptr; static PFN_CreateSampler o_CreateSampler = nullptr; static PFN_D3D11_CREATE_DEVICE o_D3D11CreateDevice = nullptr; +static PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN o_D3D11CreateDeviceAndSwapChain = nullptr; static PFN_CreateSamplerState o_CreateSamplerState = nullptr; static PFN_D3D11ON12_CREATE_DEVICE o_D3D11On12CreateDevice = nullptr; static ID3D11Device* d3d11Device = nullptr; @@ -156,8 +157,6 @@ static void CleanupRenderTargetDx12(bool clearQueue) if (!_isInited || !_dx12Device) return; - LOG_DEBUG("clearQueue: {0}!", clearQueue); - for (UINT i = 0; i < NUM_BACK_BUFFERS; ++i) { if (g_mainRenderTargetResource[i]) @@ -206,15 +205,13 @@ static void CleanupRenderTargetDx12(bool clearQueue) if (g_pd3dCommandQueue != nullptr) { - auto count = g_pd3dCommandQueue->Release(); - LOG_DEBUG("D3D12 Queue refcount: {}", count); + g_pd3dCommandQueue->Release(); g_pd3dCommandQueue = nullptr; } if (g_pd3dDeviceParam != nullptr) { - auto count = g_pd3dDeviceParam->Release(); - LOG_DEBUG("D3D12 device refcount: {}", count); + g_pd3dDeviceParam->Release(); g_pd3dDeviceParam = nullptr; } @@ -372,7 +369,7 @@ static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags ImGuiOverlayDx::currentFrameIndex = (ImGuiOverlayDx::currentFrameIndex + 1) % ImGuiOverlayDx::QUERY_BUFFER_COUNT; } - // DXVK & process hWnd check + // DXVK & process hWnd check if (Config::Instance()->IsRunningOnDXVK || hWnd != Util::GetProcessWindow()) { if (cq != nullptr) @@ -430,11 +427,8 @@ static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags g_pd3dCommandQueue = cq; g_pd3dDeviceParam = device12; - auto count = g_pd3dCommandQueue->AddRef(); - LOG_DEBUG("D3D12 Queue refcount: {}", count); - - count = g_pd3dDeviceParam->AddRef(); - LOG_DEBUG("D3D12 Device refcount: {}", count); + g_pd3dCommandQueue->AddRef(); + g_pd3dDeviceParam->AddRef(); ImGuiOverlayBase::Dx12Ready(); _isInited = true; @@ -972,6 +966,64 @@ static HRESULT hkD3D11CreateDevice(IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE Drive return result; } +static HRESULT hkD3D11CreateDeviceAndSwapChain(IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, CONST D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, UINT SDKVersion, DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, IDXGISwapChain** ppSwapChain, ID3D11Device** ppDevice, D3D_FEATURE_LEVEL* pFeatureLevel, ID3D11DeviceContext** ppImmediateContext) +{ + LOG_FUNC(); + + IDXGISwapChain* buffer = nullptr; + auto result = o_D3D11CreateDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, pSwapChainDesc, &buffer, ppDevice, pFeatureLevel, ppImmediateContext); + + if (result == S_OK && *ppDevice != nullptr) + { + LOG_INFO("Device captured"); + d3d11Device = *ppDevice; + + HookToDevice(d3d11Device); + + WrappedIDXGISwapChain4* buf = nullptr; + if (buffer != nullptr && buffer->QueryInterface(IID_PPV_ARGS(&buf)) != S_OK) + { + // check for SL proxy + IID riid; + IDXGISwapChain* real = nullptr; + auto iidResult = IIDFromString(L"{ADEC44E2-61F0-45C3-AD9F-1B37379284FF}", &riid); + + if (iidResult == S_OK) + { + auto qResult = buffer->QueryInterface(riid, (void**)&real); + + if (qResult == S_OK && real != nullptr) + { + LOG_INFO("Streamline proxy found"); + real->Release(); + } + else + { + LOG_DEBUG("Streamline proxy not found"); + } + } + + Config::Instance()->ScreenWidth = pSwapChainDesc->BufferDesc.Width; + Config::Instance()->ScreenHeight = pSwapChainDesc->BufferDesc.Height; + + LOG_DEBUG("created new swapchain: {0:X}, hWnd", (UINT64)buffer, (UINT64)pSwapChainDesc->OutputWindow); + *ppSwapChain = new WrappedIDXGISwapChain4(real == nullptr ? buffer : real, d3d11Device, pSwapChainDesc->OutputWindow, Present, CleanupRenderTarget); + LOG_DEBUG("created new WrappedIDXGISwapChain4: {0:X}, pDevice: {1:X}", (UINT64)buffer, (UINT64)d3d11Device); + } + + if (buf != nullptr) + buf->Release(); + } + + if (buffer != nullptr) + buffer->Release(); + + LOG_FUNC_RESULT(result); + + return result; +} + static HRESULT hkD3D12CreateDevice(IUnknown* pAdapter, D3D_FEATURE_LEVEL MinimumFeatureLevel, REFIID riid, void** ppDevice) { LOG_FUNC(); @@ -1380,7 +1432,7 @@ void DeatachAllHooks() if (o_D3D11On12CreateDevice != nullptr) { DetourDetach(&(PVOID&)o_D3D11On12CreateDevice, hkD3D11On12CreateDevice); - o_D3D11CreateDevice = nullptr; + o_D3D11On12CreateDevice = nullptr; } if (o_D3D12CreateDevice != nullptr) @@ -1439,8 +1491,9 @@ void ImGuiOverlayDx::HookDx() } o_D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)DetourFindFunction("d3d11.dll", "D3D11CreateDevice"); + o_D3D11CreateDeviceAndSwapChain = (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)DetourFindFunction("d3d11.dll", "D3D11CreateDeviceAndSwapChain"); o_D3D11On12CreateDevice = (PFN_D3D11ON12_CREATE_DEVICE)DetourFindFunction("d3d11.dll", "D3D11On12CreateDevice"); - if (o_D3D11CreateDevice != nullptr || o_D3D11On12CreateDevice != nullptr) + if (o_D3D11CreateDevice != nullptr || o_D3D11On12CreateDevice != nullptr || o_D3D11CreateDeviceAndSwapChain != nullptr) { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); @@ -1451,6 +1504,9 @@ void ImGuiOverlayDx::HookDx() if (o_D3D11On12CreateDevice != nullptr) DetourAttach(&(PVOID&)o_D3D11On12CreateDevice, hkD3D11On12CreateDevice); + if (o_D3D11CreateDeviceAndSwapChain != nullptr) + DetourAttach(&(PVOID&)o_D3D11CreateDeviceAndSwapChain, hkD3D11CreateDeviceAndSwapChain); + DetourTransactionCommit(); } diff --git a/OptiScaler/imgui/wrapped_swapchain.cpp b/OptiScaler/imgui/wrapped_swapchain.cpp index fe1a67ed..6d915ae2 100644 --- a/OptiScaler/imgui/wrapped_swapchain.cpp +++ b/OptiScaler/imgui/wrapped_swapchain.cpp @@ -82,6 +82,12 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::QueryInterface(REFIID riid, vo return E_NOINTERFACE; } } + else if (riid == __uuidof(this)) + { + AddRef(); + *ppvObject = (IUnknown*)this; + return S_OK; + } else if (riid == __uuidof(IUnknown)) { AddRef(); @@ -108,10 +114,18 @@ HRESULT WrappedIDXGISwapChain4::ResizeBuffers(UINT BufferCount, UINT Width, UINT { LOG_FUNC(); - if (ClearTrig != nullptr) - ClearTrig(false, Handle); + _mutex.lock(); - return m_pReal->ResizeBuffers(BufferCount, Width, Height, NewFormat, SwapChainFlags); + if (ClearTrig != nullptr) + ClearTrig(true, Handle); + + auto result = m_pReal->ResizeBuffers(BufferCount, Width, Height, NewFormat, SwapChainFlags); + + LOG_FUNC_RESULT(result); + + _mutex.unlock(); + + return result; } HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::GetContainingOutput(IDXGIOutput** ppOutput) @@ -124,10 +138,17 @@ HRESULT WrappedIDXGISwapChain4::ResizeBuffers1(UINT BufferCount, UINT Width, UIN { LOG_FUNC(); - if (ClearTrig != nullptr) - ClearTrig(false, Handle); + _mutex.lock(); - return m_pReal3->ResizeBuffers1(BufferCount, Width, Height, Format, SwapChainFlags, pCreationNodeMask, ppPresentQueue); + if (ClearTrig != nullptr) + ClearTrig(true, Handle); + + + auto result = m_pReal3->ResizeBuffers1(BufferCount, Width, Height, Format, SwapChainFlags, pCreationNodeMask, ppPresentQueue); + + _mutex.unlock(); + + return result; } HRESULT WrappedIDXGISwapChain4::SetFullscreenState(BOOL Fullscreen, IDXGIOutput* pTarget) diff --git a/OptiScaler/imgui/wrapped_swapchain.h b/OptiScaler/imgui/wrapped_swapchain.h index d9c7f470..61eeb0cb 100644 --- a/OptiScaler/imgui/wrapped_swapchain.h +++ b/OptiScaler/imgui/wrapped_swapchain.h @@ -251,5 +251,7 @@ struct DECLSPEC_UUID("3af622a3-82d0-49cd-994f-cce05122c222") WrappedIDXGISwapCha PFN_SC_Clean ClearTrig = nullptr; HWND Handle = nullptr; + std::mutex _mutex; + int id = 0; }; diff --git a/OptiScaler/pch.h b/OptiScaler/pch.h index 769d48ed..b30fcbfd 100644 --- a/OptiScaler/pch.h +++ b/OptiScaler/pch.h @@ -25,7 +25,8 @@ // Enables logging of DLSS NV Parameters //#define DLSS_PARAM_DUMP -inline HMODULE dllModule; +inline HMODULE dllModule = nullptr; +inline HMODULE skHandle = nullptr; inline DWORD processId; #define LOG_TRACE(msg, ...) \ diff --git a/OptiScaler/resource.h b/OptiScaler/resource.h index 6b1415b1..7d01a027 100644 --- a/OptiScaler/resource.h +++ b/OptiScaler/resource.h @@ -21,7 +21,7 @@ #define VER_MAJOR_VERSION 0 #define VER_MINOR_VERSION 6 #define VER_HOTFIX_VERSION 7 -#define VER_BUILD_NUMBER 8 +#define VER_BUILD_NUMBER 9 #define VER_PRE_RELEASE