From dcadadb05fc313607b043c8f47b04db02c8d83c5 Mon Sep 17 00:00:00 2001 From: cdozdil Date: Fri, 11 Jul 2025 23:20:20 +0300 Subject: [PATCH] Use games command lists --- OptiScaler/framegen/IFGFeature_Dx12.cpp | 209 ++++++++++-------- OptiScaler/framegen/IFGFeature_Dx12.h | 15 +- OptiScaler/framegen/ffx/FSRFG_Dx12.cpp | 71 +++--- OptiScaler/framegen/ffx/FSRFG_Dx12.h | 2 +- OptiScaler/hudfix/Hudfix_Dx12.cpp | 16 +- OptiScaler/hudfix/Hudfix_Dx12.h | 2 +- OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp | 2 +- .../resource_tracking/ResTrack_dx12.cpp | 201 +++++++++++------ OptiScaler/resource_tracking/ResTrack_dx12.h | 7 +- 9 files changed, 319 insertions(+), 206 deletions(-) diff --git a/OptiScaler/framegen/IFGFeature_Dx12.cpp b/OptiScaler/framegen/IFGFeature_Dx12.cpp index 6ffb71e6..f99c24a1 100644 --- a/OptiScaler/framegen/IFGFeature_Dx12.cpp +++ b/OptiScaler/framegen/IFGFeature_Dx12.cpp @@ -205,71 +205,73 @@ void IFGFeature_Dx12::SetHudless(ID3D12GraphicsCommandList* cmdList, ID3D12Resou void IFGFeature_Dx12::CreateObjects(ID3D12Device* InDevice) { - if (_commandAllocators[0] != nullptr) return; - _device = InDevice; + // if (_commandAllocators[0] != nullptr) + // return; - LOG_DEBUG(""); + //_device = InDevice; - do - { - HRESULT result; + // LOG_DEBUG(""); - for (size_t i = 0; i < BUFFER_COUNT; i++) - { - ID3D12CommandAllocator* allocator = nullptr; - result = InDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&allocator)); - if (result != S_OK) - { - LOG_ERROR("CreateCommandAllocators _commandAllocators[{}]: {:X}", i, (unsigned long) result); - break; - } - allocator->SetName(L"_commandAllocator"); - if (!CheckForRealObject(__FUNCTION__, allocator, (IUnknown**) &_commandAllocators[i])) - _commandAllocators[i] = allocator; + // do + //{ + // HRESULT result; - ID3D12GraphicsCommandList* cmdList = nullptr; - result = InDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, _commandAllocators[i], NULL, - IID_PPV_ARGS(&cmdList)); - if (result != S_OK) - { - LOG_ERROR("CreateCommandList _commandList[{}]: {:X}", i, (unsigned long) result); - break; - } - cmdList->SetName(L"_commandList"); - if (!CheckForRealObject(__FUNCTION__, cmdList, (IUnknown**) &_commandList[i])) - _commandList[i] = cmdList; + // for (size_t i = 0; i < BUFFER_COUNT; i++) + // { + // ID3D12CommandAllocator* allocator = nullptr; + // result = InDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&allocator)); + // if (result != S_OK) + // { + // LOG_ERROR("CreateCommandAllocators _commandAllocators[{}]: {:X}", i, (unsigned long) result); + // break; + // } + // allocator->SetName(L"_commandAllocator"); + // if (!CheckForRealObject(__FUNCTION__, allocator, (IUnknown**) &_commandAllocators[i])) + // _commandAllocators[i] = allocator; - result = _commandList[i]->Close(); - if (result != S_OK) - { - LOG_ERROR("_commandList[{}]->Close: {:X}", i, (unsigned long) result); - break; - } - } + // ID3D12GraphicsCommandList* cmdList = nullptr; + // result = InDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, _commandAllocators[i], NULL, + // IID_PPV_ARGS(&cmdList)); + // if (result != S_OK) + // { + // LOG_ERROR("CreateCommandList _commandList[{}]: {:X}", i, (unsigned long) result); + // break; + // } + // cmdList->SetName(L"_commandList"); + // if (!CheckForRealObject(__FUNCTION__, cmdList, (IUnknown**) &_commandList[i])) + // _commandList[i] = cmdList; - } while (false); + // result = _commandList[i]->Close(); + // if (result != S_OK) + // { + // LOG_ERROR("_commandList[{}]->Close: {:X}", i, (unsigned long) result); + // break; + // } + // } + + //} while (false); } void IFGFeature_Dx12::ReleaseObjects() { LOG_DEBUG(""); - for (size_t i = 0; i < BUFFER_COUNT; i++) - { - if (_commandAllocators[i] != nullptr) - { - _commandAllocators[i]->Release(); - _commandAllocators[i] = nullptr; - } + // for (size_t i = 0; i < BUFFER_COUNT; i++) + //{ + // if (_commandAllocators[i] != nullptr) + // { + // _commandAllocators[i]->Release(); + // _commandAllocators[i] = nullptr; + // } - if (_commandList[i] != nullptr) - { - _commandList[i]->Release(); - _commandList[i] = nullptr; - } - } + // if (_commandList[i] != nullptr) + // { + // _commandList[i]->Release(); + // _commandList[i] = nullptr; + // } + //} _mvFlip.reset(); _depthFlip.reset(); @@ -279,67 +281,90 @@ bool IFGFeature_Dx12::IsFGCommandList(void* cmdList) { auto found = false; - for (size_t i = 0; i < BUFFER_COUNT; i++) - { - if (_commandList[i] == cmdList) - { - found = true; - break; - } - } + // for (size_t i = 0; i < BUFFER_COUNT; i++) + //{ + // if (_commandList[i] == cmdList) + // { + // found = true; + // break; + // } + // } return found; } -bool IFGFeature_Dx12::ExecuteHudlessCmdList() +ID3D12CommandList* IFGFeature_Dx12::ExecuteHudlessCmdList(ID3D12CommandQueue* queue) { - if (!_hudlessDispatchReady) - return false; + return nullptr; - _mvAndDepthReady = false; - _hudlessReady = false; - _hudlessDispatchReady = false; + // static std::mutex executeMutex; - auto fIndex = GetIndex(); - auto result = _commandList[fIndex]->Close(); + // std::lock_guard lock(executeMutex); - LOG_DEBUG("_commandList[{}]->Close() result: {:X}", fIndex, (UINT) result); + // if (!_hudlessDispatchReady) + // return nullptr; - if (result == S_OK) - { - ID3D12CommandList* cl[] = { cl[0] = _commandList[fIndex] }; - _gameCommandQueue->ExecuteCommandLists(1, cl); + // auto fIndex = GetIndex(); + // auto result = _commandList[fIndex]->Close(); - return true; - } + //_mvAndDepthReady[fIndex] = false; + //_hudlessReady[fIndex] = false; + //_hudlessDispatchReady[fIndex] = false; - return false; + // LOG_DEBUG("_commandList[{}]->Close() result: {:X}", fIndex, (UINT) result); + + // if (result == S_OK) + //{ + // ID3D12CommandList* cl[] = { _commandList[fIndex] }; + + // if (queue == nullptr) + // _gameCommandQueue->ExecuteCommandLists(1, cl); + // else + // queue->ExecuteCommandLists(1, cl); + + // return _commandList[fIndex]; + //} + // else + //{ + // State::Instance().FGchanged = true; + //} + + // return nullptr; } -void IFGFeature_Dx12::SetVelocityAndDepthReady() { _mvAndDepthReady = true; } +void IFGFeature_Dx12::SetUpscaleInputsReady() { _mvAndDepthReady[GetIndex()] = true; } -void IFGFeature_Dx12::SetHudlessReady() { _hudlessReady = true; } +void IFGFeature_Dx12::SetHudlessReady() { _hudlessReady[GetIndex()] = true; } -void IFGFeature_Dx12::SetHudlessDispatchReady() { _hudlessDispatchReady = true; } +void IFGFeature_Dx12::SetHudlessDispatchReady() { _hudlessDispatchReady[GetIndex()] = true; } void IFGFeature_Dx12::Present() { - if (!_mvAndDepthReady) - { - _mvAndDepthReady = false; - _hudlessReady = false; - _hudlessDispatchReady = false; - return; - } + auto fIndex = LastDispatchedFrame() % BUFFER_COUNT; + _mvAndDepthReady[fIndex] = false; + _hudlessReady[fIndex] = false; + _hudlessDispatchReady[fIndex] = false; - auto hudless = _hudlessReady; - _mvAndDepthReady = false; - _hudlessReady = false; - _hudlessDispatchReady = false; + // if (!_mvAndDepthReady[fIndex]) + //{ + // _mvAndDepthReady[fIndex] = false; + // _hudlessReady[fIndex] = false; + // _hudlessDispatchReady[fIndex] = false; + // return; + // } - DispatchHudless(hudless, State::Instance().lastFrameTime); + // auto hudless = _hudlessReady[fIndex]; + //_mvAndDepthReady[fIndex] = false; + //_hudlessReady[fIndex] = false; + //_hudlessDispatchReady[fIndex] = false; + + // DispatchHudless(nullptr, hudless, State::Instance().lastFrameTime); } -bool IFGFeature_Dx12::UpscalerInputsReady() { return _mvAndDepthReady; } -bool IFGFeature_Dx12::HudlessReady() { return _hudlessReady; } -bool IFGFeature_Dx12::ReadyForExecute() { return _mvAndDepthReady && _hudlessReady; } +bool IFGFeature_Dx12::UpscalerInputsReady() { return _mvAndDepthReady[GetIndex()]; } +bool IFGFeature_Dx12::HudlessReady() { return _hudlessReady[GetIndex()]; } +bool IFGFeature_Dx12::ReadyForExecute() +{ + auto fIndex = GetIndex(); + return _mvAndDepthReady[fIndex] && _hudlessReady[fIndex]; +} diff --git a/OptiScaler/framegen/IFGFeature_Dx12.h b/OptiScaler/framegen/IFGFeature_Dx12.h index a29f72ee..bb445b95 100644 --- a/OptiScaler/framegen/IFGFeature_Dx12.h +++ b/OptiScaler/framegen/IFGFeature_Dx12.h @@ -12,9 +12,6 @@ class IFGFeature_Dx12 : public virtual IFGFeature { private: - bool _mvAndDepthReady = false; - bool _hudlessReady = false; - bool _hudlessDispatchReady = false; std::unique_ptr _mvFlip; std::unique_ptr _depthFlip; ID3D12Device* _device = nullptr; @@ -24,6 +21,10 @@ class IFGFeature_Dx12 : public virtual IFGFeature ID3D12CommandQueue* _gameCommandQueue = nullptr; HWND _hwnd = NULL; + bool _mvAndDepthReady[BUFFER_COUNT] = { false, false, false, false }; + bool _hudlessReady[BUFFER_COUNT] = { false, false, false, false }; + bool _hudlessDispatchReady[BUFFER_COUNT] = { false, false, false, false }; + ID3D12Resource* _paramVelocity[BUFFER_COUNT] = { nullptr, nullptr, nullptr, nullptr }; ID3D12Resource* _paramVelocityCopy[BUFFER_COUNT] = { nullptr, nullptr, nullptr, nullptr }; ID3D12Resource* _paramDepth[BUFFER_COUNT] = { nullptr, nullptr, nullptr, nullptr }; @@ -31,8 +32,8 @@ class IFGFeature_Dx12 : public virtual IFGFeature ID3D12Resource* _paramHudless[BUFFER_COUNT] = { nullptr, nullptr, nullptr, nullptr }; ID3D12Resource* _paramHudlessCopy[BUFFER_COUNT] = { nullptr, nullptr, nullptr, nullptr }; - ID3D12GraphicsCommandList* _commandList[BUFFER_COUNT] = { nullptr, nullptr, nullptr, nullptr }; - ID3D12CommandAllocator* _commandAllocators[BUFFER_COUNT] = { nullptr, nullptr, nullptr, nullptr }; + // ID3D12GraphicsCommandList* _commandList[BUFFER_COUNT] = { nullptr, nullptr, nullptr, nullptr }; + // ID3D12CommandAllocator* _commandAllocators[BUFFER_COUNT] = { nullptr, nullptr, nullptr, nullptr }; bool CreateBufferResource(ID3D12Device* InDevice, ID3D12Resource* InSource, D3D12_RESOURCE_STATES InState, ID3D12Resource** OutResource, bool UAV = false, bool depth = false); @@ -52,7 +53,7 @@ class IFGFeature_Dx12 : public virtual IFGFeature virtual void CreateContext(ID3D12Device* device, IFeature* upscalerContext) = 0; virtual bool Dispatch(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* output, double frameTime) = 0; - virtual bool DispatchHudless(bool useHudless, double frameTime) = 0; + virtual bool DispatchHudless(ID3D12GraphicsCommandList* cmdList, bool useHudless, double frameTime) = 0; virtual void* FrameGenerationContext() = 0; virtual void* SwapchainContext() = 0; @@ -68,7 +69,7 @@ class IFGFeature_Dx12 : public virtual IFGFeature bool makeCopy = false); bool IsFGCommandList(void* cmdList); - bool ExecuteHudlessCmdList(); + ID3D12CommandList* ExecuteHudlessCmdList(ID3D12CommandQueue* queue = nullptr); IFGFeature_Dx12() = default; diff --git a/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp b/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp index 3c077606..6a13a9a1 100644 --- a/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp +++ b/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp @@ -60,18 +60,19 @@ UINT64 FSRFG_Dx12::UpscaleStart() { _frameCount++; - if (!State::Instance().isShuttingDown && IsActive()) - { - auto frameIndex = GetIndex(); + // if (!State::Instance().isShuttingDown && IsActive()) + //{ + // auto frameIndex = GetIndex(); - if (Config::Instance()->FGHUDFix.value_or_default()) - { - auto allocator = _commandAllocators[frameIndex]; - auto result = allocator->Reset(); - result = _commandList[frameIndex]->Reset(allocator, nullptr); - LOG_DEBUG("_commandList[{}]->Reset()", frameIndex); - } - } + // if (Config::Instance()->FGHUDFix.value_or_default()) + // { + // auto allocator = _commandAllocators[frameIndex]; + // auto result = allocator->Reset(); + // LOG_DEBUG("_commandAllocators[{}]->Reset(): {:X}", frameIndex, result); + // result = _commandList[frameIndex]->Reset(allocator, nullptr); + // LOG_DEBUG("_commandList[{}]->Reset(): {:X}", frameIndex, result); + // } + //} return _frameCount; } @@ -256,10 +257,12 @@ bool FSRFG_Dx12::Dispatch(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* ou Mutex.unlockThis(1); } + _mvAndDepthReady[frameIndex] = false; + return retCode == FFX_API_RETURN_OK; } -bool FSRFG_Dx12::DispatchHudless(bool useHudless, double frameTime) +bool FSRFG_Dx12::DispatchHudless(ID3D12GraphicsCommandList* cmdList, bool useHudless, double frameTime) { LOG_DEBUG("useHudless: {}, frameTime: {}", useHudless, frameTime); @@ -271,11 +274,12 @@ bool FSRFG_Dx12::DispatchHudless(bool useHudless, double frameTime) ffxConfigureDescFrameGeneration m_FrameGenerationConfig = {}; m_FrameGenerationConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_FRAMEGENERATION; - if (useHudless) + if (useHudless && _paramHudless[fIndex] != nullptr) { LOG_TRACE("Using hudless: {:X}", (size_t) _paramHudless[fIndex]); m_FrameGenerationConfig.HUDLessColor = ffxApiGetResourceDX12(_paramHudless[fIndex], FFX_API_RESOURCE_STATE_COPY_DEST); + _paramHudless[fIndex] = nullptr; } else { @@ -357,8 +361,25 @@ bool FSRFG_Dx12::DispatchHudless(bool useHudless, double frameTime) dfgPrepare.header.type = FFX_API_DISPATCH_DESC_TYPE_FRAMEGENERATION_PREPARE; dfgPrepare.header.pNext = &backendDesc.header; - // GetDispatchCommandList(); - dfgPrepare.commandList = _commandList[fIndex]; + if (cmdList != nullptr) + { + dfgPrepare.commandList = cmdList; + } + else + { + // auto allocator = _commandAllocators[fIndex]; + // auto result = allocator->Reset(); + + // if (result != S_OK) + // return false; + + // result = _commandList[fIndex]->Reset(allocator, nullptr); + + // if (result != S_OK) + // return false; + + // dfgPrepare.commandList = _commandList[fIndex]; + } dfgPrepare.frameID = _frameCount; dfgPrepare.flags = m_FrameGenerationConfig.flags; @@ -383,18 +404,6 @@ bool FSRFG_Dx12::DispatchHudless(bool useHudless, double frameTime) LOG_DEBUG("D3D12_Dispatch result: {0}, frame: {1}, fIndex: {2}, commandList: {3:X}", retCode, _frameCount, fIndex, (size_t) dfgPrepare.commandList); - // if (retCode == FFX_API_RETURN_OK && !Config::Instance()->FGExecuteAfterCallback.value_or_default()) - //{ - // auto result = _commandList[fIndex]->Close(); - // LOG_DEBUG("_commandList[{}]->Close() result: {:X}", fIndex, (UINT) result); - - // if (result == S_OK) - // { - // ID3D12CommandList* cl[] = { cl[0] = _commandList[fIndex] }; - // _gameCommandQueue->ExecuteCommandLists(1, cl); - // } - //} - if (retCode == FFX_API_RETURN_OK) SetHudlessDispatchReady(); } @@ -405,6 +414,9 @@ bool FSRFG_Dx12::DispatchHudless(bool useHudless, double frameTime) Mutex.unlockThis(1); }; + _mvAndDepthReady[fIndex] = false; + _hudlessReady[fIndex] = false; + return retCode == FFX_API_RETURN_OK; } @@ -493,7 +505,7 @@ ffxReturnCode_t FSRFG_Dx12::HudlessDispatchCallback(ffxDispatchDescFrameGenerati // check for status if (!Config::Instance()->FGEnabled.value_or_default() || !Config::Instance()->FGHUDFix.value_or_default() || - _fgContext == nullptr || _gameCommandQueue == nullptr || State::Instance().SCchanged) + _fgContext == nullptr || State::Instance().SCchanged) { LOG_WARN("Cancel async dispatch"); params->numGeneratedFrames = 0; @@ -501,8 +513,7 @@ ffxReturnCode_t FSRFG_Dx12::HudlessDispatchCallback(ffxDispatchDescFrameGenerati // If fg is active but upscaling paused if (State::Instance().currentFeature == nullptr || State::Instance().FGchanged || fIndex < 0 || !IsActive() || - State::Instance().currentFeature->FrameCount() == 0 || _commandList[fIndex] == nullptr || - params->frameID == _lastUpscaledFrameId) + State::Instance().currentFeature->FrameCount() == 0 || params->frameID == _lastUpscaledFrameId) { LOG_WARN("Upscaling paused! frameID: {}", params->frameID); params->numGeneratedFrames = 0; diff --git a/OptiScaler/framegen/ffx/FSRFG_Dx12.h b/OptiScaler/framegen/ffx/FSRFG_Dx12.h index c3a51f73..ec317ade 100644 --- a/OptiScaler/framegen/ffx/FSRFG_Dx12.h +++ b/OptiScaler/framegen/ffx/FSRFG_Dx12.h @@ -37,7 +37,7 @@ class FSRFG_Dx12 : public virtual IFGFeature_Dx12 void CreateContext(ID3D12Device* device, IFeature* upscalerContext) override final; bool Dispatch(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* output, double frameTime) override final; - bool DispatchHudless(bool useHudless, double frameTime) override final; + bool DispatchHudless(ID3D12GraphicsCommandList* cmdList, bool useHudless, double frameTime) override final; void* FrameGenerationContext() override final; void* SwapchainContext() override final; diff --git a/OptiScaler/hudfix/Hudfix_Dx12.cpp b/OptiScaler/hudfix/Hudfix_Dx12.cpp index 510ac8ec..64eb148a 100644 --- a/OptiScaler/hudfix/Hudfix_Dx12.cpp +++ b/OptiScaler/hudfix/Hudfix_Dx12.cpp @@ -308,7 +308,7 @@ bool Hudfix_Dx12::CheckResource(ResourceInfo* resource) int Hudfix_Dx12::GetIndex() { return _upscaleCounter % BUFFER_COUNT; } -void Hudfix_Dx12::HudlessFound() +void Hudfix_Dx12::HudlessFound(ID3D12GraphicsCommandList* cmdList) { LOG_DEBUG("_upscaleCounter: {}, _fgCounter: {}", _upscaleCounter, _fgCounter); @@ -323,12 +323,6 @@ void Hudfix_Dx12::HudlessFound() // Increase counter _fgCounter++; - State::Instance().currentFG->DispatchHudless(true, State::Instance().lastFrameTime); - - // If Velocity and Depth copied then execute - if (State::Instance().currentFG->UpscalerInputsReady()) - State::Instance().currentFG->ExecuteHudlessCmdList(); - _skipHudlessChecks = false; } @@ -648,8 +642,9 @@ bool Hudfix_Dx12::CheckForHudless(std::string callerName, ID3D12GraphicsCommandL LOG_TRACE("Using _formatTransfer->Buffer()"); auto fg = reinterpret_cast(State::Instance().currentFG); + if (fg != nullptr) - fg->SetHudless(nullptr, _formatTransfer->Buffer(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, false); + fg->SetHudless(cmdList, _formatTransfer->Buffer(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, false); } else { @@ -665,8 +660,9 @@ bool Hudfix_Dx12::CheckForHudless(std::string callerName, ID3D12GraphicsCommandL _skipHudlessChecks = true; LOG_DEBUG("Using _captureBuffer"); auto fg = reinterpret_cast(State::Instance().currentFG); + if (fg != nullptr) - fg->SetHudless(nullptr, _captureBuffer[fIndex], D3D12_RESOURCE_STATE_COPY_DEST, false); + fg->SetHudless(cmdList, _captureBuffer[fIndex], D3D12_RESOURCE_STATE_COPY_DEST, false); } if (State::Instance().FGcaptureResources) @@ -681,7 +677,7 @@ bool Hudfix_Dx12::CheckForHudless(std::string callerName, ID3D12GraphicsCommandL // This will prevent resource tracker to check these operations // Will reset after FG dispatch _skipHudlessChecks = true; - HudlessFound(); + HudlessFound(cmdList); return true; diff --git a/OptiScaler/hudfix/Hudfix_Dx12.h b/OptiScaler/hudfix/Hudfix_Dx12.h index dbd1cb9c..31e7cc67 100644 --- a/OptiScaler/hudfix/Hudfix_Dx12.h +++ b/OptiScaler/hudfix/Hudfix_Dx12.h @@ -87,7 +87,7 @@ class Hudfix_Dx12 // Check _captureCounter for current frame static bool CheckCapture(); - static void HudlessFound(); + static void HudlessFound(ID3D12GraphicsCommandList* cmdList); static int GetIndex(); diff --git a/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp b/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp index 3660c426..59102003 100644 --- a/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp +++ b/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp @@ -1604,6 +1604,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom fg->Mutex.unlockThis(4); } + ResTrack_Dx12::SetUpscalerCmdList(InCmdList); bool allocatorReset = false; frameIndex = fg->GetIndex(); @@ -1713,7 +1714,6 @@ 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(), State::Instance().lastFrameTime); ResourceInfo info {}; diff --git a/OptiScaler/resource_tracking/ResTrack_dx12.cpp b/OptiScaler/resource_tracking/ResTrack_dx12.cpp index 1af163d8..e420601d 100644 --- a/OptiScaler/resource_tracking/ResTrack_dx12.cpp +++ b/OptiScaler/resource_tracking/ResTrack_dx12.cpp @@ -69,6 +69,7 @@ typedef void (*PFN_DrawInstanced)(ID3D12GraphicsCommandList* This, UINT VertexCo typedef void (*PFN_Dispatch)(ID3D12GraphicsCommandList* This, UINT ThreadGroupCountX, UINT ThreadGroupCountY, UINT ThreadGroupCountZ); typedef void (*PFN_ExecuteBundle)(ID3D12GraphicsCommandList* This, ID3D12GraphicsCommandList* pCommandList); +typedef void (*PFN_Close)(ID3D12GraphicsCommandList* This); typedef void (*PFN_ExecuteCommandLists)(ID3D12CommandQueue* This, UINT NumCommandLists, ID3D12CommandList* const* ppCommandLists); @@ -92,6 +93,7 @@ static PFN_Dispatch o_Dispatch = nullptr; static PFN_DrawInstanced o_DrawInstanced = nullptr; static PFN_DrawIndexedInstanced o_DrawIndexedInstanced = nullptr; static PFN_ExecuteBundle o_ExecuteBundle = nullptr; +static PFN_Close o_Close = nullptr; static PFN_ExecuteCommandLists o_ExecuteCommandLists = nullptr; static PFN_Release o_Release = nullptr; @@ -727,57 +729,65 @@ void ResTrack_Dx12::hkCreateUnorderedAccessView(ID3D12Device* This, ID3D12Resour void ResTrack_Dx12::hkExecuteCommandLists(ID3D12CommandQueue* This, UINT NumCommandLists, ID3D12CommandList* const* ppCommandLists) { + // static std::mutex cmdListMutex; + + // if (State::Instance().activeFgType == OptiFG && State::Instance().currentFG != nullptr && + // (_upscalerCommandList != nullptr /*|| _commandList != nullptr*/)) + //{ + // IFGFeature_Dx12* fg = State::Instance().currentFG; + + // if (fg->IsActive() && fg->TargetFrame() < fg->FrameCount()) + // { + // std::lock_guard lock(cmdListMutex); + + // for (size_t i = 0; i < NumCommandLists; i++) + // { + // if (!fg->HudlessReady()) + // { + // if (ppCommandLists[i] == _commandList) + // { + // LOG_DEBUG("Hudless CmdList[{}]: {:X}, Queue: {:X}", i, (size_t) ppCommandLists[i], + // (size_t) This); + + // fg->SetHudlessReady(); + + // if (fg->UpscalerInputsReady()) + // fg->DispatchHudless(_commandList, true, State::Instance().lastFrameTime); + + // _commandList = nullptr; + // } + // } + + // if (!fg->UpscalerInputsReady()) + // { + // if (ppCommandLists[i] == _upscalerCommandList) + // { + // LOG_DEBUG("Upscaler CmdList[{}]: {:X}, Queue: {:X}", i, (size_t) ppCommandLists[i], + // (size_t) This); + + // fg->SetUpscaleInputsReady(); + + // if (fg->ReadyForExecute()) + // fg->DispatchHudless(_commandList, true, State::Instance().lastFrameTime); + + // _upscalerCommandList = nullptr; + // } + // } + // } + + // if (fg != nullptr && fg->ReadyForExecute()) + // { + // auto result = fg->ExecuteHudlessCmdList(This); + // LOG_DEBUG("Execute OptiFG Cmdlist result: {:X}", (size_t) result); + + // if (result != nullptr) + // o_ExecuteCommandLists(This, 1, &result); + // } + // } + //} + // + o_ExecuteCommandLists(This, NumCommandLists, ppCommandLists); - - if (State::Instance().currentFG == nullptr) - return; - - IFGFeature_Dx12* fg = State::Instance().currentFG; - if (!fg->ReadyForExecute()) - { - for (size_t i = 0; i < NumCommandLists; i++) - { - LOG_DEBUG_ONLY("cmdlist[{}]: {:X}", i, (size_t) ppCommandLists[i]); - - // if (_commandList != nullptr && ppCommandLists[i] == _commandList) - //{ - // LOG_DEBUG("Hudless cmdlist, {}", fg->FrameCount()); - // fg->SetHudlessReady(); - // _commandList = nullptr; - // } - - if (_upscalerCommandList != nullptr && ppCommandLists[i] == _upscalerCommandList) - { - LOG_DEBUG("Upscaler cmdlist, {}", fg->FrameCount()); - fg->SetVelocityAndDepthReady(); - _upscalerCommandList = nullptr; - - if (State::Instance().activeFgType == OptiFG && fg->IsActive() && - fg->TargetFrame() < fg->FrameCount() && fg->HudlessReady()) - { - State::Instance().fgTrigSource = "ExecuteCmdList"; - fg->ExecuteHudlessCmdList(); - } - } - } - } - - // if (State::Instance().activeFgType == OptiFG && fg->IsActive() && fg->TargetFrame() < fg->FrameCount() && - // fg->ReadyForExecute()) - //{ - // State::Instance().fgTrigSource = "Immediate"; - // fg->ExecuteHudlessCmdList(); - // } - // else if (Config::Instance()->FGWaitForNextExecute.value_or_default()) - //{ - // if (State::Instance().activeFgType == OptiFG && fg->IsActive() && fg->TargetFrame() < fg->FrameCount() && - // fg->ReadyForExecute()) - // { - // LOG_DEBUG("Next execute dispatch fg"); - // State::Instance().fgTrigSource = "Next"; - // fg->ExecuteHudlessCmdList(); - // } - // } } #pragma region Heap hooks @@ -1198,7 +1208,7 @@ void ResTrack_Dx12::hkSetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList* { if (Hudfix_Dx12::CheckForHudless(__FUNCTION__, This, capturedBuffer, capturedBuffer->state)) { - _commandList = This; + SetHudlessCmdList(This); break; } } @@ -1293,7 +1303,7 @@ void ResTrack_Dx12::hkOMSetRenderTargets(ID3D12GraphicsCommandList* This, UINT N { if (Hudfix_Dx12::CheckForHudless(__FUNCTION__, This, capturedBuffer, capturedBuffer->state)) { - _commandList = This; + SetHudlessCmdList(This); break; } } @@ -1374,7 +1384,7 @@ void ResTrack_Dx12::hkSetComputeRootDescriptorTable(ID3D12GraphicsCommandList* T { if (Hudfix_Dx12::CheckForHudless(__FUNCTION__, This, capturedBuffer, capturedBuffer->state)) { - _commandList = This; + SetHudlessCmdList(This); break; } } @@ -1457,7 +1467,7 @@ void ResTrack_Dx12::hkDrawInstanced(ID3D12GraphicsCommandList* This, UINT Vertex if (Hudfix_Dx12::CheckForHudless(__FUNCTION__, This, &val, val.state)) { - _commandList = This; + SetHudlessCmdList(This); break; } } @@ -1532,7 +1542,7 @@ void ResTrack_Dx12::hkDrawIndexedInstanced(ID3D12GraphicsCommandList* This, UINT if (Hudfix_Dx12::CheckForHudless(__FUNCTION__, This, &val, val.state)) { - _commandList = This; + SetHudlessCmdList(This); break; } } @@ -1554,18 +1564,71 @@ void ResTrack_Dx12::hkExecuteBundle(ID3D12GraphicsCommandList* This, ID3D12Graph { o_ExecuteBundle(This, pCommandList); - if (pCommandList == _commandList) + IFGFeature_Dx12* fg = State::Instance().currentFG; + + if (fg->IsActive() && fg->TargetFrame() < fg->FrameCount()) { + auto index = fg->FrameCount() % BUFFER_COUNT; + + if (pCommandList == _commandList[index]) + { LOG_DEBUG("Hudless cmdlist"); - _commandList = This; + _commandList[index] = This; } - else if (pCommandList == _upscalerCommandList) + else if (pCommandList == _upscalerCommandList[index]) { LOG_DEBUG("Upscaler cmdlist"); - _upscalerCommandList = This; + _upscalerCommandList[index] = This; + } } } +void ResTrack_Dx12::hkClose(ID3D12GraphicsCommandList* This) +{ + auto fg = State::Instance().currentFG; + auto index = fg != nullptr ? fg->FrameCount() % BUFFER_COUNT : -1; + + if (State::Instance().activeFgType == OptiFG && fg != nullptr && + (_upscalerCommandList[index] != nullptr || _commandList[index] != nullptr)) + { + + if (fg->IsActive() && fg->TargetFrame() < fg->FrameCount()) + { + if (!fg->HudlessReady()) + { + if (This == _commandList[index]) + { + LOG_DEBUG("Hudless CmdList: {:X}", (size_t) This); + + fg->SetHudlessReady(); + + if (fg->ReadyForExecute()) + fg->DispatchHudless(This, true, State::Instance().lastFrameTime); + + _commandList[index] = nullptr; + } + } + + if (!fg->UpscalerInputsReady()) + { + if (This == _upscalerCommandList[index]) + { + LOG_DEBUG("Upscaler CmdList: {:X}", (size_t) This); + + fg->SetUpscaleInputsReady(); + + if (fg->ReadyForExecute()) + fg->DispatchHudless(This, true, State::Instance().lastFrameTime); + + _upscalerCommandList[index] = nullptr; + } + } + } + } + + o_Close(This); +} + void ResTrack_Dx12::hkDispatch(ID3D12GraphicsCommandList* This, UINT ThreadGroupCountX, UINT ThreadGroupCountY, UINT ThreadGroupCountZ) { @@ -1621,7 +1684,7 @@ void ResTrack_Dx12::hkDispatch(ID3D12GraphicsCommandList* This, UINT ThreadGroup if (Hudfix_Dx12::CheckForHudless(__FUNCTION__, This, &val, val.state)) { - _commandList = This; + SetHudlessCmdList(This); break; } } @@ -1702,6 +1765,7 @@ void ResTrack_Dx12::HookCommandList(ID3D12Device* InDevice) o_DrawInstanced = (PFN_DrawInstanced) pVTable[12]; o_DrawIndexedInstanced = (PFN_DrawIndexedInstanced) pVTable[13]; o_Dispatch = (PFN_Dispatch) pVTable[14]; + o_Close = (PFN_Close) pVTable[9]; // hudless compute o_SetComputeRootDescriptorTable = (PFN_SetComputeRootDescriptorTable) pVTable[31]; @@ -1734,6 +1798,9 @@ void ResTrack_Dx12::HookCommandList(ID3D12Device* InDevice) if (o_ExecuteBundle != nullptr) DetourAttach(&(PVOID&) o_ExecuteBundle, hkExecuteBundle); + if (o_Close != nullptr) + DetourAttach(&(PVOID&) o_Close, hkClose); + DetourTransactionCommit(); } @@ -1871,12 +1938,22 @@ void ResTrack_Dx12::PresentDone() { _presentDone = true; } void ResTrack_Dx12::SetUpscalerCmdList(ID3D12GraphicsCommandList* cmdList) { + auto fg = State::Instance().currentFG; + if (fg != nullptr && fg->IsActive()) + { LOG_DEBUG("cmdList: {:X}", (size_t) cmdList); - _upscalerCommandList = cmdList; + auto index = fg->FrameCount() % BUFFER_COUNT; + _upscalerCommandList[index] = cmdList; + } } void ResTrack_Dx12::SetHudlessCmdList(ID3D12GraphicsCommandList* cmdList) { + auto fg = State::Instance().currentFG; + if (fg != nullptr && fg->IsActive()) + { LOG_DEBUG("cmdList: {:X}", (size_t) cmdList); - _commandList = cmdList; + auto index = fg->FrameCount() % BUFFER_COUNT; + _commandList[index] = cmdList; + } } diff --git a/OptiScaler/resource_tracking/ResTrack_dx12.h b/OptiScaler/resource_tracking/ResTrack_dx12.h index 1c69b48c..c5f71f60 100644 --- a/OptiScaler/resource_tracking/ResTrack_dx12.h +++ b/OptiScaler/resource_tracking/ResTrack_dx12.h @@ -226,8 +226,9 @@ class ResTrack_Dx12 inline static bool _presentDone = true; inline static std::mutex _drawMutex; - inline static ID3D12GraphicsCommandList* _commandList = nullptr; - inline static ID3D12GraphicsCommandList* _upscalerCommandList = nullptr; + inline static ID3D12GraphicsCommandList* _commandList[BUFFER_COUNT] = { nullptr, nullptr, nullptr, nullptr }; + inline static ID3D12GraphicsCommandList* _upscalerCommandList[BUFFER_COUNT] = { nullptr, nullptr, nullptr, + nullptr }; static bool IsHudFixActive(); @@ -261,6 +262,8 @@ class ResTrack_Dx12 static void hkExecuteBundle(ID3D12GraphicsCommandList* This, ID3D12GraphicsCommandList* pCommandList); + static void hkClose(ID3D12GraphicsCommandList* This); + static void hkCreateRenderTargetView(ID3D12Device* This, ID3D12Resource* pResource, D3D12_RENDER_TARGET_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor);