Added an option for old Hudfix behaviour (or at least something close to it)

This commit is contained in:
cdozdil committed 2026-09-19 21:32:07 +03:00
1 parent 5d82736097
commit 57b6fa0d86
5 files changed
+69 -29

No files matched your search

+5
View File
@@ -378,6 +378,11 @@ HUDFixRelaxedResolutionCheck=auto
; true or false - Default (auto) is false
HUDFixImmediate=auto
; New advanced binding tracking system for Hudless resources
; Set false for old Hudfix behavior
; true or false - Default (auto) is true
HUDFixPersistentBindings=auto
; Resource tracking is always enabled regardless of Hudfix setting
; Might cause performance issues but disabling might cause stability issues
; true or false - Default (auto) is false
+3
View File
@@ -184,6 +184,7 @@ bool Config::Reload(std::filesystem::path iniPath)
FGHUDLimit.set_from_config(readInt("OptiFG", "HUDLimit"));
FGHUDFixExtended.set_from_config(readBool("OptiFG", "HUDFixExtended"));
FGImmediateCapture.set_from_config(readBool("OptiFG", "HUDFixImmediate"));
FGHudfixPersistentBindings.set_from_config(readBool("OptiFG", "HUDFixPersistentBindings"));
FGUseShards.set_from_config(readBool("OptiFG", "UseShards"));
FGAlwaysTrackHeaps.set_from_config(readBool("OptiFG", "AlwaysTrackHeaps"));
FGResourceBlocking.set_from_config(readBool("OptiFG", "ResourceBlocking"));
@@ -1026,6 +1027,8 @@ bool Config::SaveIni()
ini.SetValue("OptiFG", "HUDFixExtended", GetBoolValue(Instance()->FGHUDFixExtended.value_for_config()).c_str());
ini.SetValue("OptiFG", "HUDFixImmediate",
GetBoolValue(Instance()->FGImmediateCapture.value_for_config()).c_str());
ini.SetValue("OptiFG", "HUDFixPersistentBindings",
GetBoolValue(Instance()->FGHudfixPersistentBindings.value_for_config()).c_str());
ini.SetValue("OptiFG", "UseShards", GetBoolValue(Instance()->FGUseShards.value_for_config()).c_str());
ini.SetValue("OptiFG", "AlwaysTrackHeaps",
GetBoolValue(Instance()->FGAlwaysTrackHeaps.value_for_config()).c_str());
+1
View File
@@ -550,6 +550,7 @@ class Config
CustomOptional<int> FGHUDLimit { 1 };
CustomOptional<bool> FGHUDFixExtended { false };
CustomOptional<bool> FGImmediateCapture { false };
CustomOptional<bool> FGHudfixPersistentBindings { true };
CustomOptional<bool> FGDontUseSwapchainBuffers { false };
CustomOptional<bool> FGRelaxedResolutionCheck { false };
CustomOptional<bool> FGHudfixDisableRTV { false };
+37 -15
View File
@@ -394,9 +394,12 @@ static void hkSetDescriptorHeaps(ID3D12GraphicsCommandList* commandList, UINT Nu
{
if (!lateInProgressSetDescriptorHeaps && !isUpscalerActive && commandList != nullptr)
{
ResTrack_Dx12::OnSetDescriptorHeaps(commandList, NumDescriptorHeaps, ppDescriptorHeaps);
auto config = Config::Instance();
if (Config::Instance()->ExtendedStateRestore.value_or_default() && ppDescriptorHeaps != nullptr)
if (config->FGHudfixPersistentBindings.value_or_default())
ResTrack_Dx12::OnSetDescriptorHeaps(commandList, NumDescriptorHeaps, ppDescriptorHeaps);
if (config->ExtendedStateRestore.value_or_default() && ppDescriptorHeaps != nullptr)
{
std::unique_lock<std::shared_mutex> lock(descriptorHeapsMutex);
@@ -426,9 +429,12 @@ static void hkSetComputeRootSignature(ID3D12GraphicsCommandList* commandList, ID
{
if (!lateInProgressSetComputeRootSignature && !isUpscalerActive && commandList != nullptr)
{
ResTrack_Dx12::OnSetComputeRootSignature(commandList, pRootSignature);
auto config = Config::Instance();
if (Config::Instance()->RestoreComputeSignature.value_or_default() && pRootSignature != nullptr)
if (config->FGHudfixPersistentBindings.value_or_default())
ResTrack_Dx12::OnSetComputeRootSignature(commandList, pRootSignature);
if (config->RestoreComputeSignature.value_or_default() && pRootSignature != nullptr)
{
{
auto paramCount = GetRootParameterCount(pRootSignature);
@@ -573,9 +579,12 @@ static void hkSetGraphicsRootSignature(ID3D12GraphicsCommandList* commandList, I
{
if (!lateInProgressSetGraphicsRootSignature && !isUpscalerActive && commandList != nullptr)
{
ResTrack_Dx12::OnSetGraphicsRootSignature(commandList, pRootSignature);
auto config = Config::Instance();
if (Config::Instance()->RestoreGraphicSignature.value_or_default() && pRootSignature != nullptr)
if (config->FGHudfixPersistentBindings.value_or_default())
ResTrack_Dx12::OnSetGraphicsRootSignature(commandList, pRootSignature);
if (config->RestoreGraphicSignature.value_or_default() && pRootSignature != nullptr)
{
std::unique_lock<std::shared_mutex> lock(rootSignatureMutex);
@@ -734,9 +743,12 @@ static void hkSetDescriptorHeapsLate(ID3D12GraphicsCommandList* commandList, UIN
if (!isUpscalerActive && commandList != nullptr)
{
ResTrack_Dx12::OnSetDescriptorHeaps(commandList, NumDescriptorHeaps, ppDescriptorHeaps);
auto config = Config::Instance();
if (Config::Instance()->ExtendedStateRestore.value_or_default() && ppDescriptorHeaps != nullptr)
if (config->FGHudfixPersistentBindings.value_or_default())
ResTrack_Dx12::OnSetDescriptorHeaps(commandList, NumDescriptorHeaps, ppDescriptorHeaps);
if (config->ExtendedStateRestore.value_or_default() && ppDescriptorHeaps != nullptr)
{
std::unique_lock<std::shared_mutex> lock(descriptorHeapsMutex);
@@ -762,9 +774,12 @@ static void hkSetComputeRootSignatureLate(ID3D12GraphicsCommandList* commandList
if (!isUpscalerActive && commandList != nullptr)
{
ResTrack_Dx12::OnSetComputeRootSignature(commandList, pRootSignature);
auto config = Config::Instance();
if (Config::Instance()->RestoreComputeSignature.value_or_default() && pRootSignature != nullptr)
if (config->FGHudfixPersistentBindings.value_or_default())
ResTrack_Dx12::OnSetComputeRootSignature(commandList, pRootSignature);
if (config->RestoreComputeSignature.value_or_default() && pRootSignature != nullptr)
{
{
auto paramCount = GetRootParameterCount(pRootSignature);
@@ -935,9 +950,12 @@ static void hkSetGraphicsRootSignatureLate(ID3D12GraphicsCommandList* commandLis
if (!isUpscalerActive && commandList != nullptr)
{
ResTrack_Dx12::OnSetGraphicsRootSignature(commandList, pRootSignature);
auto config = Config::Instance();
if (Config::Instance()->RestoreGraphicSignature.value_or_default() && pRootSignature != nullptr)
if (config->FGHudfixPersistentBindings.value_or_default())
ResTrack_Dx12::OnSetGraphicsRootSignature(commandList, pRootSignature);
if (config->RestoreGraphicSignature.value_or_default() && pRootSignature != nullptr)
{
std::unique_lock<std::shared_mutex> lock(rootSignatureMutex);
signatures.insert_or_assign(commandList, SignatureEntry { SignatureEntryType::Graphics, pRootSignature });
@@ -1103,6 +1121,7 @@ void D3D12Hooks::HookToCommandListLate(ID3D12GraphicsCommandList* commandList)
const bool restoreComputeSignature = config->RestoreComputeSignature.value_or_default();
const bool restoreGraphicSignature = config->RestoreGraphicSignature.value_or_default();
const bool extendedRestoreSignature = config->ExtendedStateRestore.value_or_default();
const bool persistentBindings = config->FGHudfixPersistentBindings.value_or_default();
s_SetPipelineState.o_lateHook = (PFN_SetPipelineState) pVTable[25];
s_SetDescriptorHeaps.o_lateHook = (PFN_SetDescriptorHeaps) pVTable[28];
@@ -1129,7 +1148,7 @@ void D3D12Hooks::HookToCommandListLate(ID3D12GraphicsCommandList* commandList)
DetourAttach(&(PVOID&) s_SetPipelineState.o_lateHook, hkSetPipelineStateLate);
if (s_SetDescriptorHeaps.o_lateHook != nullptr &&
(extendedRestoreSignature || State::Instance().activeFgInput == FGInput::Upscaler))
(extendedRestoreSignature || (persistentBindings && State::Instance().activeFgInput == FGInput::Upscaler)))
{
DetourAttach(&(PVOID&) s_SetDescriptorHeaps.o_lateHook, hkSetDescriptorHeapsLate);
}
@@ -1267,7 +1286,9 @@ static void HookToCommandList(ID3D12Device* InDevice)
// Get the vtable pointer
PVOID* pVTable = *(PVOID**) commandList;
const bool extendedRestoreSignature = Config::Instance()->ExtendedStateRestore.value_or_default();
auto config = Config::Instance();
const bool extendedRestoreSignature = config->ExtendedStateRestore.value_or_default();
const bool persistentBindings = config->FGHudfixPersistentBindings.value_or_default();
s_SetPipelineState.o_earlyHook = (PFN_SetPipelineState) pVTable[25];
s_SetDescriptorHeaps.o_earlyHook = (PFN_SetDescriptorHeaps) pVTable[28];
@@ -1293,7 +1314,8 @@ static void HookToCommandList(ID3D12Device* InDevice)
DetourAttach(&(PVOID&) s_SetPipelineState.o_earlyHook, hkSetPipelineState);
if (s_SetDescriptorHeaps.o_earlyHook != nullptr &&
(extendedRestoreSignature || State::Instance().activeFgInput == FGInput::Upscaler))
(extendedRestoreSignature ||
(persistentBindings && State::Instance().activeFgInput == FGInput::Upscaler)))
{
DetourAttach(&(PVOID&) s_SetDescriptorHeaps.o_earlyHook, hkSetDescriptorHeaps);
}
+23 -14
View File
@@ -1238,7 +1238,8 @@ bool ResTrack_Dx12::ResolveRenderTargetBinding(SIZE_T cpuHandle, ResourceInfo& o
bool ResTrack_Dx12::ProcessGraphicsBindings(ID3D12GraphicsCommandList* commandList, UINT captureInfo)
{
if (Config::Instance()->FGImmediateCapture.value_or_default())
if (!_bindingTrackingEnabled.load(std::memory_order_acquire) ||
Config::Instance()->FGImmediateCapture.value_or_default())
return false;
auto* state = FindBindingState(commandList);
@@ -1303,7 +1304,8 @@ bool ResTrack_Dx12::ProcessGraphicsBindings(ID3D12GraphicsCommandList* commandLi
bool ResTrack_Dx12::ProcessComputeBindings(ID3D12GraphicsCommandList* commandList, UINT captureInfo)
{
if (Config::Instance()->FGImmediateCapture.value_or_default())
if (!_bindingTrackingEnabled.load(std::memory_order_acquire) ||
Config::Instance()->FGImmediateCapture.value_or_default())
return false;
auto* state = FindBindingState(commandList);
@@ -2092,10 +2094,14 @@ void ResTrack_Dx12::HookCommandList(ID3D12Device* InDevice)
// Get the vtable pointer
PVOID* pVTable = *(PVOID**) realCL;
const bool persistentBindings = Config::Instance()->FGHudfixPersistentBindings.value_or_default();
// Persistent command-list binding invalidation
o_Reset = (PFN_Reset) pVTable[10];
o_ClearState = (PFN_ClearState) pVTable[11];
if (persistentBindings)
{
o_Reset = (PFN_Reset) pVTable[10];
o_ClearState = (PFN_ClearState) pVTable[11];
}
// hudless shader
o_OMSetRenderTargets = (PFN_OMSetRenderTargets) pVTable[46];
@@ -2156,7 +2162,7 @@ void ResTrack_Dx12::HookCommandList(ID3D12Device* InDevice)
}
else if (State::Instance().activeFgInput == FGInput::Upscaler)
{
_bindingTrackingEnabled.store(true, std::memory_order_release);
_bindingTrackingEnabled.store(persistentBindings, std::memory_order_release);
}
}
@@ -2196,17 +2202,20 @@ void ResTrack_Dx12::HookDevice(ID3D12Device* device)
_trackedResources.reserve(1024);
}
if (!_useShards)
if (Config::Instance()->FGHudfixPersistentBindings.value_or_default())
{
std::lock_guard<std::mutex> lock(_bindingStateMutex);
_bindingStates.reserve(256);
}
else
{
for (auto& shard : _bindingShards)
if (!_useShards)
{
std::lock_guard<BindingStateMutex> lock(shard.mutex);
shard.map.reserve(32);
std::lock_guard<std::mutex> lock(_bindingStateMutex);
_bindingStates.reserve(256);
}
else
{
for (auto& shard : _bindingShards)
{
std::lock_guard<BindingStateMutex> lock(shard.mutex);
shard.map.reserve(32);
}
}
}
}