This commit is contained in:
cdozdil
2025-05-13 09:35:43 +03:00
10 changed files with 173 additions and 86 deletions
+10 -9
View File
@@ -31,27 +31,28 @@ protected:
public:
OwnedMutex Mutex;
bool IsActive();
int GetIndex();
virtual feature_version Version() = 0;
virtual const char* Name() = 0;
virtual UINT64 UpscaleStart() = 0;
virtual void UpscaleEnd() = 0;
virtual void FgDone() = 0;
virtual void ReleaseObjects() = 0;
virtual void StopAndDestroyContext(bool destroy, bool shutDown, bool useMutex) = 0;
bool IsActive();
int GetIndex();
void SetJitter(float x, float y);
void SetMVScale(float x, float y);
void SetCameraValues(float nearValue, float farValue, float vFov, float meterFactor = 0.0f);
void SetFrameTimeDelta(float delta);
void SetReset(UINT reset);
virtual feature_version Version() = 0;
virtual const char* Name() = 0;
virtual void ReleaseObjects() = 0;
virtual void StopAndDestroyContext(bool destroy, bool shutDown, bool useMutex) = 0;
virtual void FgDone() = 0;
void ResetCounters();
void UpdateTarget();
+16 -10
View File
@@ -43,26 +43,32 @@ protected:
public:
void SetVelocity(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* velocity, D3D12_RESOURCE_STATES state);
void SetDepth(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* depth, D3D12_RESOURCE_STATES state);
void SetHudless(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* hudless, D3D12_RESOURCE_STATES state, bool makeCopy = false);
virtual bool CreateSwapchain(IDXGIFactory* factory, ID3D12CommandQueue* cmdQueue, DXGI_SWAP_CHAIN_DESC* desc, IDXGISwapChain** swapChain) = 0;
virtual bool CreateSwapchain1(IDXGIFactory* factory, ID3D12CommandQueue* cmdQueue, HWND hwnd, DXGI_SWAP_CHAIN_DESC1* desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, IDXGISwapChain1** swapChain) = 0;
virtual bool ReleaseSwapchain(HWND hwnd) = 0;
void CreateObjects(ID3D12Device* InDevice);
virtual void CreateContext(ID3D12Device* device, IFeature* upscalerContext) = 0;
void ReleaseObjects() final;
virtual bool Dispatch(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* output, double frameTime) = 0;
virtual bool DispatchHudless(bool useHudless, double frameTime) = 0;
virtual void* FrameGenerationContext() = 0;
virtual void* SwapchainContext() = 0;
// IFGFeature
void ReleaseObjects() override final;
void CreateObjects(ID3D12Device* InDevice);
void SetVelocity(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* velocity, D3D12_RESOURCE_STATES state);
void SetDepth(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* depth, D3D12_RESOURCE_STATES state);
void SetHudless(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* hudless, D3D12_RESOURCE_STATES state, bool makeCopy = false);
ID3D12Fence* GetCopyFence();
ID3D12Fence* GetHudlessFence();
void SetWaitOnGameQueue(UINT64 value);
virtual bool Dispatch(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* output, double frameTime) = 0;
virtual bool DispatchHudless(bool useHudless, double frameTime) = 0;
bool IsFGCommandList(void* cmdList);
IFGFeature_Dx12() = default;
+22 -10
View File
@@ -19,7 +19,7 @@ typedef struct FfxSwapchainFramePacingTuning
void FSRFG_Dx12::ConfigureFramePaceTuning()
{
if (_swapChainContext == nullptr)
if (_swapChainContext == nullptr || !isVersionOrBetter(Version(), { 3, 1, 3 }))
return;
FfxSwapchainFramePacingTuning fpt{};
@@ -30,15 +30,15 @@ void FSRFG_Dx12::ConfigureFramePaceTuning()
fpt.hybridSpinTime = Config::Instance()->FGFPTHybridSpinTime.value_or_default();
fpt.safetyMarginInMs = Config::Instance()->FGFPTSafetyMarginInMs.value_or_default();
fpt.varianceFactor = Config::Instance()->FGFPTVarianceFactor.value_or_default();
ffxConfigureDescFrameGenerationSwapChainKeyValueDX12 cfgDesc{};
cfgDesc.header.type = FFX_API_CONFIGURE_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_KEYVALUE_DX12;
cfgDesc.key = 2; // FfxSwapchainFramePacingTuning
cfgDesc.ptr = &fpt;
auto result = FfxApiProxy::D3D12_Configure()(&_swapChainContext, &cfgDesc.header);
LOG_DEBUG("HybridSpin D3D12_Configure result: {}", FfxApiProxy::ReturnCodeToString(result));
}
ffxConfigureDescFrameGenerationSwapChainKeyValueDX12 cfgDesc{};
cfgDesc.header.type = FFX_API_CONFIGURE_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_KEYVALUE_DX12;
cfgDesc.key = 2; // FfxSwapchainFramePacingTuning
cfgDesc.ptr = &fpt;
auto result = FfxApiProxy::D3D12_Configure()(&_swapChainContext, &cfgDesc.header);
LOG_DEBUG("HybridSpin D3D12_Configure result: {}", FfxApiProxy::ReturnCodeToString(result));
}
void FSRFG_Dx12::GetDispatchCommandList()
@@ -562,7 +562,19 @@ void FSRFG_Dx12::FgDone()
LOG_TRACE("Releasing Mutex: {}", Mutex.getOwner());
Mutex.unlockThis(1);
}
};
}
void* FSRFG_Dx12::FrameGenerationContext()
{
LOG_DEBUG("");
return (void*)_fgContext;
}
void* FSRFG_Dx12::SwapchainContext()
{
LOG_DEBUG("");
return _swapChainContext;
}
void FSRFG_Dx12::StopAndDestroyContext(bool destroy, bool shutDown, bool useMutex)
{
+21 -19
View File
@@ -17,35 +17,37 @@ private:
void GetDispatchCommandList();
public:
// Inherited via IFGFeature_Dx12
UINT64 UpscaleStart() final;
void UpscaleEnd() final;
// IFGFeature
const char* Name() override final;
feature_version Version() override final;
feature_version Version() final;
UINT64 UpscaleStart() override final;
void UpscaleEnd() override final;
const char* Name() final;
void FgDone() override final;
void StopAndDestroyContext(bool destroy, bool shutDown, bool useMutex) override final;
bool Dispatch(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* output, double frameTime) final;
// IFGFeature_Dx12
bool CreateSwapchain(IDXGIFactory* factory, ID3D12CommandQueue* cmdQueue, DXGI_SWAP_CHAIN_DESC* desc, IDXGISwapChain** swapChain) override final;
bool CreateSwapchain1(IDXGIFactory* factory, ID3D12CommandQueue* cmdQueue, HWND hwnd, DXGI_SWAP_CHAIN_DESC1* desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, IDXGISwapChain1** swapChain) override final;
bool ReleaseSwapchain(HWND hwnd) override final;
bool DispatchHudless(bool useHudless, double frameTime) final;
void CreateContext(ID3D12Device* device, IFeature* upscalerContext) override final;
void StopAndDestroyContext(bool destroy, bool shutDown, bool useMutex) final;
bool Dispatch(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* output, double frameTime) override final;
bool DispatchHudless(bool useHudless, double frameTime) override final;
bool CreateSwapchain(IDXGIFactory* factory, ID3D12CommandQueue* cmdQueue, DXGI_SWAP_CHAIN_DESC* desc, IDXGISwapChain** swapChain) final;
bool CreateSwapchain1(IDXGIFactory* factory, ID3D12CommandQueue* cmdQueue, HWND hwnd, DXGI_SWAP_CHAIN_DESC1* desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, IDXGISwapChain1** swapChain) final;
bool ReleaseSwapchain(HWND hwnd) final;
void CreateContext(ID3D12Device* device, IFeature* upscalerContext) final;
void* FrameGenerationContext() override final;
void* SwapchainContext() override final;
// Methods
void ConfigureFramePaceTuning();
ffxReturnCode_t DispatchCallback(ffxDispatchDescFrameGeneration* params);
ffxReturnCode_t HudlessDispatchCallback(ffxDispatchDescFrameGeneration* params);
FSRFG_Dx12() = default;
// Inherited via IFGFeature_Dx12
void FgDone() override;
FSRFG_Dx12() : IFGFeature_Dx12(), IFGFeature()
{
//
}
};
+32 -32
View File
@@ -156,23 +156,23 @@ static HRESULT hkFGPresent(void* This, UINT SyncInterval, UINT Flags)
fg = reinterpret_cast<IFGFeature_Dx12*>(State::Instance().currentFG);
auto lockAccuired = false;
if (!(Flags & DXGI_PRESENT_TEST || Flags & DXGI_PRESENT_RESTART) && fg != nullptr && fg->IsActive() &&
fg->TargetFrame() < fg->FrameCount() && Config::Instance()->FGUseMutexForSwaphain.value_or_default() && fg->Mutex.getOwner() != 2)
{
LOG_TRACE("Waiting FG->Mutex 2, current: {}", fg->Mutex.getOwner());
fg->Mutex.lock(2);
//if (!(Flags & DXGI_PRESENT_TEST || Flags & DXGI_PRESENT_RESTART) && fg != nullptr && fg->IsActive() &&
// fg->TargetFrame() < fg->FrameCount() && Config::Instance()->FGUseMutexForSwaphain.value_or_default() && fg->Mutex.getOwner() != 2)
//{
// LOG_TRACE("Waiting FG->Mutex 2, current: {}", fg->Mutex.getOwner());
// fg->Mutex.lock(2);
// If half or full sync is active, we need to release the mutex after 1 or 2 frames at Present
lockAccuired = !Config::Instance()->FGHudfixHalfSync.value_or_default() && !Config::Instance()->FGHudfixFullSync.value_or_default();
_lockAccuiredForHalfOrFull = !lockAccuired;
// // If half or full sync is active, we need to release the mutex after 1 or 2 frames at Present
// lockAccuired = !Config::Instance()->FGHudfixHalfSync.value_or_default() && !Config::Instance()->FGHudfixFullSync.value_or_default();
// _lockAccuiredForHalfOrFull = !lockAccuired;
if (Config::Instance()->FGDebugView.value_or_default() || Config::Instance()->FGHudfixHalfSync.value_or_default())
_releaseMutexTargetFrame = _frameCounter + 1; // For debug 1 frame
else
_releaseMutexTargetFrame = _frameCounter + 2; // For FG 2 frames
// if (Config::Instance()->FGDebugView.value_or_default() || Config::Instance()->FGHudfixHalfSync.value_or_default())
// _releaseMutexTargetFrame = _frameCounter + 1; // For debug 1 frame
// else
// _releaseMutexTargetFrame = _frameCounter + 2; // For FG 2 frames
LOG_TRACE("Accuired FG->Mutex: {}, fgMutexReleaseFrame: {}", fg->Mutex.getOwner(), _releaseMutexTargetFrame);
}
// LOG_TRACE("Accuired FG->Mutex: {}, fgMutexReleaseFrame: {}", fg->Mutex.getOwner(), _releaseMutexTargetFrame);
//}
if (!(Flags & DXGI_PRESENT_TEST || Flags & DXGI_PRESENT_RESTART))
{
@@ -184,11 +184,11 @@ static HRESULT hkFGPresent(void* This, UINT SyncInterval, UINT Flags)
result = o_FGSCPresent(This, SyncInterval, Flags);
LOG_DEBUG("Result: {:X}", result);
if (lockAccuired && Config::Instance()->FGUseMutexForSwaphain.value_or_default())
{
LOG_TRACE("Releasing FG->Mutex: {}", fg->Mutex.getOwner());
fg->Mutex.unlockThis(2);
}
//if (lockAccuired && Config::Instance()->FGUseMutexForSwaphain.value_or_default())
//{
// LOG_TRACE("Releasing FG->Mutex: {}", fg->Mutex.getOwner());
// fg->Mutex.unlockThis(2);
//}
return result;
}
@@ -399,20 +399,20 @@ static HRESULT Present(IDXGISwapChain * pSwapChain, UINT SyncInterval, UINT Flag
ResTrack_Dx12::PresentDone();
// If Half of Full sync is active or was active (_releaseMutexTargetFrame != 0)
if (_releaseMutexTargetFrame != 0 && Config::Instance()->FGUseMutexForSwaphain.value_or_default() && _frameCounter >= _releaseMutexTargetFrame && fg != nullptr)
{
if (_lockAccuiredForHalfOrFull)
{
LOG_TRACE("Releasing FG->Mutex: {}", fg->Mutex.getOwner());
fg->Mutex.unlockThis(2);
_lockAccuiredForHalfOrFull = false;
}
//if (_releaseMutexTargetFrame != 0 && Config::Instance()->FGUseMutexForSwaphain.value_or_default() && _frameCounter >= _releaseMutexTargetFrame && fg != nullptr)
//{
// if (_lockAccuiredForHalfOrFull)
// {
// LOG_TRACE("Releasing FG->Mutex: {}", fg->Mutex.getOwner());
// fg->Mutex.unlockThis(2);
// _lockAccuiredForHalfOrFull = false;
// }
_releaseMutexTargetFrame = 0;
// _releaseMutexTargetFrame = 0;
// Signal for pause
fg->FgDone();
}
// // Signal for pause
// fg->FgDone();
//}
return presentResult;
}
@@ -1991,7 +1991,7 @@ void HooksDx::ReleaseDx12SwapChain(HWND hwnd)
if (State::Instance().currentFG != nullptr)
fg = reinterpret_cast<IFGFeature_Dx12*>(State::Instance().currentFG);
if (fg != nullptr)
if (fg != nullptr && fg->SwapchainContext() != nullptr)
fg->ReleaseSwapchain(hwnd);
}
+1
View File
@@ -254,6 +254,7 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::SetFullscreenState(BOOL Fullsc
else
LOG_DEBUG("result: {:X}", result);
/*
if (Config::Instance()->FGEnabled.value_or_default())
{
State::Instance().FGresetCapturedResources = true;
+61
View File
@@ -172,6 +172,67 @@ ffxReturnCode_t ffxCreateContext_Dx12(ffxContext* context, ffxCreateContextDescH
auto backendDesc = (ffxCreateBackendDX12Desc*)header;
_d3d12Device = backendDesc->device;
}
else if (State::Instance().activeFgType == OptiFG)
{
if (header->type == FFX_API_CREATE_CONTEXT_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_WRAP_DX12)
{
LOG_INFO("Using already wrapped swapchain");
return FFX_API_RETURN_OK;
}
else if (header->type == FFX_API_CREATE_CONTEXT_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_NEW_DX12)
{
LOG_INFO("Creating OptiFG swapchain, new swapchain");
auto fgDesc = (ffxCreateContextDescFrameGenerationSwapChainNewDX12*)header;
auto scResult = fgDesc->dxgiFactory->CreateSwapChain(fgDesc->gameQueue, fgDesc->desc, (IDXGISwapChain**)fgDesc->swapchain);
if (scResult == S_OK)
{
if (State::Instance().currentFG == nullptr)
{
LOG_ERROR("State::Instance().currentFG is nullptr");
return FFX_API_RETURN_ERROR_PARAMETER;
}
void* scContext = State::Instance().currentFG->SwapchainContext();
context = (ffxContext*)&scContext;
return FFX_API_RETURN_OK;
}
else
{
LOG_ERROR("CreateSwapChain error: {:X}", (UINT)scResult);
return FFX_API_RETURN_ERROR_PARAMETER;
}
}
else if (header->type == FFX_API_CREATE_CONTEXT_DESC_TYPE_FRAMEGENERATIONSWAPCHAIN_FOR_HWND_DX12)
{
LOG_INFO("Creating OptiFG swapchain, new swapchain for hwnd");
auto fgDesc = (ffxCreateContextDescFrameGenerationSwapChainForHwndDX12*)header;
IDXGIFactory2* factory = nullptr;
auto scResult = fgDesc->dxgiFactory->QueryInterface(IID_PPV_ARGS(&factory));
if (scResult != S_OK)
{
LOG_ERROR("CreateSwapChain error: {:X}", (UINT)scResult);
return FFX_API_RETURN_ERROR_PARAMETER;
}
factory->Release();
scResult = factory->CreateSwapChainForHwnd(fgDesc->gameQueue, fgDesc->hwnd, fgDesc->desc, fgDesc->fullscreenDesc, nullptr, (IDXGISwapChain1**)fgDesc->swapchain);
if (scResult == S_OK)
{
auto fg = reinterpret_cast<IFGFeature_Dx12*>(State::Instance().currentFG);
auto scContext = fg->SwapchainContext();
context = (ffxContext*)&scContext;
return FFX_API_RETURN_OK;
}
else
{
LOG_ERROR("CreateSwapChainForHwnd error: {:X}", (UINT)scResult);
return FFX_API_RETURN_ERROR_PARAMETER;
}
}
}
header = header->pNext;
+2 -1
View File
@@ -1619,6 +1619,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
if (Config::Instance()->FGHUDFix.value_or_default())
{
// For signal after mv & depth copies
ResTrack_Dx12::SetUpscalerCmdList(InCmdList);
Hudfix_Dx12::UpscaleEnd(deviceContext->feature->FrameCount(), ftDelta);
@@ -1659,7 +1660,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
LOG_WARN("Can't restore ComputeRootSig!");
}
if (Config::Instance()->RestoreGraphicSignature.value_or_default() && /*graphTime != 0 && graphTime > lastEvalTime && graphTime <= evaluateStart &&*/ graphicSignatures[InCmdList])
if (Config::Instance()->RestoreGraphicSignature.value_or_default() && graphicSignatures[InCmdList])
{
auto signature = graphicSignatures[InCmdList];
LOG_TRACE("restore orgGraphicRootSig: {0:X}", (UINT64)signature);
+5 -5
View File
@@ -1627,11 +1627,11 @@ bool MenuCommon::RenderMenu()
{
Config::Instance()->FGDebugView = fgDV;
//if (Config::Instance()->FGEnabled.value_or_default())
//{
// State::Instance().FGchanged = true;
// LOG_DEBUG("DebugView set FGChanged");
//}
if (Config::Instance()->FGEnabled.value_or_default())
{
State::Instance().FGchanged = true;
LOG_DEBUG("DebugView set FGChanged");
}
}
ShowHelpMarker("Enable FSR 3.1 frame generation debug view");
@@ -2182,6 +2182,9 @@ void ResTrack_Dx12::ClearPossibleHudless()
_skipHudless = false;
_rcActive = false;
_cmdList = false;
//_upscalerCommandList = nullptr;
//_commandList = nullptr;
}
void ResTrack_Dx12::PresentDone()