diff --git a/r5dev/common/callback.cpp b/r5dev/common/callback.cpp index 83a522ed..c3e8002e 100644 --- a/r5dev/common/callback.cpp +++ b/r5dev/common/callback.cpp @@ -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 diff --git a/r5dev/common/callback.h b/r5dev/common/callback.h index 31f8a2bb..7bbe6574 100644 --- a/r5dev/common/callback.h +++ b/r5dev/common/callback.h @@ -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); diff --git a/r5dev/common/global.cpp b/r5dev/common/global.cpp index 508153d2..279cbf16 100644 --- a/r5dev/common/global.cpp +++ b/r5dev/common/global.cpp @@ -74,7 +74,6 @@ ConVar* r_visualizetraces_duration = nullptr; ConVar* gfx_nvnUseLowLatency = nullptr; ConVar* gfx_nvnUseLowLatencyBoost = nullptr; -ConVar* gfx_nvnUseMarkersToOptimize = nullptr; #endif // !DEDICATED ConVar* stream_overlay = nullptr; @@ -312,12 +311,12 @@ void ConVar_StaticInit(void) r_drawWorldMeshesDepthAtTheEnd = ConVar::StaticCreate("r_drawWorldMeshesDepthAtTheEnd", "1", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, "Render world meshes (depth at the end).", false, 0.f, false, 0.f, nullptr, nullptr); #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 = 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, true, 295.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", "0", FCVAR_DEVELOPMENTONLY /*!!! MAKE RELEASE ONCE IMPLEMENTED !!!*/ | 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, 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", "1", FCVAR_RELEASE | FCVAR_ARCHIVE, "Enables NVIDIA Reflex Low Latency Boost.", false, 0.f, false, 0.f, &GFX_NVN_Changed_f, nullptr); #endif // !DEDICATED //------------------------------------------------------------------------- diff --git a/r5dev/common/global.h b/r5dev/common/global.h index a9813dff..9b20f609 100644 --- a/r5dev/common/global.h +++ b/r5dev/common/global.h @@ -65,7 +65,6 @@ extern ConVar* r_visualizetraces_duration; extern ConVar* gfx_nvnUseLowLatency; extern ConVar* gfx_nvnUseLowLatencyBoost; -extern ConVar* gfx_nvnUseMarkersToOptimize; #endif // !DEDICATED extern ConVar* stream_overlay; diff --git a/r5dev/engine/client/cdll_engine_int.cpp b/r5dev/engine/client/cdll_engine_int.cpp index 5c771b2f..5c8ae152 100644 --- a/r5dev/engine/client/cdll_engine_int.cpp +++ b/r5dev/engine/client/cdll_engine_int.cpp @@ -11,6 +11,8 @@ #include "engine/client/cl_rcon.h" #include "networksystem/bansystem.h" #include "vpc/keyvalues.h" +#include "windows/id3dx.h" +#include "geforce/reflex.h" #include "vengineclient_impl.h" #include "cdll_engine_int.h" /*****************************************************************************/ diff --git a/r5dev/engine/client/cdll_engine_int.h b/r5dev/engine/client/cdll_engine_int.h index 18455204..d447056f 100644 --- a/r5dev/engine/client/cdll_engine_int.h +++ b/r5dev/engine/client/cdll_engine_int.h @@ -10,7 +10,7 @@ enum class ClientFrameStage_t : int FRAME_UNDEFINED = -1, // (haven't run any frames yet) FRAME_START, - // A network packet is being recieved + // A network packet is being received FRAME_NET_UPDATE_START, // Data has been received and we're going to start calling PostDataUpdate FRAME_NET_UPDATE_POSTDATAUPDATE_START, diff --git a/r5dev/engine/client/cl_main.cpp b/r5dev/engine/client/cl_main.cpp index 8a54e389..c92fdb60 100644 --- a/r5dev/engine/client/cl_main.cpp +++ b/r5dev/engine/client/cl_main.cpp @@ -10,6 +10,8 @@ #include "cl_main.h" #include "engine/net.h" #include "cdll_engine_int.h" +#include "windows/id3dx.h" +#include "geforce/reflex.h" static float s_lastMovementCall = 0.0; static float s_LastFrameTime = 0.0; @@ -17,7 +19,7 @@ static float s_LastFrameTime = 0.0; //----------------------------------------------------------------------------- // Purpose: run client's movement frame //----------------------------------------------------------------------------- -void H_CL_Move() +void CL_MoveEx() { CClientState* cl = GetBaseLocalClient(); @@ -141,10 +143,10 @@ void H_CL_Move() void VCL_Main::Attach() const { - DetourAttach(&CL_Move, &H_CL_Move); + DetourAttach(&CL_Move, &CL_MoveEx); } void VCL_Main::Detach() const { - DetourDetach(&CL_Move, &H_CL_Move); + DetourDetach(&CL_Move, &CL_MoveEx); } diff --git a/r5dev/engine/framelimit.cpp b/r5dev/engine/framelimit.cpp index 364cabdf..c0477817 100644 --- a/r5dev/engine/framelimit.cpp +++ b/r5dev/engine/framelimit.cpp @@ -45,27 +45,6 @@ void CFrameLimit::Reset(double targetFps) m_Frames = 0; } -//----------------------------------------------------------------------------- -// Purpose: halts the thread until the next vertical blank occurs -// Output : true on success, false otherwise -//----------------------------------------------------------------------------- -bool CFrameLimit::WaitForVBlank(void) -{ - IDXGIOutput* dxgiOutput; - IDXGISwapChain* swapChain = D3D11SwapChain(); - - if (swapChain != nullptr && - SUCCEEDED(swapChain->GetContainingOutput(&dxgiOutput))) - { - DwmFlush(); - dxgiOutput->WaitForVBlank(); - - return true; - } - - return false; -} - //----------------------------------------------------------------------------- // Purpose: runs the frame limiter logic //----------------------------------------------------------------------------- @@ -113,23 +92,19 @@ void CFrameLimit::Run(void) //return; } - ID3D11Device* pDevice = D3D11Device(); m_Next.QuadPart = (LONGLONG)((m_Start.QuadPart + (double)m_Frames * (m_MilliSeconds / 1000.0) * (double)g_pPerformanceFrequency->QuadPart)); if (m_Next.QuadPart > 0ULL) { while (m_Time.QuadPart < m_Next.QuadPart) { - if ((double)(m_Next.QuadPart - m_Time.QuadPart) > (0.016666666667 * (double)g_pPerformanceFrequency->QuadPart)) + if ((double)(m_Next.QuadPart - m_Time.QuadPart) > (0.0166667 * (double)g_pPerformanceFrequency->QuadPart)) { - WaitForVBlank(); + Sleep(10); } QueryPerformanceCounter(&m_Time); } - - if (pDevice != nullptr) - D3D11Device()->Release(); } //m_Last.QuadPart = m_Time.QuadPart; diff --git a/r5dev/engine/framelimit.h b/r5dev/engine/framelimit.h index db4c5ad1..2f1884dd 100644 --- a/r5dev/engine/framelimit.h +++ b/r5dev/engine/framelimit.h @@ -11,7 +11,6 @@ public: void Reset(double target); void Run(void); - bool WaitForVBlank(void); private: double m_MilliSeconds; diff --git a/r5dev/engine/sys_dll2.cpp b/r5dev/engine/sys_dll2.cpp index 881d0b44..0a8317c2 100644 --- a/r5dev/engine/sys_dll2.cpp +++ b/r5dev/engine/sys_dll2.cpp @@ -1,4 +1,4 @@ -//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // @@ -17,6 +17,7 @@ #include "engine/traceinit.h" #ifndef DEDICATED #include "engine/sys_mainwind.h" +#include "materialsystem/cmaterialsystem.h" #include "windows/id3dx.h" #include "client/vengineclient_impl.h" #include "geforce/reflex.h" @@ -155,6 +156,16 @@ void CEngineAPI::VSetStartupInfo(CEngineAPI* pEngineAPI, StartupInfo_t* pStartup #endif // !(GAMEDLL_S0) || !(GAMEDLL_S1) } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CEngineAPI::PumpMessages() +{ +#ifndef DEDICATED + CEngineAPI_PumpMessages(); +#endif // !DEDICATED +} + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -173,32 +184,50 @@ bool CEngineAPI::MainLoop() } #ifndef DEDICATED - const bool bUseLowLatencyMode = gfx_nvnUseLowLatency->GetBool(); - const bool bUseLowLatencyBoost = gfx_nvnUseLowLatencyBoost->GetBool(); - const bool bUseLowLatencyTiming = gfx_nvnUseMarkersToOptimize->GetBool(); + const MaterialAdapterInfo_t& adapterInfo = g_pMaterialAdapterMgr->GetAdapterInfo(); - float fpsMax = fps_max_gfx->GetFloat(); - - if (fpsMax == -1.0f) + // Only run on NVIDIA display drivers; AMD and Intel are not + // supported by NVIDIA Reflex. + if (adapterInfo.m_VendorID == NVIDIA_VENDOR_ID) { - const float globalFps = fps_max->GetFloat(); + if (GFX_HasPendingLowLatencyParameterUpdates()) + { + const bool bUseLowLatencyMode = gfx_nvnUseLowLatency->GetBool(); + const bool bUseLowLatencyBoost = gfx_nvnUseLowLatencyBoost->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, false, fpsMax); + } + + GFX_RunLowLatencyFrame(D3D11Device()); } - GFX_RunLowLatencySDK(D3D11Device(), bUseLowLatencyMode, - bUseLowLatencyBoost, bUseLowLatencyTiming, fpsMax); - CEngineAPI_PumpMessages(); + 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 + } } } @@ -207,6 +236,7 @@ void VSys_Dll2::Attach() const { DetourAttach(&CEngineAPI_Init, &CEngineAPI::VInit); DetourAttach(&CEngineAPI_ModInit, &CEngineAPI::VModInit); + DetourAttach(&CEngineAPI_PumpMessages, &CEngineAPI::PumpMessages); DetourAttach(&CEngineAPI_MainLoop, &CEngineAPI::MainLoop); DetourAttach(&v_CEngineAPI_SetStartupInfo, &CEngineAPI::VSetStartupInfo); } @@ -215,6 +245,7 @@ void VSys_Dll2::Detach() const { DetourDetach(&CEngineAPI_Init, &CEngineAPI::VInit); DetourDetach(&CEngineAPI_ModInit, &CEngineAPI::VModInit); + DetourDetach(&CEngineAPI_PumpMessages, &CEngineAPI::PumpMessages); DetourDetach(&CEngineAPI_MainLoop, &CEngineAPI::MainLoop); DetourDetach(&v_CEngineAPI_SetStartupInfo, &CEngineAPI::VSetStartupInfo); } \ No newline at end of file diff --git a/r5dev/engine/sys_dll2.h b/r5dev/engine/sys_dll2.h index a56e8f3c..edd858bd 100644 --- a/r5dev/engine/sys_dll2.h +++ b/r5dev/engine/sys_dll2.h @@ -34,6 +34,7 @@ public: static bool VModInit(CEngineAPI* pEngineAPI, const char* pModName, const char* pGameDir); static void VSetStartupInfo(CEngineAPI* pEngineAPI, StartupInfo_t* pStartupInfo); + static void PumpMessages(); static bool MainLoop(); //private: void* m_hEditorHWnd; @@ -109,7 +110,7 @@ class VSys_Dll2 : public IDetour p_CEngineAPI_MainLoop = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ?? 84 C0 B9 ?? ?? ?? ??").FollowNearCallSelf(); p_PakFile_Init = g_GameDll.FindPatternSIMD("44 88 44 24 ?? 53 55 56 57"); #endif - p_CEngineAPI_PumpMessages = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 48 81 EC ?? ?? ?? ?? 45 33 C9"); + p_CEngineAPI_PumpMessages = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01 FF 90 ?? ?? ?? ?? 84 C0 75 7F").FollowNearCallSelf(); p_CEngineAPI_SetStartupInfo = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? ?? 48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 48 8B DA"); p_ResetMTVFTaskItem = g_GameDll.FindPatternSIMD("48 83 EC 28 48 8B 15 ?? ?? ?? ?? 48 85 D2 0F 84 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B 01 FF 90 ?? ?? ?? ?? 33 C9 E8 ?? ?? ?? ?? 0F 28 05 ?? ?? ?? ?? 0F 28 0D ?? ?? ?? ?? 0F 11 05 ?? ?? ?? ?? 0F 28 05 ?? ?? ?? ?? 0F 11 0D ?? ?? ?? ?? 0F 28 0D ?? ?? ?? ?? 0F 11 05 ?? ?? ?? ?? 0F 11 0D ?? ?? ?? ?? 48 C7 05 ?? ?? ?? ?? ?? ?? ?? ?? FF 15 ?? ?? ?? ??"); diff --git a/r5dev/geforce/reflex.cpp b/r5dev/geforce/reflex.cpp index bea44579..c25bb7aa 100644 --- a/r5dev/geforce/reflex.cpp +++ b/r5dev/geforce/reflex.cpp @@ -6,16 +6,75 @@ #include "reflex.h" #include "mathlib/mathlib.h" +// 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. +NvU64 s_ReflexFrameNumber = 0; +NvU64 s_ReflexLastFrameNumber = 0; //----------------------------------------------------------------------------- -// Purpose: runs the low latency sdk +// 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 +//----------------------------------------------------------------------------- +NvU64 GFX_GetFrameNumber(void) +{ + return s_ReflexFrameNumber; +} + +//----------------------------------------------------------------------------- +// Purpose: increments the reflex frame number +//----------------------------------------------------------------------------- +void GFX_IncrementFrameNumber(void) +{ + ++s_ReflexFrameNumber; +} + +//----------------------------------------------------------------------------- +// Purpose: updates the low latency parameters // Input : *device - // useLowLatencyMode - // useLowLatencyBoost - // useMarkersToOptimize - // maxFramesPerSecond - //----------------------------------------------------------------------------- -void GFX_RunLowLatencySDK(IUnknown* device, const bool useLowLatencyMode, +void GFX_UpdateLowLatencyParameters(IUnknown* device, const bool useLowLatencyMode, const bool useLowLatencyBoost, const bool useMarkersToOptimize, const float maxFramesPerSecond) { @@ -32,8 +91,45 @@ void GFX_RunLowLatencySDK(IUnknown* device, const bool useLowLatencyMode, : 0; params.bUseMarkersToOptimize = useMarkersToOptimize; - NvAPI_Status status = NvAPI_D3D_SetSleepMode(device, ¶ms); - - if (status == NVAPI_OK) - NvAPI_D3D_Sleep(device); + s_ReflexModeUpdateStatus = NvAPI_D3D_SetSleepMode(device, ¶ms); + GFX_MarkLowLatencyParametersUpToDate(); +} + +//----------------------------------------------------------------------------- +// Purpose: runs a frame of the low latency sdk +// Input : *device - +//----------------------------------------------------------------------------- +void GFX_RunLowLatencyFrame(IUnknown* device) +{ + NvU64 currentFrameNumber = GFX_GetFrameNumber(); + + if (s_ReflexLastFrameNumber == currentFrameNumber) + return; + + if (GFX_ParameterUpdateWasSuccessful()) + NvAPI_D3D_Sleep(device); + + s_ReflexLastFrameNumber = currentFrameNumber; +} + +//----------------------------------------------------------------------------- +// Purpose: sets the latency marker +// Input : *device - +// frameNumber - +// markerType - +//----------------------------------------------------------------------------- +void GFX_SetLatencyMarker(IUnknown* device, + const NV_LATENCY_MARKER_TYPE 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, ¶ms); + } } diff --git a/r5dev/geforce/reflex.h b/r5dev/geforce/reflex.h index 0e5d0b2c..7bfe745e 100644 --- a/r5dev/geforce/reflex.h +++ b/r5dev/geforce/reflex.h @@ -1,8 +1,19 @@ #ifndef GFSDK_REFLEX_H #define GFSDK_REFLEX_H -void GFX_RunLowLatencySDK(IUnknown* device, const bool useLowLatencyMode, +void GFX_MarkLowLatencyParametersOutOfDate(void); +bool GFX_HasPendingLowLatencyParameterUpdates(void); + +NvU64 GFX_GetFrameNumber(void); +void GFX_IncrementFrameNumber(void); + +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); + #endif // GFSDK_REFLEX_H diff --git a/r5dev/materialsystem/cmaterialsystem.h b/r5dev/materialsystem/cmaterialsystem.h index 185b75e1..29acbefd 100644 --- a/r5dev/materialsystem/cmaterialsystem.h +++ b/r5dev/materialsystem/cmaterialsystem.h @@ -1,6 +1,7 @@ #ifndef MATERIALSYSTEM_H #define MATERIALSYSTEM_H #include "cmaterialglue.h" +#include "public/imaterialsystem.h" #define STREAM_DB_EXT "stbsp" @@ -14,11 +15,47 @@ public: #endif // !MATERIALSYSTEM_NODX }; +#ifndef MATERIALSYSTEM_NODX +class CMaterialDeviceMgr +{ +public: + inline const MaterialAdapterInfo_t& GetAdapterInfo(int nIndex) const + { + Assert(nIndex >= 0 && nIndex < SDK_ARRAYSIZE(m_AdapterInfo)); + return m_AdapterInfo[nIndex]; + } + inline const MaterialAdapterInfo_t& GetAdapterInfo() const + { + // Retrieve info of the selected adapter. + return GetAdapterInfo(m_SelectedAdapter); + } + +private: + enum + { + MAX_ADAPTER_COUNT = 4 + }; + + IDXGIAdapter* m_Adapters[MAX_ADAPTER_COUNT]; + void* m_pUnknown1[MAX_ADAPTER_COUNT]; + MaterialAdapterInfo_t m_AdapterInfo[MAX_ADAPTER_COUNT]; + size_t m_AdapterMemorySize[MAX_ADAPTER_COUNT]; + int m_NumDisplayAdaptersProcessed; + int m_SelectedAdapter; + int m_NumDisplayAdapters; +}; + +inline CMaterialDeviceMgr* g_pMaterialAdapterMgr = nullptr; +#endif // !MATERIALSYSTEM_NODX + /* ==== MATERIALSYSTEM ================================================================================================================================================== */ inline CMemory p_CMaterialSystem__Init; inline InitReturnVal_t(*CMaterialSystem__Init)(CMaterialSystem* thisptr); -inline void* g_pMaterialSystem = nullptr; +inline CMemory p_CMaterialSystem__Disconnect; +inline void(*CMaterialSystem__Disconnect)(void); + +inline CMaterialSystem* g_pMaterialSystem = nullptr; inline void* g_pMaterialVFTable = nullptr; #ifndef MATERIALSYSTEM_NODX inline CMemory p_CMaterialSystem__FindMaterialEx; @@ -54,6 +91,7 @@ class VMaterialSystem : public IDetour { LogConAdr("CMaterial::`vftable'", reinterpret_cast(g_pMaterialVFTable)); LogFunAdr("CMaterialSystem::Init", p_CMaterialSystem__Init.GetPtr()); + LogFunAdr("CMaterialSystem::Disconnect", p_CMaterialSystem__Disconnect.GetPtr()); #ifndef MATERIALSYSTEM_NODX LogFunAdr("CMaterialSystem::FindMaterialEx", p_CMaterialSystem__FindMaterialEx.GetPtr()); LogFunAdr("CMaterialSystem::GetScreenSize", p_CMaterialSystem_GetScreenSize.GetPtr()); @@ -64,6 +102,7 @@ class VMaterialSystem : public IDetour LogVarAdr("g_nUnfreeStreamingTextureMemory", reinterpret_cast(g_nUnfreeStreamingTextureMemory)); LogVarAdr("g_nUnusableStreamingTextureMemory", reinterpret_cast(g_nUnusableStreamingTextureMemory)); LogVarAdr("s_pRenderContext", s_pRenderContext.GetPtr()); + LogVarAdr("g_MaterialAdapterMgr", reinterpret_cast(g_pMaterialAdapterMgr)); #endif // !MATERIALSYSTEM_NODX LogVarAdr("g_pMaterialSystem", reinterpret_cast(g_pMaterialSystem)); } @@ -71,6 +110,9 @@ class VMaterialSystem : public IDetour { p_CMaterialSystem__Init = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 56 57 41 54 41 55 41 56 41 57 48 83 EC 70 48 83 3D ?? ?? ?? ?? ??"); CMaterialSystem__Init = p_CMaterialSystem__Init.RCast(); /*48 89 5C 24 ?? 55 56 57 41 54 41 55 41 56 41 57 48 83 EC 70 48 83 3D ?? ?? ?? ?? ??*/ + + p_CMaterialSystem__Disconnect = g_GameDll.FindPatternSIMD("48 83 EC 28 8B 0D ?? ?? ?? ?? 48 89 6C 24 ??"); + CMaterialSystem__Disconnect = p_CMaterialSystem__Disconnect.RCast(); #ifndef MATERIALSYSTEM_NODX p_CMaterialSystem__FindMaterialEx = g_GameDll.FindPatternSIMD("44 89 4C 24 ?? 44 88 44 24 ?? 48 89 4C 24 ??"); CMaterialSystem__FindMaterialEx = p_CMaterialSystem__FindMaterialEx.RCast(); /*44 89 4C 24 ?? 44 88 44 24 ?? 48 89 4C 24 ??*/ @@ -99,8 +141,9 @@ class VMaterialSystem : public IDetour g_nUnusableStreamingTextureMemory = p_DrawStreamOverlay.Offset(0x50).FindPatternSelf("48 8B 05", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); s_pRenderContext = p_DispatchDrawCall.FindPattern("48 8B ?? ?? ?? ?? 01").ResolveRelativeAddressSelf(0x3, 0x7); + g_pMaterialAdapterMgr = p_CMaterialSystem__Disconnect.FindPattern("48 8D").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); #endif // !MATERIALSYSTEM_NODX - g_pMaterialSystem = g_GameDll.FindPatternSIMD("48 8B 0D ?? ?? ?? ?? 48 85 C9 74 11 48 8B 01 48 8D 15 ?? ?? ?? ??").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + g_pMaterialSystem = g_GameDll.FindPatternSIMD("48 8B 0D ?? ?? ?? ?? 48 85 C9 74 11 48 8B 01 48 8D 15 ?? ?? ?? ??").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); } virtual void GetCon(void) const { 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; diff --git a/r5dev/public/imaterialsystem.h b/r5dev/public/imaterialsystem.h index ce26761c..3fa72fc7 100644 --- a/r5dev/public/imaterialsystem.h +++ b/r5dev/public/imaterialsystem.h @@ -1,6 +1,30 @@ #ifndef IMATERIALSYSTEM_H #define IMATERIALSYSTEM_H +#define NVIDIA_VENDOR_ID 0x10DE + +//----------------------------------------------------------------------------- +// Material adapter info.. +//----------------------------------------------------------------------------- +struct MaterialAdapterInfo_t +{ + enum + { + MATERIAL_ADAPTER_NAME_LENGTH = 512 + }; + + char m_pDriverName[MATERIAL_ADAPTER_NAME_LENGTH]; + unsigned int m_VendorID; + unsigned int m_DeviceID; + unsigned int m_SubSysID; + unsigned int m_Revision; + int m_nDXSupportLevel; // This is the *preferred* dx support level + int m_nMinDXSupportLevel; + int m_nMaxDXSupportLevel; + unsigned int m_nDriverVersionHigh; + unsigned int m_nDriverVersionLow; +}; + //----------------------------------------------------------------------------- // Video mode info.. //----------------------------------------------------------------------------- diff --git a/r5dev/public/tier0/sigcache.h b/r5dev/public/tier0/sigcache.h index 91431c4a..61b31d14 100644 --- a/r5dev/public/tier0/sigcache.h +++ b/r5dev/public/tier0/sigcache.h @@ -7,7 +7,7 @@ #define SIGDB_DICT_SIZE 20 #define SIGDB_MAJOR_VERSION 0x2 // Increment when library changes are made. -#define SIGDB_MINOR_VERSION 0x6 // Increment when SDK updates are released. +#define SIGDB_MINOR_VERSION 0x7 // Increment when SDK updates are released. class CSigCache { diff --git a/r5dev/windows/id3dx.cpp b/r5dev/windows/id3dx.cpp index 48b09424..14b335a9 100644 --- a/r5dev/windows/id3dx.cpp +++ b/r5dev/windows/id3dx.cpp @@ -6,6 +6,7 @@ #include "tier1/cvar.h" #include "windows/id3dx.h" #include "windows/input.h" +#include "geforce/reflex.h" #include "gameui/IConsole.h" #include "gameui/IBrowser.h" #include "engine/framelimit.h" @@ -143,6 +144,7 @@ HRESULT __stdcall Present(IDXGISwapChain* pSwapChain, UINT nSyncInterval, UINT n g_FrameLimiter.Run(); DrawImGui(); /////////////////////////////////////////////////////////////////////////////// + HRESULT result = s_fnSwapChainPresent(pSwapChain, nSyncInterval, nFlags); return result; }