summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3D11
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2019-08-13 04:19:08 +0000
committerEgor Yusov <egor.yusov@gmail.com>2019-08-13 04:19:08 +0000
commit446d3555fa5928b14e948d6957a579fdceb37633 (patch)
tree13c8b77df7dfa3052b28d561ae30ee7bde4e455b /Graphics/GraphicsEngineD3D11
parentFixed issue with reflecting Uniform Texel Buffers in Vulkan backend (diff)
downloadDiligentCore-446d3555fa5928b14e948d6957a579fdceb37633.tar.gz
DiligentCore-446d3555fa5928b14e948d6957a579fdceb37633.zip
D3D11 backend: enabled multiple swap chain support
Diffstat (limited to 'Graphics/GraphicsEngineD3D11')
-rw-r--r--Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp59
-rw-r--r--Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp92
2 files changed, 101 insertions, 50 deletions
diff --git a/Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp
index 7be30f0c..40a3eb16 100644
--- a/Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/EngineFactoryD3D11.cpp
@@ -228,12 +228,12 @@ void EngineFactoryD3D11Impl::AttachToD3D11Device(void* pd
try
{
- ID3D11Device *pd3d11Device = reinterpret_cast<ID3D11Device *>(pd3d11NativeDevice);
- ID3D11DeviceContext *pd3d11ImmediateCtx = reinterpret_cast<ID3D11DeviceContext *>(pd3d11ImmediateContext);
+ ID3D11Device* pd3d11Device = reinterpret_cast<ID3D11Device *>(pd3d11NativeDevice);
+ ID3D11DeviceContext* pd3d11ImmediateCtx = reinterpret_cast<ID3D11DeviceContext *>(pd3d11ImmediateContext);
SetRawAllocator(EngineCI.pRawMemAllocator);
- auto &RawAlloctor = GetRawAllocator();
- RenderDeviceD3D11Impl *pRenderDeviceD3D11(NEW_RC_OBJ(RawAlloctor, "RenderDeviceD3D11Impl instance", RenderDeviceD3D11Impl)
+ auto& RawAlloctor = GetRawAllocator();
+ RenderDeviceD3D11Impl* pRenderDeviceD3D11(NEW_RC_OBJ(RawAlloctor, "RenderDeviceD3D11Impl instance", RenderDeviceD3D11Impl)
(RawAlloctor, this, EngineCI, pd3d11Device, EngineCI.NumDeferredContexts));
pRenderDeviceD3D11->QueryInterface(IID_RenderDevice, reinterpret_cast<IObject**>(ppDevice));
@@ -308,33 +308,42 @@ void EngineFactoryD3D11Impl::CreateSwapChainD3D11(IRenderDevice* pDev
try
{
- auto *pDeviceD3D11 = ValidatedCast<RenderDeviceD3D11Impl>( pDevice );
- auto *pDeviceContextD3D11 = ValidatedCast<DeviceContextD3D11Impl>(pImmediateContext);
- auto &RawMemAllocator = GetRawAllocator();
+ auto* pDeviceD3D11 = ValidatedCast<RenderDeviceD3D11Impl>(pDevice);
+ auto* pDeviceContextD3D11 = ValidatedCast<DeviceContextD3D11Impl>(pImmediateContext);
+ auto& RawMemAllocator = GetRawAllocator();
- auto *pSwapChainD3D11 = NEW_RC_OBJ(RawMemAllocator, "SwapChainD3D11Impl instance", SwapChainD3D11Impl)
+ 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.");
+ }
+
+ auto* pSwapChainD3D11 = NEW_RC_OBJ(RawMemAllocator, "SwapChainD3D11Impl instance", SwapChainD3D11Impl)
(SCDesc, FSDesc, pDeviceD3D11, pDeviceContextD3D11, pNativeWndHandle);
pSwapChainD3D11->QueryInterface( IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain) );
- pDeviceContextD3D11->SetSwapChain(pSwapChainD3D11);
- // Bind default render target
- pDeviceContextD3D11->SetRenderTargets( 0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION );
- // Set default viewport
- pDeviceContextD3D11->SetViewports( 1, nullptr, 0, 0 );
-
- auto NumDeferredCtx = pDeviceD3D11->GetNumDeferredContexts();
- for (size_t ctx = 0; ctx < NumDeferredCtx; ++ctx)
+ if (SCDesc.IsPrimary)
{
- if (auto pDeferredCtx = pDeviceD3D11->GetDeferredContext(ctx))
+ pDeviceContextD3D11->SetSwapChain(pSwapChainD3D11);
+ // Bind default render target
+ pDeviceContextD3D11->SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
+ // Set default viewport
+ pDeviceContextD3D11->SetViewports(1, nullptr, 0, 0);
+
+ auto NumDeferredCtx = pDeviceD3D11->GetNumDeferredContexts();
+ for (size_t ctx = 0; ctx < NumDeferredCtx; ++ctx)
{
- auto *pDeferredCtxD3D11 = pDeferredCtx.RawPtr<DeviceContextD3D11Impl>();
- pDeferredCtxD3D11->SetSwapChain(pSwapChainD3D11);
- // Do not bind default render target and viewport to be
- // consistent with D3D12
- //// Bind default render target
- //pDeferredCtxD3D11->SetRenderTargets( 0, nullptr, nullptr );
- //// Set default viewport
- //pDeferredCtxD3D11->SetViewports( 1, nullptr, 0, 0 );
+ if (auto pDeferredCtx = pDeviceD3D11->GetDeferredContext(ctx))
+ {
+ auto *pDeferredCtxD3D11 = pDeferredCtx.RawPtr<DeviceContextD3D11Impl>();
+ pDeferredCtxD3D11->SetSwapChain(pSwapChainD3D11);
+ // Do not bind default render target and viewport to be
+ // consistent with D3D12
+ //// Bind default render target
+ //pDeferredCtxD3D11->SetRenderTargets( 0, nullptr, nullptr );
+ //// Set default viewport
+ //pDeferredCtxD3D11->SetViewports( 1, nullptr, 0, 0 );
+ }
}
}
}
diff --git a/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp
index 85d5e054..225e3a98 100644
--- a/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/SwapChainD3D11Impl.cpp
@@ -21,6 +21,7 @@
* of the possibility of such damages.
*/
+#include <array>
#include "pch.h"
#include "SwapChainD3D11Impl.h"
#include "RenderDeviceD3D11Impl.h"
@@ -35,7 +36,7 @@ SwapChainD3D11Impl::SwapChainD3D11Impl(IReferenceCounters* pRefCounters,
const FullScreenModeDesc& FSDesc,
RenderDeviceD3D11Impl* pRenderDeviceD3D11,
DeviceContextD3D11Impl* pDeviceContextD3D11,
- void* pNativeWndHandle) :
+ void* pNativeWndHandle) :
TSwapChainBase(pRefCounters, pRenderDeviceD3D11, pDeviceContextD3D11, SCDesc, FSDesc, pNativeWndHandle)
{
auto *pd3d11Device = pRenderDeviceD3D11->GetD3D11Device();
@@ -63,7 +64,7 @@ void SwapChainD3D11Impl::CreateRTVandDSV()
DEV_CHECK_ERR(SUCCEEDED(hr), "Failed to set back buffer name");
RefCntAutoPtr<ITexture> pBackBuffer;
- pRenderDeviceD3D11Impl->CreateTextureFromD3DResource(pd3dBackBuffer, RESOURCE_STATE_UNKNOWN, &pBackBuffer);
+ pRenderDeviceD3D11Impl->CreateTextureFromD3DResource(pd3dBackBuffer, RESOURCE_STATE_UNDEFINED, &pBackBuffer);
TextureViewDesc RTVDesc;
RTVDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET;
@@ -101,30 +102,35 @@ void SwapChainD3D11Impl::Present(Uint32 SyncInterval)
#endif
auto pDeviceContext = m_wpDeviceContext.Lock();
- if( !pDeviceContext )
+ if (!pDeviceContext)
{
LOG_ERROR_MESSAGE( "Immediate context has been released" );
return;
}
- auto *pImmediateCtx = pDeviceContext.RawPtr();
- auto *pImmediateCtxD3D11 = ValidatedCast<DeviceContextD3D11Impl>( pImmediateCtx );
- // Clear the state caches to release all outstanding objects
- // that are only kept alive by references in the cache
- // It is better to do this before calling Present() as D3D11
- // also releases resources during present.
- pImmediateCtxD3D11->ReleaseCommittedShaderResources();
- // ReleaseCommittedShaderResources() does not unbind vertex and index buffers
- // as this can explicitly be done by the user
+ auto* pImmediateCtxD3D11 = pDeviceContext.RawPtr<DeviceContextD3D11Impl>();
+ if (m_SwapChainDesc.IsPrimary)
+ {
+ // Clear the state caches to release all outstanding objects
+ // that are only kept alive by references in the cache
+ // It is better to do this before calling Present() as D3D11
+ // also releases resources during present.
+ pImmediateCtxD3D11->ReleaseCommittedShaderResources();
+ // ReleaseCommittedShaderResources() does not unbind vertex and index buffers
+ // as this can explicitly be done by the user
+ }
- m_pSwapChain->Present( SyncInterval, 0 );
+ m_pSwapChain->Present(SyncInterval, 0);
- // A successful Present call for DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL SwapChains unbinds
- // backbuffer 0 from all GPU writeable bind points.
- // We need to rebind all render targets to make sure that
- // the back buffer is not unbound
- pImmediateCtxD3D11->CommitRenderTargets();
+ if (m_SwapChainDesc.IsPrimary)
+ {
+ // A successful Present call for DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL SwapChains unbinds
+ // backbuffer 0 from all GPU writeable bind points.
+ // We need to rebind all render targets to make sure that
+ // the back buffer is not unbound
+ pImmediateCtxD3D11->CommitRenderTargets();
+ }
}
void SwapChainD3D11Impl::UpdateSwapChain(bool CreateNew)
@@ -139,8 +145,36 @@ void SwapChainD3D11Impl::UpdateSwapChain(bool CreateNew)
if (pDeviceContext)
{
auto *pImmediateCtxD3D11 = pDeviceContext.RawPtr<DeviceContextD3D11Impl>();
- bool bIsDefaultFBBound = pImmediateCtxD3D11->IsDefaultFBBound();
- if (bIsDefaultFBBound)
+ 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();
// Swap chain cannot be resized until all references are released
@@ -161,7 +195,7 @@ void SwapChainD3D11Impl::UpdateSwapChain(bool CreateNew)
// https://msdn.microsoft.com/en-us/library/windows/desktop/ff476425(v=vs.85).aspx#Defer_Issues_with_Flip
pImmediateCtxD3D11->Flush();
- auto *pd3d11Device = m_pRenderDevice.RawPtr<RenderDeviceD3D11Impl>()->GetD3D11Device();
+ auto* pd3d11Device = m_pRenderDevice.RawPtr<RenderDeviceD3D11Impl>()->GetD3D11Device();
CreateDXGISwapChain(pd3d11Device);
}
else
@@ -180,11 +214,19 @@ void SwapChainD3D11Impl::UpdateSwapChain(bool CreateNew)
CreateRTVandDSV();
- if (bIsDefaultFBBound)
+ if (RebindRenderTargets)
{
- // Set default render target and viewport
- pImmediateCtxD3D11->SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
- pImmediateCtxD3D11->SetViewports(1, nullptr, 0, 0);
+ 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);
+ }
}
}
catch (const std::runtime_error &)