Add in-game toggle for Dynamic MFG

Targets monitor's refresh rate, for custom targets use FramerateTargetDMFG and restart the game
This commit is contained in:
FakeMichau
2026-04-04 19:03:48 +02:00
parent 320757287d
commit a2aef3560d
14 changed files with 274 additions and 77 deletions
+15 -3
View File
@@ -259,6 +259,21 @@ ForceBorderless=auto
; true or false - Default (auto) is 1
InterpolationCount=auto
; Default (auto) is true
UseGamesReflexMarkers=auto
; For overriding game's value sent to SL, could be Nvngx FG, could be noFG when someone uses real DLSSG
; Default (auto) is no override
OverrideInterpolationCount=auto
; Try to force Dynamic MFG. Requires Nvidia Blackwell or any AMD/Intel
; Default (auto) is false
OverrideForceDMFG=auto
; Sets the FPS target for dynamic multi frame generation
; When non-zero, you won't be able to manually adjust the FG multiplier
; Default (auto) is 0 (disabled)
FramerateTargetDMFG=auto
; -------------------------------------------------------
@@ -934,9 +949,6 @@ LatencyFlexMode=auto
; Default (auto) is 0
ForceReflex=auto
; When using FG via Nvngx, sets the FPS target for dynamic multi frame generation
; Default (auto) is 0
FramerateTargetDMFG=auto
; -------------------------------------------------------
+12 -5
View File
@@ -219,6 +219,13 @@ bool Config::Reload(std::filesystem::path iniPath)
if (FGDLSSGOverrideInterpolationCount.has_value() &&
(FGDLSSGOverrideInterpolationCount.value() < 1 || FGDLSSGOverrideInterpolationCount.value() > 6))
FGDLSSGOverrideInterpolationCount.reset();
FGDLSSGFramerateTargetDMFG.set_from_config(readInt("DLSSG", "FramerateTargetDMFG"));
FGDLSSGOverrideForceDMFG.set_from_config(readBool("DLSSG", "OverrideForceDMFG"));
// DMFG target can currently only be set on launch, inform using the ForceDMFG
if (FGDLSSGFramerateTargetDMFG.has_value() && FGDLSSGFramerateTargetDMFG.value() > 0)
FGDLSSGOverrideForceDMFG.set_volatile_value(true);
}
// FSR FG Inputs
@@ -649,10 +656,8 @@ bool Config::Reload(std::filesystem::path iniPath)
else
FN_ForceReflex.reset();
FramerateTargetDMFG.set_from_config(readInt("fakenvapi", "FramerateTargetDMFG"));
// DMFG is a mess with our reflex implementations, disable by default
if (FramerateTargetDMFG.value_or_default() != 0 && !FN_ForceReflex.has_value())
if (FGDLSSGOverrideForceDMFG.value_or_default() && !FN_ForceReflex.has_value())
FN_ForceReflex.set_volatile_value(ForceReflex::ForceDisable);
}
@@ -920,6 +925,10 @@ bool Config::SaveIni()
GetBoolValue(Instance()->FGDLSSGUseGamesReflexMarkers.value_for_config()).c_str());
ini.SetValue("DLSSG", "OverrideInterpolationCount",
GetIntValue(Instance()->FGDLSSGOverrideInterpolationCount.value_for_config()).c_str());
ini.SetValue("DLSSG", "FramerateTargetDMFG",
GetIntValue(Instance()->FGDLSSGFramerateTargetDMFG.value_for_config()).c_str());
ini.SetValue("DLSSG", "OverrideForceDMFG",
GetBoolValue(Instance()->FGDLSSGOverrideForceDMFG.value_for_config()).c_str());
}
// OptiFG
@@ -1363,8 +1372,6 @@ bool Config::SaveIni()
ini.SetValue("fakenvapi", "LatencyFlexMode",
GetIntValue(Instance()->FN_LatencyFlexMode.value_for_config()).c_str());
ini.SetValue("fakenvapi", "ForceReflex", GetIntValue(Instance()->FN_ForceReflex.value_for_config()).c_str());
ini.SetValue("fakenvapi", "FramerateTargetDMFG",
GetIntValue(Instance()->FramerateTargetDMFG.value_for_config()).c_str());
}
// inputs
+6 -3
View File
@@ -519,9 +519,13 @@ class Config
CustomOptional<bool> FGXeFGForceBorderless { false };
// DLSSG
CustomOptional<int> FGDLSSGInterpolationCount { 1 };
CustomOptional<int> FGDLSSGInterpolationCount { 1 }; // For Opti's own SL instance
CustomOptional<bool> FGDLSSGUseGamesReflexMarkers { true };
CustomOptional<int, NoDefault> FGDLSSGOverrideInterpolationCount;
CustomOptional<int, NoDefault>
FGDLSSGOverrideInterpolationCount; // For overriding game's value sent to SL, could be Nvngx FG, could be noFG
// but someone just uses real DLSSG
CustomOptional<bool> FGDLSSGOverrideForceDMFG { false }; // Overrides game's DLSSG mode to Dynamic
CustomOptional<int> FGDLSSGFramerateTargetDMFG { 0 }; // Applies on launch
// fakenvapi
CustomOptional<bool> UseFakenvapi { true };
@@ -529,7 +533,6 @@ class Config
CustomOptional<bool> FN_ForceLatencyFlex { false };
CustomOptional<LFXMode> FN_LatencyFlexMode { LFXMode::Conservative };
CustomOptional<ForceReflex> FN_ForceReflex { ForceReflex::InGame };
CustomOptional<int> FramerateTargetDMFG { 0 };
// Inputs
CustomOptional<bool> EnableDlssInputs { true };
+5
View File
@@ -9,6 +9,7 @@
#include <vulkan/vulkan.h>
#include <ankerl/unordered_dense.h>
#include <mutex>
#include <sl_dlss_g.h>
enum class FGPreset : uint32_t
{
@@ -157,6 +158,7 @@ class State
feature_version streamlineVersion = { 0, 0, 0 };
// Has value when Opti was able to hook sl and the game set DLSSG options
std::optional<int> dlssgMfgMax = std::nullopt;
API api = API::NotSelected;
@@ -182,6 +184,9 @@ class State
int xefgMaxInterpolationCount = 1;
int dlssgMaxInterpolationCount = 1;
bool dlssgDMFGSupported = false;
sl::DLSSGMode dlssgLastSetMode = sl::DLSSGMode::eOff;
int dlssgDetectedInterpolationCount = 0;
// DLSS
bool dlssPresetsOverriddenExternally = false;
-7
View File
@@ -419,13 +419,6 @@ NVSDK_NGX_Result Nvngx_FG::D3D12_EvaluateFeature(ID3D12GraphicsCommandList* InCm
}
}
if (Config::Instance()->FramerateTargetDMFG.value_or_default() != 0 && fakenvapi::isUsingAsMainNvapi())
{
int frameCount = 0;
InParameters->Get("DLSSG.MultiFrameCount", &frameCount);
Config::Instance()->FGDLSSGOverrideInterpolationCount.set_volatile_value(frameCount);
}
NVSDK_NGX_Handle TempHandle = { .Id = InFeatureHandle->Id - DLSSG_MOD_ID_OFFSET };
return _DLSSG_D3D12_EvaluateFeature(InCmdList, &TempHandle, InParameters, InCallback);
}
+11 -1
View File
@@ -642,8 +642,18 @@ void ReflexHooks::update(bool fgActive, bool isVulkan)
if (lastFgNumFramesToGenerate != _FgNumFramesToGenerate)
{
// Don't reload when using Dynamic MFG
if (fakenvapi::isUsingAsMainNvapi())
State::Instance().fakenvapiReloadLowLatency = true;
{
if (State::Instance().dlssgLastSetMode != (sl::DLSSGMode) 3)
State::Instance().fakenvapiReloadLowLatency = true;
if (Config::Instance()->FN_ForceReflex.value_or_default() != ForceReflex::ForceEnable &&
(State::Instance().dlssgLastSetMode != (sl::DLSSGMode) 3 || _FgNumFramesToGenerate > 1))
{
Config::Instance()->FN_ForceReflex.set_volatile_value(ForceReflex::ForceDisable);
}
}
lastFgNumFramesToGenerate = _FgNumFramesToGenerate;
setFPSLimit(currentFps);
+81 -11
View File
@@ -748,16 +748,29 @@ sl::Result StreamlineHooks::hkslDLSSGSetOptions(const sl::ViewportHandle& viewpo
lastDlssgViewport = viewport;
lastDlssgOptions = options;
// Make DLSSG auto always mean On
sl::DLSSGOptions newOptions = options;
newOptions.mode = newOptions.mode == sl::DLSSGMode::eOff ? sl::DLSSGMode::eOff : sl::DLSSGMode::eOn;
// Make DLSSG auto always mean On
// if (newOptions.mode == sl::DLSSGMode::eAuto)
// newOptions.mode = sl::DLSSGMode::eOn;
auto& state = State::Instance();
const auto dlssgPotentiallyActive = newOptions.mode == sl::DLSSGMode::eOn ||
newOptions.mode == sl::DLSSGMode::eAuto || newOptions.mode == (sl::DLSSGMode) 3;
bool enableDynamicMode = Config::Instance()->FGDLSSGOverrideForceDMFG.value_or_default() &&
state.dlssgDMFGSupported && dlssgPotentiallyActive;
if (enableDynamicMode)
{
newOptions.mode = (sl::DLSSGMode) 3;
}
if (state.swapchainApi == API::Vulkan)
{
// Only matters for Vulkan, DX doesn't use this delay
if (options.mode != sl::DLSSGMode::eOff && !MenuOverlayBase::IsVisible())
if (dlssgPotentiallyActive && !MenuOverlayBase::IsVisible())
state.delayMenuRenderBy = 10;
if (MenuOverlayBase::IsVisible())
@@ -770,8 +783,9 @@ sl::Result StreamlineHooks::hkslDLSSGSetOptions(const sl::ViewportHandle& viewpo
LOG_TRACE("DLSSG Modified Mode: {}", magic_enum::enum_name(newOptions.mode));
if (options.mode != sl::DLSSGMode::eOff && state.streamlineVersion >= feature_version { 2, 7, 2 })
if (dlssgPotentiallyActive && state.streamlineVersion >= feature_version { 2, 7, 1 })
{
// Populate dlssgMfgMax once
if (!state.dlssgMfgMax.has_value())
{
sl::DLSSGState localState {};
@@ -790,28 +804,84 @@ sl::Result StreamlineHooks::hkslDLSSGSetOptions(const sl::ViewportHandle& viewpo
}
}
// Won't take effect with Dynamic
if (Config::Instance()->FGDLSSGOverrideInterpolationCount.has_value())
{
newOptions.numFramesToGenerate = Config::Instance()->FGDLSSGOverrideInterpolationCount.value();
auto overrideCount = Config::Instance()->FGDLSSGOverrideInterpolationCount.value();
if (overrideCount != 0)
newOptions.numFramesToGenerate = overrideCount;
else if (!enableDynamicMode)
newOptions.mode = sl::DLSSGMode::eOff;
}
}
if (newOptions.mode == sl::DLSSGMode::eOff)
ReflexHooks::setDlssgFrameCount(0);
else
ReflexHooks::setDlssgFrameCount(newOptions.numFramesToGenerate);
state.dlssgLastSetMode = newOptions.mode;
return o_slDLSSGSetOptions(viewport, newOptions);
}
// TODO: update once sl::DLSSGState becomes v4
struct DLSSGState4 : sl::DLSSGState
{
sl::Boolean bIsDynamicMFGSupportAvailable = sl::eInvalid;
};
sl::Result StreamlineHooks::hkslDLSSGGetState(const sl::ViewportHandle& viewport, sl::DLSSGState& state,
const sl::DLSSGOptions* options)
{
auto result = o_slDLSSGGetState(viewport, state, options);
sl::Result result {};
{
static sl::DLSSGState s;
assert(s.structVersion == 3);
}
const auto originalStructVersion = state.structVersion;
if (originalStructVersion < 4)
{
DLSSGState4 newState {};
newState.structVersion = 4;
// We might be feeding a newer struct to an older SL but that seems to work just fine for this Get function
result = o_slDLSSGGetState(viewport, dynamic_cast<sl::DLSSGState&>(newState), options);
// Copy back data to game's struct
memcpy(&state, &newState, 56); // struct ver 1 size
state.structVersion = originalStructVersion;
if (originalStructVersion >= 2)
{
state.numFramesToGenerateMax = newState.numFramesToGenerateMax;
state.bReserved4 = newState.bReserved4;
state.bIsVsyncSupportAvailable = newState.bIsVsyncSupportAvailable;
}
if (originalStructVersion >= 3)
{
state.inputsProcessingCompletionFence = newState.inputsProcessingCompletionFence;
state.lastPresentInputsProcessingCompletionFenceValue =
newState.lastPresentInputsProcessingCompletionFenceValue;
}
State::Instance().dlssgDMFGSupported = newState.bIsDynamicMFGSupportAvailable == sl::eTrue;
}
else
{
result = o_slDLSSGGetState(viewport, state, options);
auto ver4struct = reinterpret_cast<DLSSGState4&>(state);
State::Instance().dlssgDMFGSupported = ver4struct.bIsDynamicMFGSupportAvailable == sl::eTrue;
}
if (!State::Instance().dlssgDMFGSupported)
{
Config::Instance()->FGDLSSGOverrideForceDMFG.set_volatile_value(false);
Config::Instance()->FGDLSSGFramerateTargetDMFG.set_volatile_value(0);
}
auto& optiState = State::Instance();
if (optiState.streamlineVersion >= feature_version { 2, 7, 2 })
if (optiState.streamlineVersion >= feature_version { 2, 7, 1 })
{
if (!optiState.dlssgMfgMax.has_value())
{
+41 -1
View File
@@ -25,6 +25,7 @@
#include <misc/IdentifyGpu.h>
static ankerl::unordered_dense::map<unsigned int, ContextData<IFeature_Dx12>> Dx12Contexts;
static std::unordered_map<unsigned int, NVSDK_NGX_Feature> HandleToFeature;
static ID3D12Device* D3D12Device = nullptr;
static int evalCounter = 0;
@@ -666,7 +667,10 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_CreateFeature(ID3D12GraphicsComma
NVSDK_NGX_Result res = Nvngx_FG::D3D12_CreateFeature(InCmdList, InFeatureID, InParameters, OutHandle);
if (*OutHandle)
{
LOG_INFO("Created modded DLSSG feature with HandleId: {}", (*OutHandle)->Id);
HandleToFeature[(*OutHandle)->Id] = InFeatureID;
}
return res;
}
@@ -682,9 +686,14 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_CreateFeature(ID3D12GraphicsComma
NVSDK_NGX_Result res = NVNGXProxy::D3D12_CreateFeature()(InCmdList, InFeatureID, InParameters, OutHandle);
if (*OutHandle)
{
LOG_INFO("Native CreateFeature success, HandleId: {}", (*OutHandle)->Id);
HandleToFeature[(*OutHandle)->Id] = InFeatureID;
}
else
{
LOG_INFO("Native CreateFeature failed: {:#x}", (uint32_t) res);
}
return res;
}
@@ -694,7 +703,12 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_CreateFeature(ID3D12GraphicsComma
}
// OptiScaler internal handling (SuperSampling or RayReconstruction)
return TryCreateOptiFeature(InCmdList, InFeatureID, InParameters, OutHandle);
auto tryResult = TryCreateOptiFeature(InCmdList, InFeatureID, InParameters, OutHandle);
if (tryResult == NVSDK_NGX_Result_Success)
HandleToFeature[(*OutHandle)->Id] = InFeatureID;
return tryResult;
}
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_ReleaseFeature(NVSDK_NGX_Handle* InHandle)
@@ -990,6 +1004,32 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
const State& state = State::Instance();
const Config& cfg = *Config::Instance();
auto feature = HandleToFeature[handleId];
static size_t evalWithoutFG = 0;
bool fgCreated = std::any_of(HandleToFeature.begin(), HandleToFeature.end(),
[](const auto& pair) { return pair.second == NVSDK_NGX_Feature_FrameGeneration; });
if (feature == NVSDK_NGX_Feature_FrameGeneration)
{
evalWithoutFG = 0;
int frameCount = 0;
InParameters->Get("DLSSG.MultiFrameCount", &frameCount);
State::Instance().dlssgDetectedInterpolationCount = frameCount;
ReflexHooks::setDlssgFrameCount(frameCount);
}
else if (fgCreated)
{
evalWithoutFG++;
if (evalWithoutFG == 6)
{
// Report FG as disabled
State::Instance().dlssgDetectedInterpolationCount = 0;
ReflexHooks::setDlssgFrameCount(0);
}
}
// Native DLSS passthrough
if (handleId < DLSS_MOD_ID_OFFSET)
{
+53 -11
View File
@@ -3101,32 +3101,45 @@ bool MenuCommon::RenderMenu()
ImGui::Spacing();
}
if (state.dlssgMfgMax.has_value() && state.dlssgMfgMax.value() > 1)
ImGui::BeginDisabled(state.dlssgDMFGSupported &&
config->FGDLSSGOverrideForceDMFG.value_or_default());
if (state.dlssgMfgMax.has_value() && state.dlssgMfgMax.value() >= 1)
{
auto maxInterpolationCount = state.dlssgMfgMax.value();
if (maxInterpolationCount > 1)
{
const char* intModes[] = { "Off", "2X", "3X", "4X", "5X", "6X" };
auto currentSet = config->FGDLSSGOverrideInterpolationCount.value_or(0);
auto currentIntCount = intModes[currentSet];
const char* intModes[] = { "Default", "Off", "2X", "3X", "4X", "5X", "6X" };
// Map config value to UI index
int currentSet = 0;
if (config->FGDLSSGOverrideInterpolationCount.has_value())
{
currentSet = config->FGDLSSGOverrideInterpolationCount.value() + 1;
}
const char* currentIntCount = intModes[currentSet];
ImGui::PushItemWidth(95.0f * menuResScale);
if (ImGui::BeginCombo("Override DLSSG", currentIntCount))
{
for (int i = 0; i <= maxInterpolationCount; i++)
for (int i = 0; i <= maxInterpolationCount + 1; i++)
{
if (ImGui::Selectable(intModes[i], (currentSet == i)))
{
if (i == 0)
{
// Default, no override
config->FGDLSSGOverrideInterpolationCount.reset();
}
else
{
LOG_DEBUG("DLSSG Interpolation Count set to: {}", i);
config->FGDLSSGOverrideInterpolationCount = i;
// UI index, store value
int framesToGenerate = i - 1;
LOG_DEBUG("DLSSG Interpolation Count set to: {}", framesToGenerate);
config->FGDLSSGOverrideInterpolationCount = framesToGenerate;
}
StreamlineHooks::updateDlssgOptions();
@@ -3137,11 +3150,38 @@ bool MenuCommon::RenderMenu()
}
ImGui::PopItemWidth();
ShowHelpMarker("Overrides DLSSG interpolation count");
}
}
ImGui::EndDisabled();
if (state.dlssgDMFGSupported)
{
ImGui::SameLine(0.0f, 16.0f);
ImGui::BeginDisabled(config->FGDLSSGFramerateTargetDMFG.value_or_default());
if (bool dynamicMFG = config->FGDLSSGOverrideForceDMFG.value_or_default();
ImGui::Checkbox("Force Dynamic MFG", &dynamicMFG))
{
config->FGDLSSGOverrideForceDMFG = dynamicMFG;
StreamlineHooks::updateDlssgOptions();
}
if (config->FGDLSSGFramerateTargetDMFG.value_or_default())
{
ShowHelpMarker("You have set a custom FPS target in the config\n"
"You cannot disable DMFG while the game is running");
}
else
{
ShowHelpMarker("Currently targets your monitors refresh rate\n"
"For custom targets set FramerateTargetDMFG in the config and restart");
}
ImGui::EndDisabled();
}
auto fgOutput = reinterpret_cast<IFGFeature_Dx12*>(state.currentFG);
if (((state.activeFgOutput == FGOutput::FSRFG || state.activeFgOutput == FGOutput::XeFG ||
state.activeFgOutput == FGOutput::DLSSG ||
@@ -4170,12 +4210,14 @@ bool MenuCommon::RenderMenu()
ImGui::Text("Using Nukem's via the MFG mod from dlss-enabler-headless.asi");
}
bool dmfgActive = state.dlssgDMFGSupported && config->FGDLSSGOverrideForceDMFG.value_or_default();
if (!ReflexHooks::isReflexHooked())
{
ImGui::TextColored(ImVec4(1.f, 0.f, 0.f, 1.f), "Reflex not hooked");
ImGui::Text("If you are using an AMD/Intel GPU, then make sure you have Fakenvapi");
}
else if (ReflexHooks::dlssgFrameCountToGenerate() == 0)
else if (ReflexHooks::dlssgFrameCountToGenerate() == 0 && !dmfgActive)
{
ImGui::Text("Please select DLSS Frame Generation in the game options\n"
"You might need to select DLSS first");
@@ -4185,7 +4227,7 @@ bool MenuCommon::RenderMenu()
{
ImGui::Text("Current DLSSG state:");
ImGui::SameLine();
if (auto count = ReflexHooks::dlssgFrameCountToGenerate(); count > 0)
if (auto count = state.dlssgDetectedInterpolationCount; count > 0)
{
ImGui::TextColored(ImVec4(0.f, 1.f, 0.25f, 1.f), std::format("ON {}x", count + 1).c_str());
}
+37
View File
@@ -59,6 +59,43 @@ NvAPI_Status __stdcall NvApiHooks::hkNvAPI_DRS_GetSetting(NvDRSSessionHandle hSe
auto result = o_NvAPI_DRS_GetSetting(hSession, hProfile, settingId, pSetting);
if (pSetting && result == NVAPI_OK)
{
const auto dmfgFpsTarget = Config::Instance()->FGDLSSGFramerateTargetDMFG.value_or_default();
if (settingId == NGX_DLSSG_MODE_ID && dmfgFpsTarget != 0)
{
pSetting->settingId = settingId;
// constexpr auto name = L"NGX_DLSSG_MODE_ID";
// memcpy_s(pSetting->settingName, sizeof(pSetting->settingName), name, sizeof(*name) * wcslen(name));
pSetting->settingType = NVDRS_DWORD_TYPE;
pSetting->isCurrentPredefined = 0;
pSetting->u32CurrentValue = NGX_DLSSG_MODE_DEFAULT;
LOG_DEBUG("Set NGX_DLSSG_MODE_ID to {}", pSetting->u32CurrentValue);
}
if (settingId == NGX_DLSSG_DYNAMIC_TARGET_FRAME_RATE_ID && dmfgFpsTarget != 0)
{
pSetting->settingId = settingId;
// constexpr auto name = L"NGX_DLSSG_DYNAMIC_TARGET_FRAME_RATE_ID";
// memcpy_s(pSetting->settingName, sizeof(pSetting->settingName), name, sizeof(*name) * wcslen(name));
pSetting->settingType = NVDRS_DWORD_TYPE;
pSetting->isCurrentPredefined = 0;
pSetting->u32CurrentValue = dmfgFpsTarget;
LOG_DEBUG("Set NGX_DLSSG_DYNAMIC_TARGET_FRAME_RATE_ID to {}", pSetting->u32CurrentValue);
}
if (settingId == NGX_DLSSG_DYNAMIC_MULTI_FRAME_COUNT_MAX_ID && dmfgFpsTarget != 0)
{
pSetting->settingId = settingId;
// constexpr auto name = L"NGX_DLSSG_DYNAMIC_MULTI_FRAME_COUNT_MAX_ID";
// memcpy_s(pSetting->settingName, sizeof(pSetting->settingName), name, sizeof(*name) * wcslen(name));
pSetting->settingType = NVDRS_DWORD_TYPE;
pSetting->isCurrentPredefined = 0;
pSetting->u32CurrentValue = NGX_DLSSG_DYNAMIC_MULTI_FRAME_COUNT_MAX_DEFAULT;
LOG_DEBUG("Set NGX_DLSSG_DYNAMIC_MULTI_FRAME_COUNT_MAX_ID to {}", pSetting->u32CurrentValue);
}
if (settingId == NGX_DLSS_SR_OVERRIDE_RENDER_PRESET_SELECTION_ID)
{
if (Config::Instance()->RenderPresetOverride.value_or_default())
@@ -42,9 +42,10 @@ bool LowLatency::update_low_latency_tech(IUnknown* pDevice)
delete currently_active_tech;
}
// Don't use AL2 and XeLL when using DMFG or MFG
if (!Config::Instance()->FN_ForceLatencyFlex.value_or_default() &&
(!Nvngx_FG::isMFG() || ReflexHooks::dlssgFrameCountToGenerate() <= 1) &&
Config::Instance()->FramerateTargetDMFG.value_or_default() == 0)
State::Instance().dlssgDetectedInterpolationCount <= 1 &&
State::Instance().dlssgLastSetMode != (sl::DLSSGMode) 3)
{
currently_active_tech = new AntiLag2();
if (currently_active_tech->init(pDevice))
@@ -83,7 +84,7 @@ bool LowLatency::update_low_latency_tech(IUnknown* pDevice)
bool change_detected = last_force_latencyflex != force_latencyflex;
last_force_latencyflex = force_latencyflex;
if (State::Instance().fakenvapiReloadLowLatency && Config::Instance()->FramerateTargetDMFG.value_or_default() == 0)
if (State::Instance().fakenvapiReloadLowLatency)
{
change_detected = true;
State::Instance().fakenvapiReloadLowLatency = false;
@@ -143,8 +143,14 @@ void AntiLag2::deinit()
amdxc64_load_times = 0;
}
if (dx12_ctx.m_pAntiLagAPI && !AMD::AntiLag2DX12::DeInitialize(&dx12_ctx))
LOG_INFO("FSR Latency Reduction 2.0 DX12 deinitialized");
if (dx12_ctx.m_pAntiLagAPI)
{
// WAR for AL2 not deiniting properly when it's enabled
AMD::AntiLag2DX12::Update(&dx12_ctx, false, 0);
if (!AMD::AntiLag2DX12::DeInitialize(&dx12_ctx))
LOG_INFO("FSR Latency Reduction 2.0 DX12 deinitialized");
}
if (dx11_ctx.m_pAntiLagAPI && !AMD::AntiLag2DX11::DeInitialize(&dx11_ctx))
LOG_INFO("FSR Latency Reduction 2.0 DX11 deinitialized");
@@ -43,7 +43,7 @@ bool LowLatency::update_low_latency_tech(HANDLE vkDevice)
bool change_detected = last_force_latencyflex != force_latencyflex;
last_force_latencyflex = force_latencyflex;
if (State::Instance().fakenvapiReloadLowLatency && Config::Instance()->FramerateTargetDMFG.value_or_default() == 0)
if (State::Instance().fakenvapiReloadLowLatency)
{
change_detected = true;
State::Instance().fakenvapiReloadLowLatency = false;
@@ -724,35 +724,6 @@ NvAPI_Status __cdecl NvAPI_DRS_GetBaseProfile(NvDRSSessionHandle session, NvDRSP
NvAPI_Status __cdecl NvAPI_DRS_GetSetting(NvDRSSessionHandle hSession, NvDRSProfileHandle hProfile, NvU32 settingId,
NVDRS_SETTING* pSetting)
{
auto setting = (ESetting) settingId;
auto dmfgFpsTarget = Config::Instance()->FramerateTargetDMFG.value_or_default();
if (setting == NGX_DLSSG_MODE_ID && dmfgFpsTarget != 0)
{
pSetting->settingId = settingId;
constexpr auto name = L"NGX_DLSSG_MODE_ID";
memcpy_s(pSetting->settingName, sizeof(pSetting->settingName), name, sizeof(*name) * wcslen(name));
pSetting->settingType = NVDRS_DWORD_TYPE;
pSetting->u32CurrentValue = NGX_DLSSG_MODE_DYNAMIC;
LOG_DEBUG("Set NGX_DLSSG_MODE_ID");
return OK();
}
if (setting == NGX_DLSSG_DYNAMIC_TARGET_FRAME_RATE_ID && dmfgFpsTarget != 0)
{
pSetting->settingId = settingId;
constexpr auto name = L"NGX_DLSSG_DYNAMIC_TARGET_FRAME_RATE_ID";
memcpy_s(pSetting->settingName, sizeof(pSetting->settingName), name, sizeof(*name) * wcslen(name));
pSetting->settingType = NVDRS_DWORD_TYPE;
pSetting->u32CurrentValue = dmfgFpsTarget;
LOG_DEBUG("Set NGX_DLSSG_DYNAMIC_TARGET_FRAME_RATE_ID to {}", pSetting->u32CurrentValue);
return OK();
}
LOG_DEBUG("Missing get setting: {:X}", settingId);
return OK();
}