diff --git a/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp b/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp index b603f10e..9c4d9a0e 100644 --- a/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp +++ b/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp @@ -256,16 +256,17 @@ bool FSRFG_Dx12::DispatchHudless(bool useHudless, double frameTime) { LOG_DEBUG("useHudless: {}, frameTime: {}", useHudless, frameTime); - // wait for copy operation - LOG_DEBUG("FG Queue wait for copy"); - _commandQueue->Wait(_copyFence, _frameCount); - + // FG queue wait for copy operations if (useHudless) { + LOG_DEBUG("FG Queue wait for copy"); + _commandQueue->Wait(_copyFence, _frameCount); + LOG_DEBUG("FG Queue wait for hudless copy"); _commandQueue->Wait(_hudlessCopyFence, _frameCount); } + // game queue wait for FG if (useHudless && State::Instance().currentCommandQueue != nullptr) { LOG_DEBUG("Game Queue wait for FG"); @@ -400,12 +401,25 @@ bool FSRFG_Dx12::DispatchHudless(bool useHudless, double frameTime) if (result == S_OK) { ID3D12CommandList* cl[] = { _commandList[fIndex] }; - _commandQueue->ExecuteCommandLists(1, cl); - if (useHudless && State::Instance().currentCommandQueue != nullptr) - _commandQueue->Signal(_fgFence, _frameCount); + // use FG queue + if (useHudless) + { + _commandQueue->ExecuteCommandLists(1, cl); + + // Signal game queue + if (State::Instance().currentCommandQueue != nullptr) + { + _commandQueue->Signal(_fgFence, _frameCount); + LOG_DEBUG("Execute and signal from FG Queue"); + } + } else + { + // Use game queue _gameCommandQueue->ExecuteCommandLists(1, cl); + LOG_DEBUG("Execute from game queue!!"); + } } //} diff --git a/OptiScaler/hooks/HooksDx.cpp b/OptiScaler/hooks/HooksDx.cpp index 9329a5ea..c788ecec 100644 --- a/OptiScaler/hooks/HooksDx.cpp +++ b/OptiScaler/hooks/HooksDx.cpp @@ -156,23 +156,23 @@ static HRESULT hkFGPresent(void* This, UINT SyncInterval, UINT Flags) fg = reinterpret_cast(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; } @@ -248,8 +248,6 @@ static HRESULT Present(IDXGISwapChain * pSwapChain, UINT SyncInterval, UINT Flag if (!_dx12Device) LOG_DEBUG("D3D12CommandQueue captured"); - //HooksDx::fgFSRCommandQueue = (ID3D12CommandQueue*)pDevice; - //HooksDx::fgFSRCommandQueue->SetName(L"fgFSRSwapChainQueue"); State::Instance().currentCommandQueue = cq; State::Instance().swapchainApi = DX12; @@ -368,10 +366,6 @@ static HRESULT Present(IDXGISwapChain * pSwapChain, UINT SyncInterval, UINT Flag fakenvapi::reportFGPresent(pSwapChain, fg != nullptr && fg->IsActive(), _frameCounter % 2); } - // death stranding fix??? - //if (_frameCounter < 5) - // std::this_thread::sleep_for(std::chrono::milliseconds(500)); - _frameCounter++; // swapchain present @@ -399,20 +393,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; } diff --git a/OptiScaler/hudfix/Hudfix_Dx12.cpp b/OptiScaler/hudfix/Hudfix_Dx12.cpp index 510c99a4..0fb87dfe 100644 --- a/OptiScaler/hudfix/Hudfix_Dx12.cpp +++ b/OptiScaler/hudfix/Hudfix_Dx12.cpp @@ -457,18 +457,30 @@ bool Hudfix_Dx12::CheckForHudless(std::string callerName, ID3D12GraphicsCommandL { auto info = &_hudlessList[resource->buffer]; - // if game starts reusing the buffer + // if game starts reusing the ignored resource & it's not banned if (info->ignore && !info->dontReuse) { - // increase reuse count once per frame + // check resource once per frame if (info->lastTriedFrame != _upscaleCounter) { + // start retry period + if (info->retryStartFrame == 0) + { + LOG_WARN("Retry for {:X} as hudless, current frame: {}", (size_t)resource->buffer, _upscaleCounter); + info->retryStartFrame = _upscaleCounter; + info->lastTriedFrame = _upscaleCounter; + info->retryCount = 0; + break; + } + info->retryCount++; info->lastTriedFrame = _upscaleCounter; - // in last 69 frames tried to use at least 20 times (around everd 3rd frame) + // If still in retry period (70 frames) if ((_upscaleCounter - info->retryStartFrame) < 69) { + // and used at least 20 times (around every 3rd frame) + // try reusing the resource if (info->retryCount > 19) { LOG_WARN("Reusing {:X} as hudless, retry start frame: {}, current frame: {}, reuse count: {}", (size_t)resource->buffer, info->retryStartFrame, _upscaleCounter, info->retryCount); @@ -483,21 +495,15 @@ bool Hudfix_Dx12::CheckForHudless(std::string callerName, ID3D12GraphicsCommandL } else { - LOG_WARN("Reset retry for {:X} as hudless, current frame: {}", (size_t)resource->buffer, _upscaleCounter); + // Retry period ended without success, reset values + + LOG_WARN("Retry failed for {:X} as hudless, current frame: {}", (size_t)resource->buffer, _upscaleCounter); info->useCount = 0; info->retryCount = 0; - info->lastTriedFrame = 0; info->retryStartFrame = 0; } } - - // update last check frame - if (info->ignore && info->retryStartFrame == 0) - { - LOG_WARN("Retry for {:X} as hudless, current frame: {}", (size_t)resource->buffer, _upscaleCounter); - info->retryStartFrame = _upscaleCounter; - } } // directly ignore @@ -513,6 +519,7 @@ bool Hudfix_Dx12::CheckForHudless(std::string callerName, ID3D12GraphicsCommandL info->retryCount = 0; info->lastTriedFrame = 0; info->retryStartFrame = 0; + info->lastUsedFrame = _upscaleCounter; // don't reuse more than 2 times if (info->reuseCount > 1) @@ -527,7 +534,7 @@ bool Hudfix_Dx12::CheckForHudless(std::string callerName, ID3D12GraphicsCommandL } else { - _hudlessList[resource->buffer] = { _upscaleCounter, 0, 0, 0, 1, false }; + _hudlessList[resource->buffer] = { _upscaleCounter, 0, 0, 0, 0, 1, false, false }; } if (!CheckCapture())