diff --git a/OptiScaler/framegen/IFGFeature.cpp b/OptiScaler/framegen/IFGFeature.cpp index cbc92d67..e7439303 100644 --- a/OptiScaler/framegen/IFGFeature.cpp +++ b/OptiScaler/framegen/IFGFeature.cpp @@ -94,6 +94,12 @@ void IFGFeature::SetFrameTimeDelta(float delta) { _ftDelta = delta; } void IFGFeature::SetReset(UINT reset) { _reset = reset; } +void IFGFeature::SetInterpolationRect(UINT width, UINT height) +{ + _interpolationWidth = width; + _interpolationHeight = height; +} + void IFGFeature::ResetCounters() { _frameCount = 0; diff --git a/OptiScaler/framegen/IFGFeature.h b/OptiScaler/framegen/IFGFeature.h index 55c0b5c8..4b3218b2 100644 --- a/OptiScaler/framegen/IFGFeature.h +++ b/OptiScaler/framegen/IFGFeature.h @@ -60,6 +60,8 @@ class IFGFeature float _cameraForward[3] {}; ///< The camera forward normalized vector in world space. float _meterFactor = 0.0; float _ftDelta = 0.0; + UINT _interpolationWidth = 0; + UINT _interpolationHeight = 0; UINT _reset = 0; UINT64 _frameCount = 0; @@ -85,9 +87,8 @@ class IFGFeature virtual feature_version Version() = 0; virtual const char* Name() = 0; - virtual bool ManualPipeline() = 0; - virtual bool Dispatch() = 0; + virtual bool Present() = 0; virtual void StopAndDestroyContext(bool destroy, bool shutDown) = 0; int GetIndex(); @@ -113,6 +114,7 @@ class IFGFeature void SetCameraData(float cameraPosition[3], float cameraUp[3], float cameraRight[3], float cameraForward[3]); void SetFrameTimeDelta(float delta); void SetReset(UINT reset); + void SetInterpolationRect(UINT width, UINT height); void ResetCounters(); void UpdateTarget(); diff --git a/OptiScaler/framegen/IFGFeature_Dx12.h b/OptiScaler/framegen/IFGFeature_Dx12.h index a3da727c..de326774 100644 --- a/OptiScaler/framegen/IFGFeature_Dx12.h +++ b/OptiScaler/framegen/IFGFeature_Dx12.h @@ -14,11 +14,14 @@ typedef struct Dx12Resource { FG_ResourceType type; ID3D12Resource* resource = nullptr; + UINT width = 0; + UINT height = 0; ID3D12Resource* copy = nullptr; ID3D12CommandList* cmdList = nullptr; D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_COMMON; FG_ResourceValidity validity = FG_ResourceValidity::ValidNow; UINT64 fenceValue = 0; + bool waitingExecution = false; ID3D12Resource* GetResource() { return (copy == nullptr) ? resource : copy; } }; @@ -69,10 +72,7 @@ class IFGFeature_Dx12 : public virtual IFGFeature void GetResourceCopy(FG_ResourceType type, D3D12_RESOURCE_STATES bufferState, ID3D12Resource** output); virtual void SetResource(FG_ResourceType type, ID3D12GraphicsCommandList* cmdList, ID3D12Resource* resource, - D3D12_RESOURCE_STATES state, FG_ResourceValidity validity) = 0; - - virtual bool ExecuteCommandList(ID3D12CommandQueue* queue) = 0; - virtual ID3D12CommandList* GetCommandList() = 0; + UINT width, UINT height, D3D12_RESOURCE_STATES state, FG_ResourceValidity validity) = 0; virtual void SetCommandQueue(FG_ResourceType type, ID3D12CommandQueue* queue) = 0; diff --git a/OptiScaler/framegen/Streamline_Inputs_Dx12.cpp b/OptiScaler/framegen/Streamline_Inputs_Dx12.cpp index 0c048b94..b7f35f41 100644 --- a/OptiScaler/framegen/Streamline_Inputs_Dx12.cpp +++ b/OptiScaler/framegen/Streamline_Inputs_Dx12.cpp @@ -167,8 +167,8 @@ bool Sl_Inputs_Dx12::reportResource(const sl::ResourceTag& tag, ID3D12GraphicsCo const auto validity = (tag.lifecycle == sl::eOnlyValidNow) ? FG_ResourceValidity::ValidNow : FG_ResourceValidity::UntilPresent; - fgOutput->SetResource(FG_ResourceType::HudlessColor, cmdBuffer, hudlessResource, - (D3D12_RESOURCE_STATES) tag.resource->state, validity); + fgOutput->SetResource(FG_ResourceType::HudlessColor, cmdBuffer, hudlessResource, tag.resource->width, + tag.resource->height, (D3D12_RESOURCE_STATES) tag.resource->state, validity); auto static lastFormat = DXGI_FORMAT_UNKNOWN; auto format = hudlessResource->GetDesc().Format; @@ -194,8 +194,8 @@ bool Sl_Inputs_Dx12::reportResource(const sl::ResourceTag& tag, ID3D12GraphicsCo const auto validity = (tag.lifecycle == sl::eOnlyValidNow) ? FG_ResourceValidity::ValidNow : FG_ResourceValidity::UntilPresent; - fgOutput->SetResource(FG_ResourceType::Depth, cmdBuffer, depthResource, - (D3D12_RESOURCE_STATES) tag.resource->state, validity); + fgOutput->SetResource(FG_ResourceType::Depth, cmdBuffer, depthResource, tag.resource->width, + tag.resource->height, (D3D12_RESOURCE_STATES) tag.resource->state, validity); } else if (tag.type == sl::kBufferTypeMotionVectors) { @@ -209,8 +209,8 @@ bool Sl_Inputs_Dx12::reportResource(const sl::ResourceTag& tag, ID3D12GraphicsCo const auto validity = (tag.lifecycle == sl::eOnlyValidNow) ? FG_ResourceValidity::ValidNow : FG_ResourceValidity::UntilPresent; - fgOutput->SetResource(FG_ResourceType::Velocity, cmdBuffer, mvResource, - (D3D12_RESOURCE_STATES) tag.resource->state, validity); + fgOutput->SetResource(FG_ResourceType::Velocity, cmdBuffer, mvResource, tag.resource->width, + tag.resource->height, (D3D12_RESOURCE_STATES) tag.resource->state, validity); } else if (tag.type == sl::kBufferTypeUIColorAndAlpha) { @@ -226,8 +226,8 @@ bool Sl_Inputs_Dx12::reportResource(const sl::ResourceTag& tag, ID3D12GraphicsCo const auto validity = (tag.lifecycle == sl::eOnlyValidNow) ? FG_ResourceValidity::ValidNow : FG_ResourceValidity::UntilPresent; - fgOutput->SetResource(FG_ResourceType::UIColor, cmdBuffer, uiResource, - (D3D12_RESOURCE_STATES) tag.resource->state, validity); + fgOutput->SetResource(FG_ResourceType::UIColor, cmdBuffer, uiResource, tag.resource->width, + tag.resource->height, (D3D12_RESOURCE_STATES) tag.resource->state, validity); } } else if (tag.type == sl::kBufferTypeBidirectionalDistortionField) @@ -242,8 +242,8 @@ bool Sl_Inputs_Dx12::reportResource(const sl::ResourceTag& tag, ID3D12GraphicsCo const auto validity = (tag.lifecycle == sl::eOnlyValidNow) ? FG_ResourceValidity::ValidNow : FG_ResourceValidity::UntilPresent; - fgOutput->SetResource(FG_ResourceType::Distortion, cmdBuffer, distortionFieldResource, - (D3D12_RESOURCE_STATES) tag.resource->state, validity); + fgOutput->SetResource(FG_ResourceType::Distortion, cmdBuffer, distortionFieldResource, tag.resource->width, + tag.resource->height, (D3D12_RESOURCE_STATES) tag.resource->state, validity); } if (readyForDispatch()) @@ -363,7 +363,7 @@ bool Sl_Inputs_Dx12::dispatchFG(ID3D12GraphicsCommandList* cmdBuffer) fgOutput->SetReset(slConstsRef.reset == sl::Boolean::eTrue); - return fgOutput->Dispatch(); + return true; } void Sl_Inputs_Dx12::markLastSendAsRequired() diff --git a/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp b/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp index 6e620a61..8f3b01af 100644 --- a/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp +++ b/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp @@ -158,7 +158,6 @@ bool FSRFG_Dx12::Dispatch() // use swapchain buffer info DXGI_SWAP_CHAIN_DESC scDesc1 {}; bool hasSwapChainDesc = State::Instance().currentSwapchain->GetDesc(&scDesc1) == S_OK; - auto feature = State::Instance().currentFeature; int bufferWidth = hasSwapChainDesc ? scDesc1.BufferDesc.Width : 0; int bufferHeight = hasSwapChainDesc ? scDesc1.BufferDesc.Height : 0; @@ -168,26 +167,10 @@ bool FSRFG_Dx12::Dispatch() int defaultWidth = 0; int defaultHeight = 0; - if (feature) - { - int displayWidth = feature->DisplayWidth(); - int displayHeight = feature->DisplayHeight(); - - defaultLeft = hasSwapChainDesc ? (bufferWidth - displayWidth) / 2 : 0; - defaultTop = hasSwapChainDesc ? (bufferHeight - displayHeight) / 2 : 0; - defaultWidth = displayWidth; - defaultHeight = displayHeight; - } - else - { - defaultLeft = 0; - defaultTop = 0; - defaultWidth = hasSwapChainDesc ? bufferWidth : 0; - defaultHeight = hasSwapChainDesc ? bufferHeight : 0; - - if (!hasSwapChainDesc) - LOG_ERROR("No swapchain or feature, invalid FG Rect values"); - } + defaultLeft = hasSwapChainDesc ? (bufferWidth - _interpolationWidth) / 2 : 0; + defaultTop = hasSwapChainDesc ? (bufferHeight - _interpolationHeight) / 2 : 0; + defaultWidth = _interpolationWidth; + defaultHeight = _interpolationHeight; m_FrameGenerationConfig.generationRect.left = Config::Instance()->FGRectLeft.value_or(defaultLeft); m_FrameGenerationConfig.generationRect.top = Config::Instance()->FGRectTop.value_or(defaultTop); @@ -701,7 +684,7 @@ void FSRFG_Dx12::ReleaseObjects() _fgCommandList = nullptr; } - // FG_ResourceType + // For each FG_ResourceType for (size_t i = 0; i < 5; i++) { if (this->_copyCommandAllocator.contains((FG_ResourceType) i)) @@ -718,15 +701,10 @@ void FSRFG_Dx12::ReleaseObjects() _depthFlip.reset(); } -ID3D12CommandList* FSRFG_Dx12::GetCommandList() { return _fgCommandList; } - -bool FSRFG_Dx12::ExecuteCommandList(ID3D12CommandQueue* queue) +bool FSRFG_Dx12::ExecuteCommandList() { LOG_DEBUG(); - if (!ManualPipeline()) - return true; - if (WaitingExecution()) { LOG_DEBUG("Executing FG cmdList: {:X} with queue: {:X}", (size_t) _fgCommandList, (size_t) _gameCommandQueue); @@ -739,20 +717,26 @@ bool FSRFG_Dx12::ExecuteCommandList(ID3D12CommandQueue* queue) } void FSRFG_Dx12::SetResource(FG_ResourceType type, ID3D12GraphicsCommandList* cmdList, ID3D12Resource* resource, - D3D12_RESOURCE_STATES state, FG_ResourceValidity validity) + UINT width, UINT height, D3D12_RESOURCE_STATES state, FG_ResourceValidity validity) { if (resource == nullptr) return; if (cmdList == nullptr && validity == FG_ResourceValidity::ValidNow && _gameCommandQueue == nullptr) { - LOG_ERROR("{}, validity == ValidNow but _gameCommandQueue is nullptr!", (UINT) type); + LOG_ERROR("{}, validity == ValidNow but _gameCommandQueue is nullptr!", magic_enum::enum_name(type)); return; } auto fIndex = GetIndex(); _frameResources[fIndex][type] = {}; auto fResource = &_frameResources[fIndex][type]; + fResource->type = type; + fResource->state = state; + fResource->validity = validity; + fResource->resource = resource; + fResource->width = width; + fResource->height = height; auto willFlip = State::Instance().activeFgInput == FGInput::Upscaler && Config::Instance()->FGResourceFlip.value_or_default() && @@ -764,7 +748,7 @@ void FSRFG_Dx12::SetResource(FG_ResourceType type, ID3D12GraphicsCommandList* cm { if (!_copyCommandAllocator.contains(type) || !_copyCommandList.contains(type)) { - LOG_ERROR("{}, _copyCommandAllocator or _copyCommandList is nullptr!", (UINT) type); + LOG_ERROR("{}, _copyCommandAllocator or _copyCommandList is nullptr!", magic_enum::enum_name(type)); return; } @@ -775,11 +759,6 @@ void FSRFG_Dx12::SetResource(FG_ResourceType type, ID3D12GraphicsCommandList* cm usingLocalCmdList = true; } - fResource->type = type; - fResource->state = state; - fResource->validity = validity; - fResource->resource = resource; - // Resource flipping if (willFlip && _device != nullptr) { @@ -792,7 +771,7 @@ void FSRFG_Dx12::SetResource(FG_ResourceType type, ID3D12GraphicsCommandList* cm if (!CreateBufferResource(_device, resource, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, &flipOutput, true, false)) { - LOG_ERROR("{}, CreateBufferResource for flip is failed!", (UINT) type); + LOG_ERROR("{}, CreateBufferResource for flip is failed!", magic_enum::enum_name(type)); return; } @@ -826,7 +805,7 @@ void FSRFG_Dx12::SetResource(FG_ResourceType type, ID3D12GraphicsCommandList* cm if (!CreateBufferResource(_device, resource, state, &flipOutput, true, true)) { - LOG_ERROR("{}, CreateBufferResource for flip is failed!", (UINT) type); + LOG_ERROR("{}, CreateBufferResource for flip is failed!", magic_enum::enum_name(type)); return; } @@ -865,7 +844,7 @@ void FSRFG_Dx12::SetResource(FG_ResourceType type, ID3D12GraphicsCommandList* cm if (!CopyResource(cmdList, resource, ©Output, state)) { - LOG_ERROR("{}, CopyResource error!", (UINT) type); + LOG_ERROR("{}, CopyResource error!", magic_enum::enum_name(type)); return; } @@ -887,42 +866,15 @@ void FSRFG_Dx12::SetResource(FG_ResourceType type, ID3D12GraphicsCommandList* cm if (usingLocalCmdList) { cmdList->Close(); - _fgCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList**) &cmdList); + _gameCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList**) &cmdList); } - LOG_TRACE("_frameResources[{}][{}]: {:X}", fIndex, (UINT) type, (size_t) fResource->GetResource()); + LOG_TRACE("_frameResources[{}][{}]: {:X}", fIndex, magic_enum::enum_name(type), (size_t) fResource->GetResource()); } -void FSRFG_Dx12::SetResourceReady(FG_ResourceType type) -{ - auto fIndex = GetIndex(); - _resourceReady[fIndex][type] = true; +void FSRFG_Dx12::SetResourceReady(FG_ResourceType type) { _resourceReady[GetIndex()][type] = true; } - // auto fResource = &_frameResources[fIndex][type]; - - // if (fResource != nullptr && fResource->validity == FG_ResourceValidity::ValidNow) - //{ - // UINT64 fenceValue = (_frameCount * 10) + (UINT64) type; - // fResource->fenceValue = fenceValue; - // LOG_DEBUG("Wait {}: {}, with queue: {:X}", (UINT)type, fResource->fenceValue, - // (size_t) _fgCommandQueue); - // _fgCommandQueue->Wait(_fgFence, fenceValue); - // } -} - -void FSRFG_Dx12::SetCommandQueue(FG_ResourceType type, ID3D12CommandQueue* queue) -{ - _gameCommandQueue = queue; - - // auto fIndex = GetIndex(); - // auto fResource = &_frameResources[fIndex][type]; - - // if (fResource != nullptr && fResource->fenceValue > 0) - //{ - // LOG_DEBUG("Signal {}: {} with queue: {:X}", (UINT)type, fResource->fenceValue, (size_t) - // queue); queue->Signal(_fgFence, fResource->fenceValue); - // } -} +void FSRFG_Dx12::SetCommandQueue(FG_ResourceType type, ID3D12CommandQueue* queue) { _gameCommandQueue = queue; } void FSRFG_Dx12::CreateObjects(ID3D12Device* InDevice) { @@ -941,22 +893,6 @@ void FSRFG_Dx12::CreateObjects(ID3D12Device* InDevice) ID3D12CommandQueue* cmdQueue = nullptr; // FG - D3D12_COMMAND_QUEUE_DESC queueDesc = {}; - queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; - queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - - result = InDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&_fgCommandQueue)); - - if (result != S_OK || _fgCommandQueue == nullptr) - { - LOG_DEBUG("CreateCommandQueue _fgCommandQueue: {0:X}", result); - break; - } - - _fgCommandQueue->SetName(L"_fgCommandQueue"); - if (CheckForRealObject(__FUNCTION__, _fgCommandQueue, (IUnknown**) &cmdQueue)) - _fgCommandQueue = cmdQueue; - result = InDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&_fgCommandAllocator)); if (result != S_OK) { @@ -964,14 +900,6 @@ void FSRFG_Dx12::CreateObjects(ID3D12Device* InDevice) break; } - result = InDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&_fgFence)); - - if (result != S_OK) - { - LOG_ERROR("CreateFence _fgFence: {0:X}", result); - break; - } - _fgCommandAllocator->SetName(L"_fgCommandAllocator"); if (CheckForRealObject(__FUNCTION__, _fgCommandAllocator, (IUnknown**) &allocator)) _fgCommandAllocator = allocator; @@ -994,6 +922,7 @@ void FSRFG_Dx12::CreateObjects(ID3D12Device* InDevice) break; } + // For each FG_ResourceType for (size_t i = 0; i < 5; i++) { auto val = (FG_ResourceType) i; @@ -1037,3 +966,20 @@ void FSRFG_Dx12::CreateObjects(ID3D12Device* InDevice) } while (false); } + +bool FSRFG_Dx12::Present() +{ + auto result = false; + + if (!IsPaused() && !IsDispatched()) + { + Dispatch(); + } + + if (!IsPaused() && WaitingExecution()) + { + result = ExecuteCommandList(); + } + + return result; +} diff --git a/OptiScaler/framegen/ffx/FSRFG_Dx12.h b/OptiScaler/framegen/ffx/FSRFG_Dx12.h index e501cdbe..0545bf53 100644 --- a/OptiScaler/framegen/ffx/FSRFG_Dx12.h +++ b/OptiScaler/framegen/ffx/FSRFG_Dx12.h @@ -21,12 +21,11 @@ class FSRFG_Dx12 : public virtual IFGFeature_Dx12 // One extra to copy things ID3D12GraphicsCommandList* _fgCommandList = nullptr; ID3D12CommandAllocator* _fgCommandAllocator = nullptr; - ID3D12CommandQueue* _fgCommandQueue = nullptr; - ID3D12Fence* _fgFence = nullptr; + // For copy operations std::map _resourceCopy[BUFFER_COUNT] {}; - std::map _copyCommandAllocator {}; std::map _copyCommandList {}; + std::map _copyCommandAllocator {}; static FfxApiResourceState GetFfxApiState(D3D12_RESOURCE_STATES state) { @@ -57,11 +56,14 @@ class FSRFG_Dx12 : public virtual IFGFeature_Dx12 } } + bool ExecuteCommandList(); + bool Dispatch(); + void ConfigureFramePaceTuning(); + public: // IFGFeature const char* Name() override final; feature_version Version() override final; - bool ManualPipeline() override final { return true; } void* FrameGenerationContext() override final; void* SwapchainContext() override final; @@ -80,20 +82,13 @@ class FSRFG_Dx12 : public virtual IFGFeature_Dx12 void ReleaseObjects() override final; void CreateObjects(ID3D12Device* InDevice) override final; - bool Dispatch() override final; - - ID3D12CommandList* GetCommandList() override final; - bool ExecuteCommandList(ID3D12CommandQueue* queue) override final; - - void SetResource(FG_ResourceType type, ID3D12GraphicsCommandList* cmdList, ID3D12Resource* resource, - D3D12_RESOURCE_STATES state, FG_ResourceValidity validity) override final; + bool Present() override final; + void SetResource(FG_ResourceType type, ID3D12GraphicsCommandList* cmdList, ID3D12Resource* resource, UINT width, + UINT height, D3D12_RESOURCE_STATES state, FG_ResourceValidity validity) override final; void SetResourceReady(FG_ResourceType type) override final; void SetCommandQueue(FG_ResourceType type, ID3D12CommandQueue* queue) override final; - // Methods - void ConfigureFramePaceTuning(); - ffxReturnCode_t DispatchCallback(ffxDispatchDescFrameGeneration* params); FSRFG_Dx12() : IFGFeature_Dx12(), IFGFeature() diff --git a/OptiScaler/framegen/xefg/XeFG_Dx12.cpp b/OptiScaler/framegen/xefg/XeFG_Dx12.cpp index a88f99ce..2dd6e13f 100644 --- a/OptiScaler/framegen/xefg/XeFG_Dx12.cpp +++ b/OptiScaler/framegen/xefg/XeFG_Dx12.cpp @@ -1,650 +1,889 @@ -// #include "XeFG_Dx12.h" -// -// #include -// #include -// #include -// -// #include -// -// void XeFG_Dx12::xefgLogCallback(const char* message, xefg_swapchain_logging_level_t level, void* userData) -//{ -// switch (level) -// { -// case XEFG_SWAPCHAIN_LOGGING_LEVEL_DEBUG: -// spdlog::debug("XeFG Log: {}", message); -// return; -// -// case XEFG_SWAPCHAIN_LOGGING_LEVEL_INFO: -// spdlog::info("XeFG Log: {}", message); -// return; -// -// case XEFG_SWAPCHAIN_LOGGING_LEVEL_WARNING: -// spdlog::warn("XeFG Log: {}", message); -// return; -// -// default: -// spdlog::error("XeFG Log: {}", message); -// return; -// } -// } -// -// bool XeFG_Dx12::CreateSwapchainContext(ID3D12Device* device) -//{ -// if (XeFGProxy::Module() == nullptr && !XeFGProxy::InitXeFG()) -// { -// LOG_ERROR("XeFG proxy can't find libxess_fg.dll!"); -// return false; -// } -// -// State::Instance().skipSpoofing = true; -// auto result = XeFGProxy::D3D12CreateContext()(device, &_swapChainContext); -// State::Instance().skipSpoofing = false; -// -// if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) -// { -// LOG_ERROR("D3D12CreateContext error: {} ({})", magic_enum::enum_name(result), (UINT) result); -// return false; -// } -// -// LOG_INFO("XeFG context created"); -// result = XeFGProxy::SetLoggingCallback()(_swapChainContext, XEFG_SWAPCHAIN_LOGGING_LEVEL_DEBUG, xefgLogCallback, -// nullptr); -// -// if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) -// { -// LOG_ERROR("SetLoggingCallback error: {} ({})", magic_enum::enum_name(result), (UINT) result); -// } -// -// if (XeLLProxy::Context() == nullptr) -// XeLLProxy::CreateContext(device); -// -// if (XeLLProxy::Context() != nullptr) -// { -// xell_sleep_params_t sleepParams = {}; -// sleepParams.bLowLatencyMode = true; -// sleepParams.bLowLatencyBoost = false; -// sleepParams.minimumIntervalUs = 0; -// -// auto xellResult = XeLLProxy::SetSleepMode()(XeLLProxy::Context(), &sleepParams); -// if (xellResult != XELL_RESULT_SUCCESS) -// { -// LOG_ERROR("SetSleepMode error: {} ({})", magic_enum::enum_name(xellResult), (UINT) xellResult); -// return false; -// } -// -// auto fnaResult = fakenvapi::setModeAndContext(XeLLProxy::Context(), Mode::XeLL); -// LOG_DEBUG("fakenvapi::setModeAndContext: {}", fnaResult); -// -// result = XeFGProxy::SetLatencyReduction()(_swapChainContext, XeLLProxy::Context()); -// -// if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) -// { -// LOG_ERROR("SetLatencyReduction error: {} ({})", magic_enum::enum_name(result), (UINT) result); -// return false; -// } -// }; -// -// return true; -// } -// -// const char* XeFG_Dx12::Name() { return "XeFG"; } -// -// feature_version XeFG_Dx12::Version() -//{ -// if (XeFGProxy::InitXeFG()) -// { -// auto ver = XeFGProxy::Version(); -// return ver; -// } -// -// return { 0, 0, 0 }; -// } -// -// void XeFG_Dx12::StopAndDestroyContext(bool destroy, bool shutDown, bool useMutex) -//{ -// LOG_DEBUG(""); -// -// bool mutexTaken = false; -// if (Config::Instance()->FGUseMutexForSwapchain.value_or_default() && useMutex) -// { -// LOG_TRACE("Waiting Mutex 1, current: {}", Mutex.getOwner()); -// Mutex.lock(1); -// mutexTaken = true; -// LOG_TRACE("Accuired Mutex: {}", Mutex.getOwner()); -// } -// -// if (_isActive) -// { -// auto result = XeFGProxy::SetEnabled()(_swapChainContext, false); -// _isActive = false; -// if (!(shutDown || State::Instance().isShuttingDown)) -// LOG_INFO("SetEnabled: false, result: {} ({})", magic_enum::enum_name(result), (UINT) result); -// } -// -// if (destroy && _fgContext != nullptr) -// { -// _fgContext = nullptr; -// } -// -// if (shutDown || State::Instance().isShuttingDown) -// ReleaseObjects(); -// -// if (mutexTaken) -// { -// LOG_TRACE("Releasing Mutex: {}", Mutex.getOwner()); -// Mutex.unlockThis(1); -// } -// } -// -// bool XeFG_Dx12::DestroySwapchainContext() -//{ -// LOG_DEBUG(""); -// -// _isActive = false; -// -// if (_swapChainContext != nullptr) -// { -// auto result = XeFGProxy::Destroy()(_swapChainContext); -// -// if (!State::Instance().isShuttingDown) -// LOG_INFO("Destroy result: {} ({})", magic_enum::enum_name(result), (UINT) result); -// -// _swapChainContext = nullptr; -// } -// -// return true; -// } -// -// bool XeFG_Dx12::CreateSwapchain(IDXGIFactory* factory, ID3D12CommandQueue* cmdQueue, DXGI_SWAP_CHAIN_DESC* desc, -// IDXGISwapChain** swapChain) -//{ -// if (_swapChainContext == nullptr) -// { -// if (State::Instance().currentD3D12Device == nullptr) -// return false; -// -// CreateSwapchainContext(State::Instance().currentD3D12Device); -// -// if (_swapChainContext == nullptr) -// return false; -// -// _width = desc->BufferDesc.Width; -// _height = desc->BufferDesc.Height; -// } -// -// IDXGIFactory* realFactory = nullptr; -// ID3D12CommandQueue* realQueue = nullptr; -// -// if (!CheckForRealObject(__FUNCTION__, factory, (IUnknown**) &realFactory)) -// realFactory = factory; -// -// if (!CheckForRealObject(__FUNCTION__, cmdQueue, (IUnknown**) &realQueue)) -// realQueue = cmdQueue; -// -// IDXGIFactory2* factory12 = nullptr; -// if (realFactory->QueryInterface(IID_PPV_ARGS(&factory12)) != S_OK) -// return false; -// -// factory12->Release(); -// -// HWND hwnd = desc->OutputWindow; -// DXGI_SWAP_CHAIN_DESC1 scDesc {}; -// -// scDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; // No info -// scDesc.BufferCount = desc->BufferCount; -// scDesc.BufferUsage = desc->BufferUsage; -// scDesc.Flags = desc->Flags; -// scDesc.Format = desc->BufferDesc.Format; -// scDesc.Height = desc->BufferDesc.Height; -// scDesc.SampleDesc = desc->SampleDesc; -// scDesc.Scaling = DXGI_SCALING_NONE; // No info -// scDesc.Stereo = false; // No info -// scDesc.SwapEffect = desc->SwapEffect; -// scDesc.Width = desc->BufferDesc.Width; -// -// DXGI_SWAP_CHAIN_FULLSCREEN_DESC fsDesc {}; -// fsDesc.RefreshRate = desc->BufferDesc.RefreshRate; -// fsDesc.Scaling = desc->BufferDesc.Scaling; -// fsDesc.ScanlineOrdering = desc->BufferDesc.ScanlineOrdering; -// fsDesc.Windowed = desc->Windowed; -// -// xefg_swapchain_d3d12_init_params_t params {}; -// params.maxInterpolatedFrames = 1; -// -// params.initFlags = XEFG_SWAPCHAIN_INIT_FLAG_NONE; -// if (Config::Instance()->FGXeFGDepthInverted.value_or_default()) -// params.initFlags |= XEFG_SWAPCHAIN_INIT_FLAG_INVERTED_DEPTH; -// -// if (Config::Instance()->FGXeFGJitteredMV.value_or_default()) -// params.initFlags |= XEFG_SWAPCHAIN_INIT_FLAG_JITTERED_MV; -// -// if (Config::Instance()->FGXeFGHighResMV.value_or_default()) -// params.initFlags |= XEFG_SWAPCHAIN_INIT_FLAG_HIGH_RES_MV; -// -// LOG_DEBUG("Inverted Depth: {}", Config::Instance()->FGXeFGDepthInverted.value_or_default()); -// LOG_DEBUG("Jittered Velocity: {}", Config::Instance()->FGXeFGJitteredMV.value_or_default()); -// LOG_DEBUG("High Res MV: {}", Config::Instance()->FGXeFGHighResMV.value_or_default()); -// -// auto result = XeFGProxy::D3D12InitFromSwapChainDesc()(_swapChainContext, hwnd, &scDesc, &fsDesc, realQueue, -// factory12, ¶ms); -// -// if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) -// { -// LOG_ERROR("D3D12InitFromSwapChainDesc error: {} ({})", magic_enum::enum_name(result), (UINT) result); -// return false; -// } -// -// LOG_INFO("XeFG swapchain created"); -// result = XeFGProxy::D3D12GetSwapChainPtr()(_swapChainContext, IID_PPV_ARGS(swapChain)); -// if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) -// { -// LOG_ERROR("D3D12GetSwapChainPtr error: {} ({})", magic_enum::enum_name(result), (UINT) result); -// return false; -// } -// -// _gameCommandQueue = realQueue; -// _swapChain = *swapChain; -// _hwnd = hwnd; -// -// return true; -// } -// -// bool XeFG_Dx12::CreateSwapchain1(IDXGIFactory* factory, ID3D12CommandQueue* cmdQueue, HWND hwnd, -// DXGI_SWAP_CHAIN_DESC1* desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, -// IDXGISwapChain1** swapChain) -//{ -// if (_swapChainContext == nullptr) -// { -// if (State::Instance().currentD3D12Device == nullptr) -// return false; -// -// CreateSwapchainContext(State::Instance().currentD3D12Device); -// -// if (_swapChainContext == nullptr) -// return false; -// -// _width = desc->Width; -// _height = desc->Height; -// } -// -// IDXGIFactory* realFactory = nullptr; -// ID3D12CommandQueue* realQueue = nullptr; -// -// if (!CheckForRealObject(__FUNCTION__, factory, (IUnknown**) &realFactory)) -// realFactory = factory; -// -// if (!CheckForRealObject(__FUNCTION__, cmdQueue, (IUnknown**) &realQueue)) -// realQueue = cmdQueue; -// -// IDXGIFactory2* factory12 = nullptr; -// if (realFactory->QueryInterface(IID_PPV_ARGS(&factory12)) != S_OK) -// return false; -// -// factory12->Release(); -// -// xefg_swapchain_d3d12_init_params_t params {}; -// params.maxInterpolatedFrames = 1; -// -// params.initFlags = XEFG_SWAPCHAIN_INIT_FLAG_NONE; -// if (Config::Instance()->FGXeFGDepthInverted.value_or_default()) -// params.initFlags |= XEFG_SWAPCHAIN_INIT_FLAG_INVERTED_DEPTH; -// -// if (Config::Instance()->FGXeFGJitteredMV.value_or_default()) -// params.initFlags |= XEFG_SWAPCHAIN_INIT_FLAG_JITTERED_MV; -// -// if (Config::Instance()->FGXeFGHighResMV.value_or_default()) -// params.initFlags |= XEFG_SWAPCHAIN_INIT_FLAG_HIGH_RES_MV; -// -// LOG_DEBUG("Inverted Depth: {}", Config::Instance()->FGXeFGDepthInverted.value_or_default()); -// LOG_DEBUG("Jittered Velocity: {}", Config::Instance()->FGXeFGJitteredMV.value_or_default()); -// LOG_DEBUG("High Res MV: {}", Config::Instance()->FGXeFGHighResMV.value_or_default()); -// -// auto result = XeFGProxy::D3D12InitFromSwapChainDesc()(_swapChainContext, hwnd, desc, pFullscreenDesc, realQueue, -// factory12, ¶ms); -// -// if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) -// { -// LOG_ERROR("D3D12InitFromSwapChainDesc error: {} ({})", magic_enum::enum_name(result), (UINT) result); -// return false; -// } -// -// LOG_INFO("XeFG swapchain created"); -// result = XeFGProxy::D3D12GetSwapChainPtr()(_swapChainContext, IID_PPV_ARGS(swapChain)); -// if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) -// { -// LOG_ERROR("D3D12GetSwapChainPtr error: {} ({})", magic_enum::enum_name(result), (UINT) result); -// return false; -// } -// -// _gameCommandQueue = realQueue; -// _swapChain = *swapChain; -// _hwnd = hwnd; -// -// return true; -// } -// -// bool XeFG_Dx12::ReleaseSwapchain(HWND hwnd) -//{ -// if (hwnd != _hwnd || _hwnd == NULL) -// return false; -// -// LOG_DEBUG(""); -// -// if (Config::Instance()->FGUseMutexForSwapchain.value_or_default()) -// { -// LOG_TRACE("Waiting Mutex 1, current: {}", Mutex.getOwner()); -// Mutex.lock(1); -// LOG_TRACE("Accuired Mutex: {}", Mutex.getOwner()); -// } -// -// MenuOverlayDx::CleanupRenderTarget(true, NULL); -// -// if (_fgContext != nullptr) -// StopAndDestroyContext(true, true, false); -// -// if (_swapChainContext != nullptr) -// DestroySwapchainContext(); -// -// if (Config::Instance()->FGUseMutexForSwapchain.value_or_default()) -// { -// LOG_TRACE("Releasing Mutex: {}", Mutex.getOwner()); -// Mutex.unlockThis(1); -// } -// -// return true; -// } -// -// void XeFG_Dx12::CreateContext(ID3D12Device* device, FG_Constants& fgConstants) -//{ -// if (_fgContext == nullptr && _swapChainContext != nullptr) -// { -// _fgContext = _swapChainContext; -// } -// -// if (!_isActive) -// { -// auto result = XeFGProxy::SetEnabled()(_swapChainContext, true); -// _isActive = true; -// LOG_INFO("SetEnabled: true, result: {} ({})", magic_enum::enum_name(result), (UINT) result); -// } -// } -// -// bool XeFG_Dx12::Dispatch() -//{ -// LOG_DEBUG(); -// -// _lastDispatchedFrame = _frameCount; -// -// auto fIndex = GetIndex(); -// -// XeFGProxy::EnableDebugFeature()(_swapChainContext, XEFG_SWAPCHAIN_DEBUG_FEATURE_TAG_INTERPOLATED_FRAMES, -// Config::Instance()->FGXeFGDebugView.value_or_default(), nullptr); -// XeFGProxy::EnableDebugFeature()(_swapChainContext, XEFG_SWAPCHAIN_DEBUG_FEATURE_SHOW_ONLY_INTERPOLATION, -// State::Instance().FGonlyGenerated, nullptr); -// XeFGProxy::EnableDebugFeature()(_swapChainContext, XEFG_SWAPCHAIN_DEBUG_FEATURE_PRESENT_FAILED_INTERPOLATION, -// State::Instance().FGonlyGenerated, nullptr); -// -// uint32_t left = 0; -// uint32_t top = 0; -// uint32_t width = _width; -// uint32_t height = _height; -// -// IFeature* upscaleFeature = State::Instance().currentFeature; -// -// // use swapchain buffer info -// DXGI_SWAP_CHAIN_DESC scDesc1 {}; -// if (State::Instance().currentSwapchain->GetDesc(&scDesc1) == S_OK) -// { -// LOG_DEBUG("SwapChain Res: {}x{}, Upscaler Display Res: {}x{}", scDesc1.BufferDesc.Width, -// scDesc1.BufferDesc.Height, upscaleFeature->DisplayWidth(), upscaleFeature->DisplayHeight()); -// -// if (upscaleFeature != nullptr) -// { -// auto calculatedLeft = ((int) scDesc1.BufferDesc.Width - (int) upscaleFeature->DisplayWidth()) / 2; -// if (calculatedLeft > 0) -// left = Config::Instance()->FGRectLeft.value_or(calculatedLeft); -// -// auto calculatedTop = ((int) scDesc1.BufferDesc.Height - (int) upscaleFeature->DisplayHeight()) / 2; -// if (calculatedTop > 0) -// top = Config::Instance()->FGRectTop.value_or(calculatedTop); -// -// width = Config::Instance()->FGRectWidth.value_or(upscaleFeature->DisplayWidth()); -// height = Config::Instance()->FGRectHeight.value_or(upscaleFeature->DisplayHeight()); -// } -// else -// { -// left = Config::Instance()->FGRectLeft.value_or(0); -// top = Config::Instance()->FGRectTop.value_or(0); -// width = Config::Instance()->FGRectWidth.value_or(_width); -// height = Config::Instance()->FGRectHeight.value_or(_height); -// } -// } -// else -// { -// left = Config::Instance()->FGRectLeft.value_or(0); -// top = Config::Instance()->FGRectTop.value_or(0); -// width = Config::Instance()->FGRectWidth.value_or(_width); -// height = Config::Instance()->FGRectHeight.value_or(_height); -// } -// -// uint32_t renderWidth = width; -// uint32_t renderHeight = height; -// -// if (upscaleFeature != nullptr) -// { -// renderWidth = upscaleFeature->RenderWidth(); -// renderHeight = upscaleFeature->RenderHeight(); -// } -// -// LOG_DEBUG("Render Size: {}x{}", renderWidth, renderHeight); -// LOG_DEBUG("Output Base: {}:{}, Size: {}x{}", left, top, width, height); -// -// xefg_swapchain_d3d12_resource_data_t backbuffer = {}; -// backbuffer.type = XEFG_SWAPCHAIN_RES_BACKBUFFER; -// backbuffer.resourceBase = { left, top }; -// backbuffer.resourceSize = { width, height }; -// -// auto result = XeFGProxy::D3D12TagFrameResource()(_swapChainContext, _commandList[fIndex], _frameCount, -// &backbuffer); if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) -// { -// LOG_ERROR("D3D12TagFrameResource Backbuffer error: {} ({})", magic_enum::enum_name(result), (UINT) result); -// return false; -// } -// -// xefg_swapchain_d3d12_resource_data_t velocity = {}; -// velocity.type = XEFG_SWAPCHAIN_RES_MOTION_VECTOR; -// velocity.validity = XEFG_SWAPCHAIN_RV_UNTIL_NEXT_PRESENT; -// -// if (upscaleFeature != nullptr) -// { -// if (upscaleFeature->LowResMV()) -// velocity.resourceSize = { renderWidth, renderHeight }; -// else -// velocity.resourceSize = { width, height }; -// } -// else -// { -// velocity.resourceSize = { renderWidth, renderHeight }; -// } -// -// velocity.pResource = _paramVelocity[fIndex].resource; -// velocity.incomingState = _paramVelocity[fIndex].getState(); -// -// result = XeFGProxy::D3D12TagFrameResource()(_swapChainContext, _commandList[fIndex], _frameCount, &velocity); -// if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) -// { -// LOG_ERROR("D3D12TagFrameResource Velocity error: {} ({})", magic_enum::enum_name(result), (UINT) result); -// return false; -// } -// -// xefg_swapchain_d3d12_resource_data_t depth = {}; -// depth.type = XEFG_SWAPCHAIN_RES_DEPTH; -// depth.validity = XEFG_SWAPCHAIN_RV_UNTIL_NEXT_PRESENT; -// depth.resourceSize = { renderWidth, renderHeight }; -// depth.pResource = _paramDepth[fIndex].resource; -// depth.incomingState = _paramDepth[fIndex].getState(); -// -// result = XeFGProxy::D3D12TagFrameResource()(_swapChainContext, _commandList[fIndex], _frameCount, &depth); -// if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) -// { -// LOG_ERROR("D3D12TagFrameResource Depth error: {} ({})", magic_enum::enum_name(result), (UINT) result); -// return false; -// } -// -// if (!_noUi[fIndex]) -// { -// xefg_swapchain_d3d12_resource_data_t ui = {}; -// ui.type = XEFG_SWAPCHAIN_RES_UI; -// ui.validity = XEFG_SWAPCHAIN_RV_UNTIL_NEXT_PRESENT; -// ui.resourceBase = { left, top }; -// ui.resourceSize = { width, height }; -// ui.pResource = _paramUi[fIndex].resource; -// ui.incomingState = _paramUi[fIndex].getState(); -// -// LOG_DEBUG("Using _paramUi[{}]: {:X}", fIndex, (size_t) _paramUi[fIndex].resource); -// -// result = XeFGProxy::D3D12TagFrameResource()(_swapChainContext, _commandList[fIndex], _frameCount, &ui); -// if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) -// { -// LOG_ERROR("D3D12TagFrameResource Hudless error: {} ({})", magic_enum::enum_name(result), (UINT) result); -// return false; -// } -// } -// else if (!_noHudless[fIndex]) -// { -// xefg_swapchain_d3d12_resource_data_t hudless = {}; -// hudless.type = XEFG_SWAPCHAIN_RES_HUDLESS_COLOR; -// hudless.validity = XEFG_SWAPCHAIN_RV_UNTIL_NEXT_PRESENT; -// hudless.resourceBase = { left, top }; -// hudless.resourceSize = { width, height }; -// hudless.pResource = _paramHudless[fIndex].resource; -// hudless.incomingState = _paramHudless[fIndex].getState(); -// -// LOG_DEBUG("Using _paramHudless[{}]: {:X}", fIndex, (size_t) _paramHudless[fIndex].resource); -// -// result = XeFGProxy::D3D12TagFrameResource()(_swapChainContext, _commandList[fIndex], _frameCount, &hudless); -// if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) -// { -// LOG_ERROR("D3D12TagFrameResource Hudless error: {} ({})", magic_enum::enum_name(result), (UINT) result); -// return false; -// } -// } -// -// xefg_swapchain_frame_constant_data_t constData = {}; -// -// if (_cameraPosition[0] != 0.0 || _cameraPosition[1] != 0.0 || _cameraPosition[2] != 0.0) -// { -// XMVECTOR right = XMLoadFloat3(reinterpret_cast(_cameraRight)); -// XMVECTOR up = XMLoadFloat3(reinterpret_cast(_cameraUp)); -// XMVECTOR forward = XMLoadFloat3(reinterpret_cast(_cameraForward)); -// XMVECTOR pos = XMLoadFloat3(reinterpret_cast(_cameraPosition)); -// -// float x = -XMVectorGetX(XMVector3Dot(pos, right)); -// float y = -XMVectorGetX(XMVector3Dot(pos, up)); -// float z = -XMVectorGetX(XMVector3Dot(pos, forward)); -// -// XMMATRIX view = { XMVectorSet(XMVectorGetX(right), XMVectorGetX(up), XMVectorGetX(forward), 0.0f), -// XMVectorSet(XMVectorGetY(right), XMVectorGetY(up), XMVectorGetY(forward), 0.0f), -// XMVectorSet(XMVectorGetZ(right), XMVectorGetZ(up), XMVectorGetZ(forward), 0.0f), -// XMVectorSet(x, y, z, 1.0f) }; -// -// memcpy(constData.viewMatrix, view.r, sizeof(view)); -// } -// -// if (Config::Instance()->FGXeFGDepthInverted.value_or_default()) -// std::swap(_cameraNear, _cameraFar); -// -// // Cyberpunk seems to be sending LH so do the same -// // it also sends some extra data in usually empty spots but no idea what that is -// auto projectionMatrix = XMMatrixPerspectiveFovLH(_cameraVFov, _cameraAspectRatio, _cameraNear, _cameraFar); -// memcpy(constData.projectionMatrix, projectionMatrix.r, sizeof(projectionMatrix)); -// -// constData.jitterOffsetX = _jitterX; -// constData.jitterOffsetY = _jitterY; -// constData.motionVectorScaleX = _mvScaleX; -// constData.motionVectorScaleY = _mvScaleY; -// constData.resetHistory = _reset; -// constData.frameRenderTime = _ftDelta; -// -// LOG_DEBUG("Reset: {}, FTDelta: {}", _reset, _ftDelta); -// -// result = XeFGProxy::TagFrameConstants()(_swapChainContext, _frameCount, &constData); -// if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) -// { -// LOG_ERROR("TagFrameConstants error: {} ({})", magic_enum::enum_name(result), (UINT) result); -// return false; -// } -// -// result = XeFGProxy::SetPresentId()(_swapChainContext, _frameCount); -// if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) -// { -// LOG_ERROR("SetPresentId error: {} ({})", magic_enum::enum_name(result), (UINT) result); -// return false; -// } -// -// _mvsReady[fIndex] = false; -// _depthReady[fIndex] = false; -// _hudlessReady[fIndex] = false; -// -// LOG_DEBUG("Result: Ok"); -// -// return true; -// } -// -// void* XeFG_Dx12::FrameGenerationContext() { return _fgContext; } -// -// void* XeFG_Dx12::SwapchainContext() { return _swapChainContext; } -// -// void XeFG_Dx12::EvaluateState(ID3D12Device* device, FG_Constants& fgConstants) -//{ -// LOG_FUNC(); -// -// if (!Config::Instance()->OverlayMenu.value_or_default()) -// return; -// -// static bool lastInfiniteDepth = false; -// bool currentInfiniteDepth = static_cast(fgConstants.flags & FG_Flags::InfiniteDepth); -// if (lastInfiniteDepth != currentInfiniteDepth) -// { -// lastInfiniteDepth = currentInfiniteDepth; -// LOG_DEBUG("Infinite Depth changed: {}", currentInfiniteDepth); -// State::Instance().FGchanged = true; -// } -// -// if (!State::Instance().FGchanged && Config::Instance()->FGEnabled.value_or_default() && !IsPaused() && -// XeFGProxy::InitXeFG() && !IsActive() && HooksDx::CurrentSwapchainFormat() != DXGI_FORMAT_UNKNOWN) -// { -// CreateObjects(device); -// CreateContext(device, fgConstants); -// ResetCounters(); -// UpdateTarget(); -// } -// else if ((!Config::Instance()->FGEnabled.value_or_default() || State::Instance().FGchanged) && IsActive()) -// { -// StopAndDestroyContext(State::Instance().SCchanged, false, false); -// -// if (State::Instance().activeFgInput == FGInput::Upscaler) -// { -// State::Instance().ClearCapturedHudlesses = true; -// Hudfix_Dx12::ResetCounters(); -// } -// } -// -// if (State::Instance().FGchanged) -// { -// LOG_DEBUG("(FG) Frame generation paused"); -// ResetCounters(); -// UpdateTarget(); -// -// if (State::Instance().activeFgInput == FGInput::Upscaler) -// Hudfix_Dx12::ResetCounters(); -// -// // Release FG mutex -// if (Mutex.getOwner() == 2) -// Mutex.unlockThis(2); -// -// State::Instance().FGchanged = false; -// } -// -// State::Instance().SCchanged = false; -// } +#include "XeFG_Dx12.h" + +#include +#include +#include +#include + +#include + +void XeFG_Dx12::xefgLogCallback(const char* message, xefg_swapchain_logging_level_t level, void* userData) +{ + switch (level) + { + case XEFG_SWAPCHAIN_LOGGING_LEVEL_DEBUG: + spdlog::debug("XeFG Log: {}", message); + return; + + case XEFG_SWAPCHAIN_LOGGING_LEVEL_INFO: + spdlog::info("XeFG Log: {}", message); + return; + + case XEFG_SWAPCHAIN_LOGGING_LEVEL_WARNING: + spdlog::warn("XeFG Log: {}", message); + return; + + default: + spdlog::error("XeFG Log: {}", message); + return; + } +} + +bool XeFG_Dx12::CreateSwapchainContext(ID3D12Device* device) +{ + if (XeFGProxy::Module() == nullptr && !XeFGProxy::InitXeFG()) + { + LOG_ERROR("XeFG proxy can't find libxess_fg.dll!"); + return false; + } + + State::Instance().skipSpoofing = true; + auto result = XeFGProxy::D3D12CreateContext()(device, &_swapChainContext); + State::Instance().skipSpoofing = false; + + if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) + { + LOG_ERROR("D3D12CreateContext error: {} ({})", magic_enum::enum_name(result), (UINT) result); + return false; + } + + LOG_INFO("XeFG context created"); + result = XeFGProxy::SetLoggingCallback()(_swapChainContext, XEFG_SWAPCHAIN_LOGGING_LEVEL_DEBUG, xefgLogCallback, + nullptr); + + if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) + { + LOG_ERROR("SetLoggingCallback error: {} ({})", magic_enum::enum_name(result), (UINT) result); + } + + if (XeLLProxy::Context() == nullptr) + XeLLProxy::CreateContext(device); + + if (XeLLProxy::Context() != nullptr) + { + xell_sleep_params_t sleepParams = {}; + sleepParams.bLowLatencyMode = true; + sleepParams.bLowLatencyBoost = false; + sleepParams.minimumIntervalUs = 0; + + auto xellResult = XeLLProxy::SetSleepMode()(XeLLProxy::Context(), &sleepParams); + if (xellResult != XELL_RESULT_SUCCESS) + { + LOG_ERROR("SetSleepMode error: {} ({})", magic_enum::enum_name(xellResult), (UINT) xellResult); + return false; + } + + auto fnaResult = fakenvapi::setModeAndContext(XeLLProxy::Context(), Mode::XeLL); + LOG_DEBUG("fakenvapi::setModeAndContext: {}", fnaResult); + + result = XeFGProxy::SetLatencyReduction()(_swapChainContext, XeLLProxy::Context()); + + if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) + { + LOG_ERROR("SetLatencyReduction error: {} ({})", magic_enum::enum_name(result), (UINT) result); + return false; + } + }; + + return true; +} + +const char* XeFG_Dx12::Name() { return "XeFG"; } + +feature_version XeFG_Dx12::Version() +{ + if (XeFGProxy::InitXeFG()) + { + auto ver = XeFGProxy::Version(); + return ver; + } + + return { 0, 0, 0 }; +} + +void XeFG_Dx12::StopAndDestroyContext(bool destroy, bool shutDown) +{ + LOG_DEBUG(""); + + if (_isActive) + { + auto result = XeFGProxy::SetEnabled()(_swapChainContext, false); + _isActive = false; + if (!(shutDown || State::Instance().isShuttingDown)) + LOG_INFO("SetEnabled: false, result: {} ({})", magic_enum::enum_name(result), (UINT) result); + } + + if (destroy && _fgContext != nullptr) + { + _fgContext = nullptr; + } + + if (shutDown || State::Instance().isShuttingDown) + ReleaseObjects(); +} + +bool XeFG_Dx12::DestroySwapchainContext() +{ + LOG_DEBUG(""); + + _isActive = false; + + if (_swapChainContext != nullptr) + { + auto result = XeFGProxy::Destroy()(_swapChainContext); + + if (!State::Instance().isShuttingDown) + LOG_INFO("Destroy result: {} ({})", magic_enum::enum_name(result), (UINT) result); + + _swapChainContext = nullptr; + } + + return true; +} + +xefg_swapchain_d3d12_resource_data_t XeFG_Dx12::GetResourceData(FG_ResourceType type) +{ + auto fIndex = GetIndex(); + + xefg_swapchain_d3d12_resource_data_t resourceParam = {}; + + if (!_frameResources[fIndex].contains(type)) + return resourceParam; + + auto fResource = &_frameResources[fIndex][type]; + + resourceParam.validity = (fResource->validity == FG_ResourceValidity::ValidNow) + ? XEFG_SWAPCHAIN_RV_ONLY_NOW + : XEFG_SWAPCHAIN_RV_UNTIL_NEXT_PRESENT; + + resourceParam.resourceSize = { fResource->width, fResource->height }; + resourceParam.pResource = fResource->GetResource(); + resourceParam.incomingState = fResource->state; + + xefg_swapchain_resource_type_t xessType; + + switch (type) + { + case FG_ResourceType::Depth: + resourceParam.type = XEFG_SWAPCHAIN_RES_DEPTH; + break; + + case FG_ResourceType::HudlessColor: + resourceParam.type = XEFG_SWAPCHAIN_RES_HUDLESS_COLOR; + break; + + case FG_ResourceType::UIColor: + resourceParam.type = XEFG_SWAPCHAIN_RES_UI; + break; + + case FG_ResourceType::Velocity: + resourceParam.type = XEFG_SWAPCHAIN_RES_MOTION_VECTOR; + break; + } + + if (type == FG_ResourceType::UIColor || type == FG_ResourceType::HudlessColor) + { + uint32_t left = 0; + uint32_t top = 0; + + // use swapchain buffer info + DXGI_SWAP_CHAIN_DESC scDesc1 {}; + if (State::Instance().currentSwapchain->GetDesc(&scDesc1) == S_OK) + { + LOG_DEBUG("SwapChain Res: {}x{}, Upscaler Display Res: {}x{}", scDesc1.BufferDesc.Width, + scDesc1.BufferDesc.Height, _interpolationWidth, _interpolationHeight); + + auto calculatedLeft = ((int) scDesc1.BufferDesc.Width - (int) _interpolationWidth) / 2; + if (calculatedLeft > 0) + left = Config::Instance()->FGRectLeft.value_or(calculatedLeft); + + auto calculatedTop = ((int) scDesc1.BufferDesc.Height - (int) _interpolationHeight) / 2; + if (calculatedTop > 0) + top = Config::Instance()->FGRectTop.value_or(calculatedTop); + } + else + { + left = Config::Instance()->FGRectLeft.value_or(0); + top = Config::Instance()->FGRectTop.value_or(0); + } + + resourceParam.resourceBase = { left, top }; + resourceParam.resourceSize = { _interpolationWidth, _interpolationHeight }; + } + + return resourceParam; +} + +bool XeFG_Dx12::CreateSwapchain(IDXGIFactory* factory, ID3D12CommandQueue* cmdQueue, DXGI_SWAP_CHAIN_DESC* desc, + IDXGISwapChain** swapChain) +{ + if (_swapChainContext == nullptr) + { + if (State::Instance().currentD3D12Device == nullptr) + return false; + + CreateSwapchainContext(State::Instance().currentD3D12Device); + + if (_swapChainContext == nullptr) + return false; + + _width = desc->BufferDesc.Width; + _height = desc->BufferDesc.Height; + } + + IDXGIFactory* realFactory = nullptr; + ID3D12CommandQueue* realQueue = nullptr; + + if (!CheckForRealObject(__FUNCTION__, factory, (IUnknown**) &realFactory)) + realFactory = factory; + + if (!CheckForRealObject(__FUNCTION__, cmdQueue, (IUnknown**) &realQueue)) + realQueue = cmdQueue; + + IDXGIFactory2* factory12 = nullptr; + if (realFactory->QueryInterface(IID_PPV_ARGS(&factory12)) != S_OK) + return false; + + factory12->Release(); + + HWND hwnd = desc->OutputWindow; + DXGI_SWAP_CHAIN_DESC1 scDesc {}; + + scDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; // No info + scDesc.BufferCount = desc->BufferCount; + scDesc.BufferUsage = desc->BufferUsage; + scDesc.Flags = desc->Flags; + scDesc.Format = desc->BufferDesc.Format; + scDesc.Height = desc->BufferDesc.Height; + scDesc.SampleDesc = desc->SampleDesc; + scDesc.Scaling = DXGI_SCALING_NONE; // No info + scDesc.Stereo = false; // No info + scDesc.SwapEffect = desc->SwapEffect; + scDesc.Width = desc->BufferDesc.Width; + + DXGI_SWAP_CHAIN_FULLSCREEN_DESC fsDesc {}; + fsDesc.RefreshRate = desc->BufferDesc.RefreshRate; + fsDesc.Scaling = desc->BufferDesc.Scaling; + fsDesc.ScanlineOrdering = desc->BufferDesc.ScanlineOrdering; + fsDesc.Windowed = desc->Windowed; + + xefg_swapchain_d3d12_init_params_t params {}; + params.maxInterpolatedFrames = 1; + + params.initFlags = XEFG_SWAPCHAIN_INIT_FLAG_NONE; + if (Config::Instance()->FGXeFGDepthInverted.value_or_default()) + params.initFlags |= XEFG_SWAPCHAIN_INIT_FLAG_INVERTED_DEPTH; + + if (Config::Instance()->FGXeFGJitteredMV.value_or_default()) + params.initFlags |= XEFG_SWAPCHAIN_INIT_FLAG_JITTERED_MV; + + if (Config::Instance()->FGXeFGHighResMV.value_or_default()) + params.initFlags |= XEFG_SWAPCHAIN_INIT_FLAG_HIGH_RES_MV; + + LOG_DEBUG("Inverted Depth: {}", Config::Instance()->FGXeFGDepthInverted.value_or_default()); + LOG_DEBUG("Jittered Velocity: {}", Config::Instance()->FGXeFGJitteredMV.value_or_default()); + LOG_DEBUG("High Res MV: {}", Config::Instance()->FGXeFGHighResMV.value_or_default()); + + auto result = XeFGProxy::D3D12InitFromSwapChainDesc()(_swapChainContext, hwnd, &scDesc, &fsDesc, realQueue, + factory12, ¶ms); + + if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) + { + LOG_ERROR("D3D12InitFromSwapChainDesc error: {} ({})", magic_enum::enum_name(result), (UINT) result); + return false; + } + + LOG_INFO("XeFG swapchain created"); + result = XeFGProxy::D3D12GetSwapChainPtr()(_swapChainContext, IID_PPV_ARGS(swapChain)); + if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) + { + LOG_ERROR("D3D12GetSwapChainPtr error: {} ({})", magic_enum::enum_name(result), (UINT) result); + return false; + } + + _gameCommandQueue = realQueue; + _swapChain = *swapChain; + _hwnd = hwnd; + + return true; +} + +bool XeFG_Dx12::CreateSwapchain1(IDXGIFactory* factory, ID3D12CommandQueue* cmdQueue, HWND hwnd, + DXGI_SWAP_CHAIN_DESC1* desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, + IDXGISwapChain1** swapChain) +{ + if (_swapChainContext == nullptr) + { + if (State::Instance().currentD3D12Device == nullptr) + return false; + + CreateSwapchainContext(State::Instance().currentD3D12Device); + + if (_swapChainContext == nullptr) + return false; + + _width = desc->Width; + _height = desc->Height; + } + + IDXGIFactory* realFactory = nullptr; + ID3D12CommandQueue* realQueue = nullptr; + + if (!CheckForRealObject(__FUNCTION__, factory, (IUnknown**) &realFactory)) + realFactory = factory; + + if (!CheckForRealObject(__FUNCTION__, cmdQueue, (IUnknown**) &realQueue)) + realQueue = cmdQueue; + + IDXGIFactory2* factory12 = nullptr; + if (realFactory->QueryInterface(IID_PPV_ARGS(&factory12)) != S_OK) + return false; + + factory12->Release(); + + xefg_swapchain_d3d12_init_params_t params {}; + params.maxInterpolatedFrames = 1; + + params.initFlags = XEFG_SWAPCHAIN_INIT_FLAG_NONE; + if (Config::Instance()->FGXeFGDepthInverted.value_or_default()) + params.initFlags |= XEFG_SWAPCHAIN_INIT_FLAG_INVERTED_DEPTH; + + if (Config::Instance()->FGXeFGJitteredMV.value_or_default()) + params.initFlags |= XEFG_SWAPCHAIN_INIT_FLAG_JITTERED_MV; + + if (Config::Instance()->FGXeFGHighResMV.value_or_default()) + params.initFlags |= XEFG_SWAPCHAIN_INIT_FLAG_HIGH_RES_MV; + + LOG_DEBUG("Inverted Depth: {}", Config::Instance()->FGXeFGDepthInverted.value_or_default()); + LOG_DEBUG("Jittered Velocity: {}", Config::Instance()->FGXeFGJitteredMV.value_or_default()); + LOG_DEBUG("High Res MV: {}", Config::Instance()->FGXeFGHighResMV.value_or_default()); + + auto result = XeFGProxy::D3D12InitFromSwapChainDesc()(_swapChainContext, hwnd, desc, pFullscreenDesc, realQueue, + factory12, ¶ms); + + if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) + { + LOG_ERROR("D3D12InitFromSwapChainDesc error: {} ({})", magic_enum::enum_name(result), (UINT) result); + return false; + } + + LOG_INFO("XeFG swapchain created"); + result = XeFGProxy::D3D12GetSwapChainPtr()(_swapChainContext, IID_PPV_ARGS(swapChain)); + if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) + { + LOG_ERROR("D3D12GetSwapChainPtr error: {} ({})", magic_enum::enum_name(result), (UINT) result); + return false; + } + + _gameCommandQueue = realQueue; + _swapChain = *swapChain; + _hwnd = hwnd; + + return true; +} + +bool XeFG_Dx12::ReleaseSwapchain(HWND hwnd) +{ + if (hwnd != _hwnd || _hwnd == NULL) + return false; + + LOG_DEBUG(""); + + if (Config::Instance()->FGUseMutexForSwapchain.value_or_default()) + { + LOG_TRACE("Waiting Mutex 1, current: {}", Mutex.getOwner()); + Mutex.lock(1); + LOG_TRACE("Accuired Mutex: {}", Mutex.getOwner()); + } + + MenuOverlayDx::CleanupRenderTarget(true, NULL); + + if (_fgContext != nullptr) + StopAndDestroyContext(true, true); + + if (_swapChainContext != nullptr) + DestroySwapchainContext(); + + if (Config::Instance()->FGUseMutexForSwapchain.value_or_default()) + { + LOG_TRACE("Releasing Mutex: {}", Mutex.getOwner()); + Mutex.unlockThis(1); + } + + return true; +} + +void XeFG_Dx12::CreateContext(ID3D12Device* device, FG_Constants& fgConstants) +{ + if (_fgContext == nullptr && _swapChainContext != nullptr) + { + _fgContext = _swapChainContext; + } + + if (!_isActive) + { + auto result = XeFGProxy::SetEnabled()(_swapChainContext, true); + _isActive = true; + LOG_INFO("SetEnabled: true, result: {} ({})", magic_enum::enum_name(result), (UINT) result); + } +} + +bool XeFG_Dx12::Dispatch() +{ + LOG_DEBUG(); + + _lastDispatchedFrame = _frameCount; + + auto fIndex = GetIndex(); + + XeFGProxy::EnableDebugFeature()(_swapChainContext, XEFG_SWAPCHAIN_DEBUG_FEATURE_TAG_INTERPOLATED_FRAMES, + Config::Instance()->FGXeFGDebugView.value_or_default(), nullptr); + XeFGProxy::EnableDebugFeature()(_swapChainContext, XEFG_SWAPCHAIN_DEBUG_FEATURE_SHOW_ONLY_INTERPOLATION, + State::Instance().FGonlyGenerated, nullptr); + XeFGProxy::EnableDebugFeature()(_swapChainContext, XEFG_SWAPCHAIN_DEBUG_FEATURE_PRESENT_FAILED_INTERPOLATION, + State::Instance().FGonlyGenerated, nullptr); + + uint32_t left = 0; + uint32_t top = 0; + uint32_t width = _width; + uint32_t height = _height; + + // use swapchain buffer info + DXGI_SWAP_CHAIN_DESC scDesc1 {}; + if (State::Instance().currentSwapchain->GetDesc(&scDesc1) == S_OK) + { + LOG_DEBUG("SwapChain Res: {}x{}, Upscaler Display Res: {}x{}", scDesc1.BufferDesc.Width, + scDesc1.BufferDesc.Height, _interpolationWidth, _interpolationHeight); + + auto calculatedLeft = ((int) scDesc1.BufferDesc.Width - (int) _interpolationWidth) / 2; + if (calculatedLeft > 0) + left = Config::Instance()->FGRectLeft.value_or(calculatedLeft); + + auto calculatedTop = ((int) scDesc1.BufferDesc.Height - (int) _interpolationHeight) / 2; + if (calculatedTop > 0) + top = Config::Instance()->FGRectTop.value_or(calculatedTop); + + width = Config::Instance()->FGRectWidth.value_or(_interpolationWidth); + height = Config::Instance()->FGRectHeight.value_or(_interpolationHeight); + } + else + { + left = Config::Instance()->FGRectLeft.value_or(0); + top = Config::Instance()->FGRectTop.value_or(0); + width = Config::Instance()->FGRectWidth.value_or(_width); + height = Config::Instance()->FGRectHeight.value_or(_height); + } + + uint32_t renderWidth = width; + uint32_t renderHeight = height; + + LOG_DEBUG("Output Base: {}:{}, Size: {}x{}", left, top, width, height); + + xefg_swapchain_d3d12_resource_data_t backbuffer = {}; + backbuffer.type = XEFG_SWAPCHAIN_RES_BACKBUFFER; + backbuffer.resourceBase = { left, top }; + backbuffer.resourceSize = { width, height }; + + auto result = XeFGProxy::D3D12TagFrameResource()(_swapChainContext, _copyCommandList[FG_ResourceType::Distortion], + _frameCount, &backbuffer); + if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) + { + LOG_ERROR("D3D12TagFrameResource Backbuffer error: {} ({})", magic_enum::enum_name(result), (UINT) result); + return false; + } + + xefg_swapchain_frame_constant_data_t constData = {}; + + if (_cameraPosition[0] != 0.0 || _cameraPosition[1] != 0.0 || _cameraPosition[2] != 0.0) + { + XMVECTOR right = XMLoadFloat3(reinterpret_cast(_cameraRight)); + XMVECTOR up = XMLoadFloat3(reinterpret_cast(_cameraUp)); + XMVECTOR forward = XMLoadFloat3(reinterpret_cast(_cameraForward)); + XMVECTOR pos = XMLoadFloat3(reinterpret_cast(_cameraPosition)); + + float x = -XMVectorGetX(XMVector3Dot(pos, right)); + float y = -XMVectorGetX(XMVector3Dot(pos, up)); + float z = -XMVectorGetX(XMVector3Dot(pos, forward)); + + XMMATRIX view = { XMVectorSet(XMVectorGetX(right), XMVectorGetX(up), XMVectorGetX(forward), 0.0f), + XMVectorSet(XMVectorGetY(right), XMVectorGetY(up), XMVectorGetY(forward), 0.0f), + XMVectorSet(XMVectorGetZ(right), XMVectorGetZ(up), XMVectorGetZ(forward), 0.0f), + XMVectorSet(x, y, z, 1.0f) }; + + memcpy(constData.viewMatrix, view.r, sizeof(view)); + } + + if (Config::Instance()->FGXeFGDepthInverted.value_or_default()) + std::swap(_cameraNear, _cameraFar); + + // Cyberpunk seems to be sending LH so do the same + // it also sends some extra data in usually empty spots but no idea what that is + auto projectionMatrix = XMMatrixPerspectiveFovLH(_cameraVFov, _cameraAspectRatio, _cameraNear, _cameraFar); + memcpy(constData.projectionMatrix, projectionMatrix.r, sizeof(projectionMatrix)); + + constData.jitterOffsetX = _jitterX; + constData.jitterOffsetY = _jitterY; + constData.motionVectorScaleX = _mvScaleX; + constData.motionVectorScaleY = _mvScaleY; + constData.resetHistory = _reset; + constData.frameRenderTime = _ftDelta; + + LOG_DEBUG("Reset: {}, FTDelta: {}", _reset, _ftDelta); + + result = XeFGProxy::TagFrameConstants()(_swapChainContext, _frameCount, &constData); + if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) + { + LOG_ERROR("TagFrameConstants error: {} ({})", magic_enum::enum_name(result), (UINT) result); + return false; + } + + result = XeFGProxy::SetPresentId()(_swapChainContext, _frameCount); + if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) + { + LOG_ERROR("SetPresentId error: {} ({})", magic_enum::enum_name(result), (UINT) result); + return false; + } + + LOG_DEBUG("Result: Ok"); + + return true; +} + +void* XeFG_Dx12::FrameGenerationContext() { return _fgContext; } + +void* XeFG_Dx12::SwapchainContext() { return _swapChainContext; } + +void XeFG_Dx12::EvaluateState(ID3D12Device* device, FG_Constants& fgConstants) +{ + LOG_FUNC(); + + if (!Config::Instance()->OverlayMenu.value_or_default()) + return; + + static bool lastInfiniteDepth = false; + bool currentInfiniteDepth = static_cast(fgConstants.flags & FG_Flags::InfiniteDepth); + if (lastInfiniteDepth != currentInfiniteDepth) + { + lastInfiniteDepth = currentInfiniteDepth; + LOG_DEBUG("Infinite Depth changed: {}", currentInfiniteDepth); + State::Instance().FGchanged = true; + } + + if (!State::Instance().FGchanged && Config::Instance()->FGEnabled.value_or_default() && !IsPaused() && + XeFGProxy::InitXeFG() && !IsActive() && HooksDx::CurrentSwapchainFormat() != DXGI_FORMAT_UNKNOWN) + { + CreateObjects(device); + CreateContext(device, fgConstants); + ResetCounters(); + UpdateTarget(); + } + else if ((!Config::Instance()->FGEnabled.value_or_default() || State::Instance().FGchanged) && IsActive()) + { + StopAndDestroyContext(State::Instance().SCchanged, false); + + if (State::Instance().activeFgInput == FGInput::Upscaler) + { + State::Instance().ClearCapturedHudlesses = true; + Hudfix_Dx12::ResetCounters(); + } + } + + if (State::Instance().FGchanged) + { + LOG_DEBUG("(FG) Frame generation paused"); + ResetCounters(); + UpdateTarget(); + + if (State::Instance().activeFgInput == FGInput::Upscaler) + Hudfix_Dx12::ResetCounters(); + + // Release FG mutex + if (Mutex.getOwner() == 2) + Mutex.unlockThis(2); + + State::Instance().FGchanged = false; + } + + State::Instance().SCchanged = false; +} + +void XeFG_Dx12::ReleaseObjects() +{ + // For each FG_ResourceType + for (size_t i = 0; i < 5; i++) + { + if (this->_copyCommandAllocator.contains((FG_ResourceType) i)) + this->_copyCommandAllocator[(FG_ResourceType) i]->Release(); + + if (this->_copyCommandList.contains((FG_ResourceType) i)) + this->_copyCommandList[(FG_ResourceType) i]->Release(); + } + + _copyCommandAllocator.clear(); + _copyCommandList.clear(); + + _mvFlip.reset(); + _depthFlip.reset(); +} + +void XeFG_Dx12::CreateObjects(ID3D12Device* InDevice) +{ + _device = InDevice; + + if (_copyCommandList.size() > 0) + ReleaseObjects(); + + LOG_DEBUG(""); + + do + { + HRESULT result; + ID3D12CommandAllocator* allocator = nullptr; + ID3D12GraphicsCommandList* cmdList = nullptr; + ID3D12CommandQueue* cmdQueue = nullptr; + + // For each FG_ResourceType + for (size_t i = 0; i < 5; i++) + { + auto val = (FG_ResourceType) i; + + ID3D12CommandAllocator* enumAllocator = nullptr; + ID3D12GraphicsCommandList* enumCmdList = nullptr; + + // Copy + auto result = InDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, + IID_PPV_ARGS(&this->_copyCommandAllocator[val])); + if (result != S_OK) + { + LOG_ERROR("CreateCommandAllocators _copyCommandAllocator[{}]: {:X}", (UINT) val, + (unsigned long) result); + return; + } + + this->_copyCommandAllocator[val]->SetName(std::format(L"_copyCommandAllocator[{}]", (UINT) val).c_str()); + if (CheckForRealObject(__FUNCTION__, this->_copyCommandAllocator[val], (IUnknown**) &enumAllocator)) + this->_copyCommandAllocator[val] = enumAllocator; + + result = InDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, this->_copyCommandAllocator[val], + NULL, IID_PPV_ARGS(&this->_copyCommandList[val])); + if (result != S_OK) + { + LOG_ERROR("CreateCommandList _copyCommandList[{}]: {:X}", (UINT) val, (unsigned long) result); + return; + } + + this->_copyCommandList[val]->SetName(std::format(L"_copyCommandAllocator[{}]", (UINT) val).c_str()); + if (CheckForRealObject(__FUNCTION__, this->_copyCommandList[val], (IUnknown**) &enumCmdList)) + this->_copyCommandList[val] = enumCmdList; + + result = this->_copyCommandList[val]->Close(); + if (result != S_OK) + { + LOG_ERROR("_copyCommandList[{}]->Close: {:X}", (UINT) val, (unsigned long) result); + return; + } + } + + } while (false); +} + +bool XeFG_Dx12::Present() { return Dispatch(); } + +void XeFG_Dx12::SetResource(FG_ResourceType type, ID3D12GraphicsCommandList* cmdList, ID3D12Resource* resource, + UINT width, UINT height, D3D12_RESOURCE_STATES state, FG_ResourceValidity validity) +{ + if (resource == nullptr) + return; + + if (cmdList == nullptr && validity == FG_ResourceValidity::ValidNow && _gameCommandQueue == nullptr) + { + LOG_ERROR("{}, validity == ValidNow but _gameCommandQueue is nullptr!", magic_enum::enum_name(type)); + return; + } + + auto fIndex = GetIndex(); + _frameResources[fIndex][type] = {}; + auto fResource = &_frameResources[fIndex][type]; + fResource->type = type; + fResource->state = state; + fResource->validity = validity; + fResource->resource = resource; + fResource->width = width; + fResource->height = height; + + auto willFlip = State::Instance().activeFgInput == FGInput::Upscaler && + Config::Instance()->FGResourceFlip.value_or_default() && + (type == FG_ResourceType::Velocity || type == FG_ResourceType::Depth); + + auto usingLocalCmdList = false; + + if (cmdList == nullptr) + { + if (!_copyCommandAllocator.contains(type) || !_copyCommandList.contains(type)) + { + LOG_ERROR("{}, _copyCommandAllocator or _copyCommandList is nullptr!", magic_enum::enum_name(type)); + return; + } + + auto allocator = _copyCommandAllocator[type]; + cmdList = _copyCommandList[type]; + + allocator->Reset(); + cmdList->Reset(allocator, nullptr); + + usingLocalCmdList = true; + } + + fResource->cmdList = cmdList; + + // Resource flipping + if (willFlip && _device != nullptr) + { + if (type == FG_ResourceType::Velocity) + { + ID3D12Resource* flipOutput = nullptr; + + flipOutput = _resourceCopy[fIndex][type]; + + if (!CreateBufferResource(_device, resource, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, &flipOutput, true, + false)) + { + LOG_ERROR("{}, CreateBufferResource for flip is failed!", magic_enum::enum_name(type)); + return; + } + + _resourceCopy[fIndex][type] = flipOutput; + + if (_mvFlip.get() == nullptr) + { + _mvFlip = std::make_unique("VelocityFlip", _device); + } + else if (_mvFlip->IsInit()) + { + auto feature = State::Instance().currentFeature; + UINT width = feature->LowResMV() ? feature->RenderWidth() : feature->DisplayWidth(); + UINT height = feature->LowResMV() ? feature->RenderHeight() : feature->DisplayHeight(); + + auto result = _mvFlip->Dispatch(_device, cmdList, resource, flipOutput, width, height, true); + + if (result) + { + LOG_TRACE("Setting velocity from flip, index: {}", fIndex); + fResource->copy = flipOutput; + fResource->state = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + } + } + } + else if (type == FG_ResourceType::Depth) + { + ID3D12Resource* flipOutput = nullptr; + + flipOutput = _resourceCopy[fIndex][type]; + + if (!CreateBufferResource(_device, resource, state, &flipOutput, true, true)) + { + LOG_ERROR("{}, CreateBufferResource for flip is failed!", magic_enum::enum_name(type)); + return; + } + + _resourceCopy[fIndex][type] = flipOutput; + + if (_depthFlip.get() == nullptr) + { + _depthFlip = std::make_unique("DepthFlip", _device); + } + else if (_depthFlip->IsInit()) + { + auto feature = State::Instance().currentFeature; + UINT width = feature->LowResMV() ? feature->RenderWidth() : feature->DisplayWidth(); + UINT height = feature->LowResMV() ? feature->RenderHeight() : feature->DisplayHeight(); + + ResourceBarrier(cmdList, flipOutput, state, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + auto result = _depthFlip->Dispatch(_device, cmdList, resource, flipOutput, width, height, false); + ResourceBarrier(cmdList, flipOutput, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, state); + + if (result) + { + LOG_TRACE("Setting velocity from flip, index: {}", fIndex); + fResource->copy = flipOutput; + } + } + } + } + + fResource->validity = (validity != FG_ResourceValidity::ValidNow && !willFlip) ? FG_ResourceValidity::UntilPresent + : FG_ResourceValidity::ValidNow; + + xefg_swapchain_d3d12_resource_data_t resourceParam = GetResourceData(type); + + if (validity == FG_ResourceValidity::UntilPresent) + { + auto result = XeFGProxy::D3D12TagFrameResource()(_swapChainContext, cmdList, _frameCount, &resourceParam); + if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) + { + LOG_ERROR("D3D12TagFrameResource Depth error: {} ({})", magic_enum::enum_name(result), (UINT) result); + return; + } + + SetResourceReady(type); + + if (usingLocalCmdList) + { + cmdList->Close(); + _gameCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList**) &cmdList); + } + } + else + { + ResTrack_Dx12::SetResourceCmdList(type, cmdList); + + if (!_copyCommandAllocator.contains(type) || !_copyCommandList.contains(type)) + { + LOG_ERROR("{}, _copyCommandAllocator or _copyCommandList is nullptr!", magic_enum::enum_name(type)); + return; + } + + auto allocator = _copyCommandAllocator[type]; + cmdList = _copyCommandList[type]; + + allocator->Reset(); + cmdList->Reset(allocator, nullptr); + + fResource->cmdList = cmdList; + } + + LOG_TRACE("_frameResources[{}][{}]: {:X}", fIndex, magic_enum::enum_name(type), (size_t) fResource->GetResource()); +} + +void XeFG_Dx12::SetResourceReady(FG_ResourceType type) { _resourceReady[GetIndex()][type] = true; } + +void XeFG_Dx12::SetCommandQueue(FG_ResourceType type, ID3D12CommandQueue* queue) +{ + //_gameCommandQueue = queue; + + auto fIndex = GetIndex(); + + if (!_frameResources[fIndex].contains(type)) + return; + + auto fResource = &_frameResources[fIndex][type]; + + auto resourceParam = GetResourceData(type); + if (resourceParam.pResource == nullptr) + return; + + if (fResource->validity == FG_ResourceValidity::JustTrackCmdlist) + resourceParam.validity == XEFG_SWAPCHAIN_RV_UNTIL_NEXT_PRESENT; + + auto result = + XeFGProxy::D3D12TagFrameResource()(_swapChainContext, fResource->cmdList, _frameCount, &resourceParam); + if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) + { + LOG_ERROR("D3D12TagFrameResource {} error: {} ({})", magic_enum::enum_name(type), magic_enum::enum_name(result), + (UINT) result); + return; + } + + ((ID3D12GraphicsCommandList*) fResource->cmdList)->Close(); + _gameCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList**) &fResource->cmdList); +} diff --git a/OptiScaler/framegen/xefg/XeFG_Dx12.h b/OptiScaler/framegen/xefg/XeFG_Dx12.h index 7677026d..a9e3ae4d 100644 --- a/OptiScaler/framegen/xefg/XeFG_Dx12.h +++ b/OptiScaler/framegen/xefg/XeFG_Dx12.h @@ -1,59 +1,74 @@ -//#pragma once -// -//#include -// -//#include -//#include -// -//#include -//#include -//#include -//#include -//#include -// -//#include -// -//class XeFG_Dx12 : public virtual IFGFeature_Dx12 -//{ -// private: -// xefg_swapchain_handle_t _swapChainContext = nullptr; -// xefg_swapchain_handle_t _fgContext = nullptr; -// -// uint32_t _width = 0; -// uint32_t _height = 0; -// int _featureFlags = 0; -// -// static void xefgLogCallback(const char* message, xefg_swapchain_logging_level_t level, void* userData); -// -// bool CreateSwapchainContext(ID3D12Device* device); -// bool DestroySwapchainContext(); -// -// public: -// // IFGFeature -// const char* Name() override final; -// feature_version Version() override final; -// bool ManualPipeline() override final { return false; } -// -// // 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; -// -// void CreateContext(ID3D12Device* device, FG_Constants& fgConstants) override final; -// void StopAndDestroyContext(bool destroy, bool shutDown, bool useMutex) override final; -// -// void EvaluateState(ID3D12Device* device, FG_Constants& fgConstants) override final; -// -// bool Dispatch() override final; -// -// void* FrameGenerationContext() override final; -// void* SwapchainContext() override final; -// -// XeFG_Dx12() : IFGFeature_Dx12(), IFGFeature() -// { -// if (XeFGProxy::Module() == nullptr) -// XeFGProxy::InitXeFG(); -// } -//}; +#pragma once + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +class XeFG_Dx12 : public virtual IFGFeature_Dx12 +{ + private: + xefg_swapchain_handle_t _swapChainContext = nullptr; + xefg_swapchain_handle_t _fgContext = nullptr; + + uint32_t _width = 0; + uint32_t _height = 0; + int _featureFlags = 0; + + // For copy operations + std::map _resourceCopy[BUFFER_COUNT] {}; + std::map _copyCommandList {}; + std::map _copyCommandAllocator {}; + + static void xefgLogCallback(const char* message, xefg_swapchain_logging_level_t level, void* userData); + + bool CreateSwapchainContext(ID3D12Device* device); + bool DestroySwapchainContext(); + xefg_swapchain_d3d12_resource_data_t GetResourceData(FG_ResourceType type); + + bool Dispatch(); + + public: + // IFGFeature + const char* Name() override final; + feature_version Version() override 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; + + void CreateContext(ID3D12Device* device, FG_Constants& fgConstants) override final; + void StopAndDestroyContext(bool destroy, bool shutDown) override final; + + void EvaluateState(ID3D12Device* device, FG_Constants& fgConstants) override final; + + void ReleaseObjects() override final; + void CreateObjects(ID3D12Device* InDevice) override final; + + bool Present() override final; + + void SetResource(FG_ResourceType type, ID3D12GraphicsCommandList* cmdList, ID3D12Resource* resource, UINT width, + UINT height, D3D12_RESOURCE_STATES state, FG_ResourceValidity validity) override final; + void SetResourceReady(FG_ResourceType type) override final; + void SetCommandQueue(FG_ResourceType type, ID3D12CommandQueue* queue) override final; + + void* FrameGenerationContext() override final; + void* SwapchainContext() override final; + + XeFG_Dx12() : IFGFeature_Dx12(), IFGFeature() + { + if (XeFGProxy::Module() == nullptr) + XeFGProxy::InitXeFG(); + } +}; diff --git a/OptiScaler/hooks/HooksDx.cpp b/OptiScaler/hooks/HooksDx.cpp index 7b0f884e..b5a80c0d 100644 --- a/OptiScaler/hooks/HooksDx.cpp +++ b/OptiScaler/hooks/HooksDx.cpp @@ -271,19 +271,7 @@ static HRESULT hkFGPresent(void* This, UINT SyncInterval, UINT Flags) if (willPresent && State::Instance().currentCommandQueue != nullptr && State::Instance().activeFgInput == FGInput::Upscaler && fg != nullptr && fg->IsActive()) { - if (!fg->IsPaused() && !fg->IsDispatched()) - { - LOG_WARN("Dispatch FG from present"); - fg->Dispatch(); - } - - // ResTrack_Dx12::ExecuteWaitingCommandLists(); - - if (!fg->IsPaused() && fg->WaitingExecution()) - { - LOG_WARN("Execute FG commandlist from present"); - fg->ExecuteCommandList(State::Instance().currentCommandQueue); - } + fg->Present(); } State::Instance().slFGInputs.markLastSendAsRequired(); @@ -860,11 +848,11 @@ static HRESULT hkCreateSwapChain(IDXGIFactory* pFactory, IUnknown* pDevice, DXGI Config::Instance()->FGOutput.set_volatile_value(FGOutput::NoFG); State::Instance().activeFgOutput = Config::Instance()->FGOutput.value_or_default(); } - // else if (State::Instance().activeFgOutput == FGOutput::XeFG && !XeFGProxy::InitXeFG()) - //{ - // Config::Instance()->FGOutput.set_volatile_value(FGOutput::NoFG); - // State::Instance().activeFgOutput = Config::Instance()->FGOutput.value_or_default(); - // } + else if (State::Instance().activeFgOutput == FGOutput::XeFG && !XeFGProxy::InitXeFG()) + { + Config::Instance()->FGOutput.set_volatile_value(FGOutput::NoFG); + State::Instance().activeFgOutput = Config::Instance()->FGOutput.value_or_default(); + } ID3D12CommandQueue* real = nullptr; if (!CheckForRealObject(__FUNCTION__, pDevice, (IUnknown**) &real)) @@ -885,8 +873,8 @@ static HRESULT hkCreateSwapChain(IDXGIFactory* pFactory, IUnknown* pDevice, DXGI { if (State::Instance().activeFgOutput == FGOutput::FSRFG) State::Instance().currentFG = new FSRFG_Dx12(); - // else if (State::Instance().activeFgOutput == FGOutput::XeFG) - // State::Instance().currentFG = new XeFG_Dx12(); + else if (State::Instance().activeFgOutput == FGOutput::XeFG) + State::Instance().currentFG = new XeFG_Dx12(); } HooksDx::ReleaseDx12SwapChain(pDesc->OutputWindow); @@ -1162,11 +1150,11 @@ static HRESULT hkCreateSwapChainForHwnd(IDXGIFactory* This, IUnknown* pDevice, H Config::Instance()->FGOutput.set_volatile_value(FGOutput::NoFG); State::Instance().activeFgOutput = Config::Instance()->FGOutput.value_or_default(); } - // else if (State::Instance().activeFgOutput == FGOutput::XeFG && !XeFGProxy::InitXeFG()) - //{ - // Config::Instance()->FGOutput.set_volatile_value(FGOutput::NoFG); - // State::Instance().activeFgOutput = Config::Instance()->FGOutput.value_or_default(); - // } + else if (State::Instance().activeFgOutput == FGOutput::XeFG && !XeFGProxy::InitXeFG()) + { + Config::Instance()->FGOutput.set_volatile_value(FGOutput::NoFG); + State::Instance().activeFgOutput = Config::Instance()->FGOutput.value_or_default(); + } ID3D12CommandQueue* real = nullptr; if (!CheckForRealObject(__FUNCTION__, pDevice, (IUnknown**) &real)) @@ -1186,8 +1174,8 @@ static HRESULT hkCreateSwapChainForHwnd(IDXGIFactory* This, IUnknown* pDevice, H { if (State::Instance().activeFgOutput == FGOutput::FSRFG) State::Instance().currentFG = new FSRFG_Dx12(); - // else if (State::Instance().activeFgOutput == FGOutput::XeFG) - // State::Instance().currentFG = new XeFG_Dx12(); + else if (State::Instance().activeFgOutput == FGOutput::XeFG) + State::Instance().currentFG = new XeFG_Dx12(); } HooksDx::ReleaseDx12SwapChain(hWnd); diff --git a/OptiScaler/hudfix/Hudfix_Dx12.cpp b/OptiScaler/hudfix/Hudfix_Dx12.cpp index ec8b6acc..5c0732fb 100644 --- a/OptiScaler/hudfix/Hudfix_Dx12.cpp +++ b/OptiScaler/hudfix/Hudfix_Dx12.cpp @@ -452,6 +452,13 @@ bool Hudfix_Dx12::CheckForHudless(std::string callerName, ID3D12GraphicsCommandL break; } + DXGI_SWAP_CHAIN_DESC scDesc {}; + if (State::Instance().currentSwapchain->GetDesc(&scDesc) != S_OK) + { + LOG_WARN("Can't get swapchain desc!"); + break; + } + // Prevent double capture LOG_DEBUG("Waiting _checkMutex"); std::lock_guard lock(_checkMutex); @@ -554,14 +561,6 @@ bool Hudfix_Dx12::CheckForHudless(std::string callerName, ID3D12GraphicsCommandL auto fIndex = GetIndex(); - DXGI_SWAP_CHAIN_DESC scDesc {}; - if (State::Instance().currentSwapchain->GetDesc(&scDesc) != S_OK) - { - LOG_WARN("Can't get swapchain desc!"); - _captureCounter[fIndex]--; - break; - } - LOG_TRACE("Capture resource: {:X}, index: {}", (size_t) resource->buffer, fIndex); if (_commandQueue == nullptr && !CreateObjects()) @@ -600,13 +599,6 @@ bool Hudfix_Dx12::CheckForHudless(std::string callerName, ID3D12GraphicsCommandL } else { - DXGI_SWAP_CHAIN_DESC scDesc {}; - if (State::Instance().currentSwapchain->GetDesc(&scDesc) != S_OK) - { - LOG_WARN("Can't get swapchain desc!"); - break; - } - if (CreateBufferResourceWithSize(State::Instance().currentD3D12Device, resource, D3D12_RESOURCE_STATE_COPY_DEST, &_captureBuffer[fIndex], scDesc.BufferDesc.Width, scDesc.BufferDesc.Height)) @@ -705,6 +697,7 @@ bool Hudfix_Dx12::CheckForHudless(std::string callerName, ID3D12GraphicsCommandL if (fg != nullptr) fg->SetResource(FG_ResourceType::HudlessColor, cmdList, _formatTransfer[fIndex]->Buffer(), + scDesc.BufferDesc.Width, scDesc.BufferDesc.Height, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, FG_ResourceValidity::JustTrackCmdlist); } else @@ -723,8 +716,9 @@ bool Hudfix_Dx12::CheckForHudless(std::string callerName, ID3D12GraphicsCommandL auto fg = reinterpret_cast(State::Instance().currentFG); if (fg != nullptr) - fg->SetResource(FG_ResourceType::HudlessColor, cmdList, _captureBuffer[fIndex], - D3D12_RESOURCE_STATE_COPY_DEST, FG_ResourceValidity::JustTrackCmdlist); + fg->SetResource(FG_ResourceType::HudlessColor, cmdList, _captureBuffer[fIndex], scDesc.BufferDesc.Width, + scDesc.BufferDesc.Height, D3D12_RESOURCE_STATE_COPY_DEST, + FG_ResourceValidity::JustTrackCmdlist); } if (State::Instance().FGcaptureResources) diff --git a/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp b/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp index 889aafea..ea537b83 100644 --- a/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp +++ b/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp @@ -1580,6 +1580,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom fg->SetFrameTimeDelta(State::Instance().lastFrameTime); fg->SetMVScale(mvScaleX, mvScaleY); fg->SetReset(reset); + fg->SetInterpolationRect(deviceContext->feature->DisplayWidth(), deviceContext->feature->DisplayHeight()); Hudfix_Dx12::UpscaleStart(); } @@ -1617,10 +1618,24 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom InParameters->Get(NVSDK_NGX_Parameter_MotionVectors, (void**) ¶mVelocity); if (paramVelocity != nullptr) - fg->SetResource(FG_ResourceType::Velocity, commandList, paramVelocity, - (D3D12_RESOURCE_STATES) Config::Instance()->MVResourceBarrier.value_or( - D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE), - FG_ResourceValidity::ValidNow); + { + if (deviceContext->feature->LowResMV()) + { + fg->SetResource(FG_ResourceType::Velocity, commandList, paramVelocity, + deviceContext->feature->RenderWidth(), deviceContext->feature->RenderHeight(), + (D3D12_RESOURCE_STATES) Config::Instance()->MVResourceBarrier.value_or( + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE), + FG_ResourceValidity::ValidNow); + } + else + { + fg->SetResource(FG_ResourceType::Velocity, commandList, paramVelocity, + deviceContext->feature->DisplayWidth(), deviceContext->feature->DisplayHeight(), + (D3D12_RESOURCE_STATES) Config::Instance()->MVResourceBarrier.value_or( + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE), + FG_ResourceValidity::ValidNow); + } + } ID3D12Resource* paramDepth = nullptr; if (InParameters->Get(NVSDK_NGX_Parameter_Depth, ¶mDepth) != NVSDK_NGX_Result_Success) @@ -1646,6 +1661,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom { DepthScale->SetBufferState(InCmdList, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); fg->SetResource(FG_ResourceType::Depth, commandList, DepthScale->Buffer(), + deviceContext->feature->RenderWidth(), deviceContext->feature->RenderHeight(), D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, FG_ResourceValidity::UntilPresent); done = true; @@ -1654,7 +1670,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom } if (!done) - fg->SetResource(FG_ResourceType::Depth, commandList, paramDepth, + fg->SetResource(FG_ResourceType::Depth, commandList, paramDepth, deviceContext->feature->RenderWidth(), + deviceContext->feature->RenderHeight(), (D3D12_RESOURCE_STATES) Config::Instance()->DepthResourceBarrier.value_or( D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE), FG_ResourceValidity::ValidNow); diff --git a/OptiScaler/resource_tracking/ResTrack_dx12.cpp b/OptiScaler/resource_tracking/ResTrack_dx12.cpp index 97547796..3863a290 100644 --- a/OptiScaler/resource_tracking/ResTrack_dx12.cpp +++ b/OptiScaler/resource_tracking/ResTrack_dx12.cpp @@ -1792,7 +1792,8 @@ void ResTrack_Dx12::HookToQueue(ID3D12Device* InDevice) void ResTrack_Dx12::HookDevice(ID3D12Device* device) { - if (State::Instance().activeFgOutput != FGOutput::FSRFG || !Config::Instance()->OverlayMenu.value_or_default()) + if ((State::Instance().activeFgOutput != FGOutput::FSRFG && State::Instance().activeFgOutput != FGOutput::XeFG) || + !Config::Instance()->OverlayMenu.value_or_default()) return; if (o_CreateDescriptorHeap != nullptr || device == nullptr)