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();
+ }
+ }
}
}