diff --git a/OptiScaler/framegen/xefg/XeFG_Dx12.cpp b/OptiScaler/framegen/xefg/XeFG_Dx12.cpp index fcf89e8c..51a75f35 100644 --- a/OptiScaler/framegen/xefg/XeFG_Dx12.cpp +++ b/OptiScaler/framegen/xefg/XeFG_Dx12.cpp @@ -67,34 +67,22 @@ bool XeFG_Dx12::CreateSwapchainContext(ID3D12Device* device) LOG_ERROR("SetLoggingCallback error: {} ({})", magic_enum::enum_name(result), (UINT) result); } - // if (XeLLProxy::Context() == nullptr) - XeLLProxy::CreateContext(device); - - if (XeLLProxy::Context() != nullptr) + // Force fakenvapi to create XeLL for us + if (fakenvapi::forceMode(device, LowLatencyMode::XeLL)) { - 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 result; - } - - auto fnaResult = fakenvapi::setModeAndContext(XeLLProxy::Context(), LowLatencyMode::XeLL); - LOG_DEBUG("fakenvapi::setModeAndContext: {}", fnaResult); - - result = XeFGProxy::SetLatencyReduction()(_swapChainContext, XeLLProxy::Context()); + result = XeFGProxy::SetLatencyReduction()(_swapChainContext, fakenvapi::getCurrentContext()); if (result != XEFG_SWAPCHAIN_RESULT_SUCCESS) { LOG_ERROR("SetLatencyReduction error: {} ({})", magic_enum::enum_name(result), (UINT) result); return result; } - }; + } + else + { + LOG_ERROR("Couldn't create XeLL"); + return false; + } createResult = true; @@ -153,9 +141,6 @@ bool XeFG_Dx12::DestroySwapchainContext() } else { - if (XeLLProxy::Context() != nullptr) - XeLLProxy::DestroyXeLLContext(); - State::Instance().currentFGSwapchain = nullptr; } } @@ -1639,7 +1624,6 @@ bool XeFG_Dx12::ReleaseSwapchain(HWND hwnd) } ReleaseObjects(); - XeLLProxy::DestroyXeLLContext(); if (Config::Instance()->FGUseMutexForSwapchain.value_or_default()) { diff --git a/OptiScaler/low_latency/input/input_common.cpp b/OptiScaler/low_latency/input/input_common.cpp index 3fa7863b..f67177db 100644 --- a/OptiScaler/low_latency/input/input_common.cpp +++ b/OptiScaler/low_latency/input/input_common.cpp @@ -138,6 +138,9 @@ bool InputCommon::update_low_latency_tech(IUnknown* pDevice, std::optional(current_tech); - return xell_tech->xellSetGeneratedFramesCount(param1, framesCount); + return xell_tech->xellSetGeneratedFramesCount(frameId, framesCount); } return XELL_RESULT_ERROR_UNKNOWN; diff --git a/OptiScaler/low_latency/input/input_common.h b/OptiScaler/low_latency/input/input_common.h index 3055e6a3..0c623fc9 100644 --- a/OptiScaler/low_latency/input/input_common.h +++ b/OptiScaler/low_latency/input/input_common.h @@ -89,6 +89,6 @@ class InputCommon // async markers can be made static xell_result_t pass_xellSetDisplayInfo(const InputContext& inputContext, void* displayInfo); static xell_result_t pass_xellSetFgEnabled(const InputContext& inputContext, uint32_t param1, uint32_t param2); - static xell_result_t pass_xellSetGeneratedFramesCount(const InputContext& inputContext, uint32_t param1, + static xell_result_t pass_xellSetGeneratedFramesCount(const InputContext& inputContext, uint32_t frameId, uint32_t framesCount); }; diff --git a/OptiScaler/low_latency/input/input_xell.cpp b/OptiScaler/low_latency/input/input_xell.cpp index 2793a0cb..ee68f11d 100644 --- a/OptiScaler/low_latency/input/input_xell.cpp +++ b/OptiScaler/low_latency/input/input_xell.cpp @@ -317,7 +317,7 @@ xell_result_t InputXeLL::SetFgEnabled(xell_input_handle_t context, uint32_t para return InputCommon::pass_xellSetFgEnabled(context->inputContext, param1, param2); } -xell_result_t InputXeLL::SetGeneratedFramesCount(xell_input_handle_t context, uint32_t param1, uint32_t framesCount) +xell_result_t InputXeLL::SetGeneratedFramesCount(xell_input_handle_t context, uint32_t frameId, uint32_t framesCount) { // TODO: figure out params and impl // TODO: store framesCount for the SleepParams::fg_multiplier @@ -325,10 +325,10 @@ xell_result_t InputXeLL::SetGeneratedFramesCount(xell_input_handle_t context, ui if (!context) return XELL_RESULT_ERROR_INVALID_CONTEXT; - context->setGeneratedFramesCountParam1 = param1; + context->setGeneratedFramesCountFrameId = frameId; context->framesCount = framesCount; - return InputCommon::pass_xellSetGeneratedFramesCount(context->inputContext, param1, framesCount); + return InputCommon::pass_xellSetGeneratedFramesCount(context->inputContext, frameId, framesCount); } #ifdef LOW_LATENCY_INPUTS @@ -391,10 +391,10 @@ XELL_EXPORT xell_result_t xellSetFgEnabled(xell_context_handle_t context, uint32 return InputXeLL::SetFgEnabled((InputXeLL::xell_input_handle_t) context, param1, param2); } -XELL_EXPORT xell_result_t xellSetGeneratedFramesCount(xell_context_handle_t context, uint32_t param1, +XELL_EXPORT xell_result_t xellSetGeneratedFramesCount(xell_context_handle_t context, uint32_t frameId, uint32_t framesCount) { - return InputXeLL::SetGeneratedFramesCount((InputXeLL::xell_input_handle_t) context, param1, framesCount); + return InputXeLL::SetGeneratedFramesCount((InputXeLL::xell_input_handle_t) context, frameId, framesCount); } XELL_EXPORT xell_result_t xellGetLastPresentStartFrameId(xell_context_handle_t context, uint32_t* p_frame_id) diff --git a/OptiScaler/low_latency/input/input_xell.h b/OptiScaler/low_latency/input/input_xell.h index dcea85b6..ee98be2d 100644 --- a/OptiScaler/low_latency/input/input_xell.h +++ b/OptiScaler/low_latency/input/input_xell.h @@ -22,7 +22,7 @@ class InputXeLL // Unsure what to do with those, just store for now uint32_t setFgEnabledParam1 {}; uint32_t setFgEnabledParam2 {}; - uint32_t setGeneratedFramesCountParam1 {}; + uint32_t setGeneratedFramesCountFrameId {}; uint32_t framesCount {}; }; @@ -69,7 +69,7 @@ extern "C" XELL_EXPORT xell_result_t xellD3D12SetAppQueue(xell_context_handle_t context, ID3D12CommandQueue* appQueue); XELL_EXPORT xell_result_t xellSetDisplayInfo(xell_context_handle_t context, void* displayInfo); XELL_EXPORT xell_result_t xellSetFgEnabled(xell_context_handle_t context, uint32_t param1, uint32_t param2); - XELL_EXPORT xell_result_t xellSetGeneratedFramesCount(xell_context_handle_t context, uint32_t param1, + XELL_EXPORT xell_result_t xellSetGeneratedFramesCount(xell_context_handle_t context, uint32_t frameId, uint32_t framesCount); XELL_EXPORT xell_result_t xellGetLastPresentStartFrameId(xell_context_handle_t context, uint32_t* p_frame_id); } \ No newline at end of file diff --git a/OptiScaler/low_latency/low_latency_tech/ll_antilag2.cpp b/OptiScaler/low_latency/low_latency_tech/ll_antilag2.cpp index fbb89ffe..f8088917 100644 --- a/OptiScaler/low_latency/low_latency_tech/ll_antilag2.cpp +++ b/OptiScaler/low_latency/low_latency_tech/ll_antilag2.cpp @@ -103,37 +103,8 @@ bool AntiLag2::init(IUnknown* pDevice) return false; } -// Only DX12 is supported -bool AntiLag2::init_using_ctx(void* context) -{ - if (!context) - { - LOG_ERROR("FSR Anti-Lag 2.0 init_using_ctx called with null context"); - return false; - } - - // TODO: try to distinguish between DX11 and DX12 contexts - dx12_ctx = *reinterpret_cast(context); - - if (dx12_ctx.m_pAntiLagAPI) - { - inited_using_context = true; - LOG_INFO("FSR Anti-Lag 2.0 DX12 initialized using existing context"); - return true; - } - - return false; -} - void AntiLag2::deinit() { - if (inited_using_context) - { - LOG_INFO("FSR Anti-Lag 2.0 DX12 deinit called while inited using context, skipping deinitialization"); - inited_using_context = false; - return; - } - { std::scoped_lock lock(amdxc64_load_mutex); diff --git a/OptiScaler/low_latency/low_latency_tech/ll_antilag2.h b/OptiScaler/low_latency/low_latency_tech/ll_antilag2.h index 71944ea8..f6024160 100644 --- a/OptiScaler/low_latency/low_latency_tech/ll_antilag2.h +++ b/OptiScaler/low_latency/low_latency_tech/ll_antilag2.h @@ -27,7 +27,6 @@ class AntiLag2 : public LowLatencyTech // From LowLatencyTech bool init(IUnknown* pDevice) override; - bool init_using_ctx(void* context) override; void deinit() override; LowLatencyMode get_mode() override { return LowLatencyMode::AntiLag2; }; diff --git a/OptiScaler/low_latency/low_latency_tech/ll_antilag_vk.cpp b/OptiScaler/low_latency/low_latency_tech/ll_antilag_vk.cpp index 51935f30..6273f4d7 100644 --- a/OptiScaler/low_latency/low_latency_tech/ll_antilag_vk.cpp +++ b/OptiScaler/low_latency/low_latency_tech/ll_antilag_vk.cpp @@ -4,14 +4,6 @@ bool AntiLagVk::init(IUnknown* pDevice) { return VulkanHooks::o_vkAntiLagUpdateAMD != nullptr; } -// Unsupported -bool AntiLagVk::init_using_ctx(void* context) -{ - LOG_ERROR("AntiLagVk init_using_ctx is not supported"); - inited_using_context = false; - return false; -} - void* AntiLagVk::get_tech_context() { return nullptr; } void AntiLagVk::get_sleep_status(SleepParams* sleep_params) diff --git a/OptiScaler/low_latency/low_latency_tech/ll_antilag_vk.h b/OptiScaler/low_latency/low_latency_tech/ll_antilag_vk.h index 21f327f8..a457a261 100644 --- a/OptiScaler/low_latency/low_latency_tech/ll_antilag_vk.h +++ b/OptiScaler/low_latency/low_latency_tech/ll_antilag_vk.h @@ -12,7 +12,6 @@ class AntiLagVk : public LowLatencyTech // From LowLatencyTech bool init(IUnknown* pDevice) override; - bool init_using_ctx(void* context) override; void deinit() override {}; // Not used by AntiLag VK LowLatencyMode get_mode() override { return LowLatencyMode::AntiLagVk; }; diff --git a/OptiScaler/low_latency/low_latency_tech/ll_latencyflex.cpp b/OptiScaler/low_latency/low_latency_tech/ll_latencyflex.cpp index 494a96a4..0997f12d 100644 --- a/OptiScaler/low_latency/low_latency_tech/ll_latencyflex.cpp +++ b/OptiScaler/low_latency/low_latency_tech/ll_latencyflex.cpp @@ -111,14 +111,6 @@ bool LatencyFlex::init(IUnknown* pDevice) return false; }; -// Unsupported -bool LatencyFlex::init_using_ctx(void* context) -{ - LOG_ERROR("LatencyFleX init_using_ctx is not supported"); - inited_using_context = false; - return false; -} - void LatencyFlex::deinit() { deinit_mutex.lock(); diff --git a/OptiScaler/low_latency/low_latency_tech/ll_latencyflex.h b/OptiScaler/low_latency/low_latency_tech/ll_latencyflex.h index 7229ab87..abd3f9f6 100644 --- a/OptiScaler/low_latency/low_latency_tech/ll_latencyflex.h +++ b/OptiScaler/low_latency/low_latency_tech/ll_latencyflex.h @@ -31,7 +31,6 @@ class LatencyFlex : public LowLatencyTech // From LowLatencyTech bool init(IUnknown* pDevice) override; - bool init_using_ctx(void* context) override; void deinit() override; LowLatencyMode get_mode() override { return LowLatencyMode::LatencyFlex; }; diff --git a/OptiScaler/low_latency/low_latency_tech/ll_xell.cpp b/OptiScaler/low_latency/low_latency_tech/ll_xell.cpp index b47750f8..230b6a31 100644 --- a/OptiScaler/low_latency/low_latency_tech/ll_xell.cpp +++ b/OptiScaler/low_latency/low_latency_tech/ll_xell.cpp @@ -10,7 +10,7 @@ void XeLL::xell_sleep(uint32_t frame_id) sent_sleep_frame_ids[frame_id % 64] = true; // Don't call XeLL when trying to disable XeLL with XeFG active - if (!inited_using_context || is_enabled()) + if (!forced_mode || is_enabled()) { LOG_TRACE_LOWLATENCY("Sleeping with frame_id: {}", frame_id); o_xellSleep(xell_context, frame_id); @@ -26,7 +26,7 @@ void XeLL::add_marker(uint32_t frame_id, xell_latency_marker_type_t marker) return; } - if (!inited_using_context || is_enabled()) + if (!forced_mode || is_enabled()) o_xellAddMarkerData(xell_context, frame_id, marker); } @@ -85,7 +85,7 @@ bool XeLL::init(IUnknown* pDevice) if (resendResult != XELL_RESULT_SUCCESS) break; - resendResult = xellSetGeneratedFramesCount(xellInputContext->setGeneratedFramesCountParam1, + resendResult = xellSetGeneratedFramesCount(xellInputContext->setGeneratedFramesCountFrameId, xellInputContext->framesCount); } while (false); @@ -99,52 +99,12 @@ bool XeLL::init(IUnknown* pDevice) return result; } -bool XeLL::init_using_ctx(void* context) -{ - if (!XeLLProxy::InitXeLL()) - { - LOG_ERROR("XeLL init_using_ctx failed to load libxell.dll"); - return false; - } - - if (!context) - { - LOG_ERROR("XeLL handed over to fakenvapi but the context is null"); - return false; - } - - if (xell_context) - { - if (o_xellDestroyContext(xell_context) == XELL_RESULT_SUCCESS) - LOG_INFO("destroy o_xell_ctx"); - else - LOG_ERROR("destroy o_xell_ctx error"); - } - xell_context = (xell_context_handle_t) context; - - // Context is handled and held inside XeLLProxy - inited_using_context = true; - XellHooks::blockExternalContexts(true); - LOG_INFO("XeLL initialized using existing context: {:X}", (uint64_t) xell_context); - - return true; -} - void XeLL::deinit() { XellHooks::blockExternalContexts(false); - if (inited_using_context) - { - // Let XeFG handle the context as XeLL can't be destroyed before XeFG - LOG_INFO("XeLL deinit called while inited using context, skipping deinitialization"); - inited_using_context = false; - } - else - { - o_xellDestroyContext(xell_context); - LOG_INFO("XeLL deinitialized"); - } + o_xellDestroyContext(xell_context); + LOG_INFO("XeLL deinitialized"); } void* XeLL::get_tech_context() { return xell_context; } @@ -166,7 +126,7 @@ void XeLL::set_sleep_mode(SleepMode* sleep_mode) low_latency_enabled = sleep_mode->low_latency_enabled; // Always report XeLL as enabled when XeFG is enabled - if (inited_using_context) + if (forced_mode) xell_sleep_params.bLowLatencyMode = true; else xell_sleep_params.bLowLatencyMode = is_enabled(); @@ -304,12 +264,12 @@ xell_result_t XeLL::xellSetFgEnabled(uint32_t param1, uint32_t param2) const return o_xellSetFgEnabled(xell_context, param1, param2); } -xell_result_t XeLL::xellSetGeneratedFramesCount(uint32_t param1, uint32_t framesCount) const +xell_result_t XeLL::xellSetGeneratedFramesCount(uint32_t frameId, uint32_t framesCount) const { if (!o_xellSetGeneratedFramesCount) return XELL_RESULT_ERROR_UNKNOWN; - return o_xellSetGeneratedFramesCount(xell_context, param1, framesCount); + return o_xellSetGeneratedFramesCount(xell_context, frameId, framesCount); } xell_result_t XeLL::xellGetLastPresentStartFrameId(uint32_t* p_frame_id) const diff --git a/OptiScaler/low_latency/low_latency_tech/ll_xell.h b/OptiScaler/low_latency/low_latency_tech/ll_xell.h index edd7907f..ff986e65 100644 --- a/OptiScaler/low_latency/low_latency_tech/ll_xell.h +++ b/OptiScaler/low_latency/low_latency_tech/ll_xell.h @@ -70,7 +70,6 @@ class XeLL : public LowLatencyTech // From LowLatencyTech bool init(IUnknown* pDevice) override; - bool init_using_ctx(void* context) override; void deinit() override; LowLatencyMode get_mode() override { return LowLatencyMode::XeLL; }; @@ -98,7 +97,7 @@ class XeLL : public LowLatencyTech xell_result_t xellD3D12SetAppQueue(ID3D12CommandQueue* appQueue) const; xell_result_t xellSetDisplayInfo(void* displayInfo) const; xell_result_t xellSetFgEnabled(uint32_t param1, uint32_t param2) const; - xell_result_t xellSetGeneratedFramesCount(uint32_t param1, uint32_t framesCount) const; + xell_result_t xellSetGeneratedFramesCount(uint32_t frameId, uint32_t framesCount) const; xell_result_t xellGetLastPresentStartFrameId(uint32_t* p_frame_id) const; xell_result_t xellGetFramesReports(xell_frame_report_t* outdata) const; }; \ No newline at end of file diff --git a/OptiScaler/low_latency/low_latency_tech/low_latency_tech.h b/OptiScaler/low_latency/low_latency_tech/low_latency_tech.h index 088ba42c..d8f41641 100644 --- a/OptiScaler/low_latency/low_latency_tech/low_latency_tech.h +++ b/OptiScaler/low_latency/low_latency_tech/low_latency_tech.h @@ -67,18 +67,17 @@ class LowLatencyTech ForceReflex low_latency_override = ForceReflex::InGame; bool low_latency_enabled = false; bool effective_fg_state = false; - bool inited_using_context = false; + bool forced_mode = false; public: LowLatencyTech() : current_call_spot(CallSpot::SimulationStart), low_latency_override(ForceReflex::InGame), - low_latency_enabled(false), effective_fg_state(false), inited_using_context(false) + low_latency_enabled(false), effective_fg_state(false), forced_mode(false) { } virtual ~LowLatencyTech() {} virtual bool init(IUnknown* pDevice) = 0; - virtual bool init_using_ctx(void* context) = 0; virtual void deinit() = 0; virtual LowLatencyMode get_mode() = 0; @@ -86,6 +85,7 @@ class LowLatencyTech virtual void set_fg_type(bool interpolated, uint64_t frame_id) = 0; virtual void set_low_latency_override(ForceReflex low_latency_override) = 0; virtual void set_effective_fg_state(bool effective_fg_state) = 0; + virtual void set_forced_mode(bool forced_mode) { this->forced_mode = forced_mode; }; virtual bool is_enabled() = 0; diff --git a/OptiScaler/nvapi/fakenvapi.cpp b/OptiScaler/nvapi/fakenvapi.cpp index 6b66c806..a1b50aee 100644 --- a/OptiScaler/nvapi/fakenvapi.cpp +++ b/OptiScaler/nvapi/fakenvapi.cpp @@ -216,7 +216,7 @@ bool fakenvapi::updateModeAndContext() return result; } -bool fakenvapi::setModeAndContext(void* context, LowLatencyMode mode) +bool fakenvapi::forceMode(IUnknown* device, LowLatencyMode mode) { LOG_FUNC(); @@ -228,7 +228,7 @@ bool fakenvapi::setModeAndContext(void* context, LowLatencyMode mode) return false; } - auto result = lowLatencyCtx->set_low_latency_tech_context(context, mode); + auto result = lowLatencyCtx->set_low_latency_tech_mode(device, mode); if (!result) LOG_TRACE_FAKENVAPI("Can't set Low Latency context from fakenvapi"); @@ -259,6 +259,14 @@ LowLatencyMode fakenvapi::getCurrentMode() return LowLatencyMode::None; } +void* fakenvapi::getCurrentContext() +{ + if (updateModeAndContext()) + return _lowLatencyTechContext; + else + return nullptr; +} + bool fakenvapi::isUsingAsMainNvapi() { return _usingFakenvapiAsMainNvapi; } void fakenvapi::setUsingAsMainNvapi(bool usingAsMain) { _usingFakenvapiAsMainNvapi = usingAsMain; } diff --git a/OptiScaler/nvapi/fakenvapi.h b/OptiScaler/nvapi/fakenvapi.h index 02151405..f42cedce 100644 --- a/OptiScaler/nvapi/fakenvapi.h +++ b/OptiScaler/nvapi/fakenvapi.h @@ -39,9 +39,11 @@ class fakenvapi static void deinit(); static void* queryInterface(NvU32 id); static void reportFGPresent(IDXGISwapChain* pSwapChain, bool fg_state, bool frame_interpolated); - static bool setModeAndContext(void* context, LowLatencyMode mode); + static bool forceMode(IUnknown* device, LowLatencyMode mode); static bool isLowLatencyActive(); + static LowLatencyMode getCurrentMode(); + static void* getCurrentContext(); static bool isUsingAsMainNvapi(); static void setUsingAsMainNvapi(bool usingAsMain); diff --git a/OptiScaler/nvapi/fakenvapi/low_latency.cpp b/OptiScaler/nvapi/fakenvapi/low_latency.cpp index 39280539..bb5aafd1 100644 --- a/OptiScaler/nvapi/fakenvapi/low_latency.cpp +++ b/OptiScaler/nvapi/fakenvapi/low_latency.cpp @@ -71,29 +71,27 @@ bool LowLatency::get_low_latency_tech_context(void** low_latency_context, LowLat return true; } -bool LowLatency::set_low_latency_tech_context(void* low_latency_context, LowLatencyMode low_latency_tech) +bool LowLatency::set_low_latency_tech_mode(IUnknown* device, LowLatencyMode low_latency_tech) { - forced_low_latency_context = low_latency_context; forced_low_latency_tech = low_latency_tech; - if (auto current_tech = currently_active_tech.load(); current_tech) - { - // If trying to init low latency tech with the same context... - if (current_tech->get_tech_context() == low_latency_context && current_tech->get_mode() == low_latency_tech) - { - // Just init itself with the correct method using that context to set the flag - current_tech->init_using_ctx(current_tech->get_tech_context()); - return true; - } - } - deinit_current_tech(); - // Only D3D - if (forced_low_latency_context) - return update_low_latency_tech((IUnknown*) nullptr); - else - return true; // no device, low latency will need to reinit itself on the next reflex call + if (!device) + return false; + + auto result = update_low_latency_tech(device); + + if (result) + { + void* lowLatencyContext = nullptr; + LowLatencyMode currentLowLatencyMode {}; + + return get_low_latency_tech_context(&lowLatencyContext, ¤tLowLatencyMode) && + low_latency_tech == currentLowLatencyMode; + } + + return false; } bool LowLatency::is_low_latency_enabled() diff --git a/OptiScaler/nvapi/fakenvapi/low_latency.h b/OptiScaler/nvapi/fakenvapi/low_latency.h index 33281967..53bda6d3 100644 --- a/OptiScaler/nvapi/fakenvapi/low_latency.h +++ b/OptiScaler/nvapi/fakenvapi/low_latency.h @@ -19,8 +19,7 @@ class LowLatency SleepMode last_sleep_mode {}; // Once set, it will be used for all init attempts - void* forced_low_latency_context = nullptr; - LowLatencyMode forced_low_latency_tech = LowLatencyMode::LatencyFlex; + LowLatencyMode forced_low_latency_tech = LowLatencyMode::None; void update_effective_fg_state(); void update_enabled_override(); @@ -50,7 +49,7 @@ class LowLatency } } bool get_low_latency_tech_context(void** low_latency_tech_context, LowLatencyMode* low_latency_tech); - bool set_low_latency_tech_context(void* low_latency_tech_context, LowLatencyMode low_latency_tech); + bool set_low_latency_tech_mode(IUnknown* device, LowLatencyMode low_latency_tech); bool is_low_latency_enabled(); diff --git a/OptiScaler/nvapi/fakenvapi/low_latency_d3d.cpp b/OptiScaler/nvapi/fakenvapi/low_latency_d3d.cpp index dffcc70c..21d050a7 100644 --- a/OptiScaler/nvapi/fakenvapi/low_latency_d3d.cpp +++ b/OptiScaler/nvapi/fakenvapi/low_latency_d3d.cpp @@ -13,7 +13,7 @@ // private bool LowLatency::update_low_latency_tech(IUnknown* pDevice) { - if (!pDevice && !forced_low_latency_context) + if (!pDevice) { LOG_ERROR("Invalid pointer"); return false; @@ -21,23 +21,20 @@ bool LowLatency::update_low_latency_tech(IUnknown* pDevice) if (!currently_active_tech.load()) { - if (forced_low_latency_context && forced_low_latency_tech == LowLatencyMode::AntiLag2) + if (forced_low_latency_tech == LowLatencyMode::XeLL) { - auto new_tech = std::make_shared(); - if (new_tech->init_using_ctx(forced_low_latency_context)) + auto new_tech_xell = std::make_shared(); + if (new_tech_xell->init(pDevice)) { - LOG_INFO("LowLatency algo: FSR Anti-Lag 2.0 (via context)"); - currently_active_tech.store(std::move(new_tech)); - return true; - } - } - else if (forced_low_latency_context && forced_low_latency_tech == LowLatencyMode::XeLL) - { - auto new_tech = std::make_shared(); - if (new_tech->init_using_ctx(forced_low_latency_context)) - { - LOG_INFO("LowLatency algo: XeLL (via context)"); - currently_active_tech.store(std::move(new_tech)); + LOG_INFO("LowLatency algo: XeLL (forced)"); + + new_tech_xell->set_forced_mode(true); + + SleepMode sleepMode {}; + sleepMode.low_latency_enabled = true; + new_tech_xell->set_sleep_mode(&sleepMode); + + currently_active_tech.store(std::move(new_tech_xell)); return true; } } @@ -81,6 +78,10 @@ bool LowLatency::update_low_latency_tech(IUnknown* pDevice) bool change_detected = last_force_latencyflex != force_latencyflex; last_force_latencyflex = force_latencyflex; + // Don't allow for deinit with forced mode + if (forced_low_latency_tech != LowLatencyMode::None) + return true; + if (State::Instance().fakenvapiReloadLowLatency) { change_detected = true; diff --git a/OptiScaler/proxies/XeLL_Proxy.h b/OptiScaler/proxies/XeLL_Proxy.h index 747c22f0..58e4faba 100644 --- a/OptiScaler/proxies/XeLL_Proxy.h +++ b/OptiScaler/proxies/XeLL_Proxy.h @@ -360,77 +360,4 @@ class XeLLProxy static PFN_xellGetFramesReports GetFramesReports() { return _xellGetFramesReports; } static PFN_xellD3D12CreateContext D3D12CreateContext() { return _xellD3D12CreateContext; } #endif - - static bool DestroyXeLLContext() - { - LOG_DEBUG(""); - - if (_xellContext != nullptr) - { - auto context = _xellContext; - _xellContext = nullptr; - auto xellResult = DestroyContext()(context); - - LOG_INFO("XeLL DestroyContext result: {} ({})", magic_enum::enum_name(xellResult), (UINT) xellResult); - - // Set it back because context is not destroyed - if (xellResult != XELL_RESULT_SUCCESS) - _xellContext = context; - } - - return true; - } - - static bool CreateContext(ID3D12Device* device) - { - if (!InitXeLL()) - { - LOG_ERROR("XeLL proxy can't find libxell.dll!"); - return false; - } - -#ifndef LOW_LATENCY_INPUTS - if (!XellHooks::Hook()) - { - LOG_ERROR("Couldn't detour XeLL"); - return false; - } -#endif - - if (_xellContext != nullptr) - DestroyXeLLContext(); - - xell_result_t xellResult; - { -#ifndef DONT_USE_XMX - ScopedSkipSpoofing skipSpoofing {}; -#endif // !DONT_USE_XMX - - xellResult = D3D12CreateContext()(device, &_xellContext); - } - - if (xellResult != XELL_RESULT_SUCCESS) - { - LOG_ERROR("XeLL D3D12CreateContext error: {} ({})", magic_enum::enum_name(xellResult), (UINT) xellResult); - return false; - } - else - { -#ifdef LOW_LATENCY_INPUTS - ((InputXeLL::xell_input_handle_t) _xellContext)->inputContext.localContext = true; -#endif - LOG_INFO("XeLL context created"); - XellHooks::setOurContext(_xellContext); - } - - xellResult = SetLoggingCallback()(_xellContext, XELL_LOGGING_LEVEL_DEBUG, xellLogCallback); - if (xellResult != XELL_RESULT_SUCCESS) - { - LOG_ERROR("XeLL SetLoggingCallback error: {} ({})", magic_enum::enum_name(xellResult), (UINT) xellResult); - } - - return true; - } - - static xell_context_handle_t Context() { return _xellContext; } };