From 4927654da0c562da255d866a63938b050fa94530 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Tue, 12 Sep 2023 20:50:38 +0200 Subject: [PATCH] Bugfix: only run NVIDIA Reflex if we ran an actual engine frame CEngine::Frame() tends to return out early if we are ahead of frame time, and therefore need to sleep. In this particular engine, CEngine::Frame() returns true if it had actually executed an engine frame, else it returns false. Therefore, we end up calling 'NvAPI_D3D_Sleep()' multiple times a frame, and thus causing a major loss in performance. Now we check if we have actually ran a frame (incrementing reflex frame if so). If the frame was not incremented, but 'GFX_RunLowLatencyFrame()' was called, it will not call 'NvAPI_D3D_Sleep()'. Code has been tested and appears to work on my system (never called twice or more per frame). Needs more testing on other systems to make sure its good. --- r5dev/engine/sys_dll2.cpp | 8 +++++++- r5dev/geforce/reflex.cpp | 10 ++++++++-- r5dev/geforce/reflex.h | 1 + r5dev/public/iengine.h | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/r5dev/engine/sys_dll2.cpp b/r5dev/engine/sys_dll2.cpp index 7c90ec8a..5c696163 100644 --- a/r5dev/engine/sys_dll2.cpp +++ b/r5dev/engine/sys_dll2.cpp @@ -232,7 +232,13 @@ bool CEngineAPI::MainLoop() CEngineAPI::PumpMessages(); #endif // !DEDICATED - g_pEngine->Frame(); + if (g_pEngine->Frame()) + { +#ifndef DEDICATED + // Only increment frame number if we ran an actual engine frame. + GFX_IncrementFrameNumber(); +#endif // !DEDICATED + } } } diff --git a/r5dev/geforce/reflex.cpp b/r5dev/geforce/reflex.cpp index 57f8ac41..747a37f8 100644 --- a/r5dev/geforce/reflex.cpp +++ b/r5dev/geforce/reflex.cpp @@ -16,7 +16,8 @@ bool s_ReflexModeInfoUpToDate = false; NvAPI_Status s_ReflexModeUpdateStatus = NvAPI_Status::NVAPI_OK; // Static frame number counter for latency markers. -int s_ReflexFrameNumber = -1; +int s_ReflexFrameNumber = 0; +int s_ReflexLastFrameNumber = 0; //----------------------------------------------------------------------------- // Purpose: mark the parameters as out-of-date; force update next frame @@ -105,10 +106,15 @@ void GFX_UpdateLowLatencyParameters(IUnknown* device, const bool useLowLatencyMo //----------------------------------------------------------------------------- void GFX_RunLowLatencyFrame(IUnknown* device) { - GFX_IncrementFrameNumber(); + int currentFrameNumber = GFX_GetFrameNumber(); + + if (s_ReflexLastFrameNumber == currentFrameNumber) + return; if (GFX_ParameterUpdateWasSuccessful()) NvAPI_D3D_Sleep(device); + + s_ReflexLastFrameNumber = currentFrameNumber; } //----------------------------------------------------------------------------- diff --git a/r5dev/geforce/reflex.h b/r5dev/geforce/reflex.h index 09aaa5ab..8cb7157a 100644 --- a/r5dev/geforce/reflex.h +++ b/r5dev/geforce/reflex.h @@ -5,6 +5,7 @@ void GFX_MarkLowLatencyParametersOutOfDate(void); bool GFX_HasPendingLowLatencyParameterUpdates(void); int GFX_GetFrameNumber(void); +void GFX_IncrementFrameNumber(void); void GFX_UpdateLowLatencyParameters(IUnknown* device, const bool useLowLatencyMode, const bool useLowLatencyBoost, const bool useMarkersToOptimize, diff --git a/r5dev/public/iengine.h b/r5dev/public/iengine.h index b5216fd1..36f084ff 100644 --- a/r5dev/public/iengine.h +++ b/r5dev/public/iengine.h @@ -45,7 +45,7 @@ public: virtual void SetNextState(EngineState_t iNextState) = 0; virtual EngineState_t GetState(void) = 0; - virtual void Frame(void) = 0; + virtual bool Frame(void) = 0; // Returns true if an engine frame is being ran. virtual float GetFrameTime(void) = 0; virtual float GetPreviousTime(void) = 0;