diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2020-08-08 23:48:40 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2020-08-08 23:48:40 +0000 |
| commit | fd6ecbc3e52569119c4e0ff30236bd23f2757737 (patch) | |
| tree | 1cc09a201840841ecd4bb579dcd23e815fa7bc74 /Graphics/GraphicsEngine | |
| parent | D3D12 backend: implemented render pass attachment state transitons (diff) | |
| download | DiligentCore-fd6ecbc3e52569119c4e0ff30236bd23f2757737.tar.gz DiligentCore-fd6ecbc3e52569119c4e0ff30236bd23f2757737.zip | |
Implemented unified render pass attachment state updates within subpasses and after the render pass ends
Diffstat (limited to 'Graphics/GraphicsEngine')
| -rw-r--r-- | Graphics/GraphicsEngine/include/DeviceContextBase.hpp | 66 | ||||
| -rw-r--r-- | Graphics/GraphicsEngine/include/TextureBase.hpp | 6 | ||||
| -rw-r--r-- | Graphics/GraphicsEngine/interface/DeviceContext.h | 22 |
3 files changed, 65 insertions, 29 deletions
diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.hpp b/Graphics/GraphicsEngine/include/DeviceContextBase.hpp index a340bbd2..e5d9b90e 100644 --- a/Graphics/GraphicsEngine/include/DeviceContextBase.hpp +++ b/Graphics/GraphicsEngine/include/DeviceContextBase.hpp @@ -126,7 +126,7 @@ public: virtual void DILIGENT_CALL_TYPE NextSubpass() override = 0; - virtual void DILIGENT_CALL_TYPE EndRenderPass(bool UpdateResourceStates) override = 0; + virtual void DILIGENT_CALL_TYPE EndRenderPass() override = 0; /// Base implementation of IDeviceContext::UpdateBuffer(); validates input parameters. virtual void DILIGENT_CALL_TYPE UpdateBuffer(IBuffer* pBuffer, @@ -228,6 +228,9 @@ protected: /// Checks if the texture is currently bound as depth-stencil buffer. bool CheckIfBoundAsDepthStencil(TextureImplType* pTexture); + /// Updates the states of render pass attachments to match states within the gievn subpass + void UpdateAttachmentStates(Uint32 SubpassIndex); + bool ClearDepthStencil(ITextureView* pView); bool ClearRenderTarget(ITextureView* pView); @@ -329,6 +332,9 @@ protected: /// Current subpass index. Uint32 m_SubpassIndex = 0; + /// Render pass attachments transition mode. + RESOURCE_STATE_TRANSITION_MODE m_RenderPassAttachmentsTransitionMode = RESOURCE_STATE_TRANSITION_MODE_NONE; + const bool m_bIsDeferred = false; #ifdef DILIGENT_DEBUG @@ -970,9 +976,11 @@ inline void DeviceContextBase<BaseInterface, ImplementationTraits>::BeginRenderP } } - m_pActiveRenderPass = pNewRenderPass; - m_pBoundFramebuffer = pNewFramebuffer; - m_SubpassIndex = 0; + m_pActiveRenderPass = pNewRenderPass; + m_pBoundFramebuffer = pNewFramebuffer; + m_SubpassIndex = 0; + m_RenderPassAttachmentsTransitionMode = Attribs.StateTransitionMode; + UpdateAttachmentStates(m_SubpassIndex); SetSubpassRenderTargets(); } @@ -982,36 +990,54 @@ inline void DeviceContextBase<BaseInterface, ImplementationTraits>::NextSubpass( VERIFY(m_pActiveRenderPass != nullptr, "There is no active render pass"); VERIFY(m_SubpassIndex + 1 < m_pActiveRenderPass->GetDesc().SubpassCount, "The render pass has reached the final subpass already"); ++m_SubpassIndex; + UpdateAttachmentStates(m_SubpassIndex); SetSubpassRenderTargets(); } template <typename BaseInterface, typename ImplementationTraits> -inline void DeviceContextBase<BaseInterface, ImplementationTraits>::EndRenderPass(bool UpdateResourceStates) +inline void DeviceContextBase<BaseInterface, ImplementationTraits>::UpdateAttachmentStates(Uint32 SubpassIndex) { - VERIFY(m_pActiveRenderPass != nullptr, "There is no active render pass"); - VERIFY(m_pBoundFramebuffer != nullptr, "There is no active framebuffer"); - VERIFY(m_pActiveRenderPass->GetDesc().SubpassCount == m_SubpassIndex + 1, - "Ending render pass at subpass ", m_SubpassIndex, " before reaching the final subpass"); + if (m_RenderPassAttachmentsTransitionMode != RESOURCE_STATE_TRANSITION_MODE_TRANSITION) + return; + + VERIFY_EXPR(m_pActiveRenderPass != nullptr); + VERIFY_EXPR(m_pBoundFramebuffer != nullptr); - if (UpdateResourceStates) + const auto& RPDesc = m_pActiveRenderPass->GetDesc(); + const auto& FBDesc = m_pBoundFramebuffer->GetDesc(); + VERIFY(FBDesc.AttachmentCount == RPDesc.AttachmentCount, + "Framebuffer attachment count (", FBDesc.AttachmentCount, ") is not consistent with the render pass attachment count (", RPDesc.AttachmentCount, ")"); + VERIFY_EXPR(SubpassIndex <= RPDesc.SubpassCount); + for (Uint32 i = 0; i < RPDesc.AttachmentCount; ++i) { - const auto& RPDesc = m_pActiveRenderPass->GetDesc(); - const auto& FBDesc = m_pBoundFramebuffer->GetDesc(); - VERIFY(FBDesc.AttachmentCount >= RPDesc.AttachmentCount, - "Framebuffer attachment count (", FBDesc.AttachmentCount, ") is smaller than the render pass attachment count (", RPDesc.AttachmentCount, ")"); - for (Uint32 i = 0; i < RPDesc.AttachmentCount; ++i) + if (auto* pView = FBDesc.ppAttachments[i]) { - if (auto* pView = FBDesc.ppAttachments[i]) + auto* pTex = ValidatedCast<TextureImplType>(pView->GetTexture()); + if (pTex->IsInKnownState()) { - auto* pTex = ValidatedCast<TextureImplType>(pView->GetTexture()); - if (pTex->IsInKnownState()) - pTex->SetState(RPDesc.pAttachments[i].FinalState); + auto CurrState = SubpassIndex < RPDesc.SubpassCount ? + m_pActiveRenderPass->GetAttachmentState(SubpassIndex, i) : + RPDesc.pAttachments[i].FinalState; + pTex->SetState(CurrState); } } } +} + +template <typename BaseInterface, typename ImplementationTraits> +inline void DeviceContextBase<BaseInterface, ImplementationTraits>::EndRenderPass() +{ + VERIFY(m_pActiveRenderPass != nullptr, "There is no active render pass"); + VERIFY(m_pBoundFramebuffer != nullptr, "There is no active framebuffer"); + VERIFY(m_pActiveRenderPass->GetDesc().SubpassCount == m_SubpassIndex + 1, + "Ending render pass at subpass ", m_SubpassIndex, " before reaching the final subpass"); + + UpdateAttachmentStates(m_SubpassIndex + 1); + m_pActiveRenderPass.Release(); m_pBoundFramebuffer.Release(); - m_SubpassIndex = 0; + m_SubpassIndex = 0; + m_RenderPassAttachmentsTransitionMode = RESOURCE_STATE_TRANSITION_MODE_NONE; ResetRenderTargets(); } diff --git a/Graphics/GraphicsEngine/include/TextureBase.hpp b/Graphics/GraphicsEngine/include/TextureBase.hpp index fd0256b6..1805f7d3 100644 --- a/Graphics/GraphicsEngine/include/TextureBase.hpp +++ b/Graphics/GraphicsEngine/include/TextureBase.hpp @@ -184,6 +184,12 @@ public: return (this->m_State & State) == State; } + bool CheckAnyState(RESOURCE_STATE States) const + { + VERIFY(IsInKnownState(), "Texture state is unknown"); + return (this->m_State & States) != 0; + } + /// Implementation of ITexture::GetDefaultView(). virtual ITextureView* DILIGENT_CALL_TYPE GetDefaultView(TEXTURE_VIEW_TYPE ViewType) override { diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h index 3445a8d6..eb77ba8e 100644 --- a/Graphics/GraphicsEngine/interface/DeviceContext.h +++ b/Graphics/GraphicsEngine/interface/DeviceContext.h @@ -633,7 +633,18 @@ struct BeginRenderPassAttribs /// Other elements of pClearValues are ignored. OptimizedClearValue* pClearValues DEFAULT_INITIALIZER(nullptr); - /// Framebuffer attachments state transition mode. + /// Framebuffer attachments state transition mode before the render pass begins. + + /// This parameter also indicates how attachment states should be handled when + /// transitioning between subpasses as well as after the render pass ends. + /// When RESOURCE_STATE_TRANSITION_MODE_TRANSITION is used, attachment states will be + /// updated so that they match the state in the current subpass as well as the final states + /// specified by the render pass when the pass ends. + /// Note that resources are always transitioned. The flag only indicates if the internal + /// state variables should be updated. + /// When RESOURCE_STATE_TRANSITION_MODE_NONE or RESOURCE_STATE_TRANSITION_MODE_VERIFY is used, + /// internal state variables are not updated and it is the application responsibility to set them + /// manually to match the actual states. RESOURCE_STATE_TRANSITION_MODE StateTransitionMode DEFAULT_INITIALIZER(RESOURCE_STATE_TRANSITION_MODE_NONE); }; typedef struct BeginRenderPassAttribs BeginRenderPassAttribs; @@ -905,14 +916,7 @@ DILIGENT_BEGIN_INTERFACE(IDeviceContext, IObject) /// Ends current render pass. - - /// \param [in] UpdateResourceStates - Indicates whether to update resource states so that they match - /// the final states specified by the render pass attachments. - /// Note that resources are always transitioned to the final states. - /// The flag only indicates if the internal state variables should be - /// updated to match the actual final states. - VIRTUAL void METHOD(EndRenderPass)(THIS_ - bool UpdateResourceStates) PURE; + VIRTUAL void METHOD(EndRenderPass)(THIS) PURE; /// Executes a draw command. |
