Only call 'NvAPI_D3D_SetSleepMode(...)' on pending changes

No need to keep calling this if there are no pending changes.
This commit is contained in:
Kawe Mazidjatari 2023-09-12 17:44:24 +02:00
parent b87d7bf1c3
commit 51a3f4a1c4
6 changed files with 113 additions and 34 deletions

View File

@ -32,6 +32,7 @@
#include "vscript/vscript.h"
#include "ebisusdk/EbisuSDK.h"
#ifndef DEDICATED
#include "geforce/reflex.h"
#include "gameui/IBrowser.h"
#include "gameui/IConsole.h"
#endif // !DEDICATED
@ -1006,6 +1007,19 @@ void RCON_InputOnlyChanged_f(IConVar* pConVar, const char* pOldString, float flO
{
RCONClient()->RequestConsoleLog(RCONClient()->ShouldReceive());
}
/*
=====================
GFX_NVN_Changed_f
force update NVIDIA Reflex
Low Latency parameters
=====================
*/
void GFX_NVN_Changed_f(IConVar* pConVar, const char* pOldString, float flOldValue)
{
GFX_MarkLowLatencyParametersOutOfDate();
}
#endif // !DEDICATED

View File

@ -51,6 +51,8 @@ void CON_ClearHistory_f(const CCommand& args);
void RCON_CmdQuery_f(const CCommand& args);
void RCON_Disconnect_f(const CCommand& args);
void RCON_InputOnlyChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue);
void GFX_NVN_Changed_f(IConVar* pConVar, const char* pOldString, float flOldValue);
#endif // !DEDICATED
void RCON_PasswordChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue);
void LanguageChanged_f(IConVar* pConVar, const char* pOldString, float flOldValue);

View File

@ -314,10 +314,11 @@ void ConVar_StaticInit(void)
#ifndef DEDICATED
fps_max_rt = ConVar::StaticCreate("fps_max_rt", "0", FCVAR_RELEASE, "Frame rate limiter within the render thread. -1 indicates use the desktop refresh. 0 is disabled.", true, -1.f, false, 0.f, nullptr, nullptr);
fps_max_rt_tolerance = ConVar::StaticCreate("fps_max_rt_tolerance", "0.25", FCVAR_RELEASE, "Maximum amount of frame time before frame limiter restarts.", true, 0.f, false, 0.f, nullptr, nullptr);
fps_max_gfx = ConVar::StaticCreate("fps_max_gfx", "0", FCVAR_RELEASE, "Frame rate limiter using NVIDIA Reflex Low Latency SDK. -1 indicates use the desktop refresh. 0 is disabled.", true, -1.f, false, 0.f, nullptr, nullptr);
gfx_nvnUseLowLatency = ConVar::StaticCreate("gfx_nvnUseLowLatency" , "1", FCVAR_RELEASE | FCVAR_ARCHIVE, "Enables NVIDIA Reflex Low Latency SDK." , false, 0.f, false, 0.f, nullptr, nullptr);
gfx_nvnUseLowLatencyBoost = ConVar::StaticCreate("gfx_nvnUseLowLatencyBoost", "1", FCVAR_RELEASE | FCVAR_ARCHIVE, "Enables NVIDIA Reflex Low Latency Boost.", false, 0.f, false, 0.f, nullptr, nullptr);
gfx_nvnUseMarkersToOptimize = ConVar::StaticCreate("gfx_nvnUseMarkersToOptimize", "1", FCVAR_RELEASE | FCVAR_ARCHIVE, "Enables NVIDIA Reflex Low Latency Timing.", false, 0.f, false, 0.f, nullptr, nullptr);
fps_max_gfx = ConVar::StaticCreate("fps_max_gfx", "0", FCVAR_RELEASE, "Frame rate limiter using NVIDIA Reflex Low Latency SDK. -1 indicates use the desktop refresh. 0 is disabled.", true, -1.f, false, 0.f, &GFX_NVN_Changed_f, nullptr);
gfx_nvnUseLowLatency = ConVar::StaticCreate("gfx_nvnUseLowLatency" , "1", FCVAR_RELEASE | FCVAR_ARCHIVE, "Enables NVIDIA Reflex Low Latency SDK." , false, 0.f, false, 0.f, &GFX_NVN_Changed_f, nullptr);
gfx_nvnUseLowLatencyBoost = ConVar::StaticCreate("gfx_nvnUseLowLatencyBoost", "1", FCVAR_RELEASE | FCVAR_ARCHIVE, "Enables NVIDIA Reflex Low Latency Boost.", false, 0.f, false, 0.f, &GFX_NVN_Changed_f, nullptr);
gfx_nvnUseMarkersToOptimize = ConVar::StaticCreate("gfx_nvnUseMarkersToOptimize", "1", FCVAR_RELEASE | FCVAR_ARCHIVE, "Enables NVIDIA Reflex Low Latency Timing.", false, 0.f, false, 0.f, &GFX_NVN_Changed_f, nullptr);
#endif // !DEDICATED
//-------------------------------------------------------------------------

View File

@ -202,28 +202,33 @@ bool CEngineAPI::MainLoop()
}
#ifndef DEDICATED
const bool bUseLowLatencyMode = gfx_nvnUseLowLatency->GetBool();
const bool bUseLowLatencyBoost = gfx_nvnUseLowLatencyBoost->GetBool();
const bool bUseLowLatencyTiming = gfx_nvnUseMarkersToOptimize->GetBool();
float fpsMax = fps_max_gfx->GetFloat();
if (fpsMax == -1.0f)
if (GFX_HasPendingLowLatencyParameterUpdates())
{
const float globalFps = fps_max->GetFloat();
const bool bUseLowLatencyMode = gfx_nvnUseLowLatency->GetBool();
const bool bUseLowLatencyBoost = gfx_nvnUseLowLatencyBoost->GetBool();
const bool bUseLowLatencyTiming = gfx_nvnUseMarkersToOptimize->GetBool();
// Make sure the global fps limiter is 'unlimited'
// before we let the gfx frame limiter cap it to
// the desktop's refresh rate; not adhering to
// this will result in a major performance drop.
if (globalFps == 0.0f)
fpsMax = g_pGame->GetTVRefreshRate();
else
fpsMax = 0.0f; // Don't let NVIDIA limit the frame rate.
float fpsMax = fps_max_gfx->GetFloat();
if (fpsMax == -1.0f)
{
const float globalFps = fps_max->GetFloat();
// Make sure the global fps limiter is 'unlimited'
// before we let the gfx frame limiter cap it to
// the desktop's refresh rate; not adhering to
// this will result in a major performance drop.
if (globalFps == 0.0f)
fpsMax = g_pGame->GetTVRefreshRate();
else
fpsMax = 0.0f; // Don't let NVIDIA limit the frame rate.
}
GFX_UpdateLowLatencyParameters(D3D11Device(), bUseLowLatencyMode,
bUseLowLatencyBoost, bUseLowLatencyTiming, fpsMax);
}
GFX_RunLowLatencyFrame(D3D11Device(), bUseLowLatencyMode,
bUseLowLatencyBoost, bUseLowLatencyTiming, fpsMax);
GFX_RunLowLatencyFrame(D3D11Device());
CEngineAPI::PumpMessages();
#endif // !DEDICATED

View File

