mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-08-25 15:46:45 +00:00
Simplify XeLL context handling
This commit is contained in:
@@ -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())
|
||||
{
|
||||
|
||||
@@ -138,6 +138,9 @@ bool InputCommon::update_low_latency_tech(IUnknown* pDevice, std::optional<LowLa
|
||||
desiredMode = LowLatencyMode::LatencyFlex;
|
||||
}
|
||||
|
||||
if (State::Instance().activeFgOutput == FGOutput::XeFG)
|
||||
desiredMode = LowLatencyMode::XeLL;
|
||||
|
||||
if (activeOutput == desiredMode)
|
||||
return true;
|
||||
|
||||
@@ -730,7 +733,7 @@ xell_result_t InputCommon::pass_xellSetFgEnabled(const InputContext& inputContex
|
||||
return XELL_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
xell_result_t InputCommon::pass_xellSetGeneratedFramesCount(const InputContext& inputContext, uint32_t param1,
|
||||
xell_result_t InputCommon::pass_xellSetGeneratedFramesCount(const InputContext& inputContext, uint32_t frameId,
|
||||
uint32_t framesCount)
|
||||
{
|
||||
if (inputContext.caller == LowLatencyInput::XeLL && activeOutput == LowLatencyMode::XeLL)
|
||||
@@ -738,7 +741,7 @@ xell_result_t InputCommon::pass_xellSetGeneratedFramesCount(const InputContext&
|
||||
if (auto current_tech = currently_active_tech.load())
|
||||
{
|
||||
auto xell_tech = std::static_pointer_cast<XeLL>(current_tech);
|
||||
return xell_tech->xellSetGeneratedFramesCount(param1, framesCount);
|
||||
return xell_tech->xellSetGeneratedFramesCount(frameId, framesCount);
|
||||
}
|
||||
|
||||
return XELL_RESULT_ERROR_UNKNOWN;
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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<AMD::AntiLag2DX12::Context*>(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);
|
||||
|
||||
|
||||
@@ -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; };
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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; };
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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; };
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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<AntiLag2>();
|
||||
if (new_tech->init_using_ctx(forced_low_latency_context))
|
||||
auto new_tech_xell = std::make_shared<XeLL>();
|
||||
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<XeLL>();
|
||||
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;
|
||||
|
||||
@@ -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; }
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user