mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-09-23 22:05:53 +00:00
add mutex to preven race condutions according to https://gpuopen.com/manuals/fidelityfx_sdk/fidelityfx_sdk-page_techniques_super-resolution-interpolation/#id11
This commit is contained in:
@@ -1412,7 +1412,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
|
||||
if (Config::Instance()->CurrentFeature != nullptr)
|
||||
fgLastFGFrame = Config::Instance()->CurrentFeature->FrameCount();
|
||||
|
||||
|
||||
auto dispatchResult = FfxApiProxy::D3D12_Dispatch()(reinterpret_cast<ffxContext*>(pUserCtx), ¶ms->header);
|
||||
|
||||
LOG_DEBUG("(FG) D3D12_Dispatch result: {}", (UINT)dispatchResult);
|
||||
@@ -1535,9 +1535,11 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
dfgPrepare.viewSpaceToMetersFactor = 1.0;
|
||||
dfgPrepare.frameTimeDelta = msDelta;
|
||||
|
||||
FrameGen_Dx12::ffxMutex.lock();
|
||||
Config::Instance()->dxgiSkipSpoofing = true;
|
||||
retCode = FfxApiProxy::D3D12_Dispatch()(&FrameGen_Dx12::fgContext, &dfgPrepare.header);
|
||||
Config::Instance()->dxgiSkipSpoofing = false;
|
||||
FrameGen_Dx12::ffxMutex.unlock();
|
||||
|
||||
if (retCode != FFX_API_RETURN_OK)
|
||||
LOG_ERROR("(FG) D3D12_Dispatch result: {}({})", retCode, FfxApiProxy::ReturnCodeToString(retCode));
|
||||
|
||||
@@ -122,7 +122,8 @@ typedef void(*PFN_CreateUnorderedAccessView)(ID3D12Device* This, ID3D12Resource*
|
||||
typedef HRESULT(*PFN_CreateDescriptorHeap)(ID3D12Device* This, D3D12_DESCRIPTOR_HEAP_DESC* pDescriptorHeapDesc, REFIID riid, void** ppvHeap);
|
||||
typedef void(*PFN_CopyDescriptors)(ID3D12Device* This, UINT NumDestDescriptorRanges, D3D12_CPU_DESCRIPTOR_HANDLE* pDestDescriptorRangeStarts, UINT* pDestDescriptorRangeSizes, UINT NumSrcDescriptorRanges, D3D12_CPU_DESCRIPTOR_HANDLE* pSrcDescriptorRangeStarts, UINT* pSrcDescriptorRangeSizes, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType);
|
||||
typedef void(*PFN_CopyDescriptorsSimple)(ID3D12Device* This, UINT NumDescriptors, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType);
|
||||
typedef UINT(*PFN_slInit)(const void* pref, uint64_t sdkVersion);
|
||||
|
||||
typedef HRESULT(*PFN_Present)(void* This, UINT SyncInterval, UINT Flags);
|
||||
|
||||
// Command list hooks for FG
|
||||
typedef void(*PFN_OMSetRenderTargets)(ID3D12GraphicsCommandList* This, UINT NumRenderTargetDescriptors, D3D12_CPU_DESCRIPTOR_HANDLE* pRenderTargetDescriptors, BOOL RTsSingleHandleToDescriptorRange, D3D12_CPU_DESCRIPTOR_HANDLE* pDepthStencilDescriptor);
|
||||
@@ -146,6 +147,7 @@ static PFN_CreateUnorderedAccessView o_CreateUnorderedAccessView = nullptr;
|
||||
static PFN_CreateDescriptorHeap o_CreateDescriptorHeap = nullptr;
|
||||
static PFN_CopyDescriptors o_CopyDescriptors = nullptr;
|
||||
static PFN_CopyDescriptorsSimple o_CopyDescriptorsSimple = nullptr;
|
||||
static PFN_Present o_FGSCPresent = nullptr;
|
||||
|
||||
// Original method calls for command list
|
||||
static PFN_OMSetRenderTargets o_OMSetRenderTargets = nullptr;
|
||||
@@ -182,7 +184,6 @@ static ShaderType fgSourceType = None;
|
||||
// mutexes
|
||||
static std::shared_mutex heapMutex;
|
||||
static std::shared_mutex resourceMutex;
|
||||
static std::shared_mutex ffxMutex;
|
||||
static std::shared_mutex hudlessMutex[FrameGen_Dx12::FG_BUFFER_SIZE];
|
||||
static std::shared_mutex counterMutex[FrameGen_Dx12::FG_BUFFER_SIZE];
|
||||
|
||||
@@ -233,7 +234,6 @@ static PFN_CreateDXGIFactory2 o_CreateDXGIFactory2 = nullptr;
|
||||
static PFN_CreateDXGIFactory o_SL_CreateDXGIFactory = nullptr;
|
||||
static PFN_CreateDXGIFactory1 o_SL_CreateDXGIFactory1 = nullptr;
|
||||
static PFN_CreateDXGIFactory2 o_SL_CreateDXGIFactory2 = nullptr;
|
||||
static PFN_slInit o_SL_slInit = nullptr;
|
||||
|
||||
inline static PFN_EnumAdapters2 ptrEnumAdapters = nullptr;
|
||||
inline static PFN_EnumAdapters12 ptrEnumAdapters1 = nullptr;
|
||||
@@ -519,8 +519,6 @@ static void GetHudless(ID3D12GraphicsCommandList* This)
|
||||
if (Config::Instance()->CurrentFeature != nullptr)
|
||||
fgLastFGFrame = Config::Instance()->CurrentFeature->FrameCount();
|
||||
|
||||
std::unique_lock<std::shared_mutex> lock(ffxMutex);
|
||||
|
||||
dispatchResult = FfxApiProxy::D3D12_Dispatch()(reinterpret_cast<ffxContext*>(pUserCtx), ¶ms->header);
|
||||
ID3D12CommandList* cl[1] = { nullptr };
|
||||
result = FrameGen_Dx12::fgCopyCommandList->Close();
|
||||
@@ -599,10 +597,14 @@ static void GetHudless(ID3D12GraphicsCommandList* This)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
FrameGen_Dx12::ffxMutex.lock();
|
||||
Config::Instance()->dxgiSkipSpoofing = true;
|
||||
retCode = FfxApiProxy::D3D12_Dispatch()(&FrameGen_Dx12::fgContext, &dfgPrepare.header);
|
||||
fgDispatchCalled = true;
|
||||
Config::Instance()->dxgiSkipSpoofing = false;
|
||||
FrameGen_Dx12::ffxMutex.unlock();
|
||||
|
||||
fgDispatchCalled = true;
|
||||
LOG_DEBUG("D3D12_Dispatch result: {0}, frame: {1}", retCode, frame);
|
||||
}
|
||||
}
|
||||
@@ -1496,17 +1498,24 @@ static void hkDispatch(ID3D12GraphicsCommandList* This, UINT ThreadGroupCountX,
|
||||
|
||||
#pragma region Callbacks for wrapped swapchain
|
||||
|
||||
static HRESULT hkFGPresent(void* This, UINT SyncInterval, UINT Flags)
|
||||
{
|
||||
FrameGen_Dx12::ffxMutex.lock();
|
||||
LOG_DEBUG("");
|
||||
auto result = o_FGSCPresent(This, SyncInterval, Flags);
|
||||
FrameGen_Dx12::ffxMutex.unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags, const DXGI_PRESENT_PARAMETERS* pPresentParameters, IUnknown* pDevice, HWND hWnd)
|
||||
{
|
||||
LOG_DEBUG("");
|
||||
|
||||
HRESULT presentResult;
|
||||
auto fIndex = fgFrameIndex;
|
||||
|
||||
|
||||
if (hWnd != Util::GetProcessWindow())
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> lock(ffxMutex);
|
||||
|
||||
if (pPresentParameters == nullptr)
|
||||
presentResult = pSwapChain->Present(SyncInterval, Flags);
|
||||
else
|
||||
@@ -1577,8 +1586,6 @@ static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags
|
||||
if (device12 != nullptr)
|
||||
device12->Release();
|
||||
|
||||
std::unique_lock<std::shared_mutex> lock(ffxMutex);
|
||||
|
||||
if (pPresentParameters == nullptr)
|
||||
presentResult = pSwapChain->Present(SyncInterval, Flags);
|
||||
else
|
||||
@@ -1678,8 +1685,6 @@ static HRESULT Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags
|
||||
|
||||
frameCounter++;
|
||||
|
||||
std::unique_lock<std::shared_mutex> lock(ffxMutex);
|
||||
|
||||
// swapchain present
|
||||
if (pPresentParameters == nullptr)
|
||||
presentResult = pSwapChain->Present(SyncInterval, Flags);
|
||||
@@ -1876,6 +1881,27 @@ static HRESULT hkCreateSwapChain(IDXGIFactory* pFactory, IUnknown* pDevice, DXGI
|
||||
|
||||
if (result == FFX_API_RETURN_OK)
|
||||
{
|
||||
// Hooking FG Swapchain present
|
||||
// for using ffxMutex during calls
|
||||
if (o_FGSCPresent == nullptr && *ppSwapChain != nullptr)
|
||||
{
|
||||
void** pFactoryVTable = *reinterpret_cast<void***>(*ppSwapChain);
|
||||
|
||||
o_FGSCPresent = (PFN_Present)pFactoryVTable[8];
|
||||
|
||||
if (o_FGSCPresent != nullptr)
|
||||
{
|
||||
LOG_INFO("Hooking native FG SwapChain present");
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
DetourAttach(&(PVOID&)o_FGSCPresent, hkFGPresent);
|
||||
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
}
|
||||
|
||||
scInfo.swapChainFormat = pDesc->BufferDesc.Format;
|
||||
scInfo.swapChainBufferCount = pDesc->BufferCount;
|
||||
scInfo.swapChain = (IDXGISwapChain4*)*ppSwapChain;
|
||||
@@ -2040,6 +2066,27 @@ static HRESULT hkCreateSwapChainForHwnd(IDXGIFactory* This, IUnknown* pDevice, H
|
||||
|
||||
if (result == FFX_API_RETURN_OK)
|
||||
{
|
||||
// Hooking FG Swapchain present
|
||||
// for using ffxMutex during calls
|
||||
if (o_FGSCPresent == nullptr && *ppSwapChain != nullptr)
|
||||
{
|
||||
void** pFactoryVTable = *reinterpret_cast<void***>(*ppSwapChain);
|
||||
|
||||
o_FGSCPresent = (PFN_Present)pFactoryVTable[8];
|
||||
|
||||
if (o_FGSCPresent != nullptr)
|
||||
{
|
||||
LOG_INFO("Hooking native FG SwapChain present");
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
DetourAttach(&(PVOID&)o_FGSCPresent, hkFGPresent);
|
||||
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
}
|
||||
|
||||
scInfo.swapChainFormat = pDesc->Format;
|
||||
scInfo.swapChainBufferCount = pDesc->BufferCount;
|
||||
scInfo.swapChain = (IDXGISwapChain4*)*ppSwapChain;
|
||||
@@ -2987,7 +3034,10 @@ void FrameGen_Dx12::ReleaseFGSwapchain(HWND hWnd)
|
||||
|
||||
if (FrameGen_Dx12::fgSwapChainContext != nullptr)
|
||||
{
|
||||
|
||||
FrameGen_Dx12::ffxMutex.lock();
|
||||
auto result = FfxApiProxy::D3D12_DestroyContext()(&FrameGen_Dx12::fgSwapChainContext, nullptr);
|
||||
FrameGen_Dx12::ffxMutex.unlock();
|
||||
LOG_INFO("Destroy Ffx Swapchain Result: {}({})", result, FfxApiProxy::ReturnCodeToString(result));
|
||||
FrameGen_Dx12::fgSwapChainContext = nullptr;
|
||||
fgSwapChains.erase(hWnd);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <d3d12.h>
|
||||
#include <dxgi1_6.h>
|
||||
|
||||
//#define ENABLE_DEBUG_LAYER
|
||||
#define ENABLE_DEBUG_LAYER
|
||||
//#define ENABLE_GPU_VALIDATION
|
||||
|
||||
#ifdef ENABLE_DEBUG_LAYER
|
||||
@@ -43,7 +43,6 @@ namespace HooksDx
|
||||
void HookDx11();
|
||||
void HookDx12();
|
||||
void HookDxgi();
|
||||
void HookSLDxgi();
|
||||
}
|
||||
|
||||
namespace FrameGen_Dx12
|
||||
@@ -71,6 +70,10 @@ namespace FrameGen_Dx12
|
||||
inline FT_Dx12* fgFormatTransfer = nullptr;
|
||||
inline bool fgIsActive = false;
|
||||
|
||||
// According to https://gpuopen.com/manuals/fidelityfx_sdk/fidelityfx_sdk-page_techniques_super-resolution-interpolation/#id11
|
||||
// will use this mutex to prevent race condutions
|
||||
inline std::mutex ffxMutex;
|
||||
|
||||
UINT ClearFrameResources();
|
||||
UINT GetFrame();
|
||||
void NewFrame();
|
||||
|
||||
Reference in New Issue
Block a user