NVIDIA: initial implementation of latency markers

This commit is contained in:
Kawe Mazidjatari 2023-12-22 14:42:28 +01:00
parent 9d5c237338
commit 5105ea771d
14 changed files with 182 additions and 21 deletions

View File

@ -75,6 +75,7 @@ ConVar* r_visualizetraces_duration = nullptr;
ConVar* gfx_nvnUseLowLatency = nullptr;
ConVar* gfx_nvnUseLowLatencyBoost = nullptr;
ConVar* gfx_nvnUseMarkersToOptimize = nullptr;
#endif // !DEDICATED
ConVar* stream_overlay = nullptr;
@ -337,8 +338,9 @@ void ConVar_StaticInit(void)
fps_max_rt_sleep_threshold = ConVar::StaticCreate("fps_max_rt_sleep_threshold", "0.016666667", FCVAR_RELEASE, "Frame limiter starts to sleep when frame time exceeds this threshold.", 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, true, 295.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", "0", FCVAR_RELEASE | FCVAR_ARCHIVE, "Enables NVIDIA Reflex Low Latency Boost.", false, 0.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" , "0", 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", "0", FCVAR_RELEASE | FCVAR_ARCHIVE, "Use NVIDIA Reflex Low Latency markers to optimize (requires Low Latency Boost to be enabled).", false, 0.f, false, 0.f, &GFX_NVN_Changed_f, nullptr);
#endif // !DEDICATED
//-------------------------------------------------------------------------

View File

@ -66,6 +66,7 @@ extern ConVar* r_visualizetraces_duration;
extern ConVar* gfx_nvnUseLowLatency;
extern ConVar* gfx_nvnUseLowLatencyBoost;
extern ConVar* gfx_nvnUseMarkersToOptimize;
#endif // !DEDICATED
extern ConVar* stream_overlay;

View File

@ -100,6 +100,7 @@
#include "engine/sys_mainwind.h"
#include "engine/matsys_interface.h"
#include "engine/gl_matsysiface.h"
#include "engine/gl_drawlights.h"
#include "engine/gl_screen.h"
#include "engine/gl_rsurf.h"
#include "engine/debugoverlay.h"
@ -581,6 +582,7 @@ void DetourRegister() // Register detour classes to be searched and hooked.
REGISTER(VGL_RMain);
REGISTER(VMatSys_Interface);
REGISTER(VGL_MatSysIFace);
REGISTER(VGL_DrawLights);
REGISTER(VGL_Screen);
#endif // !DEDICATED

View File

@ -29,6 +29,8 @@ add_sources( SOURCE_GROUP "Debug"
add_sources( SOURCE_GROUP "Render"
"framelimit.cpp"
"framelimit.h"
"gl_drawlights.cpp"
"gl_drawlights.h"
"gl_matsysiface.h"
"gl_model_private.h"
"gl_rmain.cpp"

View File

@ -18,12 +18,67 @@
/*****************************************************************************/
#ifndef DEDICATED
//-----------------------------------------------------------------------------
// Purpose: pre frame stage notify hook
//-----------------------------------------------------------------------------
void FrameStageNotify_Pre(const ClientFrameStage_t frameStage)
{
switch (frameStage)
{
case ClientFrameStage_t::FRAME_START:
break;
case ClientFrameStage_t::FRAME_NET_UPDATE_START:
break;
case ClientFrameStage_t::FRAME_NET_UPDATE_POSTDATAUPDATE_START:
break;
case ClientFrameStage_t::FRAME_NET_UPDATE_POSTDATAUPDATE_END:
break;
case ClientFrameStage_t::FRAME_NET_UPDATE_END:
break;
case ClientFrameStage_t::FRAME_RENDER_START:
break;
case ClientFrameStage_t::FRAME_RENDER_END:
break;
case ClientFrameStage_t::FRAME_NET_FULL_FRAME_UPDATE_ON_REMOVE:
break;
}
}
//-----------------------------------------------------------------------------
// Purpose: post frame stage notify hook
//-----------------------------------------------------------------------------
void FrameStageNotify_Post(const ClientFrameStage_t frameStage)
{
switch (frameStage)
{
case ClientFrameStage_t::FRAME_START:
break;
case ClientFrameStage_t::FRAME_NET_UPDATE_START:
break;
case ClientFrameStage_t::FRAME_NET_UPDATE_POSTDATAUPDATE_START:
break;
case ClientFrameStage_t::FRAME_NET_UPDATE_POSTDATAUPDATE_END:
break;
case ClientFrameStage_t::FRAME_NET_UPDATE_END:
break;
case ClientFrameStage_t::FRAME_RENDER_START:
break;
case ClientFrameStage_t::FRAME_RENDER_END:
GFX_SetLatencyMarker(D3D11Device(), SIMULATION_END);
break;
case ClientFrameStage_t::FRAME_NET_FULL_FRAME_UPDATE_ON_REMOVE:
break;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHLClient::FrameStageNotify(CHLClient* pHLClient, ClientFrameStage_t frameStage)
{
FrameStageNotify_Pre(frameStage);
CHLClient_FrameStageNotify(pHLClient, frameStage);
FrameStageNotify_Post(frameStage);
}
//-----------------------------------------------------------------------------

View File

@ -0,0 +1,13 @@
#include "gl_drawlights.h"
void DrawLightSprites(void* unkType)
{
v_DrawLightSprites(unkType);
}
void VGL_DrawLights::Detour(const bool bAttach) const
{
// Enable if needed.
//DetourSetup(&v_DrawLightSprites, &DrawLightSprites, bAttach);
}

View File

@ -0,0 +1,23 @@
#pragma once
inline CMemory p_DrawLightSprites;
inline void(*v_DrawLightSprites)(void*);
///////////////////////////////////////////////////////////////////////////////
class VGL_DrawLights : public IDetour
{
virtual void GetAdr(void) const
{
LogFunAdr("DrawLightSprites", p_DrawLightSprites.GetPtr());
}
virtual void GetFun(void) const
{
p_DrawLightSprites = g_GameDll.FindPatternSIMD("48 8B C4 55 57 48 8D 68 A1 48 81 EC ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ??");
v_DrawLightSprites = p_DrawLightSprites.RCast<void(*)(void*)>();
}
virtual void GetVar(void) const { }
virtual void GetCon(void) const { }
virtual void Detour(const bool bAttach) const;
};
///////////////////////////////////////////////////////////////////////////////

View File

@ -6,8 +6,16 @@
//===========================================================================//
#include "core/stdafx.h"
#include "tier1/cvar.h"
#include "windows/id3dx.h"
#include "geforce/reflex.h"
#include "engine/gl_rsurf.h"
void* R_DrawDepthOfField(const float a1)
{
GFX_SetLatencyMarker(D3D11Device(), RENDERSUBMIT_START);
return V_DrawDepthOfField(a1);
}
void* R_DrawWorldMeshes(void* baseEntity, void* renderContext, DrawWorldLists_t worldLists)
{
if (r_drawWorldMeshes->GetBool())
@ -34,6 +42,7 @@ void* R_DrawWorldMeshesDepthAtTheEnd(void* ptr1, void* ptr2, void* ptr3, DrawWor
void VGL_RSurf::Detour(const bool bAttach) const
{
DetourSetup(&V_DrawDepthOfField, &R_DrawDepthOfField, bAttach);
DetourSetup(&V_DrawWorldMeshes, &R_DrawWorldMeshes, bAttach);
DetourSetup(&V_DrawWorldMeshesDepthOnly, &R_DrawWorldMeshesDepthOnly, bAttach);
DetourSetup(&V_DrawWorldMeshesDepthAtTheEnd, &R_DrawWorldMeshesDepthAtTheEnd, bAttach);

View File

@ -1,6 +1,9 @@
#pragma once
#include "public/ivrenderview.h"
inline CMemory P_DrawDepthOfField;
inline void*(*V_DrawDepthOfField)(const float a1);
inline CMemory P_DrawWorldMeshes;
inline void*(*V_DrawWorldMeshes)(void* baseEntity, void* renderContext, DrawWorldLists_t worldLists);
@ -15,12 +18,14 @@ class VGL_RSurf : public IDetour
{
virtual void GetAdr(void) const
{
LogFunAdr("R_DrawDepthOfField", P_DrawDepthOfField.GetPtr());
LogFunAdr("R_DrawWorldMeshes", P_DrawWorldMeshes.GetPtr());
LogFunAdr("R_DrawWorldMeshesDepthOnly", P_DrawWorldMeshesDepthOnly.GetPtr());
LogFunAdr("R_DrawWorldMeshesDepthAtTheEnd", P_DrawWorldMeshesDepthAtTheEnd.GetPtr());
}
virtual void GetFun(void) const
{
P_DrawDepthOfField = g_GameDll.FindPatternSIMD("48 83 EC 48 0F 28 E8");
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
P_DrawWorldMeshes = g_GameDll.FindPatternSIMD("48 8B C4 48 89 48 08 53 48 83 EC 70");
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
@ -29,6 +34,7 @@ class VGL_RSurf : public IDetour
P_DrawWorldMeshesDepthOnly = g_GameDll.FindPatternSIMD("40 56 57 B8 ?? ?? ?? ??");
P_DrawWorldMeshesDepthAtTheEnd = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 41 8B F9");
V_DrawDepthOfField = P_DrawDepthOfField.RCast<void* (*)(const float)>();
V_DrawWorldMeshes = P_DrawWorldMeshes.RCast<void* (*)(void*, void*, DrawWorldLists_t)>(); /*48 8B C4 48 89 48 08 53 57 41 55*/
V_DrawWorldMeshesDepthOnly = P_DrawWorldMeshesDepthOnly.RCast<void* (*)(void*, DrawWorldLists_t)>(); /*40 56 57 B8 ?? ?? ?? ??*/
V_DrawWorldMeshesDepthAtTheEnd = P_DrawWorldMeshesDepthAtTheEnd.RCast<void* (*)(void*, void*, void*, DrawWorldLists_t)>(); /*48 89 5C 24 ?? 48 89 74 24 ? 57 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 41 8B F9*/

View File

@ -9,6 +9,8 @@
#include "tier0/frametask.h"
#include "engine/host.h"
#ifndef DEDICATED
#include "windows/id3dx.h"
#include "geforce/reflex.h"
#include "vgui/vgui_debugpanel.h"
#endif // !DEDICATED
@ -30,6 +32,23 @@ void CCommonHostState::SetWorldModel(model_t* pModel)
}
}
/*
==================
Host_CountRealTimePackets
Counts the number of
packets in non-prescaled
clock frames (does not
count for bots or Terminal
Services environments)
==================
*/
void Host_CountRealTimePackets()
{
v_Host_CountRealTimePackets();
GFX_SetLatencyMarker(D3D11Device(), SIMULATION_START);
}
/*
==================
_Host_RunFrame
@ -77,6 +96,7 @@ void _Host_Error(const char* error, ...)
void VHost::Detour(const bool bAttach) const
{
DetourSetup(&v_Host_RunFrame, &_Host_RunFrame, bAttach);
DetourSetup(&v_Host_CountRealTimePackets, &Host_CountRealTimePackets, bAttach);
#ifndef DEDICATED // Dedicated already logs this!
DetourSetup(&v_Host_Error, &_Host_Error, bAttach);

View File

@ -4,8 +4,11 @@
inline CMemory p_Host_RunFrame;
inline void(*v_Host_RunFrame)(void* unused, float time);
//inline CMemory p_Host_RunFrame_Render; // DEDICATED PATCH!
//inline void(*v_Host_RunFrame_Render)(void);
inline CMemory p_Host_RunFrame_Render;
inline void(*v_Host_RunFrame_Render)(void);
inline CMemory p_Host_CountRealTimePackets;
inline void(*v_Host_CountRealTimePackets)(void);
inline CMemory p_Host_ShouldRun;
inline bool(*v_Host_ShouldRun)();
@ -54,7 +57,8 @@ class VHost : public IDetour
virtual void GetAdr(void) const
{
LogFunAdr("_Host_RunFrame", p_Host_RunFrame.GetPtr());
//LogFunAdr("_Host_RunFrame_Render", p_Host_RunFrame_Render.GetPtr());
LogFunAdr("_Host_RunFrame_Render", p_Host_RunFrame_Render.GetPtr());
LogFunAdr("Host_CountRealTimePackets", p_Host_CountRealTimePackets.GetPtr());
LogFunAdr("Host_ShouldRun", p_Host_ShouldRun.GetPtr());
LogFunAdr("Host_Error", p_Host_Error.GetPtr());
//LogFunAdr("VCR_EnterPausedState", p_VCR_EnterPausedState.GetPtr());
@ -69,16 +73,18 @@ class VHost : public IDetour
{
p_Host_RunFrame = g_GameDll.FindPatternSIMD("48 8B C4 48 89 58 18 48 89 70 20 F3 0F 11 48 ??");
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
//p_Host_RunFrame_Render = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8B 1D ?? ?? ?? ?? 33 FF");
p_Host_RunFrame_Render = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8B 1D ?? ?? ?? ?? 33 FF");
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
//p_Host_RunFrame_Render = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 48 85 C9 75 34");
p_Host_RunFrame_Render = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 48 85 C9 75 34");
#endif
p_Host_CountRealTimePackets = g_GameDll.FindPatternSIMD("40 53 48 83 EC 30 65 48 8B 04 25 ?? ?? ?? ?? 33 DB");
p_Host_ShouldRun = g_GameDll.FindPatternSIMD("48 83 EC 28 48 8B 05 ?? ?? ?? ?? 83 78 6C 00 75 07 B0 01");
p_Host_Error = g_GameDll.FindPatternSIMD("48 89 4C 24 ?? 48 89 54 24 ?? 4C 89 44 24 ?? 4C 89 4C 24 ?? 53 57 48 81 EC ?? ?? ?? ??");
//p_VCR_EnterPausedState = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 65 48 8B 04 25 ?? ?? ?? ?? BB ?? ?? ?? ?? C6 05 ?? ?? ?? ?? ??");
v_Host_RunFrame = p_Host_RunFrame.RCast<void(*)(void*, float)>();
//v_Host_RunFrame_Render = p_Host_Error.RCast<void(*)(void)>();
v_Host_RunFrame_Render = p_Host_RunFrame_Render.RCast<void(*)(void)>();
v_Host_CountRealTimePackets = p_Host_CountRealTimePackets.RCast<void(*)(void)>();
v_Host_ShouldRun = p_Host_ShouldRun.RCast<bool(*)()>();
v_Host_Error = p_Host_Error.RCast<void(*)(const char*, ...)>();
//v_VCR_EnterPausedState = p_VCR_EnterPausedState.RCast<void(*)(void)>();

View File

@ -190,6 +190,7 @@ bool CEngineAPI::MainLoop()
{
const bool bUseLowLatencyMode = gfx_nvnUseLowLatency->GetBool();
const bool bUseLowLatencyBoost = gfx_nvnUseLowLatencyBoost->GetBool();
const bool bUseMarkersToOptimize = gfx_nvnUseMarkersToOptimize->GetBool();
float fpsMax = fps_max_gfx->GetFloat();
@ -208,7 +209,7 @@ bool CEngineAPI::MainLoop()
}
GFX_UpdateLowLatencyParameters(D3D11Device(), bUseLowLatencyMode,
bUseLowLatencyBoost, false, fpsMax);
bUseLowLatencyBoost, bUseMarkersToOptimize, fpsMax);
}
GFX_RunLowLatencyFrame(D3D11Device());

View File

@ -12,12 +12,13 @@
#include "engine/cmodel_bsp.h"
#include "geforce/reflex.h"
#ifndef MATERIALSYSTEM_NODX
#include "windows/id3dx.h"
#include "materialsystem/cmaterialglue.h"
#endif // !MATERIALSYSTEM_NODX
#include "materialsystem/cmaterialsystem.h"
#ifndef MATERIALSYSTEM_NODX
//PCLSTATS_DEFINE()
PCLSTATS_DEFINE()
#endif // MATERIALSYSTEM_NODX
//-----------------------------------------------------------------------------
@ -38,10 +39,10 @@ InitReturnVal_t CMaterialSystem::Init(CMaterialSystem* thisptr)
// Initialize as usual.
GFX_EnableLowLatencySDK(!CommandLine()->CheckParm("-gfx_nvnDisableLowLatency"));
//if (GFX_IsLowLatencySDKEnabled())
//{
// PCLSTATS_INIT(0);
//}
if (GFX_IsLowLatencySDKEnabled())
{
PCLSTATS_INIT(0);
}
return CMaterialSystem__Init(thisptr);
#endif
@ -52,10 +53,10 @@ InitReturnVal_t CMaterialSystem::Init(CMaterialSystem* thisptr)
//-----------------------------------------------------------------------------
int CMaterialSystem::Shutdown(CMaterialSystem* thisptr)
{
//if (GFX_IsLowLatencySDKEnabled())
//{
// PCLSTATS_SHUTDOWN();
//}
if (GFX_IsLowLatencySDKEnabled())
{
PCLSTATS_SHUTDOWN();
}
return CMaterialSystem__Shutdown(thisptr);
}
@ -108,9 +109,21 @@ void* __fastcall DispatchDrawCall(int64_t a1, uint64_t a2, int a3, int a4, int64
return v_DispatchDrawCall(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14);
#endif
}
#endif // !MATERIALSYSTEM_NODX
#ifndef MATERIALSYSTEM_NODX
//---------------------------------------------------------------------------------
// Purpose: run IDXGISwapChain::Present
//---------------------------------------------------------------------------------
ssize_t SpinPresent(void)
{
GFX_SetLatencyMarker(D3D11Device(), RENDERSUBMIT_END);
GFX_SetLatencyMarker(D3D11Device(), PRESENT_START);
const ssize_t val = v_SpinPresent();
GFX_SetLatencyMarker(D3D11Device(), PRESENT_END);
return val;
}
//-----------------------------------------------------------------------------
// Purpose: finds a material
// Input : *pMatSys -
@ -154,6 +167,7 @@ void VMaterialSystem::Detour(const bool bAttach) const
#ifndef MATERIALSYSTEM_NODX
DetourSetup(&v_StreamDB_Init, &StreamDB_Init, bAttach);
DetourSetup(&v_DispatchDrawCall, &DispatchDrawCall, bAttach);
DetourSetup(&v_SpinPresent, &SpinPresent, bAttach);
DetourSetup(&CMaterialSystem__FindMaterialEx, &CMaterialSystem::FindMaterialEx, bAttach);
#endif // !MATERIALSYSTEM_NODX
}

View File

@ -75,6 +75,9 @@ inline void*(*v_DispatchDrawCall)(int64_t a1, uint64_t a2, int a3, int a4, char
inline CMemory p_DispatchDrawCall;
inline void*(*v_DispatchDrawCall)(int64_t a1, uint64_t a2, int a3, int a4, int64_t a5, int a6, uint8_t a7, int64_t a8, uint32_t a9, uint32_t a10, int a11, __m128* a12, int a13, int64_t a14);
#endif
inline CMemory p_SpinPresent;
inline ssize_t(*v_SpinPresent)(void);
inline CMemory p_GetStreamOverlay;
inline void(*v_GetStreamOverlay)(const char* mode, char* buf, size_t bufSize);
@ -100,9 +103,10 @@ class VMaterialSystem : public IDetour
#ifndef MATERIALSYSTEM_NODX
LogFunAdr("CMaterialSystem::FindMaterialEx", p_CMaterialSystem__FindMaterialEx.GetPtr());
LogFunAdr("CMaterialSystem::GetScreenSize", p_CMaterialSystem_GetScreenSize.GetPtr());
LogFunAdr("CMaterialSystem::DispatchDrawCall", p_DispatchDrawCall.GetPtr());
LogFunAdr("CMaterialSystem::GetStreamOverlay", p_GetStreamOverlay.GetPtr());
LogFunAdr("CMaterialSystem::DrawStreamOverlay", p_DrawStreamOverlay.GetPtr());
LogFunAdr("DispatchDrawCall", p_DispatchDrawCall.GetPtr());
LogFunAdr("SpinPresent", p_SpinPresent.GetPtr());
LogVarAdr("g_nTotalStreamingTextureMemory", reinterpret_cast<uintptr_t>(g_nTotalStreamingTextureMemory));
LogVarAdr("g_nUnfreeStreamingTextureMemory", reinterpret_cast<uintptr_t>(g_nUnfreeStreamingTextureMemory));
LogVarAdr("g_nUnusableStreamingTextureMemory", reinterpret_cast<uintptr_t>(g_nUnusableStreamingTextureMemory));
@ -134,6 +138,9 @@ class VMaterialSystem : public IDetour
p_DispatchDrawCall = g_GameDll.FindPatternSIMD("44 89 4C 24 ?? 44 89 44 24 ?? 48 89 4C 24 ?? 55 53 56");
v_DispatchDrawCall = p_DispatchDrawCall.RCast<void*(*)(int64_t, uint64_t, int, int, int64_t, int, uint8_t, int64_t, uint32_t, uint32_t, int, __m128*, int, int64_t )>();
#endif
p_SpinPresent = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 8B 15 ?? ?? ?? ??");
v_SpinPresent = p_SpinPresent.RCast<ssize_t(*)(void)>();
p_GetStreamOverlay = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 80 7C 24 ?? ?? 0F 84 ?? ?? ?? ?? 48 89 9C 24 ?? ?? ?? ??").FollowNearCallSelf();
v_GetStreamOverlay = p_GetStreamOverlay.RCast<void(*)(const char*, char*, size_t)>(); /*E8 ? ? ? ? 80 7C 24 ? ? 0F 84 ? ? ? ? 48 89 9C 24 ? ? ? ?*/