diff --git a/OptiScaler/framegen/IFGFeature.h b/OptiScaler/framegen/IFGFeature.h index 455efdd1..63228dfe 100644 --- a/OptiScaler/framegen/IFGFeature.h +++ b/OptiScaler/framegen/IFGFeature.h @@ -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(); diff --git a/OptiScaler/framegen/IFGFeature_Dx12.h b/OptiScaler/framegen/IFGFeature_Dx12.h index 839f4618..a8be1c82 100644 --- a/OptiScaler/framegen/IFGFeature_Dx12.h +++ b/OptiScaler/framegen/IFGFeature_Dx12.h @@ -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; diff --git a/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp b/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp index 820ca93e..b603f10e 100644 --- a/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp +++ b/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp @@ -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) { diff --git a/OptiScaler/framegen/ffx/FSRFG_Dx12.h b/OptiScaler/framegen/ffx/FSRFG_Dx12.h index 7cc82b68..69c76369 100644 --- a/OptiScaler/framegen/ffx/FSRFG_Dx12.h +++ b/OptiScaler/framegen/ffx/FSRFG_Dx12.h @@ -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() + { + // + } }; diff --git a/OptiScaler/hooks/HooksDx.cpp b/OptiScaler/hooks/HooksDx.cpp index 50ec5a35..9329a5ea 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; } @@ -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(State::Instance().currentFG); - if (fg != nullptr) + if (fg != nullptr && fg->SwapchainContext() != nullptr) fg->ReleaseSwapchain(hwnd); } diff --git a/OptiScaler/hooks/wrapped_swapchain.cpp b/OptiScaler/hooks/wrapped_swapchain.cpp index a39cae7d..923ec402 100644 --- a/OptiScaler/hooks/wrapped_swapchain.cpp +++ b/OptiScaler/hooks/wrapped_swapchain.cpp @@ -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; diff --git a/OptiScaler/inputs/FfxApi_Dx12.cpp b/OptiScaler/inputs/FfxApi_Dx12.cpp index 7f591826..d1671b99 100644 --- a/OptiScaler/inputs/FfxApi_Dx12.cpp +++ b/OptiScaler/inputs/FfxApi_Dx12.cpp @@ -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(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; diff --git a/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp b/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp index 57475d82..e52d8647 100644 --- a/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp +++ b/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp @@ -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); diff --git a/OptiScaler/menu/menu_common.cpp b/OptiScaler/menu/menu_common.cpp index 33102634..de5c8681 100644 --- a/OptiScaler/menu/menu_common.cpp +++ b/OptiScaler/menu/menu_common.cpp @@ -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"); diff --git a/OptiScaler/resource_tracking/ResTrack_dx12.cpp b/OptiScaler/resource_tracking/ResTrack_dx12.cpp index 2bf5c527..88cd8ada 100644 --- a/OptiScaler/resource_tracking/ResTrack_dx12.cpp +++ b/OptiScaler/resource_tracking/ResTrack_dx12.cpp @@ -2182,6 +2182,9 @@ void ResTrack_Dx12::ClearPossibleHudless() _skipHudless = false; _rcActive = false; _cmdList = false; + //_upscalerCommandList = nullptr; + //_commandList = nullptr; + } void ResTrack_Dx12::PresentDone()