diff --git a/OptiScaler/imgui/imgui_overlay_dx12.cpp b/OptiScaler/imgui/imgui_overlay_dx12.cpp index db6d104a..0688fe60 100644 --- a/OptiScaler/imgui/imgui_overlay_dx12.cpp +++ b/OptiScaler/imgui/imgui_overlay_dx12.cpp @@ -29,14 +29,15 @@ static ID3D12CommandAllocator* g_commandAllocators[NUM_BACK_BUFFERS] = { }; static ID3D12Resource* g_mainRenderTargetResource[NUM_BACK_BUFFERS] = { }; static D3D12_CPU_DESCRIPTOR_HANDLE g_mainRenderTargetDescriptor[NUM_BACK_BUFFERS] = { }; -typedef void(__fastcall* PFN_ExecuteCommandLists)(ID3D12CommandQueue*, UINT, ID3D12CommandList*); -typedef HRESULT(__fastcall* PFN_CreateDXGIFactory1)(REFIID riid, void** ppFactory); -typedef IDXGISwapChain4* (__fastcall* PFN_ffxGetDX12SwapchainPtr)(void* ffxSwapChain); +typedef void(WINAPI* PFN_ExecuteCommandLists)(ID3D12CommandQueue*, UINT, ID3D12CommandList*); +typedef HRESULT(WINAPI* PFN_CreateDXGIFactory1)(REFIID riid, void** ppFactory); +typedef IDXGISwapChain4* (WINAPI* PFN_ffxGetDX12SwapchainPtr)(void* ffxSwapChain); +typedef void* (WINAPI* PFN_ffxGetCommandQueueDX12)(ID3D12CommandQueue* InCommandQueue); static PFN_Present oPresent_Dx12 = nullptr; -static PFN_Present1 oPresent1_Dx12= nullptr; +static PFN_Present1 oPresent1_Dx12 = nullptr; static PFN_ResizeBuffers oResizeBuffers_Dx12 = nullptr; -static PFN_ResizeBuffers1 oResizeBuffers1_Dx12= nullptr; +static PFN_ResizeBuffers1 oResizeBuffers1_Dx12 = nullptr; static PFN_Present oPresent_Dx12_FSR3 = nullptr; static PFN_Present1 oPresent1_Dx12_FSR3 = nullptr; @@ -48,7 +49,9 @@ static PFN_CreateSwapChain oCreateSwapChain_Dx12 = nullptr; static PFN_CreateSwapChainForHwnd oCreateSwapChainForHwnd_Dx12 = nullptr; static PFN_CreateSwapChainForComposition oCreateSwapChainForComposition_Dx12 = nullptr; static PFN_CreateSwapChainForCoreWindow oCreateSwapChainForCoreWindow_Dx12 = nullptr; + static PFN_ffxGetDX12SwapchainPtr offxGetDX12SwapchainPtr = nullptr; +static PFN_ffxGetCommandQueueDX12 offxGetCommandQueueDX12 = nullptr; static bool _isInited = false; @@ -127,13 +130,14 @@ static HRESULT WINAPI hkResizeBuffers1_Dx12_FSR3(IDXGISwapChain3* pSwapChain, UI return oResizeBuffers1_Dx12_FSR3(pSwapChain, BufferCount, Width, Height, NewFormat, SwapChainFlags, pCreationNodeMask, ppPresentQueue); } + static IDXGISwapChain4* WINAPI hkffxGetDX12SwapchainPtr(void* ffxSwapChain) { spdlog::debug("imgui_overlay_dx12::hkffxGetDX12SwapchainPtr!"); IDXGISwapChain4* result = offxGetDX12SwapchainPtr(ffxSwapChain); - if (oPresent_Dx12_FSR3 == nullptr) + if (oPresent_Dx12 == nullptr && oPresent_Dx12_FSR3 == nullptr && result) { result->QueryInterface(IID_PPV_ARGS(&g_pSwapChain)); @@ -162,6 +166,15 @@ static IDXGISwapChain4* WINAPI hkffxGetDX12SwapchainPtr(void* ffxSwapChain) return result; } +static void* WINAPI hkffxGetCommandQueueDX12(ID3D12CommandQueue* InCommandQueue) +{ + spdlog::debug("imgui_overlay_dx12::hkffxGetCommandQueueDX12!"); + + g_pd3dCommandQueue = InCommandQueue; + + return offxGetCommandQueueDX12(InCommandQueue); +} + static bool CreateDeviceD3D12(HWND InHWnd, ID3D12Device* InDevice) { spdlog::debug("imgui_overlay_dx12::CreateDeviceD3D12 Handle: {0:X}", (unsigned long)InHWnd); @@ -216,38 +229,63 @@ static bool CreateDeviceD3D12(HWND InHWnd, ID3D12Device* InDevice) // check for sl.interposer PFN_CreateDXGIFactory1 slFactory = (PFN_CreateDXGIFactory1)DetourFindFunction("sl.interposer.dll", "CreateDXGIFactory1"); - if(slFactory != nullptr) + if (slFactory != nullptr) spdlog::info("imgui_overlay_dx12::CreateDeviceD3D12 sl.interposer.dll CreateDXGIFactory1 found"); IDXGISwapChain1* swapChain1 = nullptr; if (slFactory != nullptr && Config::Instance()->HookSLProxy.value_or(true)) - result = slFactory(IID_PPV_ARGS(&g_dxgiFactory)); - else - result = CreateDXGIFactory1(IID_PPV_ARGS(&g_dxgiFactory)); - - if (result != S_OK) { - spdlog::error("imgui_overlay_dx12::CreateDeviceD3D12 CreateDXGIFactory1: {0:X}", (unsigned long)result); - return false; + result = slFactory(IID_PPV_ARGS(&g_dxgiFactory)); } + else + { + if (Config::Instance()->HookD3D12.value_or(true)) + { + result = CreateDXGIFactory1(IID_PPV_ARGS(&g_dxgiFactory)); + if (result != S_OK) + { + spdlog::error("imgui_overlay_dx12::CreateDeviceD3D12 CreateDXGIFactory1: {0:X}", (unsigned long)result); + return false; + } + } + } // check for uniscaler offxGetDX12SwapchainPtr = (PFN_ffxGetDX12SwapchainPtr)DetourFindFunction("Uniscaler.asi", "ffxGetDX12SwapchainPtr"); - bool uniscalerPresent = offxGetDX12SwapchainPtr != nullptr; - if(uniscalerPresent) - spdlog::info("imgui_overlay_dx12::CreateDeviceD3D12 Uniscaler ffxGetDX12SwapchainPtr found"); + if (offxGetDX12SwapchainPtr != nullptr) + { + // Mess up everything not sure why + //offxGetCommandQueueDX12 = (PFN_ffxGetCommandQueueDX12)DetourFindFunction("Uniscaler.asi", "ffxGetCommandQueueDX12"); + spdlog::info("imgui_overlay_dx12::CreateDeviceD3D12 Uniscaler's ffxGetDX12SwapchainPtr found"); + } + else + { + // check for nukem + offxGetDX12SwapchainPtr = (PFN_ffxGetDX12SwapchainPtr)DetourFindFunction("dlssg_to_fsr3_amd_is_better.dll", "ffxGetDX12SwapchainPtr"); + if (offxGetDX12SwapchainPtr) + { + offxGetCommandQueueDX12 = (PFN_ffxGetCommandQueueDX12)DetourFindFunction("dlssg_to_fsr3_amd_is_better.dll", "ffxGetCommandQueueDX12"); + spdlog::info("imgui_overlay_dx12::CreateDeviceD3D12 Nukem's ffxGetDX12SwapchainPtr found"); + } + } - // check for native fsr3 if (offxGetDX12SwapchainPtr == nullptr) + { + // check for native fsr3 offxGetDX12SwapchainPtr = (PFN_ffxGetDX12SwapchainPtr)DetourFindFunction("ffx_backend_dx12_x64.dll", "ffxGetDX12SwapchainPtr"); - if(offxGetDX12SwapchainPtr) - spdlog::info("imgui_overlay_dx12::CreateDeviceD3D12 FSR3 ffxGetDX12SwapchainPtr found"); + if (offxGetDX12SwapchainPtr) + { + offxGetCommandQueueDX12 = (PFN_ffxGetCommandQueueDX12)DetourFindFunction("ffx_backend_dx12_x64.dll", "ffxGetCommandQueueDX12"); + spdlog::info("imgui_overlay_dx12::CreateDeviceD3D12 FSR3's ffxGetDX12SwapchainPtr found"); + } + } + // hook for FSR3 methods if (offxGetDX12SwapchainPtr != nullptr && Config::Instance()->HookFSR3Proxy.value_or(true)) { DetourTransactionBegin(); @@ -255,12 +293,25 @@ static bool CreateDeviceD3D12(HWND InHWnd, ID3D12Device* InDevice) DetourAttach(&(PVOID&)offxGetDX12SwapchainPtr, hkffxGetDX12SwapchainPtr); + if (offxGetCommandQueueDX12 && (unsigned long)offxGetDX12SwapchainPtr != (unsigned long)offxGetCommandQueueDX12) + DetourAttach(&(PVOID&)offxGetCommandQueueDX12, hkffxGetCommandQueueDX12); + DetourTransactionCommit(); } - - // hook for dxgi proxy too (for dlss-fg + fsr3-fg games) - if(!uniscalerPresent) + + // hook for dxgi proxy + if (g_dxgiFactory != nullptr && Config::Instance()->HookD3D12.value_or(true) && (offxGetDX12SwapchainPtr == nullptr || !Config::Instance()->HookFSR3Proxy.value_or(true))) { + // Create queue + D3D12_COMMAND_QUEUE_DESC desc = { }; + result = g_pd3dDevice->CreateCommandQueue(&desc, IID_PPV_ARGS(&g_pd3dCommandQueue)); + if (result != S_OK) + { + spdlog::error("imgui_overlay_dx12::CreateDeviceD3D12 CreateCommandQueue: {0:X}", (unsigned long)result); + return false; + } + + // create swapchain result = g_dxgiFactory->CreateSwapChainForHwnd(g_pd3dCommandQueue, InHWnd, &sd, NULL, NULL, &swapChain1); if (result != S_OK) { @@ -587,13 +638,16 @@ void ImGuiOverlayDx12::InitDx12(HWND InHandle, ID3D12Device* InDevice) spdlog::error("imgui_overlay_dx12::InitDx12 Hooking!"); // Hook - void** pCommandQueueVTable = *reinterpret_cast(g_pd3dCommandQueue); - void** pFactoryVTable = *reinterpret_cast(g_dxgiFactory); - oCreateSwapChain_Dx12 = (PFN_CreateSwapChain)pFactoryVTable[10]; - oCreateSwapChainForHwnd_Dx12 = (PFN_CreateSwapChainForHwnd)pFactoryVTable[15]; - oCreateSwapChainForCoreWindow_Dx12 = (PFN_CreateSwapChainForCoreWindow)pFactoryVTable[16]; - oCreateSwapChainForComposition_Dx12 = (PFN_CreateSwapChainForComposition)pFactoryVTable[24]; + if (g_dxgiFactory != nullptr) + { + void** pFactoryVTable = *reinterpret_cast(g_dxgiFactory); + + oCreateSwapChain_Dx12 = (PFN_CreateSwapChain)pFactoryVTable[10]; + oCreateSwapChainForHwnd_Dx12 = (PFN_CreateSwapChainForHwnd)pFactoryVTable[15]; + oCreateSwapChainForCoreWindow_Dx12 = (PFN_CreateSwapChainForCoreWindow)pFactoryVTable[16]; + oCreateSwapChainForComposition_Dx12 = (PFN_CreateSwapChainForComposition)pFactoryVTable[24]; + } if (g_pSwapChain != nullptr) { @@ -606,10 +660,12 @@ void ImGuiOverlayDx12::InitDx12(HWND InHandle, ID3D12Device* InDevice) oResizeBuffers1_Dx12 = (PFN_ResizeBuffers1)pVTable[39]; } - oExecuteCommandLists_Dx12 = (PFN_ExecuteCommandLists)pCommandQueueVTable[10]; - - if (g_pd3dCommandQueue) + if (g_pd3dCommandQueue != nullptr) { + void** pCommandQueueVTable = *reinterpret_cast(g_pd3dCommandQueue); + + oExecuteCommandLists_Dx12 = (PFN_ExecuteCommandLists)pCommandQueueVTable[10]; + g_pd3dCommandQueue->Release(); g_pd3dCommandQueue = NULL; } @@ -620,12 +676,15 @@ void ImGuiOverlayDx12::InitDx12(HWND InHandle, ID3D12Device* InDevice) DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); - DetourAttach(&(PVOID&)oCreateSwapChain_Dx12, hkCreateSwapChain_Dx12); - DetourAttach(&(PVOID&)oCreateSwapChainForHwnd_Dx12, hkCreateSwapChainForHwnd_Dx12); - DetourAttach(&(PVOID&)oCreateSwapChainForCoreWindow_Dx12, hkCreateSwapChainForCoreWindow_Dx12); - DetourAttach(&(PVOID&)oCreateSwapChainForComposition_Dx12, hkCreateSwapChainForComposition_Dx12); + if (oCreateSwapChain_Dx12 != nullptr) + { + DetourAttach(&(PVOID&)oCreateSwapChain_Dx12, hkCreateSwapChain_Dx12); + DetourAttach(&(PVOID&)oCreateSwapChainForHwnd_Dx12, hkCreateSwapChainForHwnd_Dx12); + DetourAttach(&(PVOID&)oCreateSwapChainForCoreWindow_Dx12, hkCreateSwapChainForCoreWindow_Dx12); + DetourAttach(&(PVOID&)oCreateSwapChainForComposition_Dx12, hkCreateSwapChainForComposition_Dx12); + } - if (g_pSwapChain != nullptr) + if (oPresent_Dx12 != nullptr) { DetourAttach(&(PVOID&)oPresent_Dx12, hkPresent_Dx12); DetourAttach(&(PVOID&)oPresent1_Dx12, hkPresent1_Dx12); @@ -634,7 +693,8 @@ void ImGuiOverlayDx12::InitDx12(HWND InHandle, ID3D12Device* InDevice) DetourAttach(&(PVOID&)oResizeBuffers1_Dx12, hkResizeBuffers1_Dx12); } - DetourAttach(&(PVOID&)oExecuteCommandLists_Dx12, hkExecuteCommandLists_Dx12); + if (oExecuteCommandLists_Dx12 != nullptr) + DetourAttach(&(PVOID&)oExecuteCommandLists_Dx12, hkExecuteCommandLists_Dx12); DetourTransactionCommit(); @@ -672,7 +732,7 @@ void ImGuiOverlayDx12::ShutdownDx12() DetourDetach(&(PVOID&)oResizeBuffers_Dx12_FSR3, hkResizeBuffers_Dx12_FSR3); DetourDetach(&(PVOID&)oResizeBuffers1_Dx12_FSR3, hkResizeBuffers1_Dx12_FSR3); - + DetourDetach(&(PVOID&)offxGetDX12SwapchainPtr, hkffxGetDX12SwapchainPtr); DetourDetach(&(PVOID&)oExecuteCommandLists_Dx12, hkExecuteCommandLists_Dx12);