From c5ad3bbf31fd74d6514cdc0b4b62d4124474f881 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Mon, 12 Aug 2019 22:14:34 -0700 Subject: Vulkan backend: enabled multiple swap chain support (closed https://github.com/DiligentGraphics/DiligentCore/issues/35) --- .../GraphicsEngineVulkan/src/EngineFactoryVk.cpp | 49 +++++++++++++--------- .../GraphicsEngineVulkan/src/SwapChainVkImpl.cpp | 17 +++++--- 2 files changed, 41 insertions(+), 25 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp index 57b36201..13603ba7 100644 --- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp @@ -319,29 +319,40 @@ void EngineFactoryVkImpl::CreateSwapChainVk(IRenderDevice* pDevice, try { - auto *pDeviceVk = ValidatedCast( pDevice ); - auto *pDeviceContextVk = ValidatedCast(pImmediateContext); - auto &RawMemAllocator = GetRawAllocator(); - auto *pSwapChainVk = NEW_RC_OBJ(RawMemAllocator, "SwapChainVkImpl instance", SwapChainVkImpl)(SCDesc, pDeviceVk, pDeviceContextVk, pNativeWndHandle); + auto* pDeviceVk = ValidatedCast( pDevice ); + auto* pDeviceContextVk = ValidatedCast(pImmediateContext); + auto& RawMemAllocator = GetRawAllocator(); + + if (pDeviceContextVk->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* pSwapChainVk = NEW_RC_OBJ(RawMemAllocator, "SwapChainVkImpl instance", SwapChainVkImpl)(SCDesc, pDeviceVk, pDeviceContextVk, pNativeWndHandle); pSwapChainVk->QueryInterface( IID_SwapChain, reinterpret_cast(ppSwapChain) ); - pDeviceContextVk->SetSwapChain(pSwapChainVk); - // Bind default render target - pDeviceContextVk->SetRenderTargets( 0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION ); - // Set default viewport - pDeviceContextVk->SetViewports( 1, nullptr, 0, 0 ); - - auto NumDeferredCtx = pDeviceVk->GetNumDeferredContexts(); - for (size_t ctx = 0; ctx < NumDeferredCtx; ++ctx) + if (SCDesc.IsPrimary) { - if (auto pDeferredCtx = pDeviceVk->GetDeferredContext(ctx)) + pDeviceContextVk->SetSwapChain(pSwapChainVk); + // Bind default render target + pDeviceContextVk->SetRenderTargets( 0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION ); + // Set default viewport + pDeviceContextVk->SetViewports( 1, nullptr, 0, 0 ); + + auto NumDeferredCtx = pDeviceVk->GetNumDeferredContexts(); + for (size_t ctx = 0; ctx < NumDeferredCtx; ++ctx) { - auto *pDeferredCtxVk = pDeferredCtx.RawPtr(); - pDeferredCtxVk->SetSwapChain(pSwapChainVk); - // 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 = pDeviceVk->GetDeferredContext(ctx)) + { + auto *pDeferredCtxVk = pDeferredCtx.RawPtr(); + pDeferredCtxVk->SetSwapChain(pSwapChainVk); + // 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/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp index cf3cba5f..5988ddaa 100644 --- a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp @@ -543,8 +543,11 @@ void SwapChainVkImpl::Present(Uint32 SyncInterval) } } - pImmediateCtxVk->FinishFrame(); - pDeviceVk->ReleaseStaleResources(); + if (m_SwapChainDesc.IsPrimary) + { + pImmediateCtxVk->FinishFrame(); + pDeviceVk->ReleaseStaleResources(); + } if (!m_IsMinimized) { @@ -561,7 +564,7 @@ void SwapChainVkImpl::Present(Uint32 SyncInterval) } DEV_CHECK_ERR(res == VK_SUCCESS, "Failed to acquire next swap chain image"); - if (IsDefaultFBBound) + if (m_SwapChainDesc.IsPrimary && IsDefaultFBBound) { // If default framebuffer is bound, we need to call SetRenderTargets() // to bind new back buffer RTV @@ -586,8 +589,10 @@ void SwapChainVkImpl::WaitForImageAcquiredFences() void SwapChainVkImpl::RecreateVulkanSwapchain(DeviceContextVkImpl* pImmediateCtxVk) { - if (pImmediateCtxVk->IsDefaultFBBound()) - pImmediateCtxVk->ResetRenderTargets(); + std::vector pBackBufferRTVs(m_pBackBufferRTV.size()); + for(size_t i=0; i < m_pBackBufferRTV.size(); ++i) + pBackBufferRTVs[i] = m_pBackBufferRTV[i]; + UnbindRenderTargets(pImmediateCtxVk, pBackBufferRTVs.data(), static_cast(m_pBackBufferRTV.size()), m_pDepthBufferDSV); RenderDeviceVkImpl* pDeviceVk = m_pRenderDevice.RawPtr(); @@ -637,7 +642,7 @@ void SwapChainVkImpl::Resize( Uint32 NewWidth, Uint32 NewHeight ) auto res = AcquireNextImage(pImmediateCtxVk); DEV_CHECK_ERR(res == VK_SUCCESS, "Failed to acquire next image for the just resized swap chain"); (void)res; - if( bIsDefaultFBBound ) + if (m_SwapChainDesc.IsPrimary && bIsDefaultFBBound) { // Set default render target and viewport pDeviceContext->SetRenderTargets( 0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); -- cgit v1.2.3