summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2019-08-13 05:00:42 +0000
committerEgor Yusov <egor.yusov@gmail.com>2019-08-13 05:00:42 +0000
commit97b32f52cc123544a1352527c2509c804fd3d190 (patch)
tree6fe5dc267b8a9087df2afe9bca871f9607438391 /Graphics
parentD3D11 backend: enabled multiple swap chain support (diff)
downloadDiligentCore-97b32f52cc123544a1352527c2509c804fd3d190.tar.gz
DiligentCore-97b32f52cc123544a1352527c2509c804fd3d190.zip
D3D12 backend: enabled multiple swap chain support
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsEngine/include/SwapChainBase.h50
-rw-r--r--Graphics/GraphicsEngine/interface/SwapChain.h3
-rw-r--r--Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp2
-rw-r--r--Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp52
-rw-r--r--Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp48
-rw-r--r--Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp25
6 files changed, 101 insertions, 79 deletions
diff --git a/Graphics/GraphicsEngine/include/SwapChainBase.h b/Graphics/GraphicsEngine/include/SwapChainBase.h
index 8b9aa86f..5a60c9ed 100644
--- a/Graphics/GraphicsEngine/include/SwapChainBase.h
+++ b/Graphics/GraphicsEngine/include/SwapChainBase.h
@@ -26,6 +26,8 @@
/// \file
/// Implementation of the Diligent::SwapChainBase template class
+#include <array>
+
#include "RenderDevice.h"
#include "DeviceContext.h"
#include "SwapChain.h"
@@ -89,13 +91,55 @@ protected:
return false;
}
-
+
+ template<typename DeviceContextImplType>
+ bool UnbindRenderTargets(DeviceContextImplType* pImmediateCtx,
+ ITextureView* ppBackBufferRTVs[],
+ Uint32 NumBackBufferRTVs,
+ ITextureView* pDSV)
+ {
+ bool RebindRenderTargets = false;
+ bool UnbindRenderTargets = false;
+ if (m_SwapChainDesc.IsPrimary)
+ {
+ RebindRenderTargets = UnbindRenderTargets = pImmediateCtx->IsDefaultFBBound();
+ }
+ else
+ {
+ std::array<ITextureView*, MaxRenderTargets> pBoundRTVs = {};
+ RefCntAutoPtr<ITextureView> pBoundDSV;
+ Uint32 NumRenderTargets = 0;
+ pImmediateCtx->GetRenderTargets(NumRenderTargets, pBoundRTVs.data(), &pBoundDSV);
+ for (Uint32 i=0; i < NumRenderTargets; ++i)
+ {
+ for (Uint32 j=0; j < NumBackBufferRTVs; ++j)
+ {
+ if (pBoundRTVs[i] == ppBackBufferRTVs[j])
+ UnbindRenderTargets = true;
+ }
+ }
+ if (pBoundDSV == pDSV)
+ UnbindRenderTargets = true;
+
+ for (auto pRTV : pBoundRTVs)
+ {
+ if (pRTV != nullptr)
+ pRTV->Release();
+ }
+ }
+
+ if (UnbindRenderTargets)
+ pImmediateCtx->ResetRenderTargets();
+
+ return RebindRenderTargets;
+ }
+
/// Strong reference to the render device
- Diligent::RefCntAutoPtr<IRenderDevice> m_pRenderDevice;
+ RefCntAutoPtr<IRenderDevice> m_pRenderDevice;
/// Weak references to the immediate device context. The context holds
/// the strong reference to the swap chain.
- Diligent::RefCntWeakPtr<IDeviceContext> m_wpDeviceContext;
+ RefCntWeakPtr<IDeviceContext> m_wpDeviceContext;
/// Swap chain description
SwapChainDesc m_SwapChainDesc;
diff --git a/Graphics/GraphicsEngine/interface/SwapChain.h b/Graphics/GraphicsEngine/interface/SwapChain.h
index 5e780292..164608e1 100644
--- a/Graphics/GraphicsEngine/interface/SwapChain.h
+++ b/Graphics/GraphicsEngine/interface/SwapChain.h
@@ -54,6 +54,9 @@ public:
/// \param [in] NewWidth - New swap chain width, in pixels
/// \param [in] NewHeight - New swap chain height, in pixels
+ ///
+ /// \note When resizing non-primary swap chains, the engine unbinds the
+ /// swap chain buffers from the output.
virtual void Resize( Uint32 NewWidth, Uint32 NewHeight ) = 0;
/// Sets fullscreen mode (only supported on Win32 platform)
diff --git a/Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp
index 40a3eb16..87ffbdc5 100644
--- a/Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp
@@ -315,7 +315,7 @@ void EngineFactoryD3D11Impl::CreateSwapChainD3D11(IRenderDevice* pDev
if (pDeviceContextD3D11->GetSwapChain() != nullptr && SCDesc.IsPrimary)
{
LOG_ERROR_AND_THROW("Another swap chain labeled as primary has already been created. "
- "There must be only one primary swap chain.");
+ "There must only be one primary swap chain.");
}
auto* pSwapChainD3D11 = NEW_RC_OBJ(RawMemAllocator, "SwapChainD3D11Impl instance", SwapChainD3D11Impl)
diff --git a/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp
index 225e3a98..0ffc8070 100644
--- a/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp
@@ -21,7 +21,6 @@
* of the possibility of such damages.
*/
-#include <array>
#include "pch.h"
#include "SwapChainD3D11Impl.h"
#include "RenderDeviceD3D11Impl.h"
@@ -144,38 +143,9 @@ void SwapChainD3D11Impl::UpdateSwapChain(bool CreateNew)
VERIFY(pDeviceContext, "Immediate context has been released");
if (pDeviceContext)
{
- auto *pImmediateCtxD3D11 = pDeviceContext.RawPtr<DeviceContextD3D11Impl>();
- bool RebindRenderTargets = false;
- bool UnbindRenderTargets = false;
- if (m_SwapChainDesc.IsPrimary)
- {
- RebindRenderTargets = UnbindRenderTargets = pImmediateCtxD3D11->IsDefaultFBBound();
- }
- else
- {
- std::array<ITextureView*, MaxRenderTargets> pOrigRTVs = {};
- RefCntAutoPtr<ITextureView> pOrigDSV;
- Uint32 NumRenderTargets = 0;
- pImmediateCtxD3D11->GetRenderTargets(NumRenderTargets, pOrigRTVs.data(), &pOrigDSV);
- for (Uint32 i=0; i < NumRenderTargets; ++i)
- {
- if (pOrigRTVs[i] == m_pRenderTargetView)
- UnbindRenderTargets = true;
- }
- if (pOrigDSV == m_pDepthStencilView)
- UnbindRenderTargets = true;
-
- RebindRenderTargets = NumRenderTargets == 1 && pOrigRTVs[0] == m_pRenderTargetView && pOrigDSV == m_pDepthStencilView;
-
- for(auto pRTV : pOrigRTVs)
- {
- if (pRTV != nullptr)
- pRTV->Release();
- }
- }
-
- if (UnbindRenderTargets)
- pImmediateCtxD3D11->ResetRenderTargets();
+ auto* pImmediateCtxD3D11 = pDeviceContext.RawPtr<DeviceContextD3D11Impl>();
+ ITextureView* pBackBufferRTVs[] = {m_pRenderTargetView};
+ bool RebindRenderTargets = UnbindRenderTargets(pImmediateCtxD3D11, pBackBufferRTVs, 1, m_pDepthStencilView);
// Swap chain cannot be resized until all references are released
m_pRenderTargetView.Release();
@@ -214,19 +184,11 @@ void SwapChainD3D11Impl::UpdateSwapChain(bool CreateNew)
CreateRTVandDSV();
- if (RebindRenderTargets)
+ if (m_SwapChainDesc.IsPrimary && RebindRenderTargets)
{
- if (m_SwapChainDesc.IsPrimary)
- {
- // Set default render target and viewport
- pImmediateCtxD3D11->SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
- pImmediateCtxD3D11->SetViewports(1, nullptr, 0, 0);
- }
- else
- {
- ITextureView* pRTVs[] = {GetCurrentBackBufferRTV()};
- pImmediateCtxD3D11->SetRenderTargets(1, pRTVs, GetDepthBufferDSV(), RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
- }
+ // Set default render target and viewport
+ pImmediateCtxD3D11->SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
+ pImmediateCtxD3D11->SetViewports(1, nullptr, 0, 0);
}
}
catch (const std::runtime_error &)
diff --git a/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp
index 53ede9e3..3c20c1bc 100644
--- a/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp
@@ -367,29 +367,39 @@ void EngineFactoryD3D12Impl::CreateSwapChainD3D12(IRenderDevice* pDev
try
{
- auto *pDeviceD3D12 = ValidatedCast<RenderDeviceD3D12Impl>( pDevice );
- auto *pDeviceContextD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pImmediateContext);
- auto &RawMemAllocator = GetRawAllocator();
- auto *pSwapChainD3D12 = NEW_RC_OBJ(RawMemAllocator, "SwapChainD3D12Impl instance", SwapChainD3D12Impl)(SCDesc, FSDesc, pDeviceD3D12, pDeviceContextD3D12, pNativeWndHandle);
+ auto* pDeviceD3D12 = ValidatedCast<RenderDeviceD3D12Impl>( pDevice );
+ auto* pDeviceContextD3D12 = ValidatedCast<DeviceContextD3D12Impl>(pImmediateContext);
+ auto& RawMemAllocator = GetRawAllocator();
+
+ if (pDeviceContextD3D12->GetSwapChain() != nullptr && SCDesc.IsPrimary)
+ {
+ LOG_ERROR_AND_THROW("Another swap chain labeled as primary has already been created. "
+ "There must only be one primary swap chain.");
+ }
+
+ auto* pSwapChainD3D12 = NEW_RC_OBJ(RawMemAllocator, "SwapChainD3D12Impl instance", SwapChainD3D12Impl)(SCDesc, FSDesc, pDeviceD3D12, pDeviceContextD3D12, pNativeWndHandle);
pSwapChainD3D12->QueryInterface( IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain) );
- pDeviceContextD3D12->SetSwapChain(pSwapChainD3D12);
- // Bind default render target
- pDeviceContextD3D12->SetRenderTargets( 0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION );
- // Set default viewport
- pDeviceContextD3D12->SetViewports( 1, nullptr, 0, 0 );
-
- auto NumDeferredCtx = pDeviceD3D12->GetNumDeferredContexts();
- for (size_t ctx = 0; ctx < NumDeferredCtx; ++ctx)
+ if (SCDesc.IsPrimary)
{
- if (auto pDeferredCtx = pDeviceD3D12->GetDeferredContext(ctx))
+ pDeviceContextD3D12->SetSwapChain(pSwapChainD3D12);
+ // Bind default render target
+ pDeviceContextD3D12->SetRenderTargets( 0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION );
+ // Set default viewport
+ pDeviceContextD3D12->SetViewports( 1, nullptr, 0, 0 );
+
+ auto NumDeferredCtx = pDeviceD3D12->GetNumDeferredContexts();
+ for (size_t ctx = 0; ctx < NumDeferredCtx; ++ctx)
{
- auto* pDeferredCtxD3D12 = pDeferredCtx.RawPtr<DeviceContextD3D12Impl>();
- pDeferredCtxD3D12->SetSwapChain(pSwapChainD3D12);
- // We cannot bind default render target here because
- // there is no guarantee that deferred context will be used
- // in this frame. It is an error to bind
- // RTV of an inactive buffer in the swap chain
+ if (auto pDeferredCtx = pDeviceD3D12->GetDeferredContext(ctx))
+ {
+ auto* pDeferredCtxD3D12 = pDeferredCtx.RawPtr<DeviceContextD3D12Impl>();
+ pDeferredCtxD3D12->SetSwapChain(pSwapChainD3D12);
+ // We cannot bind default render target here because
+ // there is no guarantee that deferred context will be used
+ // in this frame. It is an error to bind
+ // RTV of an inactive buffer in the swap chain
+ }
}
}
}
diff --git a/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp
index c9e986b4..8658d649 100644
--- a/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp
@@ -111,7 +111,7 @@ void SwapChainD3D12Impl::Present(Uint32 SyncInterval)
#endif
auto pDeviceContext = m_wpDeviceContext.Lock();
- if( !pDeviceContext )
+ if (!pDeviceContext)
{
LOG_ERROR_MESSAGE( "Immediate context has been released" );
return;
@@ -120,18 +120,20 @@ void SwapChainD3D12Impl::Present(Uint32 SyncInterval)
auto* pImmediateCtxD3D12 = pDeviceContext.RawPtr<DeviceContextD3D12Impl>();
auto& CmdCtx = pImmediateCtxD3D12->GetCmdContext();
- auto* pBackBuffer = ValidatedCast<TextureD3D12Impl>( GetCurrentBackBufferRTV()->GetTexture() );
+ auto* pBackBuffer = ValidatedCast<TextureD3D12Impl>(GetCurrentBackBufferRTV()->GetTexture());
CmdCtx.TransitionResource(pBackBuffer, RESOURCE_STATE_PRESENT);
pImmediateCtxD3D12->Flush();
- auto *pDeviceD3D12 = ValidatedCast<RenderDeviceD3D12Impl>( pImmediateCtxD3D12->GetDevice() );
-
auto hr = m_pSwapChain->Present( SyncInterval, 0 );
VERIFY(SUCCEEDED(hr), "Present failed");
- pImmediateCtxD3D12->FinishFrame();
- pDeviceD3D12->ReleaseStaleResources();
+ if (m_SwapChainDesc.IsPrimary)
+ {
+ pImmediateCtxD3D12->FinishFrame();
+ auto* pDeviceD3D12 = ValidatedCast<RenderDeviceD3D12Impl>( pImmediateCtxD3D12->GetDevice() );
+ pDeviceD3D12->ReleaseStaleResources();
+ }
#if 0
#if PLATFORM_UNIVERSAL_WINDOWS
@@ -160,10 +162,11 @@ void SwapChainD3D12Impl::UpdateSwapChain(bool CreateNew)
try
{
- auto *pImmediateCtxD3D12 = pDeviceContext.RawPtr<DeviceContextD3D12Impl>();
- bool bIsDefaultFBBound = pImmediateCtxD3D12->IsDefaultFBBound();
- if(bIsDefaultFBBound)
- pImmediateCtxD3D12->ResetRenderTargets();
+ auto* pImmediateCtxD3D12 = pDeviceContext.RawPtr<DeviceContextD3D12Impl>();
+ std::vector<ITextureView*> pBackBufferRTVs(m_pBackBufferRTV.size());
+ for(size_t i=0; i < m_pBackBufferRTV.size(); ++i)
+ pBackBufferRTVs[i] = m_pBackBufferRTV[i];
+ bool RebindRenderTargets = UnbindRenderTargets(pImmediateCtxD3D12, pBackBufferRTVs.data(), static_cast<Uint32>(m_pBackBufferRTV.size()), m_pDepthBufferDSV);
// All references to the swap chain must be released before it can be resized
m_pBackBufferRTV.clear();
@@ -196,7 +199,7 @@ void SwapChainD3D12Impl::UpdateSwapChain(bool CreateNew)
InitBuffersAndViews();
- if (bIsDefaultFBBound)
+ if (m_SwapChainDesc.IsPrimary && RebindRenderTargets)
{
// Set default render target and viewport
pDeviceContext->SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);