mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-08-25 15:46:45 +00:00
When possible use game's XeLL instance instead of Fallback for FPS limit
This commit is contained in:
@@ -1584,6 +1584,8 @@ void CheckMemoryForProxies()
|
||||
XeFGProxy::InitXeFG();
|
||||
XeLLProxy::InitXeLL();
|
||||
|
||||
XellHooks::Hook();
|
||||
|
||||
NVNGXProxy::InitNVNGX();
|
||||
}
|
||||
|
||||
|
||||
@@ -1175,7 +1175,7 @@ HRESULT FGHooks::FGPresent(IDXGISwapChain* This, UINT SyncInterval, UINT Flags,
|
||||
Hudfix_Dx12::PresentEnd();
|
||||
|
||||
if (willPresent && !State::Instance().reflexLimitsFps && State::Instance().activeFgOutput != FGOutput::NoFG &&
|
||||
!IdentifyGpu::getPrimaryGpu().usesDxvk)
|
||||
!IdentifyGpu::getPrimaryGpu().usesDxvk && !XellHooks::canLimit())
|
||||
{
|
||||
FrameLimit::sleep(fg != nullptr ? fg->IsActive() && !fg->IsPaused() : false);
|
||||
}
|
||||
|
||||
@@ -52,12 +52,44 @@ void XellHooks::blockExternalContexts(bool state) { blockExternal = state; }
|
||||
// Use context to determine blocking, otherwise just block calls from exe
|
||||
bool XellHooks::shouldBlock(xell_context_handle_t context)
|
||||
{
|
||||
if (context && ourContext != context && gamesContext != context)
|
||||
gamesContext = context;
|
||||
|
||||
if (!blockExternal)
|
||||
return false;
|
||||
|
||||
if (context)
|
||||
return blockExternal && ourContext != context;
|
||||
return ourContext != context;
|
||||
else
|
||||
return GetModuleHandle(nullptr) == Util::GetCallerModule(_ReturnAddress());
|
||||
}
|
||||
|
||||
bool XellHooks::canLimit() { return gamesContextCanLimitFps; }
|
||||
|
||||
// only DX12
|
||||
bool XellHooks::update()
|
||||
{
|
||||
if (!o_xellGetSleepMode || !o_xellSetSleepMode || blockExternal || gamesContext == nullptr)
|
||||
return false;
|
||||
|
||||
xell_sleep_params_t currentParams;
|
||||
o_xellGetSleepMode(gamesContext, ¤tParams);
|
||||
|
||||
if (!currentParams.bLowLatencyMode)
|
||||
return false;
|
||||
|
||||
gamesContextCanLimitFps = true;
|
||||
|
||||
float fpsLimit = Config::Instance()->FramerateLimit.value_or_default();
|
||||
|
||||
if (fpsLimit < 0.0f)
|
||||
fpsLimit = 0.0f;
|
||||
|
||||
currentParams.minimumIntervalUs = static_cast<uint32_t>(std::round(1'000'000 / fpsLimit));
|
||||
|
||||
return o_xellSetSleepMode(gamesContext, ¤tParams) == XELL_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
xell_result_t XellHooks::hkxellDestroyContext(xell_context_handle_t context)
|
||||
{
|
||||
if (shouldBlock(context))
|
||||
|
||||
@@ -21,6 +21,8 @@ typedef decltype(&xellD3D12CreateContext) PFN_xellD3D12CreateContext;
|
||||
class XellHooks
|
||||
{
|
||||
inline static xell_context_handle_t ourContext = nullptr;
|
||||
inline static xell_context_handle_t gamesContext = nullptr;
|
||||
inline static bool gamesContextCanLimitFps = false;
|
||||
inline static bool blockExternal = false;
|
||||
|
||||
inline static PFN_xellDestroyContext o_xellDestroyContext = nullptr;
|
||||
@@ -39,6 +41,9 @@ class XellHooks
|
||||
static void blockExternalContexts(bool state);
|
||||
static bool shouldBlock(xell_context_handle_t context);
|
||||
|
||||
static bool canLimit();
|
||||
static bool update();
|
||||
|
||||
static xell_result_t hkxellDestroyContext(xell_context_handle_t context);
|
||||
static xell_result_t hkxellSetSleepMode(xell_context_handle_t context, const xell_sleep_params_t* param);
|
||||
static xell_result_t hkxellGetSleepMode(xell_context_handle_t context, xell_sleep_params_t* param);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <misc/IdentifyGpu.h>
|
||||
#include <hooks/Xell_Hooks.h>
|
||||
|
||||
#define MARK_ALL_BACKENDS_CHANGED() \
|
||||
for (auto& singleChangeBackend : State::Instance().changeBackend) \
|
||||
@@ -4621,7 +4622,10 @@ bool MenuCommon::RenderMenu()
|
||||
}
|
||||
else
|
||||
{
|
||||
currentMethod = "Fallback";
|
||||
if (XellHooks::canLimit())
|
||||
currentMethod = "Game's XeLL";
|
||||
else
|
||||
currentMethod = "Fallback";
|
||||
}
|
||||
|
||||
if (state.rtssReflexInjection)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <d3d11.h>
|
||||
#include <d3d12.h>
|
||||
#include <misc/IdentifyGpu.h>
|
||||
#include <hooks/Xell_Hooks.h>
|
||||
|
||||
#pragma intrinsic(_ReturnAddress)
|
||||
|
||||
@@ -123,6 +124,8 @@ static HRESULT LocalPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT
|
||||
else
|
||||
ReflexHooks::update(false, false);
|
||||
|
||||
XellHooks::update();
|
||||
|
||||
// Upscaler GPU time computation
|
||||
if (willPresent && (fg == nullptr || !fg->IsActive() || fg->IsPaused()))
|
||||
{
|
||||
@@ -470,7 +473,7 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::Present(UINT SyncInterval, UIN
|
||||
|
||||
// When Reflex can't be used to limit, sleep in present
|
||||
if (!State::Instance().reflexLimitsFps && State::Instance().activeFgOutput == FGOutput::NoFG &&
|
||||
!IdentifyGpu::getPrimaryGpu().usesDxvk)
|
||||
!IdentifyGpu::getPrimaryGpu().usesDxvk && !XellHooks::canLimit())
|
||||
FrameLimit::sleep(false);
|
||||
}
|
||||
else
|
||||
@@ -760,7 +763,7 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::Present1(UINT SyncInterval, UI
|
||||
|
||||
// When Reflex can't be used to limit, sleep in present
|
||||
if (!State::Instance().reflexLimitsFps && State::Instance().activeFgOutput == FGOutput::NoFG &&
|
||||
!IdentifyGpu::getPrimaryGpu().usesDxvk)
|
||||
!IdentifyGpu::getPrimaryGpu().usesDxvk && !XellHooks::canLimit())
|
||||
FrameLimit::sleep(false);
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user