@ -8,9 +8,48 @@
#define GFX_NVN_MAX_FRAME_COUNT 4000
// If false, the system will call 'NvAPI_D3D_SetSleepMode' to update the parameters.
bool s_ReflexModeInfoUpToDate = false;
// This is 'NVAPI_OK' If the call to 'NvAPI_D3D_SetSleepMode' was successful.
// If not, the Low Latency SDK will not run.
NvAPI_Status s_ReflexModeUpdateStatus = NvAPI_Status::NVAPI_OK;
// Static frame number counter for latency markers.
int s_ReflexFrameNumber = -1;
//-----------------------------------------------------------------------------
// Purpose: mark the parameters as out-of-date; force update next frame
//-----------------------------------------------------------------------------
void GFX_MarkLowLatencyParametersOutOfDate(void)
{
s_ReflexModeInfoUpToDate = false;
}
//-----------------------------------------------------------------------------
// Purpose: mark the parameters as up-to-date
//-----------------------------------------------------------------------------
void GFX_MarkLowLatencyParametersUpToDate(void)
{
s_ReflexModeInfoUpToDate = true;
}
//-----------------------------------------------------------------------------
// Purpose: has the user requested any changes to the low latency parameters?
//-----------------------------------------------------------------------------
bool GFX_HasPendingLowLatencyParameterUpdates(void)
{
return s_ReflexModeInfoUpToDate == false;
}
//-----------------------------------------------------------------------------
// Purpose: returns whether the call to 'NvAPI_D3D_SetSleepMode' was successful
//-----------------------------------------------------------------------------
bool GFX_ParameterUpdateWasSuccessful(void)
{
return s_ReflexModeUpdateStatus == NvAPI_Status::NVAPI_OK;
}
//-----------------------------------------------------------------------------
// Purpose: gets the reflex frame number
// Output : int
@ -32,22 +71,20 @@ void GFX_IncrementFrameNumber(void)
}
//-----------------------------------------------------------------------------
// Purpose: runs a frame of the low latency sdk
// Purpose: updates the low latency parameters
// Input : *device -
// useLowLatencyMode -
// useLowLatencyBoost -
// useMarkersToOptimize -
// maxFramesPerSecond -
//-----------------------------------------------------------------------------
void GFX_RunLowLatencyFrame(IUnknown* device, const bool useLowLatencyMode,
void GFX_UpdateLowLatencyParameters(IUnknown* device, const bool useLowLatencyMode,
const bool useLowLatencyBoost, const bool useMarkersToOptimize,
const float maxFramesPerSecond)
{
Assert(device);
Assert(IsFinite(maxFramesPerSecond));
GFX_IncrementFrameNumber();
NV_SET_SLEEP_MODE_PARAMS params = {};
params.version = NV_SET_SLEEP_MODE_PARAMS_VER1;
@ -58,9 +95,19 @@ void GFX_RunLowLatencyFrame(IUnknown* device, const bool useLowLatencyMode,
: 0;
params.bUseMarkersToOptimize = useMarkersToOptimize;
NvAPI_Status status = NvAPI_D3D_SetSleepMode(device, &params);
s_ReflexModeUpdateStatus = NvAPI_D3D_SetSleepMode(device, &params);
GFX_MarkLowLatencyParametersUpToDate();
}
if (status == NVAPI_OK)
//-----------------------------------------------------------------------------
// Purpose: runs a frame of the low latency sdk
// Input : *device -
//-----------------------------------------------------------------------------
void GFX_RunLowLatencyFrame(IUnknown* device)
{
GFX_IncrementFrameNumber();
if (GFX_ParameterUpdateWasSuccessful())
NvAPI_D3D_Sleep(device);
}
@ -73,10 +120,15 @@ void GFX_RunLowLatencyFrame(IUnknown* device, const bool useLowLatencyMode,
void GFX_SetLatencyMarker(IUnknown* device,
const NV_LATENCY_MARKER_TYPE markerType)
{
NV_LATENCY_MARKER_PARAMS params = {};
params.version = NV_LATENCY_MARKER_PARAMS_VER1;
params.frameID = s_ReflexFrameNumber;
params.markerType = markerType;
// TODO[ AMOS ]: should we keep calling this, even when the call to
// 'NvAPI_D3D_SetSleepMode(...)' has failed?
if (GFX_ParameterUpdateWasSuccessful())
{
NV_LATENCY_MARKER_PARAMS params = {};
params.version = NV_LATENCY_MARKER_PARAMS_VER1;
params.frameID = s_ReflexFrameNumber;
params.markerType = markerType;
NvAPI_D3D_SetLatencyMarker(device, &params);
NvAPI_D3D_SetLatencyMarker(device, &params);
}
}

View File

@ -1,12 +1,17 @@
#ifndef GFSDK_REFLEX_H
#define GFSDK_REFLEX_H
void GFX_MarkLowLatencyParametersOutOfDate(void);
bool GFX_HasPendingLowLatencyParameterUpdates(void);
int GFX_GetFrameNumber(void);
void GFX_RunLowLatencyFrame(IUnknown* device, const bool useLowLatencyMode,
void GFX_UpdateLowLatencyParameters(IUnknown* device, const bool useLowLatencyMode,
const bool useLowLatencyBoost, const bool useMarkersToOptimize,
const float maxFramesPerSecond);
void GFX_RunLowLatencyFrame(IUnknown* device);
void GFX_SetLatencyMarker(IUnknown* device,
const NV_LATENCY_MARKER_TYPE markerType);