diff --git a/OptiScaler/NVNGX_Parameter.h b/OptiScaler/NVNGX_Parameter.h index f40075bb..9a2cbeca 100644 --- a/OptiScaler/NVNGX_Parameter.h +++ b/OptiScaler/NVNGX_Parameter.h @@ -530,7 +530,15 @@ inline static void InitNGXParameters(NVSDK_NGX_Parameter* InParams) InParams->Set("FrameInterpolation.Available", 1); InParams->Set(NVSDK_NGX_Parameter_FrameInterpolation_NeedsUpdatedDriver, 0); InParams->Set(NVSDK_NGX_Parameter_FrameInterpolation_FeatureInitResult, 1); - InParams->Set("DLSSG.MultiFrameCountMax", 1); + + if (State::Instance().NukemsMFG) + { + InParams->Set("DLSSG.MultiFrameCountMax", 3); + } + else + { + InParams->Set("DLSSG.MultiFrameCountMax", 1); + } if (State::Instance().NVNGX_Engine == NVSDK_NGX_ENGINE_TYPE_UNREAL || State::Instance().gameQuirks & GameQuirk::ForceUnrealEngine) diff --git a/OptiScaler/State.h b/OptiScaler/State.h index f2e19cfd..476e373c 100644 --- a/OptiScaler/State.h +++ b/OptiScaler/State.h @@ -85,6 +85,7 @@ class State // DLSSG bool NukemsFilesAvailable = false; + bool NukemsMFG = false; bool DLSSGDebugView = false; bool DLSSGInterpolatedOnly = false; uint32_t delayMenuRenderBy = 0; diff --git a/OptiScaler/hooks/Advapi32_Hooks.h b/OptiScaler/hooks/Advapi32_Hooks.h index 1832581b..e1916320 100644 --- a/OptiScaler/hooks/Advapi32_Hooks.h +++ b/OptiScaler/hooks/Advapi32_Hooks.h @@ -22,8 +22,10 @@ static PFN_RegQueryValueExA o_RegQueryValueExA = nullptr; VALIDATE_HOOK(hkRegOpenKeyExW, PFN_RegOpenKeyExW) static LSTATUS hkRegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult) { - if (lpSubKey != nullptr && (wcscmp(L"SOFTWARE\\NVIDIA Corporation\\Global", lpSubKey) == 0 || - wcscmp(L"SYSTEM\\ControlSet001\\Services\\nvlddmkm", lpSubKey) == 0)) + if (lpSubKey != nullptr && + (wcscmp(L"SOFTWARE\\NVIDIA Corporation\\Global", lpSubKey) == 0 || + wcscmp(L"SYSTEM\\ControlSet001\\Services\\nvlddmkm", lpSubKey) == 0) && + !State::Instance().NukemsMFG) { *phkResult = signatureMark; return 0; diff --git a/OptiScaler/inputs/FG/DLSSG_Mod.h b/OptiScaler/inputs/FG/DLSSG_Mod.h index 9f533924..c3e1bff3 100644 --- a/OptiScaler/inputs/FG/DLSSG_Mod.h +++ b/OptiScaler/inputs/FG/DLSSG_Mod.h @@ -51,7 +51,7 @@ class DLSSGMod // DLSSGTOFSR3_EnableInterpolatedFramesOnly static inline void setSetting(const wchar_t* setting, const wchar_t* value) { - if (is120orNewer()) + if (is120orNewer() && !State::Instance().NukemsMFG) { SetEnvironmentVariable(setting, value); _refreshGlobalConfiguration(); @@ -66,8 +66,40 @@ class DLSSGMod if (_dx12_inited || Config::Instance()->FGInput.value_or_default() != FGInput::Nukems) return; - if (_dll == nullptr) + auto dllPath = Util::DllPath().parent_path() / "fsr3fg_mfg.asi"; + + // set early so the hooks know + State::Instance().NukemsMFG = true; + _dll = NtdllProxy::LoadLibraryExW_Ldr(dllPath.c_str(), NULL, 0); + + if (_dll != nullptr) { + _DLSSG_D3D12_Init = (PFN_D3D12_Init) GetProcAddress(_dll, "DLSSG_NVSDK_NGX_D3D12_Init"); + _DLSSG_D3D12_Init_Ext = (PFN_D3D12_Init_Ext) GetProcAddress(_dll, "DLSSG_NVSDK_NGX_D3D12_Init_Ext"); + _DLSSG_D3D12_Shutdown = (PFN_D3D12_Shutdown) GetProcAddress(_dll, "DLSSG_NVSDK_NGX_D3D12_Shutdown"); + _DLSSG_D3D12_Shutdown1 = (PFN_D3D12_Shutdown1) GetProcAddress(_dll, "DLSSG_NVSDK_NGX_D3D12_Shutdown1"); + _DLSSG_D3D12_GetScratchBufferSize = + (PFN_D3D12_GetScratchBufferSize) GetProcAddress(_dll, "DLSSG_NVSDK_NGX_D3D12_GetScratchBufferSize"); + _DLSSG_D3D12_CreateFeature = + (PFN_D3D12_CreateFeature) GetProcAddress(_dll, "DLSSG_NVSDK_NGX_D3D12_CreateFeature"); + _DLSSG_D3D12_ReleaseFeature = + (PFN_D3D12_ReleaseFeature) GetProcAddress(_dll, "DLSSG_NVSDK_NGX_D3D12_ReleaseFeature"); + _DLSSG_D3D12_GetFeatureRequirements = + (PFN_D3D12_GetFeatureRequirements) GetProcAddress(_dll, "DLSSG_NVSDK_NGX_D3D12_GetFeatureRequirements"); + _DLSSG_D3D12_EvaluateFeature = + (PFN_D3D12_EvaluateFeature) GetProcAddress(_dll, "DLSSG_NVSDK_NGX_D3D12_EvaluateFeature"); + _DLSSG_D3D12_PopulateParameters_Impl = (PFN_D3D12_PopulateParameters_Impl) GetProcAddress( + _dll, "DLSSG_NVSDK_NGX_D3D12_PopulateParameters_Impl"); + _dx12_inited = true; + + LOG_INFO("DLSSG MFG Mod initialized for DX12"); + + return; + } + else + { + State::Instance().NukemsMFG = false; + auto dllPath = Util::DllPath().parent_path() / "dlssg_to_fsr3_amd_is_better.dll"; _dll = NtdllProxy::LoadLibraryExW_Ldr(dllPath.c_str(), NULL, 0); } diff --git a/OptiScaler/menu/menu_common.cpp b/OptiScaler/menu/menu_common.cpp index fe14632b..3d6b04eb 100644 --- a/OptiScaler/menu/menu_common.cpp +++ b/OptiScaler/menu/menu_common.cpp @@ -3970,7 +3970,8 @@ bool MenuCommon::RenderMenu() } // Nukems Mod - if (state.activeFgInput == FGInput::Nukems && state.activeFgOutput == FGOutput::Nukems) + if (state.activeFgInput == FGInput::Nukems && state.activeFgOutput == FGOutput::Nukems && + !State::Instance().NukemsMFG) { SeparatorWithHelpMarker("Frame Generation (FSR3-FG via Nukem's DLSSG)", "Requires Nukem's dlssg_to_fsr3 dll\nSelect DLSS-FG in-game"); @@ -4035,6 +4036,13 @@ bool MenuCommon::RenderMenu() } } + if (state.activeFgInput == FGInput::Nukems && state.activeFgOutput == FGOutput::Nukems && + State::Instance().NukemsMFG) + { + ImGui::Text( + "Using Nukem's via the MFG mod from fsr3fg_mfg.asi\nSelect MFG from the game's options"); + } + // FSR-FG Inputs if (state.currentFGSwapchain != nullptr && (state.activeFgInput == FGInput::FSRFG || state.activeFgInput == FGInput::FSRFG30))