From 54d99b430b0dccfa2faeddbca1d1b0779a2d14a5 Mon Sep 17 00:00:00 2001 From: FakeMichau <49685661+FakeMichau@users.noreply.github.com> Date: Sun, 21 Jun 2026 00:27:47 +0200 Subject: [PATCH] Restore sleep mode when switching low latency tech + stop using reflex to calculate fake frames count Now it strictly uses what's being sent via NVNGX to DLSSG --- OptiScaler/hooks/Reflex_Hooks.cpp | 122 +++++++++--------- OptiScaler/nvapi/fakenvapi/low_latency.h | 1 + .../nvapi/fakenvapi/low_latency_d3d.cpp | 15 ++- 3 files changed, 71 insertions(+), 67 deletions(-) diff --git a/OptiScaler/hooks/Reflex_Hooks.cpp b/OptiScaler/hooks/Reflex_Hooks.cpp index 39611ae2..ce2eec07 100644 --- a/OptiScaler/hooks/Reflex_Hooks.cpp +++ b/OptiScaler/hooks/Reflex_Hooks.cpp @@ -269,77 +269,77 @@ NvAPI_Status ReflexHooks::hkNvAPI_D3D12_SetAsyncFrameMarker(ID3D12CommandQueue* _lastAsyncMarkerFrameId = pSetAsyncFrameMarkerParams->frameID; - if (pSetAsyncFrameMarkerParams->markerType == OUT_OF_BAND_PRESENT_START) - { - constexpr size_t history_size = 20; - static size_t counter = 0; - static NvU64 previous_frame_ids[history_size] = {}; + // if (pSetAsyncFrameMarkerParams->markerType == OUT_OF_BAND_PRESENT_START) + //{ + // constexpr size_t history_size = 20; + // static size_t counter = 0; + // static NvU64 previous_frame_ids[history_size] = {}; - previous_frame_ids[counter % history_size] = pSetAsyncFrameMarkerParams->frameID; - counter++; + // previous_frame_ids[counter % history_size] = pSetAsyncFrameMarkerParams->frameID; + // counter++; - size_t valid_count = (counter < history_size) ? counter : history_size; + // size_t valid_count = (counter < history_size) ? counter : history_size; - size_t max_run_length = 1; - size_t current_run = 1; + // size_t max_run_length = 1; + // size_t current_run = 1; - for (size_t i = 1; i < valid_count; i++) - { - if (previous_frame_ids[i] == previous_frame_ids[i - 1]) - { - current_run++; - } - else - { - max_run_length = std::max(max_run_length, current_run); - current_run = 1; - } - } + // for (size_t i = 1; i < valid_count; i++) + // { + // if (previous_frame_ids[i] == previous_frame_ids[i - 1]) + // { + // current_run++; + // } + // else + // { + // max_run_length = std::max(max_run_length, current_run); + // current_run = 1; + // } + // } - max_run_length = std::max(max_run_length, current_run); + // max_run_length = std::max(max_run_length, current_run); - int detected_mode = 0; - if (max_run_length >= 4) - detected_mode = 3; - else if (max_run_length == 3) - detected_mode = 2; - else if (max_run_length == 2) - detected_mode = 1; + // int detected_mode = 0; + // if (max_run_length >= 4) + // detected_mode = 3; + // else if (max_run_length == 3) + // detected_mode = 2; + // else if (max_run_length == 2) + // detected_mode = 1; - // --- Stability filter --- - static int candidate_mode = 0; // No FG at start - static int candidate_count = 0; - constexpr int stability_threshold = 4; + // // --- Stability filter --- + // static int candidate_mode = 0; // No FG at start + // static int candidate_count = 0; + // constexpr int stability_threshold = 4; - if (detected_mode == candidate_mode) - { - candidate_count++; - } - else - { - candidate_mode = detected_mode; - candidate_count = 1; - } + // if (detected_mode == candidate_mode) + // { + // candidate_count++; + // } + // else + // { + // candidate_mode = detected_mode; + // candidate_count = 1; + // } - // Redundant - // max_run_length = std::max(max_run_length, current_run); + // // Redundant + // // max_run_length = std::max(max_run_length, current_run); - // Only commit after stable detection - if (candidate_count >= stability_threshold) - { - if (candidate_mode == 0 && _FgNumFramesToGenerate > 0) - { - _FgNumFramesToGenerate = 0; - LOG_DEBUG("DLSS FG no longer detected"); - } - else if (_FgNumFramesToGenerate != candidate_mode) - { - _FgNumFramesToGenerate = candidate_mode; + // // Only commit after stable detection + // if (candidate_count >= stability_threshold) + // { + // if (candidate_mode == 0 && _FgNumFramesToGenerate > 0) + // { + // _FgNumFramesToGenerate = 0; + // LOG_DEBUG("DLSS FG no longer detected"); + // } + // else if (_FgNumFramesToGenerate != candidate_mode) + // { + // _FgNumFramesToGenerate = candidate_mode; - LOG_DEBUG("DLSS FG detected: {}x mode", candidate_mode + 1); - } - } - } + // LOG_DEBUG("DLSS FG detected: {}x mode", candidate_mode + 1); + // } + // } + //} if (State::Instance().activeFgOutput == FGOutput::XeFG) return nvapi_calls::NvAPI_D3D12_SetAsyncFrameMarker(pCommandQueue, pSetAsyncFrameMarkerParams); @@ -621,7 +621,9 @@ void ReflexHooks::update(bool fgActive, bool isVulkan) // 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 more than 1 fake frame if (Config::Instance()->FN_ForceReflex.value_or_default() != ForceReflex::ForceEnable && diff --git a/OptiScaler/nvapi/fakenvapi/low_latency.h b/OptiScaler/nvapi/fakenvapi/low_latency.h index aa008928..33281967 100644 --- a/OptiScaler/nvapi/fakenvapi/low_latency.h +++ b/OptiScaler/nvapi/fakenvapi/low_latency.h @@ -16,6 +16,7 @@ class LowLatency std::optional forced_fg; bool fg; uint32_t delay_deinit = 0; + SleepMode last_sleep_mode {}; // Once set, it will be used for all init attempts void* forced_low_latency_context = nullptr; diff --git a/OptiScaler/nvapi/fakenvapi/low_latency_d3d.cpp b/OptiScaler/nvapi/fakenvapi/low_latency_d3d.cpp index 64de65f3..b326cc5b 100644 --- a/OptiScaler/nvapi/fakenvapi/low_latency_d3d.cpp +++ b/OptiScaler/nvapi/fakenvapi/low_latency_d3d.cpp @@ -51,6 +51,7 @@ bool LowLatency::update_low_latency_tech(IUnknown* pDevice) if (new_tech_al2->init(pDevice)) { LOG_INFO("LowLatency algo: FSR Latency Reduction 2.0"); + new_tech_al2->set_sleep_mode(&last_sleep_mode); currently_active_tech.store(std::move(new_tech_al2)); return true; } @@ -59,6 +60,7 @@ bool LowLatency::update_low_latency_tech(IUnknown* pDevice) 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; } @@ -68,6 +70,7 @@ bool LowLatency::update_low_latency_tech(IUnknown* pDevice) 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; } @@ -231,15 +234,13 @@ NvAPI_Status LowLatency::SetSleepMode(IUnknown* pDevice, NV_SET_SLEEP_MODE_PARAM if (!update_low_latency_tech(pDevice)) 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 = pSetSleepModeParams->bUseMarkersToOptimize; + 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(&sleep_mode); + current_tech->set_sleep_mode(&last_sleep_mode); return OK(); }