diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index e762dd9eb..9a684286a 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -156,7 +156,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11ImmediateContext::Flush() { D3D10DeviceLock lock = LockContext(); - ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr, true); + if (!IgnoreExplicitFlush()) + ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr, true); } @@ -165,7 +166,8 @@ namespace dxvk { HANDLE hEvent) { D3D10DeviceLock lock = LockContext(); - ExecuteFlush(GpuFlushType::ExplicitFlush, hEvent, true); + if (!IgnoreExplicitFlush()) + ExecuteFlush(GpuFlushType::ExplicitFlush, hEvent, true); } @@ -1078,6 +1080,22 @@ namespace dxvk { } + bool D3D11ImmediateContext::IgnoreExplicitFlush() { + // This is sketchy in general since not respecting an explicit flush can + // keep resources alive indefinitely when they shouldn't be. Only do this + // in tiler mode if flushing would prevent resolve optimizations, and if + // we don't break submission order w.r.t. other D3D devices. + if (!m_device->perfHints().preferRenderPassOps) + return false; + + if (m_parent->Is11on12Device() + || m_parent->HasSharedResources()) + return false; + + return m_hasPendingMsaaResolve; + } + + GpuFlushType D3D11ImmediateContext::GetMaxFlushType( D3D11Device* pParent, const Rc& Device) { diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index a73dfe6d0..3b0dea9a1 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -210,6 +210,8 @@ namespace dxvk { DxvkStagingBufferStats GetStagingMemoryStatistics(); + bool IgnoreExplicitFlush(); + static GpuFlushType GetMaxFlushType( D3D11Device* pParent, const Rc& Device); diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 2ffc50e26..7e92d8fe0 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -2375,6 +2375,8 @@ namespace dxvk { Logger::err(e.message()); return E_INVALIDARG; } + + m_hasSharedResources.store(true, std::memory_order_release); #else Logger::warn("D3D11Device::OpenSharedResourceGeneric: Not supported on this platform."); return E_INVALIDARG; diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 48356f8b4..837d0afee 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -464,6 +464,10 @@ namespace dxvk { bool Is11on12Device() const; + bool HasSharedResources() const { + return m_hasSharedResources.load(std::memory_order_acquire); + } + static D3D_FEATURE_LEVEL GetMaxFeatureLevel( const Rc& Instance, const Rc& Adapter); @@ -512,6 +516,8 @@ namespace dxvk { D3D_FEATURE_LEVEL m_maxFeatureLevel; D3D11DeviceFeatures m_deviceFeatures; + std::atomic m_hasSharedResources = { false }; + HRESULT CreateShaderModule( D3D11CommonShader* pShaderModule, DxvkShaderKey ShaderKey,