From 5dfedd68365cb1f6fa96b769671bfefd287a7086 Mon Sep 17 00:00:00 2001
From: FakeMichau <49685661+FakeMichau@users.noreply.github.com>
Date: Fri, 23 Oct 2026 02:01:18 +0200
Subject: [PATCH] Lobotomize fakenvapi
Alternative titles: complete the move of low latency code out of fakenvapi
---
OptiScaler/OptiScaler.vcxproj | 4 -
OptiScaler/OptiScaler.vcxproj.filters | 12 -
OptiScaler/State.h | 1 -
OptiScaler/hooks/Reflex_Hooks.cpp | 55 +--
OptiScaler/low_latency/input/input_common.cpp | 28 +-
OptiScaler/low_latency/input/input_common.h | 8 +-
OptiScaler/low_latency/input/input_reflex.cpp | 4 +-
.../low_latency_tech/ll_reflex.cpp | 4 +-
OptiScaler/menu/menu_common.cpp | 76 +---
OptiScaler/nvapi/NvApiHooks.cpp | 10 -
OptiScaler/nvapi/fakenvapi.cpp | 73 ----
OptiScaler/nvapi/fakenvapi.h | 12 -
OptiScaler/nvapi/fakenvapi/low_latency.cpp | 79 -----
OptiScaler/nvapi/fakenvapi/low_latency.h | 80 -----
.../nvapi/fakenvapi/low_latency_d3d.cpp | 327 ------------------
OptiScaler/nvapi/fakenvapi/low_latency_vk.cpp | 238 -------------
OptiScaler/nvapi/fakenvapi/nvapi_calls.cpp | 152 +-------
OptiScaler/nvapi/fakenvapi/nvapi_calls.h | 20 --
18 files changed, 47 insertions(+), 1136 deletions(-)
delete mode 100644 OptiScaler/nvapi/fakenvapi/low_latency.cpp
delete mode 100644 OptiScaler/nvapi/fakenvapi/low_latency.h
delete mode 100644 OptiScaler/nvapi/fakenvapi/low_latency_d3d.cpp
delete mode 100644 OptiScaler/nvapi/fakenvapi/low_latency_vk.cpp
diff --git a/OptiScaler/OptiScaler.vcxproj b/OptiScaler/OptiScaler.vcxproj
index b350356d..8dfeda69 100644
--- a/OptiScaler/OptiScaler.vcxproj
+++ b/OptiScaler/OptiScaler.vcxproj
@@ -270,7 +270,6 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
-
@@ -618,8 +617,6 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
-
-
@@ -627,7 +624,6 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
-
diff --git a/OptiScaler/OptiScaler.vcxproj.filters b/OptiScaler/OptiScaler.vcxproj.filters
index 9ee36ec7..aeb98ce6 100644
--- a/OptiScaler/OptiScaler.vcxproj.filters
+++ b/OptiScaler/OptiScaler.vcxproj.filters
@@ -806,9 +806,6 @@
Header Files
-
- Header Files
-
Header Files
@@ -1604,12 +1601,6 @@
Source Files
-
- Source Files
-
-
- Source Files
-
Source Files
@@ -1631,9 +1622,6 @@
Source Files
-
- Source Files
-
Source Files
diff --git a/OptiScaler/State.h b/OptiScaler/State.h
index deb6ebd8..5fda0959 100644
--- a/OptiScaler/State.h
+++ b/OptiScaler/State.h
@@ -278,7 +278,6 @@ class State
bool reflexLimitsFps = false;
bool reflexShowWarning = false;
bool rtssReflexInjection = false;
- bool fakenvapiReloadLowLatency = false;
UINT64 reflexFrameId = 0;
UINT64 frameCount = 0;
bool vkAntiLagSupported = false;
diff --git a/OptiScaler/hooks/Reflex_Hooks.cpp b/OptiScaler/hooks/Reflex_Hooks.cpp
index 64d5271d..6125fc89 100644
--- a/OptiScaler/hooks/Reflex_Hooks.cpp
+++ b/OptiScaler/hooks/Reflex_Hooks.cpp
@@ -2,8 +2,6 @@
#include "Reflex_Hooks.h"
#include
-#include
-
#include
#include
@@ -537,8 +535,7 @@ void ReflexHooks::update(bool fgActive, bool isVulkan)
if (isVulkan && _lastVkSleepDev)
{
// fgActive doesn't matter for vulkan
- // isUsingAsMainNvapi() because fakenvapi might override the reflex' setting and we don't know it
- State::Instance().reflexLimitsFps = fakenvapi::isUsingAsMainNvapi() || _lastVkSleepParams.bLowLatencyMode;
+ State::Instance().reflexLimitsFps = _lastVkSleepParams.bLowLatencyMode;
}
else if (!reflexOutput)
{
@@ -548,33 +545,17 @@ void ReflexHooks::update(bool fgActive, bool isVulkan)
else if (_lastSleepDev)
{
// Don't use when: Real Reflex markers + FSR FG + Reflex disabled, causes huge input latency
- State::Instance().reflexLimitsFps =
- fakenvapi::isUsingAsMainNvapi() || !fgActive || _lastSleepParams.bLowLatencyMode;
- State::Instance().reflexShowWarning = State::Instance().activeFgOutput == FGOutput::FSRFG &&
- !fakenvapi::isUsingAsMainNvapi() && fgActive &&
- _lastSleepParams.bLowLatencyMode;
+ State::Instance().reflexLimitsFps = !fgActive || _lastSleepParams.bLowLatencyMode;
+ State::Instance().reflexShowWarning =
+ State::Instance().activeFgOutput == FGOutput::FSRFG && fgActive && _lastSleepParams.bLowLatencyMode;
}
else
{
State::Instance().reflexLimitsFps = false;
}
- // Disable reflex fps limiting when reflex is force disabled
- // TODO: It changes without pressing apply, XeLL with XeFG can't actually be disabled so this is wrong
- //
- // Wait for fakenvapi to be merged into Opti for better integration
- //
- // if (State::Instance().reflexLimitsFps && (fakenvapi::isUsingAsMainNvapi() ||
- // fakenvapi::isUsingOnNvidia())
- // &&
- // Config::Instance()->FN_ForceReflex.value_or_default() == 1)
- //{
- // State::Instance().reflexLimitsFps = false;
- //}
-
static float lastFps = 0;
static bool lastReflexLimitsFps = State::Instance().reflexLimitsFps;
- static LowLatencyMode lastLowLatencyMode = fakenvapi::getCurrentMode();
// Reset required when toggling Reflex
if (State::Instance().reflexLimitsFps != lastReflexLimitsFps)
@@ -583,12 +564,6 @@ void ReflexHooks::update(bool fgActive, bool isVulkan)
lastFps = 0;
setFPSLimit(0);
}
- else if (fakenvapi::isUsingAsMainNvapi() && lastLowLatencyMode != fakenvapi::getCurrentMode())
- {
- lastLowLatencyMode = fakenvapi::getCurrentMode();
- lastFps = 0;
- setFPSLimit(0);
- }
if (!State::Instance().reflexLimitsFps)
return;
@@ -599,23 +574,6 @@ void ReflexHooks::update(bool fgActive, bool isVulkan)
if (lastFgNumFramesToGenerate != _FgNumFramesToGenerate)
{
- if (fakenvapi::isUsingAsMainNvapi())
- {
- // Don't reload when using Dynamic MFG
- if (State::Instance().dlssgLastSetMode != sl::DLSSGMode::eDynamic &&
- !Config::Instance()->FGDLSSGForceDMFG.value_or_default())
- {
- State::Instance().fakenvapiReloadLowLatency = true;
- }
-
- // fakenvapi's latency techs fall apart with Dynamic MFG
- if (Config::Instance()->FN_ForceReflex.value_or_default() != ForceReflex::ForceEnable &&
- State::Instance().dlssgLastSetMode == sl::DLSSGMode::eDynamic)
- {
- Config::Instance()->FN_ForceReflex.set_volatile_value(ForceReflex::ForceDisable);
- }
- }
-
lastFgNumFramesToGenerate = _FgNumFramesToGenerate;
setFPSLimit(currentFps);
@@ -635,11 +593,6 @@ void ReflexHooks::update(bool fgActive, bool isVulkan)
if (!driverCountsFg)
currentFps /= 2;
}
- else if (_FgNumFramesToGenerate > 0 && fakenvapi::isUsingAsMainNvapi() &&
- fakenvapi::getCurrentMode() != LowLatencyMode::XeLL)
- {
- currentFps /= (_FgNumFramesToGenerate + 1);
- }
if (currentFps != lastFps)
{
diff --git a/OptiScaler/low_latency/input/input_common.cpp b/OptiScaler/low_latency/input/input_common.cpp
index ad6a94c4..07f8d4d7 100644
--- a/OptiScaler/low_latency/input/input_common.cpp
+++ b/OptiScaler/low_latency/input/input_common.cpp
@@ -145,7 +145,7 @@ LowLatencyMode InputCommon::default_output(API api)
if (vendorId == VendorId::AMD && VulkanHooks::o_vkAntiLagUpdateAMD != nullptr)
return LowLatencyMode::AntiLagVk;
- if (vendorId == VendorId::Nvidia && VulkanHooks::o_vkSetLatencySleepModeNV != nullptr)
+ if (driver_reflex_available(api))
return LowLatencyMode::Reflex;
return LowLatencyMode::LatencyFlex;
@@ -158,7 +158,7 @@ LowLatencyMode InputCommon::default_output(API api)
if (vendorId == VendorId::AMD)
return LowLatencyMode::AntiLag2;
- if (vendorId == VendorId::Nvidia && !fakenvapi::isUsingAsMainNvapi())
+ if (driver_reflex_available(api))
return LowLatencyMode::Reflex;
return LowLatencyMode::LatencyFlex;
@@ -166,21 +166,29 @@ LowLatencyMode InputCommon::default_output(API api)
const char* InputCommon::output_unavailable(LowLatencyMode output, API api)
{
- auto vendorId = IdentifyGpu::getPrimaryGpu().vendorId;
+ if (output == LowLatencyMode::Reflex && !driver_reflex_available(api))
+ return api == API::Vulkan ? "Needs an Nvidia GPU with VK_NV_low_latency2" : "Needs an Nvidia GPU";
- // On D3D the driver's Reflex is reached through nvapi, fakenvapi's is a translation of its own
- if (output == LowLatencyMode::Reflex &&
- (vendorId != VendorId::Nvidia || (api != API::Vulkan && fakenvapi::isUsingAsMainNvapi())))
- {
- return "Needs an Nvidia GPU";
- }
+ if (output == LowLatencyMode::AntiLagVk && VulkanHooks::o_vkAntiLagUpdateAMD == nullptr)
+ return "Needs an AMD GPU with VK_AMD_anti_lag";
- if ((output == LowLatencyMode::AntiLag2 || output == LowLatencyMode::AntiLagVk) && vendorId != VendorId::AMD)
+ if (output == LowLatencyMode::AntiLag2 && IdentifyGpu::getPrimaryGpu().vendorId != VendorId::AMD)
return "Needs an AMD GPU";
return nullptr;
}
+bool InputCommon::driver_reflex_available(API api)
+{
+ if (IdentifyGpu::getPrimaryGpu().vendorId != VendorId::Nvidia)
+ return false;
+
+ if (api == API::Vulkan)
+ return VulkanHooks::o_vkSetLatencySleepModeNV != nullptr;
+
+ return !fakenvapi::isUsingAsMainNvapi();
+}
+
LowLatencyMode InputCommon::for_api(LowLatencyMode mode, API api)
{
if (api == API::Vulkan && mode == LowLatencyMode::AntiLag2)
diff --git a/OptiScaler/low_latency/input/input_common.h b/OptiScaler/low_latency/input/input_common.h
index 72572b49..6b9fcd6c 100644
--- a/OptiScaler/low_latency/input/input_common.h
+++ b/OptiScaler/low_latency/input/input_common.h
@@ -193,10 +193,14 @@ class InputCommon
// The GPU vendor's own low latency output
static LowLatencyMode default_output(API api);
- // Why the GPU can't run the output, nullptr when it can: Reflex needs an Nvidia GPU (and its nvapi on D3D),
- // AntiLag 2 an AMD GPU
+ // Why the GPU can't run the output, nullptr when it can: Reflex needs the driver's Reflex, AntiLag an AMD GPU
+ // (and VK_AMD_anti_lag on Vulkan)
static const char* output_unavailable(LowLatencyMode output, API api);
+ // The driver's Reflex: an Nvidia GPU with its nvapi on D3D (fakenvapi's isn't Reflex), with VK_NV_low_latency2
+ // on Vulkan
+ static bool driver_reflex_available(API api);
+
// Why the input can't drive the output, nullptr when it can
static const char* incompatibility(LowLatencyInput input, LowLatencyMode output);
diff --git a/OptiScaler/low_latency/input/input_reflex.cpp b/OptiScaler/low_latency/input/input_reflex.cpp
index b6138c99..bcc4c84f 100644
--- a/OptiScaler/low_latency/input/input_reflex.cpp
+++ b/OptiScaler/low_latency/input/input_reflex.cpp
@@ -23,7 +23,7 @@ static bool FromOptiScaler(void* returnAddress)
// With NVIDIA's nvapi OptiScaler's Streamline reaches the driver, with fakenvapi it's the OptiScaler input
template static Fn ToDriver(unsigned int id)
{
- if (fakenvapi::isUsingAsMainNvapi())
+ if (!InputCommon::driver_reflex_available(API::DX12))
return nullptr;
return reinterpret_cast(ReflexHooks::getHookedReflex(id));
@@ -79,7 +79,7 @@ NvAPI_Status InputReflex::D3D_GetSleepStatus(IUnknown* pDevice, NV_GET_SLEEP_STA
bool own = FromOptiScaler(_ReturnAddress());
- if (own && !fakenvapi::isUsingAsMainNvapi() && NvApiHooks::o_NvAPI_QueryInterface != nullptr)
+ if (own && InputCommon::driver_reflex_available(API::DX12) && NvApiHooks::o_NvAPI_QueryInterface != nullptr)
{
if (auto driver = GET_INTERFACE(NvAPI_D3D_GetSleepStatus, NvApiHooks::o_NvAPI_QueryInterface))
return driver(pDevice, pGetSleepStatusParams);
diff --git a/OptiScaler/low_latency/low_latency_tech/ll_reflex.cpp b/OptiScaler/low_latency/low_latency_tech/ll_reflex.cpp
index b06bae10..c88b187c 100644
--- a/OptiScaler/low_latency/low_latency_tech/ll_reflex.cpp
+++ b/OptiScaler/low_latency/low_latency_tech/ll_reflex.cpp
@@ -3,6 +3,7 @@
#include
#include
+#include
bool Reflex::init(IUnknown* pDevice)
{
@@ -12,8 +13,7 @@ bool Reflex::init(IUnknown* pDevice)
if (NvApiHooks::o_NvAPI_QueryInterface == nullptr)
LibraryLoadHooks::LoadNvApi();
- // fakenvapi's Reflex is a translation of its own, only the driver's is Reflex
- if (NvApiHooks::o_NvAPI_QueryInterface == nullptr || fakenvapi::isUsingAsMainNvapi())
+ if (NvApiHooks::o_NvAPI_QueryInterface == nullptr || !InputCommon::driver_reflex_available(API::DX12))
{
LOG_INFO("Reflex needs NVIDIA's nvapi");
return false;
diff --git a/OptiScaler/menu/menu_common.cpp b/OptiScaler/menu/menu_common.cpp
index 4af1083d..0c34cd72 100644
--- a/OptiScaler/menu/menu_common.cpp
+++ b/OptiScaler/menu/menu_common.cpp
@@ -5864,57 +5864,27 @@ void MenuCommon::RenderFramerateSettings(RenderMenuContext& ctx)
"Framerate", "Uses Reflex when possible\nOn AMD/Intel cards, you can use Fakenvapi to substitute Reflex");
static std::string currentMethod {};
- LowLatencyMode fakenvapiMode = {};
+ const LowLatencyMode activeOutput = InputCommon::active_output();
+
+ // The Reflex output limits through the driver's Reflex
if (state.reflexLimitsFps)
{
- fakenvapiMode = fakenvapi::getCurrentMode();
-
- // The D3D Reflex output limits through the driver's Reflex, fakenvapi's mode is only its own
- LowLatencyInput activeInput {};
- LowLatencyMode activeOutput {};
- InputCommon::get_currently_active(activeInput, activeOutput);
-
- if (activeOutput == LowLatencyMode::Reflex)
- fakenvapiMode = LowLatencyMode::None;
-
- if (fakenvapiMode == LowLatencyMode::AntiLag2)
- currentMethod = "FSR Anti-Lag 2.0";
- else if (fakenvapiMode == LowLatencyMode::LatencyFlex)
- currentMethod = "LatencyFlex";
- else if (fakenvapiMode == LowLatencyMode::XeLL)
- currentMethod = "XeLL";
- else if (fakenvapiMode == LowLatencyMode::AntiLagVk)
- currentMethod = "Vulkan AntiLag";
- else if (fakenvapiMode == LowLatencyMode::None)
- {
- if (fakenvapi::isUsingAsMainNvapi())
- currentMethod = "None";
- else
- currentMethod = "Reflex";
- }
-
- if (state.rtssReflexInjection && fakenvapiMode == LowLatencyMode::AntiLag2 &&
- config->FGOutput.value_or_default() == FGOutput::FSRFG)
- ImGui::TextColored(toneMapColor(ImVec4(1.f, 0.8f, 0.f, 1.f)),
- "Using RTSS Reflex injection with FSR Anti-Lag 2.0 and FSR FG "
- "might cause issues");
+ currentMethod = "Reflex";
}
else if (InputCommon::can_limit_fps())
{
- fakenvapiMode = InputCommon::active_output();
-
// The game's XeFG with its own XeLL
if (InputXeLL::IsNative())
currentMethod = "Game's XeLL";
- else if (fakenvapiMode == LowLatencyMode::AntiLag2)
+ else if (activeOutput == LowLatencyMode::AntiLag2)
currentMethod = "FSR Anti-Lag 2.0";
- else if (fakenvapiMode == LowLatencyMode::LatencyFlex)
+ else if (activeOutput == LowLatencyMode::LatencyFlex)
currentMethod = "LatencyFlex";
- else if (fakenvapiMode == LowLatencyMode::AntiLagVk)
+ else if (activeOutput == LowLatencyMode::AntiLagVk)
currentMethod = "Vulkan AntiLag";
- else if (fakenvapiMode == LowLatencyMode::Reflex)
+ else if (activeOutput == LowLatencyMode::Reflex)
currentMethod = "Reflex";
- else if (fakenvapiMode == LowLatencyMode::FpsLimiter)
+ else if (activeOutput == LowLatencyMode::FpsLimiter)
currentMethod = "FPS Limiter";
else
currentMethod = "XeLL";
@@ -5927,15 +5897,9 @@ void MenuCommon::RenderFramerateSettings(RenderMenuContext& ctx)
if (state.rtssReflexInjection)
currentMethod.append(" (RTSS)");
- const bool fakenvapiInactive = (fakenvapi::isUsingAsMainNvapi() || fakenvapiMode == LowLatencyMode::XeLL) &&
- !fakenvapi::isLowLatencyActive() && state.reflexLimitsFps;
-
- if (fakenvapiInactive)
- currentMethod.append(" (inactive)");
-
ImGui::Text("Current method: %s", currentMethod.c_str());
- if (fakenvapiMode == LowLatencyMode::AntiLag2)
+ if (activeOutput == LowLatencyMode::AntiLag2)
ShowTooltip("FSR Anti-Lag 2.0 is the new name for AntiLag 2\nDon't ask me why");
if (state.reflexShowWarning)
@@ -5978,7 +5942,7 @@ void MenuCommon::RenderFramerateSettings(RenderMenuContext& ctx)
float refreshRateF = static_cast(refreshRate);
// it's fine to use with real reflex, we only care about antilag
- auto fpsLimitTech = fakenvapi::getCurrentMode();
+ auto fpsLimitTech = InputCommon::active_output();
constexpr float margin = 0.3f; // in ms
float frameCap = std::round(10000.f / (1000.f / refreshRateF + margin)) / 10.f;
@@ -6109,8 +6073,6 @@ void MenuCommon::RenderLowLatencySettings(RenderMenuContext& ctx)
const auto api = InputCommon::uses_api();
const bool vulkan = api == API::Vulkan;
const bool outputForced = InputCommon::forced_output().has_value();
- const auto vendorId = IdentifyGpu::getPrimaryGpu().vendorId;
- const bool nvidia = vendorId == VendorId::Nvidia;
// OptiScaler's XeFG paces with XeLL on D3D12 (also for D3D11 games through interop), the GPU's Reflex or
// AntiLag 2 output can sleep instead while XeFG keeps an XeLL context of its own
@@ -6127,22 +6089,12 @@ void MenuCommon::RenderLowLatencySettings(RenderMenuContext& ctx)
option.tooltip = condition ? reason : "";
};
- disable(lowLatencyOutput[(uint32_t) LowLatencyMode::AntiLagVk], VulkanHooks::o_vkAntiLagUpdateAMD == nullptr,
- "Needs an AMD GPU with VK_AMD_anti_lag");
-
- if (vulkan)
+ for (auto mode : { LowLatencyMode::Reflex, LowLatencyMode::AntiLag2, LowLatencyMode::AntiLagVk })
{
- disable(lowLatencyOutput[(uint32_t) LowLatencyMode::Reflex],
- !nvidia || VulkanHooks::o_vkSetLatencySleepModeNV == nullptr,
- "Needs an Nvidia GPU with VK_NV_low_latency2");
- }
- else
- {
- disable(lowLatencyOutput[(uint32_t) LowLatencyMode::Reflex], !nvidia || fakenvapi::isUsingAsMainNvapi(),
- "Needs an Nvidia GPU");
+ auto reason = InputCommon::output_unavailable(mode, api);
+ disable(lowLatencyOutput[(uint32_t) mode], reason != nullptr, reason);
}
- disable(lowLatencyOutput[(uint32_t) LowLatencyMode::AntiLag2], vendorId != VendorId::AMD, "Needs an AMD GPU");
disable(lowLatencyOutput[(uint32_t) LowLatencyMode::LatencyFlex], optiXefg, "Not with XeFG");
lowLatencyOutput[(uint32_t) LowLatencyMode::Auto].label = "Auto";
diff --git a/OptiScaler/nvapi/NvApiHooks.cpp b/OptiScaler/nvapi/NvApiHooks.cpp
index ecc7f372..746c8a52 100644
--- a/OptiScaler/nvapi/NvApiHooks.cpp
+++ b/OptiScaler/nvapi/NvApiHooks.cpp
@@ -263,10 +263,6 @@ void* __stdcall NvApiHooks::hkNvAPI_QueryInterface(unsigned int InterfaceId)
return InputReflex::Vulkan_SetLatencyMarker;
else if (InterfaceId == GET_ID(NvAPI_Vulkan_NotifyOutOfBandVkQueue))
return InputReflex::Vulkan_NotifyOutOfBandVkQueue;
-
- // LOG_DEBUG("counter: {}, hookReflex()", qiCounter);
- ReflexHooks::hookReflex(o_NvAPI_QueryInterface);
- return ReflexHooks::getHookedReflex(InterfaceId);
}
ReflexHooks::hookReflex(o_NvAPI_QueryInterface);
@@ -315,12 +311,6 @@ void NvApiHooks::Hook(HMODULE nvapiModule)
{
LOG_INFO("NvAPI_QueryInterface found, hooking!");
- constexpr bool leanMode = true;
- if (fakenvapi::isUsingAsMainNvapi())
- fakenvapi::init(!leanMode);
- else if (State::Instance().activeFgOutput == FGOutput::XeFG)
- fakenvapi::init(leanMode);
-
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&) o_NvAPI_QueryInterface, hkNvAPI_QueryInterface);
diff --git a/OptiScaler/nvapi/fakenvapi.cpp b/OptiScaler/nvapi/fakenvapi.cpp
index f05c1df2..a5b85831 100644
--- a/OptiScaler/nvapi/fakenvapi.cpp
+++ b/OptiScaler/nvapi/fakenvapi.cpp
@@ -12,20 +12,6 @@
std::unordered_map fakenvapi::idToFuncMapping;
-void fakenvapi::init(bool onlyContext)
-{
- LowLatencyCtx::init();
-
- if (onlyContext)
- return;
-}
-
-void fakenvapi::deinit()
-{
- LowLatencyCtx::get()->deinit_current_tech();
- LowLatencyCtx::shutdown();
-}
-
// names from: https://github.com/SveSop/nvapi_standalone/blob/master/dlls/nvapi/nvapi.c
static NVAPI_INTERFACE_TABLE additional_interface_table[] = { { "NvAPI_Diag_ReportCallStart", 0x33c7358c },
{ "NvAPI_Diag_ReportCallReturn", 0x593e8644 },
@@ -102,11 +88,6 @@ void* __cdecl fakenvapi::queryInterface(NvU32 id)
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_SYS_GetGpuAndOutputIdFromDisplayId)
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D_SetResourceHint)
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D_GetObjectHandleForResource)
- INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D_GetSleepStatus)
- INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D_GetLatency)
- INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D_SetSleepMode)
- INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D_SetLatencyMarker)
- INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D_Sleep)
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D_SetReflexSync)
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D11_IsNvShaderExtnOpCodeSupported)
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D11_BeginUAVOverlap)
@@ -118,14 +99,6 @@ void* __cdecl fakenvapi::queryInterface(NvU32 id)
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx)
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx)
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_NotifyOutOfBandCommandQueue)
- INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_SetAsyncFrameMarker)
- INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_Vulkan_InitLowLatencyDevice)
- INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_Vulkan_DestroyLowLatencyDevice)
- INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_Vulkan_GetSleepStatus)
- INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_Vulkan_SetSleepMode)
- INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_Vulkan_Sleep)
- INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_Vulkan_GetLatency)
- INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_Vulkan_SetLatencyMarker)
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_Vulkan_NotifyOutOfBandVkQueue)
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_DRS_CreateSession)
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_DRS_LoadSettings)
@@ -148,52 +121,6 @@ void* __cdecl fakenvapi::queryInterface(NvU32 id)
// return registry.insert({ id, nullptr }).first->second;
}
-bool fakenvapi::updateModeAndContext()
-{
- LOG_FUNC();
-
- auto lowLatencyCtx = LowLatencyCtx::get();
-
- if (!lowLatencyCtx)
- {
- // Real reflex should fall here and not log
- if (_usingFakenvapiAsMainNvapi)
- LOG_ERROR("Couldn't get low latency context");
-
- return false;
- }
-
- auto result = lowLatencyCtx->get_low_latency_tech_context(&_lowLatencyTechContext, &_lowLatencyMode);
-
- if (!result)
- LOG_TRACE_FAKENVAPI("Can't get Low Latency context from fakenvapi");
-
- return result;
-}
-
-bool fakenvapi::isLowLatencyActive()
-{
- auto lowLatencyCtx = LowLatencyCtx::get();
-
- if (!lowLatencyCtx)
- {
- if (_usingFakenvapiAsMainNvapi)
- LOG_ERROR("Couldn't get low latency context");
-
- return false;
- }
-
- return lowLatencyCtx->is_low_latency_enabled();
-}
-
-LowLatencyMode fakenvapi::getCurrentMode()
-{
- if (updateModeAndContext())
- return _lowLatencyMode;
- else
- return LowLatencyMode::None;
-}
-
bool fakenvapi::isUsingAsMainNvapi() { return _usingFakenvapiAsMainNvapi; }
void fakenvapi::setUsingAsMainNvapi(bool usingAsMain) { _usingFakenvapiAsMainNvapi = usingAsMain; }
diff --git a/OptiScaler/nvapi/fakenvapi.h b/OptiScaler/nvapi/fakenvapi.h
index ca2b7dfb..57457c1c 100644
--- a/OptiScaler/nvapi/fakenvapi.h
+++ b/OptiScaler/nvapi/fakenvapi.h
@@ -8,15 +8,9 @@
class fakenvapi
{
inline static bool _usingFakenvapiAsMainNvapi = false;
- inline static bool _usingOnNvidia = false;
- inline static void* _lowLatencyTechContext = nullptr;
- inline static LowLatencyMode _lowLatencyMode = LowLatencyMode::LatencyFlex;
- inline static HMODULE _dllForNvidia = nullptr;
static std::unordered_map idToFuncMapping;
- static bool updateModeAndContext();
-
static NvAPI_Status __cdecl placeholder()
{
// return OK();
@@ -25,13 +19,7 @@ class fakenvapi
}
public:
- static void init(bool onlyContext);
- static void deinit();
static void* queryInterface(NvU32 id);
- static bool isLowLatencyActive();
-
- static LowLatencyMode getCurrentMode();
-
static bool isUsingAsMainNvapi();
static void setUsingAsMainNvapi(bool usingAsMain);
};
diff --git a/OptiScaler/nvapi/fakenvapi/low_latency.cpp b/OptiScaler/nvapi/fakenvapi/low_latency.cpp
deleted file mode 100644
index 0b19a91d..00000000
--- a/OptiScaler/nvapi/fakenvapi/low_latency.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-#include "pch.h"
-#include "low_latency.h"
-
-// private
-void LowLatency::update_effective_fg_state()
-{
- if (auto current_tech = currently_active_tech.load())
- {
- if (!current_tech)
- return;
-
- current_tech->set_effective_fg_state(fg);
- }
-}
-
-void LowLatency::update_enabled_override()
-{
- if (auto current_tech = currently_active_tech.load())
- {
- if (!current_tech)
- return;
-
- current_tech->set_low_latency_override((ForceReflex) Config::Instance()->FN_ForceReflex.value_or_default());
- }
-}
-
-// public
-bool LowLatency::deinit_current_tech()
-{
- // currently_active_tech becomes nullptr
- // but we need to wait for all users of the old one to release
- auto old_tech = currently_active_tech.exchange(nullptr);
-
- if (old_tech)
- {
- LOG_TRACE("Deiniting current tech");
- while (old_tech.use_count() > 1)
- std::this_thread::yield();
-
- old_tech->deinit();
-
- std::memset(frame_reports, 0, sizeof(frame_reports));
-
- return true;
- }
-
- return false;
-}
-
-bool LowLatency::get_low_latency_tech_context(void** low_latency_context, LowLatencyMode* low_latency_tech)
-{
- if (auto current_tech = currently_active_tech.load())
- {
- if (!current_tech || !low_latency_context || !low_latency_tech)
- return false;
-
- *low_latency_context = current_tech->get_tech_context();
- *low_latency_tech = current_tech->get_mode();
- }
-
- // We are during deinit, don't let app use the context
- if (delay_deinit > 0)
- {
- *low_latency_context = nullptr;
- delay_deinit = 1;
- }
-
- return true;
-}
-
-bool LowLatency::is_low_latency_enabled()
-{
- auto current_tech = currently_active_tech.load();
-
- if (!current_tech)
- return false;
-
- return current_tech->is_enabled();
-}
\ No newline at end of file
diff --git a/OptiScaler/nvapi/fakenvapi/low_latency.h b/OptiScaler/nvapi/fakenvapi/low_latency.h
deleted file mode 100644
index b0baab68..00000000
--- a/OptiScaler/nvapi/fakenvapi/low_latency.h
+++ /dev/null
@@ -1,80 +0,0 @@
-#pragma once
-
-#include "low_latency/low_latency_tech/low_latency_tech.h"
-
-#include
-#include
-
-#include "low_latency/ll_util.h"
-#include
-
-class LowLatency
-{
- private:
- std::atomic> currently_active_tech;
- FrameReport frame_reports[FRAME_REPORTS_BUFFER_SIZE] {};
- bool fg;
- uint32_t delay_deinit = 0;
- SleepMode last_sleep_mode {};
-
- void update_effective_fg_state();
- void update_enabled_override();
-
- // D3D
- bool update_low_latency_tech(IUnknown* pDevice);
- void get_latency_result(NV_LATENCY_RESULT_PARAMS* pGetLatencyParams);
- void add_marker_to_report(NV_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams);
-
- // Vulkan
- bool update_low_latency_tech(HANDLE vkDevice);
- void get_latency_result(NV_VULKAN_LATENCY_RESULT_PARAMS* pGetLatencyParams);
- void add_marker_to_report(NV_VULKAN_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams);
-
- public:
- LowLatency() = default;
- ~LowLatency() { deinit_current_tech(); };
-
- bool deinit_current_tech();
- bool get_low_latency_tech_context(void** low_latency_tech_context, LowLatencyMode* low_latency_tech);
-
- bool is_low_latency_enabled();
-
- // D3D
- NvAPI_Status Sleep(IUnknown* pDevice);
- NvAPI_Status SetSleepMode(IUnknown* pDevice, NV_SET_SLEEP_MODE_PARAMS* pSetSleepModeParams);
- NvAPI_Status GetSleepStatus(IUnknown* pDevice, NV_GET_SLEEP_STATUS_PARAMS* pGetSleepStatusParams);
- NvAPI_Status SetLatencyMarker(IUnknown* pDev, NV_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams);
- NvAPI_Status SetAsyncFrameMarker(ID3D12CommandQueue* pCommandQueue,
- NV_ASYNC_FRAME_MARKER_PARAMS* pSetAsyncFrameMarkerParams);
- NvAPI_Status GetLatency(IUnknown* pDev, NV_LATENCY_RESULT_PARAMS* pGetLatencyParams);
-
- // Vulkan
- NvAPI_Status Sleep(HANDLE vkDevice);
- NvAPI_Status SetSleepMode(HANDLE vkDevice, NV_VULKAN_SET_SLEEP_MODE_PARAMS* pSetSleepModeParams);
- NvAPI_Status GetSleepStatus(HANDLE vkDevice, NV_VULKAN_GET_SLEEP_STATUS_PARAMS* pGetSleepStatusParams);
- NvAPI_Status SetLatencyMarker(HANDLE vkDevice, NV_VULKAN_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams);
- NvAPI_Status GetLatency(HANDLE vkDevice, NV_VULKAN_LATENCY_RESULT_PARAMS* pGetLatencyParams);
-};
-
-// This is a wrapper for the entire LowLatency abstraction layer
-// If you need a specific *tech* context then you need to query this abstraction layer
-class LowLatencyCtx
-{
- public:
- static void init()
- {
- if (!lowlatency_ctx)
- lowlatency_ctx = new LowLatency();
- }
-
- static void shutdown()
- {
- delete lowlatency_ctx;
- lowlatency_ctx = nullptr;
- }
-
- static LowLatency* get() { return lowlatency_ctx; }
-
- private:
- static LowLatency* lowlatency_ctx;
-};
diff --git a/OptiScaler/nvapi/fakenvapi/low_latency_d3d.cpp b/OptiScaler/nvapi/fakenvapi/low_latency_d3d.cpp
deleted file mode 100644
index 2fb23656..00000000
--- a/OptiScaler/nvapi/fakenvapi/low_latency_d3d.cpp
+++ /dev/null
@@ -1,327 +0,0 @@
-#include "pch.h"
-#include "low_latency.h"
-
-#include "low_latency/low_latency_tech/ll_antilag2.h"
-#include "low_latency/low_latency_tech/ll_latencyflex.h"
-#include "low_latency/low_latency_tech/ll_xell.h"
-
-#include "log.h"
-#include "config.h"
-#include
-#include
-
-// private
-bool LowLatency::update_low_latency_tech(IUnknown* pDevice)
-{
- if (!pDevice)
- {
- LOG_ERROR("Invalid pointer");
- return false;
- }
-
- if (!currently_active_tech.load())
- {
- // Don't use AL2 and XeLL when using DMFG
- if (!Config::Instance()->FN_ForceLatencyFlex.value_or_default() &&
- State::Instance().dlssgLastSetMode != sl::DLSSGMode::eDynamic)
- {
- auto new_tech_al2 = std::make_shared();
- if (new_tech_al2->init(pDevice))
- {
- LOG_INFO("LowLatency algo: FSR Anti-Lag 2.0");
- new_tech_al2->set_sleep_mode(&last_sleep_mode);
- currently_active_tech.store(std::move(new_tech_al2));
- return true;
- }
-
- auto new_tech_xell = std::make_shared();
- if (new_tech_xell->init(pDevice))
- {
- LOG_INFO("LowLatency algo: XeLL");
- new_tech_xell->set_sleep_mode(&last_sleep_mode);
- currently_active_tech.store(std::move(new_tech_xell));
- return true;
- }
- }
-
- auto new_tech = std::make_shared();
- if (new_tech->init(pDevice))
- {
- LOG_INFO("LowLatency algo: LatencyFlex");
- new_tech->set_sleep_mode(&last_sleep_mode);
- currently_active_tech.store(std::move(new_tech));
- return true;
- }
- }
-
- static bool last_force_latencyflex = Config::Instance()->FN_ForceLatencyFlex.value_or_default();
- bool force_latencyflex = Config::Instance()->FN_ForceLatencyFlex.value_or_default();
- bool change_detected = last_force_latencyflex != force_latencyflex;
- last_force_latencyflex = force_latencyflex;
-
- if (State::Instance().fakenvapiReloadLowLatency)
- {
- change_detected = true;
- State::Instance().fakenvapiReloadLowLatency = false;
- }
-
- auto try_reinit = [&]() -> bool
- {
- if (!deinit_current_tech())
- {
- LOG_ERROR("Couldn't deinitialize low latency tech");
- return false;
- }
- return update_low_latency_tech(pDevice);
- };
-
- // FSR FG might still be using AntiLag 2, give Opti time to set AL2 context to null
- if (change_detected)
- {
- bool al2 = false;
- bool xell = false;
- {
- auto current_tech = currently_active_tech.load();
- if (current_tech)
- {
- auto mode = current_tech->get_mode();
- al2 = mode == LowLatencyMode::AntiLag2;
- xell = mode == LowLatencyMode::XeLL;
- }
- }
-
- if (al2 || xell)
- {
- delay_deinit = 50;
- }
- else
- {
- return try_reinit();
- }
- }
-
- if (delay_deinit > 0)
- {
- if (--delay_deinit == 0)
- return try_reinit();
- }
-
- return true;
-}
-
-void LowLatency::get_latency_result(NV_LATENCY_RESULT_PARAMS* pGetLatencyParams)
-{
- if (pGetLatencyParams->version != NV_LATENCY_RESULT_PARAMS_VER1)
- {
- LOG_ERROR("GetLatency: Unsupported version {}", pGetLatencyParams->version);
- return;
- }
-
- // Assume no frame reports collected yet, report all zeros
- if (frame_reports[FRAME_REPORTS_BUFFER_SIZE - 1].frameID == 0)
- {
- std::memset(pGetLatencyParams->frameReport, 0, sizeof(pGetLatencyParams->frameReport));
- // spdlog::warn("GetLatency: Not enough data to report");
- return;
- }
-
- // Sort frame reports, find the oldest
- size_t minIdx = 0;
- uint64_t minID = frame_reports[0].frameID;
- for (size_t i = 1; i < FRAME_REPORTS_BUFFER_SIZE; i++)
- {
- if (frame_reports[i].frameID < minID)
- {
- minID = frame_reports[i].frameID;
- minIdx = i;
- }
- }
-
- // Copy starting from older before wrapping around
- size_t firstChunk = std::min(NVAPI_BUFFER_SIZE, FRAME_REPORTS_BUFFER_SIZE - minIdx);
- std::memcpy(pGetLatencyParams->frameReport, frame_reports + minIdx, firstChunk * sizeof(FrameReport));
-
- // Copy the rest after wrapping around
- if (firstChunk < NVAPI_BUFFER_SIZE)
- {
- std::memcpy(pGetLatencyParams->frameReport + firstChunk, frame_reports,
- (NVAPI_BUFFER_SIZE - firstChunk) * sizeof(FrameReport));
- }
-}
-
-void LowLatency::add_marker_to_report(NV_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams)
-{
- auto current_timestamp = Util::GetTimestamp() / 1000;
- static auto last_sim_start = current_timestamp;
- static auto _2nd_last_sim_start = current_timestamp;
- auto current_report = &frame_reports[pSetLatencyMarkerParams->frameID % FRAME_REPORTS_BUFFER_SIZE];
-
- if (current_report->frameID != pSetLatencyMarkerParams->frameID)
- {
- *current_report = FrameReport {};
- }
-
- current_report->frameID = pSetLatencyMarkerParams->frameID;
- current_report->gpuFrameTimeUs = (uint32_t) (last_sim_start - _2nd_last_sim_start);
- current_report->gpuActiveRenderTimeUs = 100;
- current_report->driverStartTime = current_timestamp;
- current_report->driverEndTime = current_timestamp + 100;
- current_report->gpuRenderStartTime = current_timestamp;
- current_report->gpuRenderEndTime = current_timestamp + 100;
- current_report->osRenderQueueStartTime = current_timestamp;
- current_report->osRenderQueueEndTime = current_timestamp + 100;
- switch (pSetLatencyMarkerParams->markerType)
- {
- case SIMULATION_START:
- _2nd_last_sim_start = last_sim_start;
- last_sim_start = Util::GetTimestamp() / 1000;
- current_report->simStartTime = last_sim_start;
- break;
- case SIMULATION_END:
- current_report->simEndTime = Util::GetTimestamp() / 1000;
- break;
- case RENDERSUBMIT_START:
- current_report->renderSubmitStartTime = Util::GetTimestamp() / 1000;
- break;
- case RENDERSUBMIT_END:
- current_report->renderSubmitEndTime = Util::GetTimestamp() / 1000;
- break;
- case PRESENT_START:
- current_report->presentStartTime = Util::GetTimestamp() / 1000;
- break;
- case PRESENT_END:
- current_report->presentEndTime = Util::GetTimestamp() / 1000;
- break;
- case INPUT_SAMPLE:
- current_report->inputSampleTime = Util::GetTimestamp() / 1000;
- break;
- default:
- break;
- }
-}
-
-// public
-NvAPI_Status LowLatency::Sleep(IUnknown* pDevice)
-{
- if (!update_low_latency_tech(pDevice))
- return ERROR();
-
- if (auto current_tech = currently_active_tech.load())
- current_tech->sleep();
-
- return OK();
-}
-
-NvAPI_Status LowLatency::SetSleepMode(IUnknown* pDevice, NV_SET_SLEEP_MODE_PARAMS* pSetSleepModeParams)
-{
- if (!update_low_latency_tech(pDevice))
- return ERROR();
-
- last_sleep_mode.low_latency_enabled = pSetSleepModeParams->bLowLatencyMode;
- last_sleep_mode.low_latency_boost = pSetSleepModeParams->bLowLatencyBoost;
- last_sleep_mode.minimum_interval_us = pSetSleepModeParams->minimumIntervalUs;
- last_sleep_mode.use_markers_to_optimize = pSetSleepModeParams->bUseMarkersToOptimize;
-
- if (auto current_tech = currently_active_tech.load())
- current_tech->set_sleep_mode(&last_sleep_mode);
-
- return OK();
-}
-
-NvAPI_Status LowLatency::GetSleepStatus(IUnknown* pDevice, NV_GET_SLEEP_STATUS_PARAMS* pGetSleepStatusParams)
-{
- if (!update_low_latency_tech(pDevice))
- return ERROR();
-
- SleepParams sleep_params {};
-
- if (auto current_tech = currently_active_tech.load())
- current_tech->get_sleep_status(&sleep_params);
-
- pGetSleepStatusParams->bLowLatencyMode = sleep_params.low_latency_enabled;
- pGetSleepStatusParams->bFsVrr = sleep_params.fullscreen_vrr;
- pGetSleepStatusParams->bCplVsyncOn = sleep_params.control_panel_vsync_override;
-
- return OK();
-}
-
-NvAPI_Status LowLatency::SetLatencyMarker(IUnknown* pDev, NV_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams)
-{
- if (!update_low_latency_tech(pDev))
- return ERROR();
-
- update_effective_fg_state();
-
- update_enabled_override();
-
- add_marker_to_report(pSetLatencyMarkerParams);
-
- MarkerParams marker_params {};
-
- marker_params.frame_id = pSetLatencyMarkerParams->frameID;
- marker_params.marker_type = (MarkerType) pSetLatencyMarkerParams->markerType; // requires enums to match
-
- if (auto current_tech = currently_active_tech.load())
- current_tech->set_marker(pDev, marker_params);
-
- LOG_TRACE_FAKENVAPI("{}: {}", magic_enum::enum_name(marker_params.marker_type), marker_params.frame_id);
-
- return NVAPI_OK;
-}
-
-NvAPI_Status LowLatency::SetAsyncFrameMarker(ID3D12CommandQueue* pCommandQueue,
- NV_ASYNC_FRAME_MARKER_PARAMS* pSetAsyncFrameMarkerParams)
-{
- if (!currently_active_tech.load()) // can't init using ID3D12CommandQueue, can only check if available
- return ERROR();
-
- MarkerParams marker_params {};
-
- marker_params.frame_id = pSetAsyncFrameMarkerParams->frameID;
- marker_params.marker_type = (MarkerType) pSetAsyncFrameMarkerParams->markerType; // requires enums to match
-
- if (marker_params.marker_type == MarkerType::OUT_OF_BAND_PRESENT_START)
- {
- constexpr size_t history_size = 12;
- static size_t counter = 0;
- static NvU64 previous_frame_ids[history_size] = {};
-
- previous_frame_ids[counter % history_size] = pSetAsyncFrameMarkerParams->frameID;
- counter++;
-
- int repeat_count = 0;
-
- for (size_t i = 1; i < history_size; i++)
- {
- // won't catch repeat frame ids across array wrap around
- if (previous_frame_ids[i] == previous_frame_ids[i - 1])
- {
- repeat_count++;
- }
- }
-
- if (fg && repeat_count == 0)
- fg = false;
- else if (!fg && repeat_count >= history_size / 2 - 1)
- fg = true;
-
- update_effective_fg_state();
- }
-
- if (auto current_tech = currently_active_tech.load())
- current_tech->set_async_marker(pCommandQueue, marker_params);
-
- LOG_TRACE_FAKENVAPI("Async {}: {}", magic_enum::enum_name(marker_params.marker_type), marker_params.frame_id);
-
- return NVAPI_OK;
-}
-
-NvAPI_Status LowLatency::GetLatency(IUnknown* pDev, NV_LATENCY_RESULT_PARAMS* pGetLatencyParams)
-{
- if (!update_low_latency_tech(pDev))
- return ERROR();
-
- get_latency_result(pGetLatencyParams);
-
- return OK();
-}
diff --git a/OptiScaler/nvapi/fakenvapi/low_latency_vk.cpp b/OptiScaler/nvapi/fakenvapi/low_latency_vk.cpp
deleted file mode 100644
index 9fb85548..00000000
--- a/OptiScaler/nvapi/fakenvapi/low_latency_vk.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-#include "pch.h"
-#include "low_latency.h"
-
-#include "low_latency/low_latency_tech/ll_antilag_vk.h"
-#include "low_latency/low_latency_tech/ll_latencyflex.h"
-
-#include "log.h"
-#include "config.h"
-
-// private
-bool LowLatency::update_low_latency_tech(HANDLE vkDevice)
-{
- if (!currently_active_tech.load())
- {
- if (!Config::Instance()->FN_ForceLatencyFlex.value_or_default())
- {
- auto new_tech = std::make_shared();
- if (new_tech->init(nullptr))
- {
- LOG_INFO("LowLatency algo: AntiLag Vulkan");
- currently_active_tech.store(std::move(new_tech));
- return true;
- }
- }
-
- auto new_tech = std::make_shared();
- if (new_tech->init(nullptr))
- {
- LOG_INFO("LowLatency algo: LatencyFlex");
- currently_active_tech.store(std::move(new_tech));
- return true;
- }
- }
-
- static bool last_force_latencyflex = Config::Instance()->FN_ForceLatencyFlex.value_or_default();
- bool force_latencyflex = Config::Instance()->FN_ForceLatencyFlex.value_or_default();
- bool change_detected = last_force_latencyflex != force_latencyflex;
- last_force_latencyflex = force_latencyflex;
-
- if (State::Instance().fakenvapiReloadLowLatency)
- {
- change_detected = true;
- State::Instance().fakenvapiReloadLowLatency = false;
- }
-
- if (change_detected)
- {
- if (deinit_current_tech())
- {
- return update_low_latency_tech((HANDLE) nullptr); // call again to reinit
- }
- else
- {
- LOG_ERROR("Couldn't deinitialize low latency tech");
- return false;
- }
- }
-
- return true;
-}
-
-void LowLatency::get_latency_result(NV_VULKAN_LATENCY_RESULT_PARAMS* pGetLatencyParams)
-{
- if (pGetLatencyParams->version != NV_VULKAN_LATENCY_RESULT_PARAMS_VER1)
- {
- LOG_ERROR("GetLatency: Unsupported version {}", pGetLatencyParams->version);
- return;
- }
-
- // Assume no frame reports collected yet, report all zeros
- if (frame_reports[FRAME_REPORTS_BUFFER_SIZE - 1].frameID == 0)
- {
- std::memset(pGetLatencyParams->frameReport, 0, sizeof(pGetLatencyParams->frameReport));
- // spdlog::warn("GetLatency: Not enough data to report");
- return;
- }
-
- // Sort frame reports, find the oldest
- size_t minIdx = 0;
- uint64_t minID = frame_reports[0].frameID;
- for (size_t i = 1; i < FRAME_REPORTS_BUFFER_SIZE; i++)
- {
- if (frame_reports[i].frameID < minID)
- {
- minID = frame_reports[i].frameID;
- minIdx = i;
- }
- }
-
- // Copy starting from older before wrapping around
- size_t firstChunk = std::min(NVAPI_BUFFER_SIZE, FRAME_REPORTS_BUFFER_SIZE - minIdx);
- std::memcpy(pGetLatencyParams->frameReport, frame_reports + minIdx, firstChunk * sizeof(FrameReport));
-
- // Copy the rest after wrapping around
- if (firstChunk < NVAPI_BUFFER_SIZE)
- {
- std::memcpy(pGetLatencyParams->frameReport + firstChunk, frame_reports,
- (NVAPI_BUFFER_SIZE - firstChunk) * sizeof(FrameReport));
- }
-
- // gpuFrameTimeUs and gpuActiveRenderTimeUs are missing in the vk struct
- for (auto i = 0; i < NVAPI_BUFFER_SIZE; i++)
- {
- std::memset(&pGetLatencyParams->frameReport[i].rsvd[0], 0,
- sizeof(FrameReport::gpuFrameTimeUs) + sizeof(FrameReport::gpuActiveRenderTimeUs));
- }
-}
-
-void LowLatency::add_marker_to_report(NV_VULKAN_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams)
-{
- auto current_timestamp = Util::GetTimestamp() / 1000;
- static auto last_sim_start = current_timestamp;
- static auto _2nd_last_sim_start = current_timestamp;
- auto current_report = &frame_reports[pSetLatencyMarkerParams->frameID % FRAME_REPORTS_BUFFER_SIZE];
-
- if (current_report->frameID != pSetLatencyMarkerParams->frameID)
- {
- *current_report = FrameReport {};
- }
-
- current_report->frameID = pSetLatencyMarkerParams->frameID;
- current_report->gpuFrameTimeUs = (uint32_t) (last_sim_start - _2nd_last_sim_start);
- current_report->gpuActiveRenderTimeUs = 100;
- current_report->driverStartTime = current_timestamp;
- current_report->driverEndTime = current_timestamp + 100;
- current_report->gpuRenderStartTime = current_timestamp;
- current_report->gpuRenderEndTime = current_timestamp + 100;
- current_report->osRenderQueueStartTime = current_timestamp;
- current_report->osRenderQueueEndTime = current_timestamp + 100;
- switch (pSetLatencyMarkerParams->markerType)
- {
- case VULKAN_SIMULATION_START:
- _2nd_last_sim_start = last_sim_start;
- last_sim_start = Util::GetTimestamp() / 1000;
- current_report->simStartTime = last_sim_start;
- break;
- case VULKAN_SIMULATION_END:
- current_report->simEndTime = Util::GetTimestamp() / 1000;
- break;
- case VULKAN_RENDERSUBMIT_START:
- current_report->renderSubmitStartTime = Util::GetTimestamp() / 1000;
- break;
- case VULKAN_RENDERSUBMIT_END:
- current_report->renderSubmitEndTime = Util::GetTimestamp() / 1000;
- break;
- case VULKAN_PRESENT_START:
- current_report->presentStartTime = Util::GetTimestamp() / 1000;
- break;
- case VULKAN_PRESENT_END:
- current_report->presentEndTime = Util::GetTimestamp() / 1000;
- break;
- case VULKAN_INPUT_SAMPLE:
- current_report->inputSampleTime = Util::GetTimestamp() / 1000;
- break;
- default:
- break;
- }
-}
-
-// public
-NvAPI_Status LowLatency::Sleep(HANDLE vkDevice)
-{
- if (!update_low_latency_tech(vkDevice))
- return ERROR();
-
- if (auto current_tech = currently_active_tech.load())
- current_tech->sleep();
-
- return OK();
-}
-
-NvAPI_Status LowLatency::SetSleepMode(HANDLE vkDevice, NV_VULKAN_SET_SLEEP_MODE_PARAMS* pSetSleepModeParams)
-{
- if (!update_low_latency_tech(vkDevice))
- return ERROR();
-
- SleepMode sleep_mode {};
-
- sleep_mode.low_latency_enabled = pSetSleepModeParams->bLowLatencyMode;
- sleep_mode.low_latency_boost = pSetSleepModeParams->bLowLatencyBoost;
- sleep_mode.minimum_interval_us = pSetSleepModeParams->minimumIntervalUs;
- sleep_mode.use_markers_to_optimize = true;
-
- if (auto current_tech = currently_active_tech.load())
- current_tech->set_sleep_mode(&sleep_mode);
-
- return OK();
-}
-
-NvAPI_Status LowLatency::GetSleepStatus(HANDLE vkDevice, NV_VULKAN_GET_SLEEP_STATUS_PARAMS* pGetSleepStatusParams)
-{
- if (!update_low_latency_tech(vkDevice))
- return ERROR();
-
- SleepParams sleep_params {};
-
- if (auto current_tech = currently_active_tech.load())
- current_tech->get_sleep_status(&sleep_params);
-
- pGetSleepStatusParams->bLowLatencyMode = sleep_params.low_latency_enabled;
-
- return OK();
-}
-
-NvAPI_Status LowLatency::SetLatencyMarker(HANDLE vkDevice, NV_VULKAN_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams)
-{
- if (!update_low_latency_tech(vkDevice))
- return ERROR();
-
- update_effective_fg_state();
-
- update_enabled_override();
-
- add_marker_to_report(pSetLatencyMarkerParams);
-
- MarkerParams marker_params {};
-
- marker_params.frame_id = pSetLatencyMarkerParams->frameID;
- marker_params.marker_type = (MarkerType) pSetLatencyMarkerParams->markerType; // requires enums to match
-
- // This cast is not ideal as it needs to be cast to VkDevice while knowing it's vulkan
- if (auto current_tech = currently_active_tech.load())
- current_tech->set_marker((IUnknown*) vkDevice, marker_params);
-
- LOG_TRACE_FAKENVAPI("{}: {}", magic_enum::enum_name(marker_params.marker_type), marker_params.frame_id);
-
- return NVAPI_OK;
-}
-
-NvAPI_Status LowLatency::GetLatency(HANDLE vkDevice, NV_VULKAN_LATENCY_RESULT_PARAMS* pGetLatencyParams)
-{
- if (!update_low_latency_tech(vkDevice))
- return ERROR();
-
- get_latency_result(pGetLatencyParams);
-
- return OK();
-}
diff --git a/OptiScaler/nvapi/fakenvapi/nvapi_calls.cpp b/OptiScaler/nvapi/fakenvapi/nvapi_calls.cpp
index bdd01145..5ffb14e0 100644
--- a/OptiScaler/nvapi/fakenvapi/nvapi_calls.cpp
+++ b/OptiScaler/nvapi/fakenvapi/nvapi_calls.cpp
@@ -3,11 +3,9 @@
#include "proxies/Dxgi_Proxy.h"
#include
#include
-#include
using Microsoft::WRL::ComPtr;
-LowLatency* LowLatencyCtx::lowlatency_ctx = nullptr;
static auto init_mutex = std::mutex {};
namespace nvapi_calls
@@ -346,47 +344,6 @@ NvAPI_Status __cdecl NvAPI_D3D_GetObjectHandleForResource(IUnknown* invalid, IUn
NvAPI_Status __cdecl NvAPI_D3D_SetResourceHint() { return ERROR_VALUE(NVAPI_NO_IMPLEMENTATION); }
-NvAPI_Status __cdecl NvAPI_D3D_GetSleepStatus(IUnknown* pDevice, NV_GET_SLEEP_STATUS_PARAMS* pGetSleepStatusParams)
-{
- if (!pDevice || !pGetSleepStatusParams)
- return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
-
- return LowLatencyCtx::get()->GetSleepStatus(pDevice, pGetSleepStatusParams);
-}
-
-NvAPI_Status __cdecl NvAPI_D3D_GetLatency(IUnknown* pDevice, NV_LATENCY_RESULT_PARAMS* pGetLatencyParams)
-{
- if (!pDevice || !pGetLatencyParams)
- return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
-
- // xellGetFramesReports() currently doesn't give any extra data that we can't already get
- return LowLatencyCtx::get()->GetLatency(pDevice, pGetLatencyParams);
-}
-
-NvAPI_Status __cdecl NvAPI_D3D_SetSleepMode(IUnknown* pDevice, NV_SET_SLEEP_MODE_PARAMS* pSetSleepModeParams)
-{
- if (!pDevice || !pSetSleepModeParams)
- return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
-
- return LowLatencyCtx::get()->SetSleepMode(pDevice, pSetSleepModeParams);
-}
-
-NvAPI_Status __cdecl NvAPI_D3D_SetLatencyMarker(IUnknown* pDevice, NV_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams)
-{
- if (!pDevice || !pSetLatencyMarkerParams)
- return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
-
- return LowLatencyCtx::get()->SetLatencyMarker(pDevice, pSetLatencyMarkerParams);
-}
-
-NvAPI_Status __cdecl NvAPI_D3D_Sleep(IUnknown* pDevice)
-{
- if (!pDevice)
- return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
-
- return LowLatencyCtx::get()->Sleep(pDevice);
-}
-
NvAPI_Status __cdecl NvAPI_D3D_SetReflexSync(IUnknown* pDevice, NV_SET_REFLEX_SYNC_PARAMS* pSetReflexSyncParams)
{
return OK();
@@ -600,105 +557,6 @@ NvAPI_Status __cdecl NvAPI_D3D12_NotifyOutOfBandCommandQueue(ID3D12CommandQueue*
return OK();
}
-NvAPI_Status __cdecl NvAPI_D3D12_SetAsyncFrameMarker(ID3D12CommandQueue* pCommandQueue,
- NV_ASYNC_FRAME_MARKER_PARAMS* pSetAsyncFrameMarkerParams)
-{
- if (pSetAsyncFrameMarkerParams == nullptr)
- return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
-
- return LowLatencyCtx::get()->SetAsyncFrameMarker(pCommandQueue, pSetAsyncFrameMarkerParams);
-}
-
-NvAPI_Status __cdecl NvAPI_Vulkan_InitLowLatencyDevice(HANDLE vkDevice, HANDLE* signalSemaphoreHandle)
-{
- if (!vkDevice || !signalSemaphoreHandle)
- return ERROR();
-
- VkDevice device = reinterpret_cast(vkDevice);
-
- VkSemaphoreTypeCreateInfo timelineInfo {};
- timelineInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
- timelineInfo.pNext = nullptr;
- timelineInfo.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
- timelineInfo.initialValue = 0;
-
- VkSemaphoreCreateInfo createInfo {};
- createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
- createInfo.pNext = &timelineInfo;
- createInfo.flags = 0;
-
- VkResult res = VK_ERROR_UNKNOWN;
-
- if (VulkanHooks::o_vkCreateSemaphore && low_latency_semaphore == VK_NULL_HANDLE)
- res = VulkanHooks::o_vkCreateSemaphore(device, &createInfo, nullptr, &low_latency_semaphore);
-
- if (res != VK_SUCCESS)
- return NVAPI_ERROR;
-
- *signalSemaphoreHandle = reinterpret_cast(low_latency_semaphore);
-
- // It happens automatically on every reflex call
- return OK();
-}
-
-NvAPI_Status __cdecl NvAPI_Vulkan_DestroyLowLatencyDevice(HANDLE vkDevice)
-{
- LowLatencyCtx::get()->deinit_current_tech();
- return OK();
-}
-
-NvAPI_Status __cdecl NvAPI_Vulkan_GetSleepStatus(HANDLE vkDevice,
- NV_VULKAN_GET_SLEEP_STATUS_PARAMS* pGetSleepStatusParams)
-{
- if (!vkDevice || !pGetSleepStatusParams)
- return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
-
- return LowLatencyCtx::get()->GetSleepStatus(vkDevice, pGetSleepStatusParams);
-}
-
-NvAPI_Status __cdecl NvAPI_Vulkan_SetSleepMode(HANDLE vkDevice, NV_VULKAN_SET_SLEEP_MODE_PARAMS* pSetSleepModeParams)
-{
- if (!vkDevice || !pSetSleepModeParams)
- return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
-
- return LowLatencyCtx::get()->SetSleepMode(vkDevice, pSetSleepModeParams);
-}
-
-NvAPI_Status __cdecl NvAPI_Vulkan_Sleep(HANDLE vkDevice, NvU64 signalValue)
-{
- if (!vkDevice)
- return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
-
- VkSemaphoreSignalInfo signalInfo {};
- signalInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO;
- signalInfo.pNext = nullptr;
- signalInfo.semaphore = low_latency_semaphore;
- signalInfo.value = signalValue;
-
- VkDevice device = reinterpret_cast(vkDevice);
-
- VulkanHooks::SignalSemaphore(device, &signalInfo);
-
- return LowLatencyCtx::get()->Sleep(vkDevice);
-}
-
-NvAPI_Status __cdecl NvAPI_Vulkan_GetLatency(HANDLE vkDevice, NV_VULKAN_LATENCY_RESULT_PARAMS* pGetLatencyParams)
-{
- if (!vkDevice || !pGetLatencyParams)
- return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
-
- return LowLatencyCtx::get()->GetLatency(vkDevice, pGetLatencyParams);
-}
-
-NvAPI_Status __cdecl NvAPI_Vulkan_SetLatencyMarker(HANDLE vkDevice,
- NV_VULKAN_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams)
-{
- if (!vkDevice || !pSetLatencyMarkerParams)
- return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
-
- return LowLatencyCtx::get()->SetLatencyMarker(vkDevice, pSetLatencyMarkerParams);
-}
-
NvAPI_Status __cdecl NvAPI_Vulkan_NotifyOutOfBandVkQueue(HANDLE vkDevice, HANDLE queueHandle,
NV_VULKAN_OUT_OF_BAND_QUEUE_TYPE queueType)
{
@@ -770,15 +628,7 @@ NvAPI_Status __cdecl NvAPI_Unload()
if (ref_count == 0)
return ERROR_VALUE(NVAPI_API_NOT_INITIALIZED);
- if (--ref_count == 0)
- {
- auto context = LowLatencyCtx::get();
-
- if (!context)
- return ERROR();
-
- context->deinit_current_tech();
- }
+ --ref_count;
return OK();
}
diff --git a/OptiScaler/nvapi/fakenvapi/nvapi_calls.h b/OptiScaler/nvapi/fakenvapi/nvapi_calls.h
index 1a7acf86..d14b195a 100644
--- a/OptiScaler/nvapi/fakenvapi/nvapi_calls.h
+++ b/OptiScaler/nvapi/fakenvapi/nvapi_calls.h
@@ -4,8 +4,6 @@
#include
#include
-#include "low_latency.h"
-
#include "low_latency/ll_util.h"
#include "log.h"
@@ -17,8 +15,6 @@ static auto drs_profile = reinterpret_cast(&drs);
static uint64_t ref_count = 0;
-static VkSemaphore low_latency_semaphore = VK_NULL_HANDLE;
-
NvAPI_Status __cdecl NvAPI_Initialize();
NvAPI_Status __cdecl NvAPI_GetInterfaceVersionString(NvAPI_ShortString desc);
NvAPI_Status __cdecl NvAPI_EnumPhysicalGPUs(NvPhysicalGpuHandle handles[NVAPI_MAX_PHYSICAL_GPUS], NvU32* count);
@@ -67,11 +63,6 @@ NvAPI_Status __cdecl NvAPI_SYS_GetGpuAndOutputIdFromDisplayId(NvU32 displayId, N
NvAPI_Status __cdecl NvAPI_D3D_GetObjectHandleForResource(IUnknown* invalid, IUnknown* pResource,
NVDX_ObjectHandle* pHandle);
NvAPI_Status __cdecl NvAPI_D3D_SetResourceHint();
-NvAPI_Status __cdecl NvAPI_D3D_GetSleepStatus(IUnknown* pDevice, NV_GET_SLEEP_STATUS_PARAMS* pGetSleepStatusParams);
-NvAPI_Status __cdecl NvAPI_D3D_GetLatency(IUnknown* pDev, NV_LATENCY_RESULT_PARAMS* pGetLatencyParams);
-NvAPI_Status __cdecl NvAPI_D3D_SetSleepMode(IUnknown* pDevice, NV_SET_SLEEP_MODE_PARAMS* pSetSleepModeParams);
-NvAPI_Status __cdecl NvAPI_D3D_SetLatencyMarker(IUnknown* pDev, NV_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams);
-NvAPI_Status __cdecl NvAPI_D3D_Sleep(IUnknown* pDevice);
NvAPI_Status __cdecl NvAPI_D3D_SetReflexSync(IUnknown* pDev, NV_SET_REFLEX_SYNC_PARAMS* pSetReflexSyncParams);
NvAPI_Status __cdecl NvAPI_D3D11_IsNvShaderExtnOpCodeSupported(IUnknown* invalid, NvU32 opCode, bool* pSupported);
NvAPI_Status __cdecl NvAPI_D3D11_BeginUAVOverlap(IUnknown* pDeviceOrContext);
@@ -87,17 +78,6 @@ NvAPI_Status __cdecl NvAPI_D3D12_BuildRaytracingAccelerationStructureEx(
ID3D12GraphicsCommandList4* pCommandList, const NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS* pParams);
NvAPI_Status __cdecl NvAPI_D3D12_NotifyOutOfBandCommandQueue(ID3D12CommandQueue* pCommandQueue,
NV_OUT_OF_BAND_CQ_TYPE cqType);
-NvAPI_Status __cdecl NvAPI_D3D12_SetAsyncFrameMarker(ID3D12CommandQueue* pCommandQueue,
- NV_ASYNC_FRAME_MARKER_PARAMS* pSetAsyncFrameMarkerParams);
-NvAPI_Status __cdecl NvAPI_Vulkan_InitLowLatencyDevice(HANDLE vkDevice, HANDLE* signalSemaphoreHandle);
-NvAPI_Status __cdecl NvAPI_Vulkan_DestroyLowLatencyDevice(HANDLE vkDevice);
-NvAPI_Status __cdecl NvAPI_Vulkan_GetSleepStatus(HANDLE vkDevice,
- NV_VULKAN_GET_SLEEP_STATUS_PARAMS* pGetSleepStatusParams);
-NvAPI_Status __cdecl NvAPI_Vulkan_SetSleepMode(HANDLE vkDevice, NV_VULKAN_SET_SLEEP_MODE_PARAMS* pSetSleepModeParams);
-NvAPI_Status __cdecl NvAPI_Vulkan_Sleep(HANDLE vkDevice, NvU64 signalValue);
-NvAPI_Status __cdecl NvAPI_Vulkan_GetLatency(HANDLE vkDevice, NV_VULKAN_LATENCY_RESULT_PARAMS* pGetLatencyParams);
-NvAPI_Status __cdecl NvAPI_Vulkan_SetLatencyMarker(HANDLE vkDevice,
- NV_VULKAN_LATENCY_MARKER_PARAMS* pSetLatencyMarkerParams);
NvAPI_Status __cdecl NvAPI_Vulkan_NotifyOutOfBandVkQueue(HANDLE vkDevice, HANDLE queueHandle,
NV_VULKAN_OUT_OF_BAND_QUEUE_TYPE queueType);
NvAPI_Status __cdecl NvAPI_DRS_CreateSession(NvDRSSessionHandle* session);