This commit is contained in:
cdozdil
2025-08-28 01:46:08 +03:00
15 changed files with 300 additions and 134 deletions
+24 -8
View File
@@ -18,6 +18,9 @@ VulkanUpscaler=auto
; -------------------------------------------------------
[FrameGen]
; -------------------------------------------------------
; Enables frame generation
; true or false - Default (auto) is false
Enabled=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.
@@ -34,18 +37,31 @@ 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]
; -------------------------------------------------------
; 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
+21 -29
View File
@@ -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)
@@ -85,12 +87,14 @@ 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
{
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 +114,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 +305,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 +670,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())
{
@@ -714,12 +701,16 @@ 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
// 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 +737,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());
+17 -3
View File
@@ -146,6 +146,18 @@ template <class T, HasDefaultValue defaultState = WithDefault> 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<int> FpsOverlayType { 0 };
CustomOptional<FpsOverlay> FpsOverlayType { FpsOverlay_JustFPS };
CustomOptional<int> FpsShortcutKey { VK_PRIOR };
CustomOptional<int> FpsCycleShortcutKey { VK_NEXT };
CustomOptional<bool> FpsOverlayHorizontal { false };
@@ -350,8 +362,10 @@ class Config
// Frame Generation
CustomOptional<FGInput> FGInput { FGInput::NoFG };
CustomOptional<FGOutput> FGOutput { FGOutput::NoFG };
CustomOptional<bool> DrawUIOverFG { false };
CustomOptional<bool> UIPremultipliedAlpha { true };
CustomOptional<bool> FGDrawUIOverFG { false };
CustomOptional<bool> FGUIPremultipliedAlpha { true };
CustomOptional<bool> FGDisableHudless { false };
CustomOptional<bool> FGDisableUI { true };
// OptiFG
CustomOptional<bool> FGEnabled { false };
+27 -30
View File
@@ -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,30 @@ 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;
if (!Config::Instance()->OverrideNvapiDll.has_value())
{
spdlog::info("OverrideNvapiDll not set, setting it to: {}",
+8
View File
@@ -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)
{
+1
View File
@@ -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);
+10 -3
View File
@@ -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))
@@ -839,7 +839,15 @@ 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()->FGDisableHudless.value_or_default())
return;
if (type == FG_ResourceType::UIColor && Config::Instance()->FGDisableUI.value_or_default())
return;
std::lock_guard<std::mutex> lock(_frMutex);
if (inputResource->cmdList == nullptr && inputResource->validity == FG_ResourceValidity::ValidNow)
@@ -848,7 +856,6 @@ void FSRFG_Dx12::SetResource(Dx12Resource* inputResource)
return;
}
auto fIndex = GetIndex();
_frameResources[fIndex][type] = {};
auto fResource = &_frameResources[fIndex][type];
fResource->type = type;
+28 -11
View File
@@ -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());
@@ -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]++;
@@ -534,13 +535,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
{
@@ -747,7 +757,15 @@ 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()->FGDisableHudless.value_or_default())
return;
if (type == FG_ResourceType::UIColor && Config::Instance()->FGDisableUI.value_or_default())
return;
std::lock_guard<std::mutex> lock(_frMutex);
if (inputResource->cmdList == nullptr && inputResource->validity == FG_ResourceValidity::ValidNow)
@@ -762,7 +780,6 @@ void XeFG_Dx12::SetResource(Dx12Resource* inputResource)
return;
}
auto fIndex = GetIndex();
auto fResource = &_frameResources[fIndex][type];
fResource->type = type;
fResource->state = inputResource->state;
+78
View File
@@ -147,6 +147,73 @@ inline static std::vector<std::filesystem::path> 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<uint64_t*>(&data[0x00]) = 16;
*reinterpret_cast<uint64_t*>(&data[0x08]) = 16;
*reinterpret_cast<uint64_t*>(&data[0x10]) = 16;
*reinterpret_cast<uint32_t*>(&data[0x18]) = 11;
*reinterpret_cast<uint32_t*>(&data[0x1C]) = 11;
*reinterpret_cast<uint32_t*>(&data[0x20]) = 1;
*reinterpret_cast<uint32_t*>(&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;
}
+1 -1
View File
@@ -560,7 +560,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);
+1 -1
View File
@@ -294,7 +294,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)
{
@@ -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;
}
@@ -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;
+71 -47
View File
@@ -77,7 +77,8 @@ static std::vector<std::string> splashText = { "May the coping commence...",
"0.8 was an inside job",
"<Your funny text goes here>",
"FSR4 DP4a wenETA, AMD plz",
"OptiCopers, assemble!" };
"OptiCopers, assemble!",
"The Way It's Meant To Be Upscaled" };
void MenuCommon::ShowTooltip(const char* tip)
{
@@ -1341,7 +1342,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 +1610,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 +1641,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 +1659,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 +1692,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 +1708,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 +1718,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 +1734,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 +1744,7 @@ bool MenuCommon::RenderMenu()
static_cast<int>(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;
@@ -2758,6 +2760,63 @@ bool MenuCommon::RenderMenu()
ImGui::Spacing();
}
if (State::Instance().activeFgInput == FGInput::DLSSG ||
State::Instance().activeFgInput == FGInput::FSRFG)
{
auto fgOutput = reinterpret_cast<IFGFeature_Dx12*>(State::Instance().currentFG);
if (fgOutput)
{
ImGui::BeginDisabled(!fgOutput->IsActive());
const auto isUsingUIAny = fgOutput->IsUsingUIAny();
const auto isUsingHudlessAny = fgOutput->IsUsingHudlessAny();
bool disableUI = Config::Instance()->FGDisableUI.value_or_default();
ImGui::BeginDisabled(!isUsingUIAny && !disableUI);
if (ImGui::Checkbox("Disable UI texture", &disableUI))
{
Config::Instance()->FGDisableUI = 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()->FGDisableHudless.value_or_default();
ImGui::BeginDisabled(!isUsingHudlessAny && !disableHudless);
if (ImGui::Checkbox("Disable hudless", &disableHudless))
{
// TODO: this can crash when toggling
Config::Instance()->FGDisableHudless = 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()->FGDrawUIOverFG.value_or_default();
ImGui::Checkbox("Draw UI over FG", &drawUIOverFG))
Config::Instance()->FGDrawUIOverFG = drawUIOverFG;
ImGui::EndDisabled();
ImGui::SameLine();
ImGui::BeginDisabled(!isUsingUIAny);
if (bool uiPremultipliedAlpha = Config::Instance()->FGUIPremultipliedAlpha.value_or_default();
ImGui::Checkbox("UI Premult. alpha", &uiPremultipliedAlpha))
Config::Instance()->FGUIPremultipliedAlpha = uiPremultipliedAlpha;
ImGui::EndDisabled();
ImGui::EndDisabled();
}
}
// FSR FG controls
if (State::Instance().activeFgOutput == FGOutput::FSRFG &&
State::Instance().activeFgInput != FGInput::NoFG &&
@@ -3388,29 +3447,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();
}
else
{
ImGui::TextColored(ImVec4(1.0f, 0.647f, 0.0f, 1.f), "ACTIVATE FG");
}
}
else
{
@@ -3441,21 +3480,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();
}
else
{
@@ -4407,7 +4431,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();
+1 -1
View File
@@ -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