From 64888e8097027b9becb6ab4def09b510d291cf64 Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 19 May 2020 23:13:41 -0700 Subject: Improved latency handling in D3D11 and D3D12 (API 240061, fixed https://github.com/DiligentGraphics/DiligentEngine/issues/81) --- .../include/SwapChainD3D11Impl.hpp | 5 ++-- .../GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp | 6 +++-- .../GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp | 31 +++++++++++++++++++++- 3 files changed, 37 insertions(+), 5 deletions(-) (limited to 'Graphics/GraphicsEngineD3D11') diff --git a/Graphics/GraphicsEngineD3D11/include/SwapChainD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/SwapChainD3D11Impl.hpp index 2e6efb6a..0c36c5d3 100644 --- a/Graphics/GraphicsEngineD3D11/include/SwapChainD3D11Impl.hpp +++ b/Graphics/GraphicsEngineD3D11/include/SwapChainD3D11Impl.hpp @@ -37,10 +37,10 @@ namespace Diligent { /// Swap chain implementation in Direct3D11 backend. -class SwapChainD3D11Impl final : public SwapChainD3DBase +class SwapChainD3D11Impl final : public SwapChainD3DBase { public: - using TSwapChainBase = SwapChainD3DBase; + using TSwapChainBase = SwapChainD3DBase; SwapChainD3D11Impl(IReferenceCounters* pRefCounters, const SwapChainDesc& SCDesc, @@ -70,6 +70,7 @@ public: private: virtual void UpdateSwapChain(bool CreateNew) override final; void CreateRTVandDSV(); + virtual void SetDXGIDeviceMaximumFrameLatency() override final; RefCntAutoPtr m_pRenderTargetView; RefCntAutoPtr m_pDepthStencilView; diff --git a/Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp index d82f0668..4d7c1321 100644 --- a/Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp +++ b/Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp @@ -29,6 +29,10 @@ /// Routines that initialize D3D11-based engine implementation #include "pch.h" + +#include +#include + #include "EngineFactoryD3D11.h" #include "RenderDeviceD3D11Impl.hpp" #include "DeviceContextD3D11Impl.hpp" @@ -36,8 +40,6 @@ #include "D3D11TypeConversions.hpp" #include "EngineMemory.h" #include "EngineFactoryD3DBase.hpp" -#include -#include namespace Diligent { diff --git a/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp index d65df7f3..d10aa2d1 100644 --- a/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp @@ -26,10 +26,11 @@ */ #include "pch.h" +#include + #include "SwapChainD3D11Impl.hpp" #include "RenderDeviceD3D11Impl.hpp" #include "DeviceContextD3D11Impl.hpp" -#include namespace Diligent { @@ -143,6 +144,11 @@ void SwapChainD3D11Impl::Present(Uint32 SyncInterval) // as this can explicitly be done by the user } + // In contrast to MSDN sample, we wait for the frame as late as possible - right + // before presenting. + // https://docs.microsoft.com/en-us/windows/uwp/gaming/reduce-latency-with-dxgi-1-3-swap-chains#step-4-wait-before-rendering-each-frame + WaitForFrame(); + m_pSwapChain->Present(SyncInterval, 0); } @@ -218,4 +224,27 @@ void SwapChainD3D11Impl::Resize(Uint32 NewWidth, Uint32 NewHeight, SURFACE_TRANS } } +void SwapChainD3D11Impl::SetDXGIDeviceMaximumFrameLatency() +{ + VERIFY(m_FrameLatencyWaitableObject == NULL, "This method should only be used as a workaround for swap chains that are not waitable"); + + auto* pd3d11Device = m_pRenderDevice.RawPtr()->GetD3D11Device(); + + CComPtr pDXGIDevice; + + auto hr = pd3d11Device->QueryInterface(__uuidof(pDXGIDevice), reinterpret_cast(static_cast(&pDXGIDevice))); + if (SUCCEEDED(hr) && pDXGIDevice) + { + hr = pDXGIDevice->SetMaximumFrameLatency(m_MaxFrameLatency); + if (FAILED(hr)) + { + LOG_ERROR_MESSAGE("Failed to set the maximum frame latency for DXGI device"); + } + } + else + { + LOG_ERROR("Failed to query IDXGIDevice1 interface from D3D11 device"); + } +} + } // namespace Diligent -- cgit v1.2.3