From 0de095a05ea383adb52c105d013ad6e0dfb285af Mon Sep 17 00:00:00 2001 From: FakeMichau <49685661+FakeMichau@users.noreply.github.com> Date: Tue, 26 Aug 2025 14:10:05 +0200 Subject: [PATCH 01/10] SL Inputs: make hudless optional, add option to disable hudless --- OptiScaler/Config.h | 3 ++- OptiScaler/framegen/IFGFeature.cpp | 8 ++++++ OptiScaler/framegen/IFGFeature.h | 1 + OptiScaler/framegen/IFGFeature_Dx12.cpp | 2 +- OptiScaler/framegen/ffx/FSRFG_Dx12.cpp | 6 ++++- OptiScaler/framegen/xefg/XeFG_Dx12.cpp | 27 ++++++++++++++----- .../inputs/FG/Streamline_Inputs_Dx12.cpp | 9 +++++++ OptiScaler/inputs/FG/Streamline_Inputs_Dx12.h | 3 +++ OptiScaler/menu/menu_common.cpp | 26 ++++++++++++++++++ 9 files changed, 75 insertions(+), 10 deletions(-) diff --git a/OptiScaler/Config.h b/OptiScaler/Config.h index f00cb444..d69f1be1 100644 --- a/OptiScaler/Config.h +++ b/OptiScaler/Config.h @@ -350,8 +350,9 @@ class Config // Frame Generation CustomOptional FGInput { FGInput::NoFG }; CustomOptional FGOutput { FGOutput::NoFG }; - CustomOptional DrawUIOverFG { false }; + CustomOptional DrawUIOverFG { false }; // TODO: not saved CustomOptional UIPremultipliedAlpha { true }; + CustomOptional DisableHudless { false }; // OptiFG CustomOptional FGEnabled { false }; diff --git a/OptiScaler/framegen/IFGFeature.cpp b/OptiScaler/framegen/IFGFeature.cpp index 63cd1676..bd97dc75 100644 --- a/OptiScaler/framegen/IFGFeature.cpp +++ b/OptiScaler/framegen/IFGFeature.cpp @@ -63,6 +63,14 @@ bool IFGFeature::IsUsingUIAny() } bool IFGFeature::IsUsingDistortionField() { return !_noDistortionField[GetIndex()]; } bool IFGFeature::IsUsingHudless() { return !_noHudless[GetIndex()]; } +bool IFGFeature::IsUsingHudlessAny() +{ + for (const auto& value : _noHudless) + if (value == false) + return true; + + return false; +} bool IFGFeature::CheckForRealObject(std::string functionName, IUnknown* pObject, IUnknown** ppRealObject) { diff --git a/OptiScaler/framegen/IFGFeature.h b/OptiScaler/framegen/IFGFeature.h index d3995125..95aec8d9 100644 --- a/OptiScaler/framegen/IFGFeature.h +++ b/OptiScaler/framegen/IFGFeature.h @@ -112,6 +112,7 @@ class IFGFeature bool IsUsingUIAny(); // Same as IsUsingUI but checks if at least once buffer has UI bool IsUsingDistortionField(); bool IsUsingHudless(); + bool IsUsingHudlessAny(); void SetExecuted(); bool WaitingExecution(int index = -1); diff --git a/OptiScaler/framegen/IFGFeature_Dx12.cpp b/OptiScaler/framegen/IFGFeature_Dx12.cpp index 64972a2e..51cafdf2 100644 --- a/OptiScaler/framegen/IFGFeature_Dx12.cpp +++ b/OptiScaler/framegen/IFGFeature_Dx12.cpp @@ -12,7 +12,7 @@ bool IFGFeature_Dx12::GetResourceCopy(FG_ResourceType type, D3D12_RESOURCE_STATE auto resource = GetResource(type); - if (resource->copy == nullptr && resource->validity == FG_ResourceValidity::ValidNow) + if (!resource || resource->copy == nullptr && resource->validity == FG_ResourceValidity::ValidNow) { LOG_WARN("No resource copy of type {} to use", magic_enum::enum_name(type)); return false; diff --git a/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp b/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp index bf0818f2..a2f75530 100644 --- a/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp +++ b/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp @@ -839,7 +839,12 @@ void FSRFG_Dx12::SetResource(Dx12Resource* inputResource) if (inputResource == nullptr || inputResource->resource == nullptr) return; + auto fIndex = GetIndex(); auto& type = inputResource->type; + + if (type == FG_ResourceType::HudlessColor && Config::Instance()->DisableHudless.value_or_default()) + return; + std::lock_guard lock(_frMutex); if (inputResource->cmdList == nullptr && inputResource->validity == FG_ResourceValidity::ValidNow) @@ -848,7 +853,6 @@ void FSRFG_Dx12::SetResource(Dx12Resource* inputResource) return; } - auto fIndex = GetIndex(); _frameResources[fIndex][type] = {}; auto fResource = &_frameResources[fIndex][type]; fResource->type = type; diff --git a/OptiScaler/framegen/xefg/XeFG_Dx12.cpp b/OptiScaler/framegen/xefg/XeFG_Dx12.cpp index d00a5f6d..e35bb56a 100644 --- a/OptiScaler/framegen/xefg/XeFG_Dx12.cpp +++ b/OptiScaler/framegen/xefg/XeFG_Dx12.cpp @@ -534,13 +534,22 @@ bool XeFG_Dx12::Dispatch() LOG_DEBUG("SwapChain Res: {}x{}, Interpolation Res: {}x{}", scDesc1.BufferDesc.Width, scDesc1.BufferDesc.Height, _interpolationWidth[fIndex], _interpolationHeight[fIndex]); - auto calculatedLeft = ((int) scDesc1.BufferDesc.Width - (int) _interpolationWidth[fIndex]) / 2; - if (calculatedLeft > 0) - left = Config::Instance()->FGRectLeft.value_or(_interpolationLeft[fIndex].value_or(calculatedLeft)); + if (_interpolationWidth[fIndex] == 0 && _interpolationHeight[fIndex] == 0) + { + LOG_WARN("Interpolation size is 0, using swapchain size"); + _interpolationWidth[fIndex] = scDesc1.BufferDesc.Width; + _interpolationHeight[fIndex] = scDesc1.BufferDesc.Height; + } + else + { + auto calculatedLeft = ((int) scDesc1.BufferDesc.Width - (int) _interpolationWidth[fIndex]) / 2; + if (calculatedLeft > 0) + left = Config::Instance()->FGRectLeft.value_or(_interpolationLeft[fIndex].value_or(calculatedLeft)); - auto calculatedTop = ((int) scDesc1.BufferDesc.Height - (int) _interpolationHeight[fIndex]) / 2; - if (calculatedTop > 0) - top = Config::Instance()->FGRectTop.value_or(_interpolationTop[fIndex].value_or(calculatedTop)); + auto calculatedTop = ((int) scDesc1.BufferDesc.Height - (int) _interpolationHeight[fIndex]) / 2; + if (calculatedTop > 0) + top = Config::Instance()->FGRectTop.value_or(_interpolationTop[fIndex].value_or(calculatedTop)); + } } else { @@ -696,7 +705,12 @@ void XeFG_Dx12::SetResource(Dx12Resource* inputResource) if (inputResource == nullptr || inputResource->resource == nullptr) return; + auto fIndex = GetIndex(); auto& type = inputResource->type; + + if (type == FG_ResourceType::HudlessColor && Config::Instance()->DisableHudless.value_or_default()) + return; + std::lock_guard lock(_frMutex); if (inputResource->cmdList == nullptr && inputResource->validity == FG_ResourceValidity::ValidNow) @@ -711,7 +725,6 @@ void XeFG_Dx12::SetResource(Dx12Resource* inputResource) return; } - auto fIndex = GetIndex(); auto fResource = &_frameResources[fIndex][type]; fResource->type = type; fResource->state = inputResource->state; diff --git a/OptiScaler/inputs/FG/Streamline_Inputs_Dx12.cpp b/OptiScaler/inputs/FG/Streamline_Inputs_Dx12.cpp index b4e16cbd..246689ca 100644 --- a/OptiScaler/inputs/FG/Streamline_Inputs_Dx12.cpp +++ b/OptiScaler/inputs/FG/Streamline_Inputs_Dx12.cpp @@ -323,6 +323,13 @@ bool Sl_Inputs_Dx12::reportResource(const sl::ResourceTag& tag, ID3D12GraphicsCo setResource.validity = validity; fgOutput->SetResource(&setResource); + + // Use UI size as fallback for interpolated size + if (interpolationWidth == 0 && interpolationHeight == 0) + { + interpolationWidth = width; + interpolationHeight = height; + } } else if (tag.type == sl::kBufferTypeBidirectionalDistortionField) { @@ -476,6 +483,8 @@ bool Sl_Inputs_Dx12::dispatchFG() fgOutput->SetReset(slConstsRef.reset == sl::Boolean::eTrue); fgOutput->SetInterpolationRect(interpolationWidth, interpolationHeight); + interpolationWidth = 0; + interpolationHeight = 0; return true; } diff --git a/OptiScaler/inputs/FG/Streamline_Inputs_Dx12.h b/OptiScaler/inputs/FG/Streamline_Inputs_Dx12.h index 09dd3ee5..447801c9 100644 --- a/OptiScaler/inputs/FG/Streamline_Inputs_Dx12.h +++ b/OptiScaler/inputs/FG/Streamline_Inputs_Dx12.h @@ -22,6 +22,9 @@ class Sl_Inputs_Dx12 uint32_t mvsWidth = 0; uint32_t mvsHeight = 0; + // TODO: add full position + // uint32_t interpolationTop = 0; + // uint32_t interpolationLeft = 0; uint32_t interpolationWidth = 0; uint32_t interpolationHeight = 0; diff --git a/OptiScaler/menu/menu_common.cpp b/OptiScaler/menu/menu_common.cpp index db00b9d8..51a91f4f 100644 --- a/OptiScaler/menu/menu_common.cpp +++ b/OptiScaler/menu/menu_common.cpp @@ -3406,6 +3406,18 @@ bool MenuCommon::RenderMenu() Config::Instance()->UIPremultipliedAlpha = uiPremultipliedAlpha; ImGui::EndDisabled(); + + bool disableHudless = Config::Instance()->DisableHudless.value_or_default(); + ImGui::BeginDisabled(!fgOutput->IsUsingHudlessAny() && !disableHudless); + + // TODO: doesn't save to config + if (ImGui::Checkbox("Disable hudless", &disableHudless)) + { + Config::Instance()->DisableHudless = disableHudless; + State::Instance().FGchanged = true; + } + + ShowHelpMarker("For when the game sends hudless but you want to disable it"); } else { @@ -3456,6 +3468,20 @@ bool MenuCommon::RenderMenu() Config::Instance()->UIPremultipliedAlpha = uiPremultipliedAlpha; ImGui::EndDisabled(); + + bool disableHudless = Config::Instance()->DisableHudless.value_or_default(); + ImGui::BeginDisabled(!fgOutput->IsUsingHudlessAny() && !disableHudless); + + // TODO: doesn't save to config + if (ImGui::Checkbox("Disable hudless", &disableHudless)) + { + Config::Instance()->DisableHudless = disableHudless; + State::Instance().FGchanged = true; + } + + ShowHelpMarker("For when the game sends hudless but you want to disable it"); + + ImGui::EndDisabled(); } else { From 4573d85961634df5a46de38d599cc89edb81c000 Mon Sep 17 00:00:00 2001 From: FakeMichau <49685661+FakeMichau@users.noreply.github.com> Date: Tue, 26 Aug 2025 20:18:30 +0200 Subject: [PATCH 02/10] Add support for the new SDK in the amdxc64-less FSR 4 --- OptiScaler/fsr4/FSR4Upgrade.h | 78 +++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/OptiScaler/fsr4/FSR4Upgrade.h b/OptiScaler/fsr4/FSR4Upgrade.h index eeeab1a0..5fd0831a 100644 --- a/OptiScaler/fsr4/FSR4Upgrade.h +++ b/OptiScaler/fsr4/FSR4Upgrade.h @@ -147,6 +147,73 @@ inline static std::vector GetDriverStore() #pragma endregion +#define STUB(number) \ + HRESULT STDMETHODCALLTYPE unknown##number() \ + { \ + LOG_FUNC(); \ + return S_OK; \ + } + +MIDL_INTERFACE("F714E11A-B54E-4E0F-ABC5-DF58B18133D1") +IAmdExtFfxThird : public IUnknown +{ + virtual HRESULT unknown1() = 0; // not used + virtual HRESULT unknown2() = 0; // not used + virtual HRESULT unknown3() = 0; // not used + virtual HRESULT unknown4() = 0; // not used + virtual HRESULT unknown5() = 0; // not used + virtual HRESULT unknown6() = 0; // not used + virtual HRESULT unknown7() = 0; // not used + virtual HRESULT unknown8() = 0; // not used + virtual HRESULT unknown9() = 0; // not used + virtual HRESULT unknown10() = 0; // not used + virtual HRESULT unknown11() = 0; // not used + virtual HRESULT unknown12() = 0; // not used + virtual HRESULT unknown13() = 0; // not used + virtual HRESULT unknown14(uint64_t* a, uint8_t* data) = 0; +}; + +struct AmdExtFfxThird : public IAmdExtFfxThird +{ + STUB(1) + STUB(2) + STUB(3) + STUB(4) + STUB(5) + STUB(6) + STUB(7) + STUB(8) + STUB(9) + STUB(10) + STUB(11) + STUB(12) + STUB(13) + HRESULT STDMETHODCALLTYPE unknown14(uint64_t* a, uint8_t* data) + { + LOG_TRACE(": {}", *a); + + *reinterpret_cast(&data[0x00]) = 16; + *reinterpret_cast(&data[0x08]) = 16; + *reinterpret_cast(&data[0x10]) = 16; + + *reinterpret_cast(&data[0x18]) = 11; + *reinterpret_cast(&data[0x1C]) = 11; + + *reinterpret_cast(&data[0x20]) = 1; + *reinterpret_cast(&data[0x24]) = 1; + + data[0x28] = 0; + + return S_OK; + } + + HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override { return E_NOTIMPL; } + ULONG __stdcall AddRef(void) override { return 0; } + ULONG __stdcall Release(void) override { return 0; } +}; + +static AmdExtFfxThird* _amdExtFfxThird = nullptr; + // Internal interfaces needed for custom the IAmdExtFfxApi MIDL_INTERFACE("BA019D53-CCAB-4CBD-B56A-7230ED4330AD") IAmdExtFfxSecond : public IUnknown @@ -204,6 +271,17 @@ struct AmdExtFfxFirst : public IAmdExtFfxFirst return S_OK; } + else if (riid == __uuidof(IAmdExtFfxThird)) + { + if (_amdExtFfxThird == nullptr) + _amdExtFfxThird = new AmdExtFfxThird(); + + *ppvObject = _amdExtFfxThird; + + LOG_INFO("Custom IAmdExtFfxThird queried, returning custom AmdExtFfxThird"); + + return S_OK; + } return E_NOINTERFACE; } From 9a17bae4cc13fefb90b2ae10f9b862f8b2c3c731 Mon Sep 17 00:00:00 2001 From: FakeMichau <49685661+FakeMichau@users.noreply.github.com> Date: Tue, 26 Aug 2025 20:28:06 +0200 Subject: [PATCH 03/10] Bump version to pre 2 --- OptiScaler/resource.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OptiScaler/resource.h b/OptiScaler/resource.h index 9b04bd13..8d68cdea 100644 --- a/OptiScaler/resource.h +++ b/OptiScaler/resource.h @@ -27,7 +27,7 @@ #define VER_MAJOR_VERSION 0 #define VER_MINOR_VERSION 9 #define VER_HOTFIX_VERSION 0 -#define VER_BUILD_NUMBER 1 +#define VER_BUILD_NUMBER 2 #define VER_PRE_RELEASE From f3f615f690951beb84041321669133c39e10a9b1 Mon Sep 17 00:00:00 2001 From: FakeMichau <49685661+FakeMichau@users.noreply.github.com> Date: Wed, 27 Aug 2025 10:48:37 +0200 Subject: [PATCH 04/10] Reorder quirk checks --- OptiScaler/dllmain.cpp | 61 +++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/OptiScaler/dllmain.cpp b/OptiScaler/dllmain.cpp index 4e85bfb8..05a633b6 100644 --- a/OptiScaler/dllmain.cpp +++ b/OptiScaler/dllmain.cpp @@ -992,6 +992,9 @@ static void CheckQuirks() if (quirks & GameQuirk::DisableFFXInputs && !Config::Instance()->EnableFfxInputs.has_value()) Config::Instance()->EnableFfxInputs.set_volatile_value(false); + if (quirks & GameQuirk::DisableDxgiSpoofing && !Config::Instance()->DxgiSpoofing.has_value()) + Config::Instance()->DxgiSpoofing.set_volatile_value(false); + if (quirks & GameQuirk::RestoreComputeSigOnNonNvidia && !State::Instance().isRunningOnNvidia && !Config::Instance()->DxgiSpoofing.value_or_default() && !Config::Instance()->RestoreComputeSignature.has_value()) @@ -1014,9 +1017,6 @@ static void CheckQuirks() if (quirks & GameQuirk::DisableUseFsrInputValues) Config::Instance()->FsrUseFsrInputValues.set_volatile_value(false); - if (quirks & GameQuirk::DisableDxgiSpoofing && !Config::Instance()->DxgiSpoofing.has_value()) - Config::Instance()->DxgiSpoofing.set_volatile_value(false); - if (quirks & GameQuirk::EnableVulkanSpoofing && !State::Instance().isRunningOnNvidia && !Config::Instance()->VulkanSpoofing.has_value()) Config::Instance()->VulkanSpoofing.set_volatile_value(true); @@ -1162,38 +1162,11 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv spdlog::warn("Can't read windows version"); spdlog::info(""); - CheckQuirks(); - - // OptiFG & Overlay Checks - // TODO: Either FGInput == FGInput::Upscaler or FGOutput == FGOutput::FSRFG - if ((Config::Instance()->FGInput.value_or_default() == FGInput::Upscaler) && - !Config::Instance()->DisableOverlays.has_value()) - Config::Instance()->DisableOverlays.set_volatile_value(true); - - if (Config::Instance()->DisableOverlays.value_or_default()) - SetEnvironmentVariable(L"SteamNoOverlayUIDrawing", L"1"); - - // Initial state of FG - State::Instance().activeFgInput = Config::Instance()->FGInput.value_or_default(); - State::Instance().activeFgOutput = Config::Instance()->FGOutput.value_or_default(); // Init Kernel proxies KernelBaseProxy::Init(); Kernel32Proxy::Init(); - // Hook FSR4 stuff as early as possible - spdlog::info(""); - InitFSR4Update(); - - // Check for Wine - spdlog::info(""); - State::Instance().isRunningOnLinux = IsRunningOnWine(); - State::Instance().isRunningOnDXVK = State::Instance().isRunningOnLinux; - - // Disable splash for Linux - if (!Config::Instance()->DisableSplash.has_value()) - Config::Instance()->DisableSplash.set_volatile_value(State::Instance().isRunningOnLinux); - // Check if real DLSS available if (Config::Instance()->DLSSEnabled.value_or_default()) { @@ -1221,6 +1194,34 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv } } + CheckQuirks(); + + // OptiFG & Overlay Checks + // TODO: Either FGInput == FGInput::Upscaler or FGOutput == FGOutput::FSRFG + if ((Config::Instance()->FGInput.value_or_default() == FGInput::Upscaler) && + !Config::Instance()->DisableOverlays.has_value()) + Config::Instance()->DisableOverlays.set_volatile_value(true); + + if (Config::Instance()->DisableOverlays.value_or_default()) + SetEnvironmentVariable(L"SteamNoOverlayUIDrawing", L"1"); + + // Initial state of FG + State::Instance().activeFgInput = Config::Instance()->FGInput.value_or_default(); + State::Instance().activeFgOutput = Config::Instance()->FGOutput.value_or_default(); + + // Hook FSR4 stuff as early as possible + spdlog::info(""); + InitFSR4Update(); + + // Check for Wine + spdlog::info(""); + State::Instance().isRunningOnLinux = IsRunningOnWine(); + State::Instance().isRunningOnDXVK = State::Instance().isRunningOnLinux; + + // Disable splash for Linux + if (!Config::Instance()->DisableSplash.has_value()) + Config::Instance()->DisableSplash.set_volatile_value(State::Instance().isRunningOnLinux); + if (!Config::Instance()->OverrideNvapiDll.has_value()) { spdlog::info("OverrideNvapiDll not set, setting it to: {}", From d271dd2bc06677772a0222a58c421f4a627b0bb5 Mon Sep 17 00:00:00 2001 From: FakeMichau <49685661+FakeMichau@users.noreply.github.com> Date: Wed, 27 Aug 2025 10:48:52 +0200 Subject: [PATCH 05/10] Enable splash on Linux --- OptiScaler/dllmain.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/OptiScaler/dllmain.cpp b/OptiScaler/dllmain.cpp index 05a633b6..1a22adae 100644 --- a/OptiScaler/dllmain.cpp +++ b/OptiScaler/dllmain.cpp @@ -1218,9 +1218,6 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv State::Instance().isRunningOnLinux = IsRunningOnWine(); State::Instance().isRunningOnDXVK = State::Instance().isRunningOnLinux; - // Disable splash for Linux - if (!Config::Instance()->DisableSplash.has_value()) - Config::Instance()->DisableSplash.set_volatile_value(State::Instance().isRunningOnLinux); if (!Config::Instance()->OverrideNvapiDll.has_value()) { From e2dcdf8017ed065ed6c871f60b66d545e0b24266 Mon Sep 17 00:00:00 2001 From: FakeMichau <49685661+FakeMichau@users.noreply.github.com> Date: Wed, 27 Aug 2025 10:59:37 +0200 Subject: [PATCH 06/10] Add missing EndDisabled --- OptiScaler/menu/menu_common.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OptiScaler/menu/menu_common.cpp b/OptiScaler/menu/menu_common.cpp index 51a91f4f..ec6bbb90 100644 --- a/OptiScaler/menu/menu_common.cpp +++ b/OptiScaler/menu/menu_common.cpp @@ -3418,6 +3418,8 @@ bool MenuCommon::RenderMenu() } ShowHelpMarker("For when the game sends hudless but you want to disable it"); + + ImGui::EndDisabled(); } else { From 014b63d13112079a1b8a6b645374f560006b9a39 Mon Sep 17 00:00:00 2001 From: FakeMichau <49685661+FakeMichau@users.noreply.github.com> Date: Wed, 27 Aug 2025 12:13:52 +0200 Subject: [PATCH 07/10] Add option to disable UI texture (active by default) and move settings under common tab --- OptiScaler/Config.h | 1 + OptiScaler/framegen/ffx/FSRFG_Dx12.cpp | 3 + OptiScaler/framegen/xefg/XeFG_Dx12.cpp | 8 +- OptiScaler/menu/menu_common.cpp | 120 ++++++++++++------------- 4 files changed, 67 insertions(+), 65 deletions(-) diff --git a/OptiScaler/Config.h b/OptiScaler/Config.h index d69f1be1..5ec49d64 100644 --- a/OptiScaler/Config.h +++ b/OptiScaler/Config.h @@ -353,6 +353,7 @@ class Config CustomOptional DrawUIOverFG { false }; // TODO: not saved CustomOptional UIPremultipliedAlpha { true }; CustomOptional DisableHudless { false }; + CustomOptional DisableUI { true }; // OptiFG CustomOptional FGEnabled { false }; diff --git a/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp b/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp index a2f75530..7052037c 100644 --- a/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp +++ b/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp @@ -845,6 +845,9 @@ void FSRFG_Dx12::SetResource(Dx12Resource* inputResource) if (type == FG_ResourceType::HudlessColor && Config::Instance()->DisableHudless.value_or_default()) return; + if (type == FG_ResourceType::UIColor && Config::Instance()->DisableUI.value_or_default()) + return; + std::lock_guard lock(_frMutex); if (inputResource->cmdList == nullptr && inputResource->validity == FG_ResourceValidity::ValidNow) diff --git a/OptiScaler/framegen/xefg/XeFG_Dx12.cpp b/OptiScaler/framegen/xefg/XeFG_Dx12.cpp index e35bb56a..109d379f 100644 --- a/OptiScaler/framegen/xefg/XeFG_Dx12.cpp +++ b/OptiScaler/framegen/xefg/XeFG_Dx12.cpp @@ -484,8 +484,9 @@ bool XeFG_Dx12::Dispatch() // Cyberpunk seems to be sending LH so do the same // it also sends some extra data in usually empty spots but no idea what that is - if (_cameraNear[fIndex] > 0.f && _cameraFar[fIndex] > 0.f && _cameraVFov[fIndex] > 0.00001f && - _cameraAspectRatio[fIndex] > 0.00001f) + if (_cameraNear[fIndex] > 0.f && _cameraFar[fIndex] > 0.f && + !XMScalarNearEqual(_cameraVFov[fIndex], 0.0f, 0.00001f) && + !XMScalarNearEqual(_cameraAspectRatio[fIndex], 0.0f, 0.00001f)) { if (XMScalarNearEqual(_cameraNear[fIndex], _cameraFar[fIndex], 0.00001f)) _cameraFar[fIndex]++; @@ -711,6 +712,9 @@ void XeFG_Dx12::SetResource(Dx12Resource* inputResource) if (type == FG_ResourceType::HudlessColor && Config::Instance()->DisableHudless.value_or_default()) return; + if (type == FG_ResourceType::UIColor && Config::Instance()->DisableUI.value_or_default()) + return; + std::lock_guard lock(_frMutex); if (inputResource->cmdList == nullptr && inputResource->validity == FG_ResourceValidity::ValidNow) diff --git a/OptiScaler/menu/menu_common.cpp b/OptiScaler/menu/menu_common.cpp index ec6bbb90..def1023e 100644 --- a/OptiScaler/menu/menu_common.cpp +++ b/OptiScaler/menu/menu_common.cpp @@ -2758,6 +2758,63 @@ bool MenuCommon::RenderMenu() ImGui::Spacing(); } + if (State::Instance().activeFgInput == FGInput::DLSSG || + State::Instance().activeFgInput == FGInput::FSRFG) + { + auto fgOutput = reinterpret_cast(State::Instance().currentFG); + if (fgOutput) + { + ImGui::BeginDisabled(!fgOutput->IsActive()); + const auto isUsingUIAny = fgOutput->IsUsingUIAny(); + const auto isUsingHudlessAny = fgOutput->IsUsingHudlessAny(); + + bool disableUI = Config::Instance()->DisableUI.value_or_default(); + ImGui::BeginDisabled(!isUsingUIAny && !disableUI); + + if (ImGui::Checkbox("Disable UI texture", &disableUI)) + { + Config::Instance()->DisableUI = disableUI; + State::Instance().FGchanged = true; + } + + ShowHelpMarker("For when the game sends a UI texture but you want to disable it"); + + ImGui::EndDisabled(); + + ImGui::SameLine(); + + bool disableHudless = Config::Instance()->DisableHudless.value_or_default(); + ImGui::BeginDisabled(!isUsingHudlessAny && !disableHudless); + + if (ImGui::Checkbox("Disable hudless", &disableHudless)) + { + // TODO: this can crash when toggling + Config::Instance()->DisableHudless = disableHudless; + State::Instance().FGchanged = true; + } + + ShowHelpMarker("For when the game sends hudless but you want to disable it"); + + ImGui::EndDisabled(); + + ImGui::BeginDisabled(!isUsingUIAny || !isUsingHudlessAny); + if (bool drawUIOverFG = Config::Instance()->DrawUIOverFG.value_or_default(); + ImGui::Checkbox("Draw UI over FG", &drawUIOverFG)) + Config::Instance()->DrawUIOverFG = drawUIOverFG; + ImGui::EndDisabled(); + + ImGui::SameLine(); + + ImGui::BeginDisabled(!isUsingUIAny); + if (bool uiPremultipliedAlpha = Config::Instance()->UIPremultipliedAlpha.value_or_default(); + ImGui::Checkbox("UI Premult. alpha", &uiPremultipliedAlpha)) + Config::Instance()->UIPremultipliedAlpha = uiPremultipliedAlpha; + ImGui::EndDisabled(); + + ImGui::EndDisabled(); + } + } + // FSR FG controls if (State::Instance().activeFgOutput == FGOutput::FSRFG && State::Instance().activeFgInput != FGInput::NoFG && @@ -3388,43 +3445,9 @@ bool MenuCommon::RenderMenu() if (State::Instance().FSRFGInputActive) { if (fgOutput->IsActive()) - { ImGui::TextColored(ImVec4(0.f, 1.f, 0.25f, 1.f), "ON"); - - ImGui::BeginDisabled(!fgOutput->IsUsingUIAny()); - - // TODO: doesn't save to config - if (bool drawUIOverFG = Config::Instance()->DrawUIOverFG.value_or_default(); - ImGui::Checkbox("Draw UI over FG", &drawUIOverFG)) - Config::Instance()->DrawUIOverFG = drawUIOverFG; - - ImGui::SameLine(); - - if (bool uiPremultipliedAlpha = - Config::Instance()->UIPremultipliedAlpha.value_or_default(); - ImGui::Checkbox("UI Premult. alpha", &uiPremultipliedAlpha)) - Config::Instance()->UIPremultipliedAlpha = uiPremultipliedAlpha; - - ImGui::EndDisabled(); - - bool disableHudless = Config::Instance()->DisableHudless.value_or_default(); - ImGui::BeginDisabled(!fgOutput->IsUsingHudlessAny() && !disableHudless); - - // TODO: doesn't save to config - if (ImGui::Checkbox("Disable hudless", &disableHudless)) - { - Config::Instance()->DisableHudless = disableHudless; - State::Instance().FGchanged = true; - } - - ShowHelpMarker("For when the game sends hudless but you want to disable it"); - - ImGui::EndDisabled(); - } else - { ImGui::TextColored(ImVec4(1.0f, 0.647f, 0.0f, 1.f), "ACTIVATE FG"); - } } else { @@ -3455,35 +3478,6 @@ bool MenuCommon::RenderMenu() if (fgOutput->IsActive()) { ImGui::TextColored(ImVec4(0.f, 1.f, 0.25f, 1.f), "ON"); - - ImGui::BeginDisabled(!fgOutput->IsUsingUIAny()); - - // TODO: doesn't save to config - if (bool drawUIOverFG = Config::Instance()->DrawUIOverFG.value_or_default(); - ImGui::Checkbox("Draw UI over FG", &drawUIOverFG)) - Config::Instance()->DrawUIOverFG = drawUIOverFG; - - ImGui::SameLine(); - - if (bool uiPremultipliedAlpha = Config::Instance()->UIPremultipliedAlpha.value_or_default(); - ImGui::Checkbox("UI Premult. alpha", &uiPremultipliedAlpha)) - Config::Instance()->UIPremultipliedAlpha = uiPremultipliedAlpha; - - ImGui::EndDisabled(); - - bool disableHudless = Config::Instance()->DisableHudless.value_or_default(); - ImGui::BeginDisabled(!fgOutput->IsUsingHudlessAny() && !disableHudless); - - // TODO: doesn't save to config - if (ImGui::Checkbox("Disable hudless", &disableHudless)) - { - Config::Instance()->DisableHudless = disableHudless; - State::Instance().FGchanged = true; - } - - ShowHelpMarker("For when the game sends hudless but you want to disable it"); - - ImGui::EndDisabled(); } else { From 4093f6e8ade2cb3ca3ff85909ea7c549c438533e Mon Sep 17 00:00:00 2001 From: FakeMichau <49685661+FakeMichau@users.noreply.github.com> Date: Wed, 27 Aug 2025 19:14:15 +0200 Subject: [PATCH 08/10] Move FG configs to common; turn fps overlay type into an enum --- OptiScaler.ini | 15 ++++++------- OptiScaler/Config.cpp | 40 +++++++++------------------------ OptiScaler/Config.h | 14 +++++++++++- OptiScaler/dllmain.cpp | 1 - OptiScaler/menu/menu_common.cpp | 23 ++++++++++--------- 5 files changed, 43 insertions(+), 50 deletions(-) diff --git a/OptiScaler.ini b/OptiScaler.ini index 6d788b5a..a7847933 100644 --- a/OptiScaler.ini +++ b/OptiScaler.ini @@ -18,6 +18,13 @@ VulkanUpscaler=auto ; ------------------------------------------------------- [FrameGen] ; ------------------------------------------------------- +; Enables frame generation +; true or false - Default (auto) is false +Enabled=auto + +; Enables frame generation debug view +; true or false - Default (auto) is false +DebugView=auto ; Selected FG Input/Source ; nukems - Limited to FSR 3 FG. Requires DLSSG in the game. Supports hudless out of the box. Uses streamline swapchain for pacing. @@ -38,14 +45,6 @@ FGOutput=auto ; ------------------------------------------------------- [FSRFG] ; ------------------------------------------------------- -; Enables FSR3.1 frame generation -; true or false - Default (auto) is false -Enabled=auto - -; Enables FSR3.1 frame generation debug view -; true or false - Default (auto) is false -DebugView=auto - ; Enables FSR3.1 frame generation tear lines ; true or false - Default (auto) is false DebugTearLines=auto diff --git a/OptiScaler/Config.cpp b/OptiScaler/Config.cpp index 594aff45..445e9105 100644 --- a/OptiScaler/Config.cpp +++ b/OptiScaler/Config.cpp @@ -56,6 +56,8 @@ bool Config::Reload(std::filesystem::path iniPath) // Frame Generation { + FGEnabled.set_from_config(readBool("FrameGen", "Enabled")); + FGDebugView.set_from_config(readBool("FrameGen", "DebugView")); if (auto FGInputString = readString("FrameGen", "FGInput"); FGInputString.has_value()) { if (lstrcmpiA(FGInputString.value().c_str(), "nofg") == 0) @@ -89,8 +91,6 @@ bool Config::Reload(std::filesystem::path iniPath) // FSR FG { - FGEnabled.set_from_config(readBool("FSRFG", "Enabled")); - FGDebugView.set_from_config(readBool("FSRFG", "DebugView")); FGDebugTearLines.set_from_config(readBool("FSRFG", "DebugTearLines")); FGDebugResetLines.set_from_config(readBool("FSRFG", "DebugResetLines")); FGDebugPacingLines.set_from_config(readBool("FSRFG", "DebugPacingLines")); @@ -110,28 +110,6 @@ bool Config::Reload(std::filesystem::path iniPath) // OptiFG { - { - // If settings in the FSRFG section are not set, try using the old OptiFG section - FGEnabled.set_from_config(readBool("OptiFG", "Enabled")); - FGDebugView.set_from_config(readBool("OptiFG", "DebugView")); - FGDebugTearLines.set_from_config(readBool("OptiFG", "DebugTearLines")); - FGDebugResetLines.set_from_config(readBool("OptiFG", "DebugResetLines")); - FGDebugPacingLines.set_from_config(readBool("OptiFG", "DebugPacingLines")); - FGAsync.set_from_config(readBool("OptiFG", "AllowAsync")); - FGRectLeft.set_from_config(readInt("OptiFG", "RectLeft")); - FGRectTop.set_from_config(readInt("OptiFG", "RectTop")); - FGRectWidth.set_from_config(readInt("OptiFG", "RectWidth")); - FGRectHeight.set_from_config(readInt("OptiFG", "RectHeight")); - FGUseMutexForSwapchain.set_from_config(readBool("OptiFG", "UseMutexForSwapchain")); - FGFramePacingTuning.set_from_config(readBool("OptiFG", "FramePacingTuning")); - FGFPTSafetyMarginInMs.set_from_config(readFloat("OptiFG", "FPTSafetyMarginInMs")); - FGFPTVarianceFactor.set_from_config(readFloat("OptiFG", "FPTVarianceFactor")); - FGFPTAllowHybridSpin.set_from_config(readBool("OptiFG", "FPTHybridSpin")); - FGFPTHybridSpinTime.set_from_config(readInt("OptiFG", "FPTHybridSpinTime")); - FGFPTAllowWaitForSingleObjectOnFence.set_from_config( - readInt("OptiFG", "FPTWaitForSingleObjectOnFence")); - } - FGHUDFix.set_from_config(readBool("OptiFG", "HUDFix")); FGHUDLimit.set_from_config(readInt("OptiFG", "HUDLimit")); FGHUDFixExtended.set_from_config(readBool("OptiFG", "HUDFixExtended")); @@ -323,8 +301,11 @@ bool Config::Reload(std::filesystem::path iniPath) if (auto setting = readInt("Menu", "FpsOverlayPos"); setting.has_value()) FpsOverlayPos.set_from_config(std::clamp(setting.value(), 0, 3)); - if (auto setting = readInt("Menu", "FpsOverlayType"); setting.has_value()) - FpsOverlayType.set_from_config(std::clamp(setting.value(), 0, 6)); + if (auto setting = readUInt("Menu", "FpsOverlayType"); setting.has_value()) + { + FpsOverlayType.set_from_config( + (FpsOverlay) std::clamp(setting.value(), (uint32_t) FpsOverlay_JustFPS, FpsOverlay_COUNT - 1)); + } FpsShortcutKey.set_from_config(readInt("Menu", "FpsShortcutKey")); FpsCycleShortcutKey.set_from_config(readInt("Menu", "FpsCycleShortcutKey")); @@ -685,6 +666,8 @@ bool Config::SaveIni() // Frame Generation { + ini.SetValue("FrameGen", "Enabled", GetBoolValue(Instance()->FGEnabled.value_for_config()).c_str()); + ini.SetValue("FrameGen", "DebugView", GetBoolValue(Instance()->FGDebugView.value_for_config()).c_str()); std::string FGInputString = "auto"; if (auto FGInputHeld = Instance()->FGInput.value_for_config(); FGInputHeld.has_value()) { @@ -716,10 +699,8 @@ bool Config::SaveIni() ini.SetValue("FrameGen", "FGOutput", FGOutputString.c_str()); } - // FSR FG + // FSR FG output { - ini.SetValue("FSRFG", "Enabled", GetBoolValue(Instance()->FGEnabled.value_for_config()).c_str()); - ini.SetValue("FSRFG", "DebugView", GetBoolValue(Instance()->FGDebugView.value_for_config()).c_str()); ini.SetValue("FSRFG", "DebugTearLines", GetBoolValue(Instance()->FGDebugTearLines.value_for_config()).c_str()); ini.SetValue("FSRFG", "DebugResetLines", GetBoolValue(Instance()->FGDebugResetLines.value_for_config()).c_str()); @@ -746,6 +727,7 @@ bool Config::SaveIni() GetBoolValue(Instance()->FGFPTAllowWaitForSingleObjectOnFence.value_for_config()).c_str()); } + // XeFG output { ini.SetValue("XeFG", "DepthInverted", GetBoolValue(Instance()->FGXeFGDepthInverted.value_for_config()).c_str()); ini.SetValue("XeFG", "JitteredMV", GetBoolValue(Instance()->FGXeFGJitteredMV.value_for_config()).c_str()); diff --git a/OptiScaler/Config.h b/OptiScaler/Config.h index 5ec49d64..f2204f25 100644 --- a/OptiScaler/Config.h +++ b/OptiScaler/Config.h @@ -146,6 +146,18 @@ template class CustomOptio constexpr int UnboundKey = -1; +enum FpsOverlay : uint32_t +{ + FpsOverlay_JustFPS, + FpsOverlay_Simple, + FpsOverlay_Detailed, + FpsOverlay_DetailedGraph, + FpsOverlay_Full, + FpsOverlay_FullGraph, + FpsOverlay_ReflexTimings, + FpsOverlay_COUNT, +}; + class Config { public: @@ -221,7 +233,7 @@ class Config /// 0 Only FPS, 1 +Avg FPS & Upscaler info 2 +Frame Time, /// 3 +Upscaler Time, 4 +Frame Time Graph, 5 +Upscaler Time Graph /// 6 +Reflex timings - CustomOptional FpsOverlayType { 0 }; + CustomOptional FpsOverlayType { FpsOverlay_JustFPS }; CustomOptional FpsShortcutKey { VK_PRIOR }; CustomOptional FpsCycleShortcutKey { VK_NEXT }; CustomOptional FpsOverlayHorizontal { false }; diff --git a/OptiScaler/dllmain.cpp b/OptiScaler/dllmain.cpp index 1a22adae..660896fc 100644 --- a/OptiScaler/dllmain.cpp +++ b/OptiScaler/dllmain.cpp @@ -1218,7 +1218,6 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv State::Instance().isRunningOnLinux = IsRunningOnWine(); State::Instance().isRunningOnDXVK = State::Instance().isRunningOnLinux; - if (!Config::Instance()->OverrideNvapiDll.has_value()) { spdlog::info("OverrideNvapiDll not set, setting it to: {}", diff --git a/OptiScaler/menu/menu_common.cpp b/OptiScaler/menu/menu_common.cpp index def1023e..b5cc4bd0 100644 --- a/OptiScaler/menu/menu_common.cpp +++ b/OptiScaler/menu/menu_common.cpp @@ -1341,7 +1341,8 @@ bool MenuCommon::RenderMenu() } if (inputFpsCycle && Config::Instance()->ShowFps.value_or_default()) - Config::Instance()->FpsOverlayType = (Config::Instance()->FpsOverlayType.value_or_default() + 1) % 6; + Config::Instance()->FpsOverlayType = + (FpsOverlay) ((Config::Instance()->FpsOverlayType.value_or_default() + 1) % FpsOverlay_COUNT); if (inputMenu) { @@ -1608,11 +1609,11 @@ bool MenuCommon::RenderMenu() std::string thirdLine = ""; // Prepare Line 1 - if (Config::Instance()->FpsOverlayType.value_or_default() == 0) + if (Config::Instance()->FpsOverlayType.value_or_default() == FpsOverlay_JustFPS) { firstLine = std::format("{} | FPS: {:5.1f}", api.c_str(), frameRate); } - else if (Config::Instance()->FpsOverlayType.value_or_default() == 1) + else if (Config::Instance()->FpsOverlayType.value_or_default() == FpsOverlay_Simple) { if (currentFeature != nullptr && !currentFeature->IsFrozen()) firstLine = @@ -1639,7 +1640,7 @@ bool MenuCommon::RenderMenu() } // Prepare Line 2 - if (Config::Instance()->FpsOverlayType.value_or_default() > 1) + if (Config::Instance()->FpsOverlayType.value_or_default() >= FpsOverlay_Detailed) { if (Config::Instance()->FpsOverlayHorizontal.value_or_default()) { @@ -1657,7 +1658,7 @@ bool MenuCommon::RenderMenu() } // Prepare Line 3 - if (Config::Instance()->FpsOverlayType.value_or_default() > 3) + if (Config::Instance()->FpsOverlayType.value_or_default() >= FpsOverlay_Full) { thirdLine = std::format("Upscaler Time: {:6.2f} ms, Avg: {:6.2f} ms", State::Instance().upscaleTimes.back(), averageUpscalerFT); @@ -1690,7 +1691,7 @@ bool MenuCommon::RenderMenu() // Draw the overlay ImGui::Text(firstLine.c_str()); - if (Config::Instance()->FpsOverlayType.value_or_default() > 1) + if (Config::Instance()->FpsOverlayType.value_or_default() >= FpsOverlay_Detailed) { if (Config::Instance()->FpsOverlayHorizontal.value_or_default()) { @@ -1706,7 +1707,7 @@ bool MenuCommon::RenderMenu() ImGui::Text(secondLine.c_str()); } - if (Config::Instance()->FpsOverlayType.value_or_default() > 2) + if (Config::Instance()->FpsOverlayType.value_or_default() >= FpsOverlay_DetailedGraph) { if (Config::Instance()->FpsOverlayHorizontal.value_or_default()) ImGui::SameLine(0.0f, 0.0f); @@ -1716,7 +1717,7 @@ bool MenuCommon::RenderMenu() nullptr, 0.0f, 66.6f, plotSize); } - if (Config::Instance()->FpsOverlayType.value_or_default() > 3) + if (Config::Instance()->FpsOverlayType.value_or_default() >= FpsOverlay_Full) { if (Config::Instance()->FpsOverlayHorizontal.value_or_default()) { @@ -1732,7 +1733,7 @@ bool MenuCommon::RenderMenu() ImGui::Text(thirdLine.c_str()); } - if (Config::Instance()->FpsOverlayType.value_or_default() > 4) + if (Config::Instance()->FpsOverlayType.value_or_default() >= FpsOverlay_FullGraph) { if (Config::Instance()->FpsOverlayHorizontal.value_or_default()) ImGui::SameLine(0.0f, 0.0f); @@ -1742,7 +1743,7 @@ bool MenuCommon::RenderMenu() static_cast(upscalerFrameTimeArray.size()), 0, nullptr, 0.0f, 20.0f, plotSize); } - if (Config::Instance()->FpsOverlayType.value_or_default() > 5) + if (Config::Instance()->FpsOverlayType.value_or_default() >= FpsOverlay_ReflexTimings) { constexpr auto delayBetweenPollsMs = 500; static auto previousPoll = 0; @@ -4429,7 +4430,7 @@ bool MenuCommon::RenderMenu() { if (ImGui::Selectable(fpsType[n], (Config::Instance()->FpsOverlayType.value_or_default() == n))) - Config::Instance()->FpsOverlayType = n; + Config::Instance()->FpsOverlayType = (FpsOverlay) n; } ImGui::EndCombo(); From 8e13aba55f8782151c47c79cb47a3c0a256c7ddd Mon Sep 17 00:00:00 2001 From: FakeMichau <49685661+FakeMichau@users.noreply.github.com> Date: Wed, 27 Aug 2025 19:55:47 +0200 Subject: [PATCH 09/10] Save the new FG settings to the config --- OptiScaler.ini | 25 +++++++++++++++++++++---- OptiScaler/Config.cpp | 10 ++++++++++ OptiScaler/Config.h | 8 ++++---- OptiScaler/framegen/ffx/FSRFG_Dx12.cpp | 8 ++++---- OptiScaler/framegen/xefg/XeFG_Dx12.cpp | 8 ++++---- OptiScaler/hooks/HooksDx.cpp | 2 +- OptiScaler/inputs/FG/FfxApi_Dx12_FG.cpp | 2 +- OptiScaler/menu/menu_common.cpp | 16 ++++++++-------- 8 files changed, 53 insertions(+), 26 deletions(-) diff --git a/OptiScaler.ini b/OptiScaler.ini index a7847933..24bdce7d 100644 --- a/OptiScaler.ini +++ b/OptiScaler.ini @@ -22,10 +22,6 @@ VulkanUpscaler=auto ; true or false - Default (auto) is false Enabled=auto -; Enables frame generation debug view -; true or false - Default (auto) is false -DebugView=auto - ; Selected FG Input/Source ; nukems - Limited to FSR 3 FG. Requires DLSSG in the game. Supports hudless out of the box. Uses streamline swapchain for pacing. ; fsrfg - Can be used with any FG Output. Supports hudless out of the box. Currently only FSR3.1 FG is supported @@ -41,6 +37,27 @@ FGInput=auto ; nofg, fsrfg, xefg, nukems - Default (auto) is nofg FGOutput=auto +; Enables frame generation debug view +; true or false - Default (auto) is false +DebugView=auto + +; Draw UI over FG, requires Hudless and a UI texture, mostly for FSR FG +; true or false - Default (auto) is false +DrawUIOverFG=auto + +; Sets the type of a provided UI texture, with DrawUIOverFG + FSR FG it will change how the UI looks +; true or false - Default (auto) is true +UIPremultipliedAlpha=auto + +; Control hudless, even if FG source provides one +; true or false - Default (auto) is false +DisableHudless=auto + +; Control a UI texture, even if FG source provides one +; true or false - Default (auto) is true +DisableUI=auto + + ; ------------------------------------------------------- [FSRFG] diff --git a/OptiScaler/Config.cpp b/OptiScaler/Config.cpp index 445e9105..2d97c4ea 100644 --- a/OptiScaler/Config.cpp +++ b/OptiScaler/Config.cpp @@ -87,6 +87,10 @@ bool Config::Reload(std::filesystem::path iniPath) else if (lstrcmpiA(FGOutputString.value().c_str(), "xefg") == 0) FGOutput.set_from_config(FGOutput::XeFG); } + FGDrawUIOverFG.set_from_config(readBool("FrameGen", "DrawUIOverFG")); + FGUIPremultipliedAlpha.set_from_config(readBool("FrameGen", "UIPremultipliedAlpha")); + FGDisableHudless.set_from_config(readBool("FrameGen", "DisableHudless")); + FGDisableUI.set_from_config(readBool("FrameGen", "DisableUI")); } // FSR FG @@ -697,6 +701,12 @@ bool Config::SaveIni() FGOutputString = "XeFG"; } ini.SetValue("FrameGen", "FGOutput", FGOutputString.c_str()); + ini.SetValue("FrameGen", "DrawUIOverFG", GetBoolValue(Instance()->FGDrawUIOverFG.value_for_config()).c_str()); + ini.SetValue("FrameGen", "UIPremultipliedAlpha", + GetBoolValue(Instance()->FGUIPremultipliedAlpha.value_for_config()).c_str()); + ini.SetValue("FrameGen", "DisableHudless", + GetBoolValue(Instance()->FGDisableHudless.value_for_config()).c_str()); + ini.SetValue("FrameGen", "DisableUI", GetBoolValue(Instance()->FGDisableUI.value_for_config()).c_str()); } // FSR FG output diff --git a/OptiScaler/Config.h b/OptiScaler/Config.h index f2204f25..2ae08678 100644 --- a/OptiScaler/Config.h +++ b/OptiScaler/Config.h @@ -362,10 +362,10 @@ class Config // Frame Generation CustomOptional FGInput { FGInput::NoFG }; CustomOptional FGOutput { FGOutput::NoFG }; - CustomOptional DrawUIOverFG { false }; // TODO: not saved - CustomOptional UIPremultipliedAlpha { true }; - CustomOptional DisableHudless { false }; - CustomOptional DisableUI { true }; + CustomOptional FGDrawUIOverFG { false }; + CustomOptional FGUIPremultipliedAlpha { true }; + CustomOptional FGDisableHudless { false }; + CustomOptional FGDisableUI { true }; // OptiFG CustomOptional FGEnabled { false }; diff --git a/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp b/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp index 7052037c..3e0dadbc 100644 --- a/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp +++ b/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp @@ -115,13 +115,13 @@ bool FSRFG_Dx12::Dispatch() auto uiColor = GetResource(FG_ResourceType::UIColor, fIndex); auto hudless = GetResource(FG_ResourceType::HudlessColor, fIndex); if (uiColor != nullptr && IsResourceReady(FG_ResourceType::UIColor, fIndex) && - Config::Instance()->DrawUIOverFG.value_or_default()) + Config::Instance()->FGDrawUIOverFG.value_or_default()) { LOG_TRACE("Using UI: {:X}", (size_t) uiColor->GetResource()); uiDesc.uiResource = ffxApiGetResourceDX12(uiColor->GetResource(), GetFfxApiState(uiColor->state)); - if (Config::Instance()->UIPremultipliedAlpha.value_or_default()) + if (Config::Instance()->FGUIPremultipliedAlpha.value_or_default()) uiDesc.flags = FFX_FRAMEGENERATION_UI_COMPOSITION_FLAG_USE_PREMUL_ALPHA; } else if (hudless != nullptr && IsResourceReady(FG_ResourceType::HudlessColor, fIndex)) @@ -842,10 +842,10 @@ void FSRFG_Dx12::SetResource(Dx12Resource* inputResource) auto fIndex = GetIndex(); auto& type = inputResource->type; - if (type == FG_ResourceType::HudlessColor && Config::Instance()->DisableHudless.value_or_default()) + if (type == FG_ResourceType::HudlessColor && Config::Instance()->FGDisableHudless.value_or_default()) return; - if (type == FG_ResourceType::UIColor && Config::Instance()->DisableUI.value_or_default()) + if (type == FG_ResourceType::UIColor && Config::Instance()->FGDisableUI.value_or_default()) return; std::lock_guard lock(_frMutex); diff --git a/OptiScaler/framegen/xefg/XeFG_Dx12.cpp b/OptiScaler/framegen/xefg/XeFG_Dx12.cpp index 109d379f..66f64bc8 100644 --- a/OptiScaler/framegen/xefg/XeFG_Dx12.cpp +++ b/OptiScaler/framegen/xefg/XeFG_Dx12.cpp @@ -232,7 +232,7 @@ bool XeFG_Dx12::CreateSwapchain(IDXGIFactory* factory, ID3D12CommandQueue* cmdQu if (Config::Instance()->FGXeFGHighResMV.value_or_default()) params.initFlags |= XEFG_SWAPCHAIN_INIT_FLAG_HIGH_RES_MV; - if (!Config::Instance()->UIPremultipliedAlpha.value_or_default()) + if (!Config::Instance()->FGUIPremultipliedAlpha.value_or_default()) params.initFlags |= XEFG_SWAPCHAIN_INIT_FLAG_UITEXTURE_NOT_PREMUL_ALPHA; LOG_DEBUG("Inverted Depth: {}", Config::Instance()->FGXeFGDepthInverted.value_or_default()); @@ -318,7 +318,7 @@ bool XeFG_Dx12::CreateSwapchain1(IDXGIFactory* factory, ID3D12CommandQueue* cmdQ if (Config::Instance()->FGXeFGHighResMV.value_or_default()) params.initFlags |= XEFG_SWAPCHAIN_INIT_FLAG_HIGH_RES_MV; - if (!Config::Instance()->UIPremultipliedAlpha.value_or_default()) + if (!Config::Instance()->FGUIPremultipliedAlpha.value_or_default()) params.initFlags |= XEFG_SWAPCHAIN_INIT_FLAG_UITEXTURE_NOT_PREMUL_ALPHA; LOG_DEBUG("Inverted Depth: {}", Config::Instance()->FGXeFGDepthInverted.value_or_default()); @@ -709,10 +709,10 @@ void XeFG_Dx12::SetResource(Dx12Resource* inputResource) auto fIndex = GetIndex(); auto& type = inputResource->type; - if (type == FG_ResourceType::HudlessColor && Config::Instance()->DisableHudless.value_or_default()) + if (type == FG_ResourceType::HudlessColor && Config::Instance()->FGDisableHudless.value_or_default()) return; - if (type == FG_ResourceType::UIColor && Config::Instance()->DisableUI.value_or_default()) + if (type == FG_ResourceType::UIColor && Config::Instance()->FGDisableUI.value_or_default()) return; std::lock_guard lock(_frMutex); diff --git a/OptiScaler/hooks/HooksDx.cpp b/OptiScaler/hooks/HooksDx.cpp index 9f3a3838..9008b5e3 100644 --- a/OptiScaler/hooks/HooksDx.cpp +++ b/OptiScaler/hooks/HooksDx.cpp @@ -558,7 +558,7 @@ static HRESULT FGPresent(void* This, UINT SyncInterval, UINT Flags, const DXGI_P Hudfix_Dx12::PresentStart(); } - if (willPresent && fg != nullptr && fg->IsUsingUI() && Config::Instance()->DrawUIOverFG.value_or_default()) + if (willPresent && fg != nullptr && fg->IsUsingUI() && Config::Instance()->FGDrawUIOverFG.value_or_default()) { ID3D12Resource* backBuffer = nullptr; auto swapchain = ((IDXGISwapChain3*) This); diff --git a/OptiScaler/inputs/FG/FfxApi_Dx12_FG.cpp b/OptiScaler/inputs/FG/FfxApi_Dx12_FG.cpp index a8ea3690..023cc816 100644 --- a/OptiScaler/inputs/FG/FfxApi_Dx12_FG.cpp +++ b/OptiScaler/inputs/FG/FfxApi_Dx12_FG.cpp @@ -231,7 +231,7 @@ ffxReturnCode_t ffxConfigure_Dx12FG(ffxContext* context, ffxConfigureDescHeader* return FFX_API_RETURN_ERROR_RUNTIME_ERROR; } - bool UIDisabled = !Config::Instance()->DrawUIOverFG.value_or_default(); + bool UIDisabled = Config::Instance()->FGDisableUI.value_or_default(); if (desc->type == FFX_API_CONFIGURE_DESC_TYPE_FRAMEGENERATION) { diff --git a/OptiScaler/menu/menu_common.cpp b/OptiScaler/menu/menu_common.cpp index b5cc4bd0..4e56755b 100644 --- a/OptiScaler/menu/menu_common.cpp +++ b/OptiScaler/menu/menu_common.cpp @@ -2769,12 +2769,12 @@ bool MenuCommon::RenderMenu() const auto isUsingUIAny = fgOutput->IsUsingUIAny(); const auto isUsingHudlessAny = fgOutput->IsUsingHudlessAny(); - bool disableUI = Config::Instance()->DisableUI.value_or_default(); + bool disableUI = Config::Instance()->FGDisableUI.value_or_default(); ImGui::BeginDisabled(!isUsingUIAny && !disableUI); if (ImGui::Checkbox("Disable UI texture", &disableUI)) { - Config::Instance()->DisableUI = disableUI; + Config::Instance()->FGDisableUI = disableUI; State::Instance().FGchanged = true; } @@ -2784,13 +2784,13 @@ bool MenuCommon::RenderMenu() ImGui::SameLine(); - bool disableHudless = Config::Instance()->DisableHudless.value_or_default(); + bool disableHudless = Config::Instance()->FGDisableHudless.value_or_default(); ImGui::BeginDisabled(!isUsingHudlessAny && !disableHudless); if (ImGui::Checkbox("Disable hudless", &disableHudless)) { // TODO: this can crash when toggling - Config::Instance()->DisableHudless = disableHudless; + Config::Instance()->FGDisableHudless = disableHudless; State::Instance().FGchanged = true; } @@ -2799,17 +2799,17 @@ bool MenuCommon::RenderMenu() ImGui::EndDisabled(); ImGui::BeginDisabled(!isUsingUIAny || !isUsingHudlessAny); - if (bool drawUIOverFG = Config::Instance()->DrawUIOverFG.value_or_default(); + if (bool drawUIOverFG = Config::Instance()->FGDrawUIOverFG.value_or_default(); ImGui::Checkbox("Draw UI over FG", &drawUIOverFG)) - Config::Instance()->DrawUIOverFG = drawUIOverFG; + Config::Instance()->FGDrawUIOverFG = drawUIOverFG; ImGui::EndDisabled(); ImGui::SameLine(); ImGui::BeginDisabled(!isUsingUIAny); - if (bool uiPremultipliedAlpha = Config::Instance()->UIPremultipliedAlpha.value_or_default(); + if (bool uiPremultipliedAlpha = Config::Instance()->FGUIPremultipliedAlpha.value_or_default(); ImGui::Checkbox("UI Premult. alpha", &uiPremultipliedAlpha)) - Config::Instance()->UIPremultipliedAlpha = uiPremultipliedAlpha; + Config::Instance()->FGUIPremultipliedAlpha = uiPremultipliedAlpha; ImGui::EndDisabled(); ImGui::EndDisabled(); From b282307369c1cd5a58317d2953f718233979d44a Mon Sep 17 00:00:00 2001 From: TheRazerMD Date: Wed, 27 Aug 2025 23:17:59 +0200 Subject: [PATCH 10/10] Funny --- OptiScaler/menu/menu_common.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OptiScaler/menu/menu_common.cpp b/OptiScaler/menu/menu_common.cpp index 4e56755b..6a0abc59 100644 --- a/OptiScaler/menu/menu_common.cpp +++ b/OptiScaler/menu/menu_common.cpp @@ -77,7 +77,8 @@ static std::vector splashText = { "May the coping commence...", "0.8 was an inside job", "", "FSR4 DP4a wenETA, AMD plz", - "OptiCopers, assemble!" }; + "OptiCopers, assemble!", + "The Way It's Meant To Be Upscaled" }; void MenuCommon::ShowTooltip(const char* tip) {