summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngine
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-08-08 23:48:40 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-08-08 23:48:40 +0000
commitfd6ecbc3e52569119c4e0ff30236bd23f2757737 (patch)
tree1cc09a201840841ecd4bb579dcd23e815fa7bc74 /Graphics/GraphicsEngine
parentD3D12 backend: implemented render pass attachment state transitons (diff)
downloadDiligentCore-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.hpp66
-rw-r--r--Graphics/GraphicsEngine/include/TextureBase.hpp6
-rw-r--r--Graphics/GraphicsEngine/interface/DeviceContext.h22
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.