diff --git a/OptiScaler/OptiScaler.vcxproj b/OptiScaler/OptiScaler.vcxproj index fd1fcb5a..ee5652e8 100644 --- a/OptiScaler/OptiScaler.vcxproj +++ b/OptiScaler/OptiScaler.vcxproj @@ -81,8 +81,8 @@ $(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) - nvngx - D:\Folders\Games\Deep Rock Galactic\FSD\Binaries\Win64\ + dxgi + D:\Folders\Games\SteamLibrary\steamapps\common\Ghost of Tsushima DIRECTOR%27S CUT\ .\x64\Debug diff --git a/OptiScaler/backends/IFeature_Dx12.cpp b/OptiScaler/backends/IFeature_Dx12.cpp index 2dc7bd59..2b310213 100644 --- a/OptiScaler/backends/IFeature_Dx12.cpp +++ b/OptiScaler/backends/IFeature_Dx12.cpp @@ -25,6 +25,9 @@ void IFeature_Dx12::Shutdown() IFeature_Dx12::~IFeature_Dx12() { + if (OutputScaler != nullptr && OutputScaler.get() != nullptr) + OutputScaler.reset(); + if (Device) { ID3D12Fence* d3d12Fence = nullptr; @@ -52,7 +55,4 @@ IFeature_Dx12::~IFeature_Dx12() d3d12Fence = nullptr; } } - - if (OutputScaler != nullptr && OutputScaler.get() != nullptr) - OutputScaler.reset(); } diff --git a/OptiScaler/backends/IFeature_Dx12.h b/OptiScaler/backends/IFeature_Dx12.h index 01d5d8f0..bbbe4da6 100644 --- a/OptiScaler/backends/IFeature_Dx12.h +++ b/OptiScaler/backends/IFeature_Dx12.h @@ -15,7 +15,6 @@ protected: ID3D12Device* Device = nullptr; static inline std::unique_ptr Imgui = nullptr; std::unique_ptr OutputScaler = nullptr; - std::unique_ptr RCAS = nullptr; void ResourceBarrier(ID3D12GraphicsCommandList* InCommandList, ID3D12Resource* InResource, D3D12_RESOURCE_STATES InBeforeState, D3D12_RESOURCE_STATES InAfterState) const; diff --git a/OptiScaler/bicubicscaling/BS_Dx12.cpp b/OptiScaler/bicubicscaling/BS_Dx12.cpp index e428c27c..a4003e1a 100644 --- a/OptiScaler/bicubicscaling/BS_Dx12.cpp +++ b/OptiScaler/bicubicscaling/BS_Dx12.cpp @@ -417,18 +417,18 @@ BS_Dx12::~BS_Dx12() d3d12Fence = nullptr; } - if (_rootSignature != nullptr) - { - _rootSignature->Release(); - _rootSignature = nullptr; - } - if (_pipelineState != nullptr) { _pipelineState->Release(); _pipelineState = nullptr; } + if (_rootSignature != nullptr) + { + _rootSignature->Release(); + _rootSignature = nullptr; + } + if (_srvHeap[0] != nullptr) { _srvHeap[0]->Release(); diff --git a/OptiScaler/imgui/imgui_overlay_dx12.cpp b/OptiScaler/imgui/imgui_overlay_dx12.cpp index b41b9504..8cc480bd 100644 --- a/OptiScaler/imgui/imgui_overlay_dx12.cpp +++ b/OptiScaler/imgui/imgui_overlay_dx12.cpp @@ -5,6 +5,11 @@ #include "../Logger.h" #include "../Config.h" +#include "ffx_api.h" +#include "ffx_framegeneration.h" +#include "dx12/ffx_api_dx12.h" + + #include #include @@ -122,6 +127,9 @@ static PFN_ffxFsr3ConfigureFrameGeneration offxFsr3ConfigureFrameGeneration_Mod // Native FSR3 static PFN_ffxCreateFrameinterpolationSwapchainForHwndDX12 offxCreateFrameinterpolationSwapchainForHwndDX12_FSR3 = nullptr; static PFN_ffxFsr3ConfigureFrameGeneration offxFsr3ConfigureFrameGeneration_FSR3 = nullptr; +// FSR3.1 +static PfnFfxCreateContext oFfxCreateContext_FSR3 = nullptr; +static PfnFfxConfigure oFfxConfigure_FSR3 = nullptr; static bool _isInited = false; static bool _reInit = false; @@ -855,6 +863,62 @@ static int32_t WINAPI hkffxCreateFrameinterpolationSwapchainForHwndDX12_FSR3(HWN return result; } +static ffxReturnCode_t hkFfxCreateContext_FSR3(ffxContext* context, ffxCreateContextDescHeader* desc, const ffxAllocationCallbacks* memCb) +{ + auto result = oFfxCreateContext_FSR3(context, desc, memCb); + + if (oPresent_FSR3 == nullptr) + { + auto header = (ffxCreateContextDescHeader*)desc; + + while (header != nullptr) + { + if (header->type == FFX_API_CREATE_CONTEXT_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_WRAP_DX12 || + header->type == FFX_API_CREATE_CONTEXT_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_NEW_DX12 || + header->type == FFX_API_CREATE_CONTEXT_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_FOR_HWND_DX12) + { + auto cscHeader = (ffxCreateContextDescFrameGenerationSwapChainWrapDX12*)header; + + if (*cscHeader->swapchain != nullptr) + { + void** pVTable = *reinterpret_cast(*cscHeader->swapchain); + + oPresent_FSR3 = (PFN_Present)pVTable[8]; + oPresent1_FSR3 = (PFN_Present1)pVTable[22]; + oResizeBuffers_FSR3 = (PFN_ResizeBuffers)pVTable[13]; + oResizeBuffers1_FSR3 = (PFN_ResizeBuffers1)pVTable[39]; + + // Apply the detour + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + + if (oPresent_FSR3 != nullptr) + DetourAttach(&(PVOID&)oPresent_FSR3, hkPresent_FSR3); + + if (oPresent1_Mod != nullptr) + DetourAttach(&(PVOID&)oPresent1_FSR3, hkPresent1_FSR3); + + if (oResizeBuffers_Mod != nullptr) + DetourAttach(&(PVOID&)oResizeBuffers_FSR3, hkResizeBuffers_FSR3); + + if (oResizeBuffers1_Mod != nullptr) + DetourAttach(&(PVOID&)oResizeBuffers1_FSR3, hkResizeBuffers1_FSR3); + + DetourTransactionCommit(); + + spdlog::info("ImGuiOverlayDx12::hkFfxCreateContext_FSR3 added swapchain hooks!"); + + break; + } + } + + header = (ffxCreateContextDescHeader*)header->pNext; + } + } + + return result; +} + static int32_t WINAPI hkffxFsr3ConfigureFrameGeneration_FSR3(void* context, FfxFrameGenerationConfig* config) { auto result = offxFsr3ConfigureFrameGeneration_FSR3(context, config); @@ -892,6 +956,61 @@ static int32_t WINAPI hkffxFsr3ConfigureFrameGeneration_FSR3(void* context, FfxF return result; } +static ffxReturnCode_t hkFfxConfigure_FSR3(ffxContext* context, const ffxConfigureDescHeader* desc) +{ + auto result = oFfxConfigure_FSR3(context, desc); + + if (oPresent_FSR3 == nullptr) + { + auto header = (ffxConfigureDescHeader*)desc; + + while (header != nullptr) + { + if (header->type == FFX_API_CONFIGURE_DESC_TYPE_FRAMEGENERATION) + { + auto cfgHeader = (ffxConfigureDescFrameGeneration*)header; + + if (cfgHeader->swapChain != nullptr) + { + void** pVTable = *reinterpret_cast(cfgHeader->swapChain); + + oPresent_FSR3 = (PFN_Present)pVTable[8]; + oPresent1_FSR3 = (PFN_Present1)pVTable[22]; + oResizeBuffers_FSR3 = (PFN_ResizeBuffers)pVTable[13]; + oResizeBuffers1_FSR3 = (PFN_ResizeBuffers1)pVTable[39]; + + // Apply the detour + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + + if (oPresent_FSR3 != nullptr) + DetourAttach(&(PVOID&)oPresent_FSR3, hkPresent_FSR3); + + if (oPresent1_Mod != nullptr) + DetourAttach(&(PVOID&)oPresent1_FSR3, hkPresent1_FSR3); + + if (oResizeBuffers_Mod != nullptr) + DetourAttach(&(PVOID&)oResizeBuffers_FSR3, hkResizeBuffers_FSR3); + + if (oResizeBuffers1_Mod != nullptr) + DetourAttach(&(PVOID&)oResizeBuffers1_FSR3, hkResizeBuffers1_FSR3); + + DetourTransactionCommit(); + + spdlog::info("ImGuiOverlayDx12::hkFfxConfigure_FSR3 added swapchain hooks!"); + + break; + } + } + + header = (ffxCreateContextDescHeader*)header->pNext; + } + } + + return result; +} + + #pragma endregion #pragma region Hooks for ExecuteCommandLists @@ -1395,22 +1514,18 @@ static bool CheckFSR3() } } - if (offxCreateFrameinterpolationSwapchainForHwndDX12_FSR3 == nullptr) + if (offxCreateFrameinterpolationSwapchainForHwndDX12_FSR3 == nullptr && oFfxCreateContext_FSR3 == nullptr) { // Check for native FSR3 (if game has native FSR3-FG) offxCreateFrameinterpolationSwapchainForHwndDX12_FSR3 = (PFN_ffxCreateFrameinterpolationSwapchainForHwndDX12)DetourFindFunction("ffx_backend_dx12_x64.dll", "ffxCreateFrameinterpolationSwapchainForHwndDX12"); offxFsr3ConfigureFrameGeneration_FSR3 = (PFN_ffxFsr3ConfigureFrameGeneration)DetourFindFunction("ffx_fsr3_x64.dll", "ffxFsr3ConfigureFrameGeneration"); - + // Hook FSR3 ffxGetDX12SwapchainPtr methods if (offxCreateFrameinterpolationSwapchainForHwndDX12_FSR3) { spdlog::info("ImGuiOverlayDx12::CheckMods FSR3's ffxCreateFrameinterpolationSwapchainForHwndDX12 found"); _bindedFSR3_Native = true; - } - // Hook FSR3 ffxGetDX12SwapchainPtr methods - if (offxCreateFrameinterpolationSwapchainForHwndDX12_FSR3 != nullptr && _bindedFSR3_Native) - { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); @@ -1420,6 +1535,28 @@ static bool CheckFSR3() DetourTransactionCommit(); } + else + { + oFfxCreateContext_FSR3 = (PfnFfxCreateContext)DetourFindFunction("amd_fidelityfx_dx12.dll", "ffxCreateContext"); + oFfxConfigure_FSR3 = (PfnFfxConfigure)DetourFindFunction("amd_fidelityfx_dx12.dll", "ffxConfigure"); + + if (oFfxCreateContext_FSR3) + { + spdlog::info("ImGuiOverlayDx12::CheckMods FSR3's ffxCreateContext found"); + _bindedFSR3_Native = true; + + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + + if (oFfxCreateContext_FSR3 != nullptr) + DetourAttach(&(PVOID&)oFfxCreateContext_FSR3, hkFfxCreateContext_FSR3); + + if (oFfxConfigure_FSR3 != nullptr) + DetourAttach(&(PVOID&)oFfxConfigure_FSR3, hkFfxConfigure_FSR3); + + DetourTransactionCommit(); + } + } } }