Pass the resource lock to the user of GetResource

Should fix Witcher 3 crashing during alt tabbing with XeFG
This commit is contained in:
FakeMichau
2026-06-30 23:18:59 +02:00
parent 0649f067de
commit 833e971703
7 changed files with 49 additions and 38 deletions
+6 -5
View File
@@ -12,7 +12,7 @@ bool IFGFeature_Dx12::GetResourceCopy(FG_ResourceType type, D3D12_RESOURCE_STATE
auto resource = GetResource(type);
if (resource == nullptr || (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;
@@ -195,7 +195,7 @@ ID3D12GraphicsCommandList* IFGFeature_Dx12::GetSCCommandList(int index)
return _scCommandList[index];
}
Dx12Resource* IFGFeature_Dx12::GetResource(FG_ResourceType type, int index)
LockedDx12Resource IFGFeature_Dx12::GetResource(FG_ResourceType type, int index)
{
if (index < 0)
index = GetIndex();
@@ -204,10 +204,11 @@ Dx12Resource* IFGFeature_Dx12::GetResource(FG_ResourceType type, int index)
auto& resources = _frameResources[index];
if (resources.contains(type))
return &resources[type];
auto it = resources.find(type);
if (it != resources.end())
return { &it->second, std::move(lock) };
return nullptr;
return { nullptr, std::move(lock) };
}
void IFGFeature_Dx12::NewFrame()
+12 -1
View File
@@ -31,6 +31,17 @@ struct Dx12Resource
ID3D12Resource* GetResource() { return (copy == nullptr) ? resource : copy; }
};
struct LockedDx12Resource
{
Dx12Resource* resource = nullptr;
std::shared_lock<std::shared_mutex> lock;
Dx12Resource* operator->() { return resource; }
Dx12Resource& operator*() { return *resource; }
explicit operator bool() const { return resource != nullptr; }
};
class IFGFeature_Dx12 : public virtual IFGFeature
{
private:
@@ -110,7 +121,7 @@ class IFGFeature_Dx12 : public virtual IFGFeature
ID3D12GraphicsCommandList* GetUICommandList(int index = -1);
ID3D12GraphicsCommandList* GetSCCommandList(int index = -1);
Dx12Resource* GetResource(FG_ResourceType type, int index = -1);
LockedDx12Resource GetResource(FG_ResourceType type, int index = -1);
bool GetResourceCopy(FG_ResourceType type, D3D12_RESOURCE_STATES bufferState, ID3D12Resource* output);
ID3D12CommandQueue* GetCommandQueue();
+8 -8
View File
@@ -779,9 +779,9 @@ bool DLSSG_Dx12::Present()
if (Config::Instance()->FGDrawUIOverFG.value_or_default())
{
auto ui = GetResource(FG_ResourceType::UIColor, fIndex);
if (ui != nullptr && (ui->validity == FG_ResourceValidity::UntilPresent ||
ui->validity == FG_ResourceValidity::JustTrackCmdlist ||
ui->validity == FG_ResourceValidity::UntilPresentFromDispatch))
if (ui && (ui->validity == FG_ResourceValidity::UntilPresent ||
ui->validity == FG_ResourceValidity::JustTrackCmdlist ||
ui->validity == FG_ResourceValidity::UntilPresentFromDispatch))
{
LOG_DEBUG("UI[{}] resource: {:X}, copy: {}", fIndex, (size_t) ui->resource, (size_t) ui->copy);
if (_renderUI.get() == nullptr)
@@ -804,7 +804,7 @@ bool DLSSG_Dx12::Present()
}
}
}
else if (ui == nullptr)
else if (!ui)
{
LOG_WARN("UI resource is nullptr");
}
@@ -815,9 +815,9 @@ bool DLSSG_Dx12::Present()
if (State::Instance().fgHudlessCompare)
{
auto hudless = GetResource(FG_ResourceType::HudlessColor, fIndex);
if (hudless != nullptr && (hudless->validity == FG_ResourceValidity::UntilPresent ||
hudless->validity == FG_ResourceValidity::JustTrackCmdlist ||
hudless->validity == FG_ResourceValidity::UntilPresentFromDispatch))
if (hudless && (hudless->validity == FG_ResourceValidity::UntilPresent ||
hudless->validity == FG_ResourceValidity::JustTrackCmdlist ||
hudless->validity == FG_ResourceValidity::UntilPresentFromDispatch))
{
LOG_DEBUG("Hudless[{}] resource: {:X}, copy: {}", fIndex, (size_t) hudless->resource,
(size_t) hudless->copy);
@@ -835,7 +835,7 @@ bool DLSSG_Dx12::Present()
}
}
}
else if (hudless == nullptr)
else if (!hudless)
{
LOG_WARN("Hudless resource is nullptr");
}
+7 -7
View File
@@ -354,7 +354,7 @@ bool FSRFG_Dx12::Dispatch()
distortionFieldDesc.header.type = FFX_API_CONFIGURE_DESC_TYPE_FRAMEGENERATION_REGISTERDISTORTIONRESOURCE;
auto distortion = GetResource(FG_ResourceType::Distortion, fIndex);
if (distortion != nullptr && IsResourceReady(FG_ResourceType::Distortion, fIndex))
if (distortion && IsResourceReady(FG_ResourceType::Distortion, fIndex))
{
LOG_TRACE("Using Distortion Field: {:X}", (size_t) distortion->GetResource());
@@ -373,7 +373,7 @@ bool FSRFG_Dx12::Dispatch()
std::shared_lock<std::shared_mutex> lock(_resourceMutex[fIndex]);
auto hudless = GetResource(FG_ResourceType::HudlessColor, fIndex);
if (hudless != nullptr && IsResourceReady(FG_ResourceType::HudlessColor, fIndex))
if (hudless && IsResourceReady(FG_ResourceType::HudlessColor, fIndex))
{
LOG_TRACE("Using hudless: {:X}", (size_t) hudless->GetResource());
@@ -527,7 +527,7 @@ bool FSRFG_Dx12::Dispatch()
auto velocity = GetResource(FG_ResourceType::Velocity, fIndex);
auto depth = GetResource(FG_ResourceType::Depth, fIndex);
if (velocity != nullptr && IsResourceReady(FG_ResourceType::Velocity, fIndex))
if (velocity && IsResourceReady(FG_ResourceType::Velocity, fIndex))
{
LOG_DEBUG("Velocity resource: {:X}", (size_t) velocity->GetResource());
dfgPrepare.motionVectors = ffxApiGetResourceDX12(velocity->GetResource(), GetFfxApiState(velocity->state));
@@ -539,7 +539,7 @@ bool FSRFG_Dx12::Dispatch()
return false;
}
if (depth != nullptr && IsResourceReady(FG_ResourceType::Depth, fIndex))
if (depth && IsResourceReady(FG_ResourceType::Depth, fIndex))
{
LOG_DEBUG("Depth resource: {:X}", (size_t) depth->GetResource());
dfgPrepare.depth = ffxApiGetResourceDX12(depth->GetResource(), GetFfxApiState(depth->state));
@@ -553,7 +553,7 @@ bool FSRFG_Dx12::Dispatch()
if (state.currentFeature && state.activeFgInput == FGInput::Upscaler)
dfgPrepare.renderSize = { state.currentFeature->RenderWidth(), state.currentFeature->RenderHeight() };
else if (depth != nullptr)
else if (depth)
dfgPrepare.renderSize = { static_cast<uint32_t>(depth->width), depth->height };
else
dfgPrepare.renderSize = { dfgPrepare.depth.description.width, dfgPrepare.depth.description.height };
@@ -1685,7 +1685,7 @@ bool FSRFG_Dx12::Present()
if (Config::Instance()->FGDrawUIOverFG.value_or_default())
{
auto ui = GetResource(FG_ResourceType::UIColor, fIndex);
if (ui != nullptr)
if (ui)
{
LOG_DEBUG("UI[{}] resource: {:X}, copy: {}", fIndex, (size_t) ui->resource, (size_t) ui->copy);
if (_renderUI.get() == nullptr)
@@ -1708,7 +1708,7 @@ bool FSRFG_Dx12::Present()
}
}
}
else if (ui == nullptr)
else if (!ui)
{
LOG_WARN("UI resource is nullptr");
}
+8 -8
View File
@@ -1250,9 +1250,9 @@ bool XeFG_Dx12::Present()
if (Config::Instance()->FGDrawUIOverFG.value_or_default())
{
auto ui = GetResource(FG_ResourceType::UIColor, fIndex);
if (ui != nullptr && (ui->validity == FG_ResourceValidity::UntilPresent ||
ui->validity == FG_ResourceValidity::JustTrackCmdlist ||
ui->validity == FG_ResourceValidity::UntilPresentFromDispatch))
if (ui && (ui->validity == FG_ResourceValidity::UntilPresent ||
ui->validity == FG_ResourceValidity::JustTrackCmdlist ||
ui->validity == FG_ResourceValidity::UntilPresentFromDispatch))
{
LOG_DEBUG("UI[{}] resource: {:X}, copy: {}", fIndex, (size_t) ui->resource, (size_t) ui->copy);
if (_renderUI.get() == nullptr)
@@ -1275,7 +1275,7 @@ bool XeFG_Dx12::Present()
}
}
}
else if (ui == nullptr)
else if (!ui)
{
LOG_WARN("UI resource is nullptr");
}
@@ -1286,9 +1286,9 @@ bool XeFG_Dx12::Present()
if (State::Instance().fgHudlessCompare)
{
auto hudless = GetResource(FG_ResourceType::HudlessColor, fIndex);
if (hudless != nullptr && (hudless->validity == FG_ResourceValidity::UntilPresent ||
hudless->validity == FG_ResourceValidity::JustTrackCmdlist ||
hudless->validity == FG_ResourceValidity::UntilPresentFromDispatch))
if (hudless && (hudless->validity == FG_ResourceValidity::UntilPresent ||
hudless->validity == FG_ResourceValidity::JustTrackCmdlist ||
hudless->validity == FG_ResourceValidity::UntilPresentFromDispatch))
{
LOG_DEBUG("Hudless[{}] resource: {:X}, copy: {}", fIndex, (size_t) hudless->resource,
(size_t) hudless->copy);
@@ -1306,7 +1306,7 @@ bool XeFG_Dx12::Present()
}
}
}
else if (hudless == nullptr)
else if (!hudless)
{
LOG_WARN("Hudless resource is nullptr");
}
+5 -6
View File
@@ -610,8 +610,7 @@ static Fsr3::FfxErrorCode hkffxFrameInterpolationDispatch(FfxFrameInterpolationC
fg->SetFrameTimeDelta(params->frameTimeDelta);
fg->SetReset(params->reset ? 1 : 0);
if (params->currentBackBuffer_HUDLess.resource != nullptr &&
fg->GetResource(FG_ResourceType::HudlessColor) == nullptr)
if (params->currentBackBuffer_HUDLess.resource != nullptr && !fg->GetResource(FG_ResourceType::HudlessColor))
{
UINT width = params->interpolationRect.width;
UINT height = params->interpolationRect.height;
@@ -640,7 +639,7 @@ static Fsr3::FfxErrorCode hkffxFrameInterpolationDispatch(FfxFrameInterpolationC
}
if (_presentCallback != nullptr && params->currentBackBuffer.resource != nullptr &&
fg->GetResource(FG_ResourceType::HudlessColor) == nullptr)
!fg->GetResource(FG_ResourceType::HudlessColor))
{
UINT width = params->interpolationRect.width;
UINT height = params->interpolationRect.height;
@@ -821,7 +820,7 @@ static Fsr3::FfxErrorCode hkffxSetFrameGenerationConfigToSwapchainDX12(Fsr3::Ffx
left = 0;
}
if (config->HUDLessColor.resource != nullptr && fg->GetResource(FG_ResourceType::HudlessColor) == nullptr)
if (config->HUDLessColor.resource != nullptr && !fg->GetResource(FG_ResourceType::HudlessColor))
{
Dx12Resource ui {};
ui.cmdList = nullptr; // Not sure about this
@@ -1177,7 +1176,7 @@ void FSR3FG::ffxPresentCallback()
if (result == FFX_API_RETURN_OK)
{
if (fg->GetResource(FG_ResourceType::HudlessColor, fIndex) == nullptr)
if (!fg->GetResource(FG_ResourceType::HudlessColor, fIndex))
{
auto hDesc = _hudless[fIndex]->GetDesc();
Dx12Resource hudless {};
@@ -1271,7 +1270,7 @@ void FSR3FG::ffxPresentCallback()
if (result == FFX_API_RETURN_OK)
{
if (fg->GetResource(FG_ResourceType::HudlessColor, fIndex) == nullptr)
if (!fg->GetResource(FG_ResourceType::HudlessColor, fIndex))
{
auto hDesc = _hudless[fIndex]->GetDesc();
Dx12Resource hudless {};
+3 -3
View File
@@ -992,7 +992,7 @@ ffxReturnCode_t ffxDispatch_Dx12FG(ffxContext* context, ffxDispatchDescHeader* d
if (cdDesc->presentColor.resource != nullptr &&
!Config::Instance()->FSRFGSkipDispatchForHudless.value_or_default() &&
fg->GetResource(FG_ResourceType::HudlessColor) == nullptr)
!fg->GetResource(FG_ResourceType::HudlessColor))
{
UINT width = cdDesc->generationRect.width;
UINT height = cdDesc->generationRect.height;
@@ -1334,7 +1334,7 @@ void ffxPresentCallback()
if (result == FFX_API_RETURN_OK)
{
if (fg->GetResource(FG_ResourceType::HudlessColor, fIndex) == nullptr)
if (!fg->GetResource(FG_ResourceType::HudlessColor, fIndex))
{
auto hDesc = _hudless[fIndex]->GetDesc();
Dx12Resource hudless {};
@@ -1432,7 +1432,7 @@ void ffxPresentCallback()
if (result == FFX_API_RETURN_OK)
{
if (fg->GetResource(FG_ResourceType::HudlessColor, fIndex) == nullptr)
if (!fg->GetResource(FG_ResourceType::HudlessColor, fIndex))
{
auto hDesc = _hudless[fIndex]->GetDesc();
Dx12Resource hudless {};