diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ebcb530a..928411f1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,6 +16,7 @@ add_subdirectory( vphysics ) add_subdirectory( ebisusdk ) add_subdirectory( codecs ) add_subdirectory( geforce ) +add_subdirectory( radeon ) set( FOLDER_CONTEXT "Protocols" ) add_subdirectory( protoc ) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ea40638b..b2b31069 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -91,6 +91,7 @@ target_link_libraries( ${PROJECT_NAME} PRIVATE "datacache" "EbisuSDK" "GFSDK" + "RDSDK" "localize" diff --git a/src/core/stdafx.h b/src/core/stdafx.h index 108f4f6d..edcc83a8 100644 --- a/src/core/stdafx.h +++ b/src/core/stdafx.h @@ -44,6 +44,8 @@ #include "thirdparty/nvapi/pclstats.h" #include "thirdparty/nvapi/nvapi.h" #include "thirdparty/nvapi/nvapi_lite_common.h" + +#include "thirdparty/fidelityfx/ffx_antilag2_dx11.h" #endif // !DEDICATED && !PLUGINSDK diff --git a/src/engine/sys_dll2.cpp b/src/engine/sys_dll2.cpp index 16d10dbf..5ff022cf 100644 --- a/src/engine/sys_dll2.cpp +++ b/src/engine/sys_dll2.cpp @@ -23,6 +23,7 @@ #include "windows/id3dx.h" #include "client/vengineclient_impl.h" #include "geforce/reflex.h" +#include "radeon/antilag.h" #endif // !DEDICATED #include "filesystem/filesystem.h" constexpr char DFS_ENABLE_PATH[] = "/vpk/enable.txt"; @@ -182,14 +183,40 @@ static void GFX_NVN_Changed_f(IConVar* pConVar, const char* pOldString, float fl GeForce_MarkLowLatencyParametersOutOfDate(); } -static ConVar fps_max_gfx("fps_max_nvn", "0", FCVAR_RELEASE, "Frame rate limiter using NVIDIA Reflex Low Latency SDK. -1 indicates the use of desktop refresh. 0 is disabled.", true, -1.f, true, 295.f, GFX_NVN_Changed_f); +static void GFX_FFX_Changed_f(IConVar* pConVar, const char* pOldString, float flOldValue, ChangeUserData_t pUserData) +{ + const ConVar* pConVarRef = g_pCVar->FindVar(pConVar->GetName()); + Radeon_EnableLowLatencySDK(pConVarRef->GetBool()); +} + +static ConVar fps_max_low_latency("fps_max_low_latency", "0", FCVAR_RELEASE, "Frame rate limiter using Low Latency SDK. -1 indicates the use of desktop refresh. 0 is disabled.", true, -1.f, true, 295.f, GFX_NVN_Changed_f); + static ConVar gfx_nvnUseLowLatency("gfx_nvnUseLowLatency", "1", FCVAR_RELEASE | FCVAR_ARCHIVE, "Enables NVIDIA Reflex Low Latency SDK.", GFX_NVN_Changed_f); static ConVar gfx_nvnUseLowLatencyBoost("gfx_nvnUseLowLatencyBoost", "0", FCVAR_RELEASE | FCVAR_ARCHIVE, "Enables NVIDIA Reflex Low Latency Boost.", GFX_NVN_Changed_f); // NOTE: defaulted to 0 as it causes rubber banding on some hardware. static ConVar gfx_nvnUseMarkersToOptimize("gfx_nvnUseMarkersToOptimize", "0", FCVAR_RELEASE, "Use NVIDIA Reflex Low Latency markers to optimize (requires Low Latency Boost to be enabled).", GFX_NVN_Changed_f); + +static ConVar gfx_ffxUseLowLatency("gfx_ffxUseLowLatency", "1", FCVAR_RELEASE | FCVAR_ARCHIVE, "Enables AMD Anti-Lag 2 Low Latency SDK.", GFX_FFX_Changed_f); #endif // !DEDICATED +static float NormalizeFrameRate(const float fpsMax) +{ + if (fpsMax != -1.0f) + return fpsMax; + + const float globalFps = fps_max->GetFloat(); + + // Make sure the global fps limiter is 'unlimited' + // before we let the low-latency 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) + return g_pGame->GetTVRefreshRate(); + else + return 0.0f; // Don't let the low-latency SDK limit the frame rate. +} + void CEngineAPI::UpdateLowLatencyParameters() { #ifndef DEDICATED @@ -197,21 +224,7 @@ void CEngineAPI::UpdateLowLatencyParameters() const bool bUseLowLatencyBoost = gfx_nvnUseLowLatencyBoost.GetBool(); const bool bUseMarkersToOptimize = gfx_nvnUseMarkersToOptimize.GetBool(); - 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. - } + const float fpsMax = NormalizeFrameRate(fps_max_low_latency.GetFloat()); GeForce_UpdateLowLatencyParameters(D3D11Device(), bUseLowLatencyMode, bUseLowLatencyBoost, bUseMarkersToOptimize, fpsMax); @@ -230,6 +243,12 @@ void CEngineAPI::RunLowLatencyFrame() GeForce_RunLowLatencyFrame(D3D11Device()); } + + if (Radeon_IsLowLatencySDKAvailable()) + { + const float maxFps = NormalizeFrameRate(fps_max_low_latency.GetFloat()); + Radeon_RunLowLatencyFrame((unsigned int)maxFps); + } #endif // !DEDICATED } @@ -266,7 +285,7 @@ bool CEngineAPI::MainLoop() if (g_pEngine->Frame()) { #ifndef DEDICATED - // Only run reflex if we ran an actual engine frame. + // Only run low-latency if we ran an actual engine frame. bRunLowLatency = true; #endif // !DEDICATED } diff --git a/src/materialsystem/cmaterialsystem.cpp b/src/materialsystem/cmaterialsystem.cpp index 39cdda92..eb9d375e 100644 --- a/src/materialsystem/cmaterialsystem.cpp +++ b/src/materialsystem/cmaterialsystem.cpp @@ -12,6 +12,7 @@ #include "engine/cmodel_bsp.h" #include "engine/sys_engine.h" #include "geforce/reflex.h" +#include "radeon/antilag.h" #ifndef MATERIALSYSTEM_NODX #include "gameui/imgui_system.h" #include "materialsystem/cmaterialglue.h" @@ -33,6 +34,10 @@ void CMaterialSystem::Disconnect(CMaterialSystem* thisptr) CMaterialSystem__Disconnect(thisptr); } +#ifndef MATERIALSYSTEM_NODX +static bool s_useLowLatency = false; +#endif + //----------------------------------------------------------------------------- // Purpose: initialization of the material system //----------------------------------------------------------------------------- @@ -49,10 +54,14 @@ InitReturnVal_t CMaterialSystem::Init(CMaterialSystem* thisptr) return INIT_FAILED; #else // Initialize as usual. - GeForce_EnableLowLatencySDK(!CommandLine()->CheckParm("-gfx_nvnDisableLowLatency")); + s_useLowLatency = !CommandLine()->CheckParm("-gfx_disableLowLatency"); - if (GeForce_IsLowLatencySDKEnabled()) + GeForce_EnableLowLatencySDK(s_useLowLatency); + Radeon_EnableLowLatencySDK(s_useLowLatency); + + if (s_useLowLatency) { + Radeon_InitLowLatencySDK(); PCLSTATS_INIT(0); } @@ -66,9 +75,10 @@ InitReturnVal_t CMaterialSystem::Init(CMaterialSystem* thisptr) int CMaterialSystem::Shutdown(CMaterialSystem* thisptr) { #ifndef MATERIALSYSTEM_NODX - if (GeForce_IsLowLatencySDKEnabled()) + if (s_useLowLatency) { PCLSTATS_SHUTDOWN(); + Radeon_ShutdownLowLatencySDK(); } #endif diff --git a/src/radeon/CMakeLists.txt b/src/radeon/CMakeLists.txt new file mode 100644 index 00000000..8431f7ab --- /dev/null +++ b/src/radeon/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required( VERSION 3.16 ) +add_module( "lib" "RDSDK" "vpc" ${FOLDER_CONTEXT} TRUE TRUE ) + +start_sources() + +add_sources( SOURCE_GROUP "Runtime" + "antilag.cpp" + "antilag.h" +) + +end_sources() + +target_include_directories( ${PROJECT_NAME} PRIVATE "${ENGINE_SOURCE_DIR}/tier0/" "${ENGINE_SOURCE_DIR}/tier1/" ) diff --git a/src/radeon/antilag.cpp b/src/radeon/antilag.cpp new file mode 100644 index 00000000..453cddff --- /dev/null +++ b/src/radeon/antilag.cpp @@ -0,0 +1,68 @@ +//===========================================================================// +// +// Purpose: AMD Anti-Lag 2 utilities +// +//===========================================================================// +#include "antilag.h" +#include "mathlib/mathlib.h" +#include "materialsystem/cmaterialsystem.h" + +static bool s_LowLatencySDKEnabled = false; + +// This will be true if the call to 'AMD::AntiLag2DX11::Initialize' succeeds. +static bool s_LowLatencyAvailable = false; + +static AMD::AntiLag2DX11::Context s_LowLatencyContext = {}; + +//----------------------------------------------------------------------------- +// Purpose: enable/disable low latency SDK +// Input : enable - +//----------------------------------------------------------------------------- +void Radeon_EnableLowLatencySDK(const bool enable) +{ + s_LowLatencySDKEnabled = enable; +} + +//----------------------------------------------------------------------------- +// Purpose: whether we should run the low latency SDK +//----------------------------------------------------------------------------- +bool Radeon_IsLowLatencySDKAvailable(void) +{ + if (!s_LowLatencyAvailable) + return false; + + const MaterialAdapterInfo_t& adapterInfo = g_pMaterialAdapterMgr->GetAdapterInfo(); + // Only run on AMD display drivers; NVIDIA and Intel are not + // supported by AMD Anti-Lag 2. + return adapterInfo.m_VendorID == AMD_VENDOR_ID; +} + +//----------------------------------------------------------------------------- +// Purpose: initialize the low latency SDK +//----------------------------------------------------------------------------- +bool Radeon_InitLowLatencySDK(void) +{ + if (AMD::AntiLag2DX11::Initialize(&s_LowLatencyContext) == S_OK) + s_LowLatencyAvailable = true; + + return s_LowLatencyAvailable; +} + +//----------------------------------------------------------------------------- +// Purpose: shutdown the low latency SDK +//----------------------------------------------------------------------------- +void Radeon_ShutdownLowLatencySDK() +{ + if (AMD::AntiLag2DX11::DeInitialize(&s_LowLatencyContext) == 0) + s_LowLatencyAvailable = false; +} + +//----------------------------------------------------------------------------- +// Purpose: runs a frame of the low latency sdk +// Input : maxFPS - +//----------------------------------------------------------------------------- +void Radeon_RunLowLatencyFrame(const unsigned int maxFPS) +{ + Assert(Radeon_IsLowLatencySDKAvailable()); + AMD::AntiLag2DX11::Update(&s_LowLatencyContext, s_LowLatencySDKEnabled, maxFPS); +} diff --git a/src/radeon/antilag.h b/src/radeon/antilag.h new file mode 100644 index 00000000..15c65769 --- /dev/null +++ b/src/radeon/antilag.h @@ -0,0 +1,12 @@ +#ifndef RDSDK_ANTILAG_H +#define RDSDK_ANTILAG_H + +void Radeon_EnableLowLatencySDK(const bool enable); +bool Radeon_IsLowLatencySDKAvailable(void); + +bool Radeon_InitLowLatencySDK(); +void Radeon_ShutdownLowLatencySDK(); + +void Radeon_RunLowLatencyFrame(const unsigned int maxFPS); + +#endif // RDSDK_ANTILAG_H