summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngine
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-08-07 19:14:43 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-08-07 19:14:43 +0000
commita34d7e04dc092e6c1bae4db120edbf5e6fc8c564 (patch)
treeda8797d3bfcd4685ba57e42699dae3dc1b43b448 /Graphics/GraphicsEngine
parentVk backend: fixed ClearRenderTarget and ClearDepthStencil for subpass attachm... (diff)
downloadDiligentCore-a34d7e04dc092e6c1bae4db120edbf5e6fc8c564.tar.gz
DiligentCore-a34d7e04dc092e6c1bae4db120edbf5e6fc8c564.zip
First implementation of render passes in d3d11
Diffstat (limited to 'Graphics/GraphicsEngine')
-rw-r--r--Graphics/GraphicsEngine/include/DeviceContextBase.hpp4
-rw-r--r--Graphics/GraphicsEngine/include/RenderPassBase.hpp130
2 files changed, 94 insertions, 40 deletions
diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.hpp b/Graphics/GraphicsEngine/include/DeviceContextBase.hpp
index 3e1a5779..a340bbd2 100644
--- a/Graphics/GraphicsEngine/include/DeviceContextBase.hpp
+++ b/Graphics/GraphicsEngine/include/DeviceContextBase.hpp
@@ -935,6 +935,7 @@ inline void DeviceContextBase<BaseInterface, ImplementationTraits>::BeginRenderP
}
#endif
+ // Reset current render targets (in Vulkan backend, this may end current render pass).
ResetRenderTargets();
auto* pNewRenderPass = ValidatedCast<RenderPassImplType>(Attribs.pRenderPass);
@@ -1003,7 +1004,8 @@ inline void DeviceContextBase<BaseInterface, ImplementationTraits>::EndRenderPas
if (auto* pView = FBDesc.ppAttachments[i])
{
auto* pTex = ValidatedCast<TextureImplType>(pView->GetTexture());
- pTex->SetState(RPDesc.pAttachments[i].FinalState);
+ if (pTex->IsInKnownState())
+ pTex->SetState(RPDesc.pAttachments[i].FinalState);
}
}
}
diff --git a/Graphics/GraphicsEngine/include/RenderPassBase.hpp b/Graphics/GraphicsEngine/include/RenderPassBase.hpp
index 8099abb2..46432ea0 100644
--- a/Graphics/GraphicsEngine/include/RenderPassBase.hpp
+++ b/Graphics/GraphicsEngine/include/RenderPassBase.hpp
@@ -30,6 +30,7 @@
/// \file
/// Implementation of the Diligent::RenderPassBase template class
+#include <vector>
#include "RenderPass.h"
#include "DeviceObjectBase.hpp"
#include "RenderDeviceBase.hpp"
@@ -88,62 +89,88 @@ public:
m_pPreserveAttachments = ALLOCATE(GetRawAllocator(), "Memory for subpass preserve attachments array", Uint32, TotalPreserveAttachmentsCount);
}
+ m_AttachmentStates.resize(Desc.AttachmentCount * Desc.SubpassCount);
+ m_AttachmentFirstUseSubpass.resize(Desc.AttachmentCount, ATTACHMENT_UNUSED);
+
auto* pCurrAttachmentRef = m_pAttachmentReferences;
auto* pCurrPreserveAttachment = m_pPreserveAttachments;
- if (Desc.SubpassCount != 0)
+ VERIFY(Desc.SubpassCount != 0, "Render pass must have at least one subpass");
+ auto* pSubpasses =
+ ALLOCATE(GetRawAllocator(), "Memory for SubpassDesc array", SubpassDesc, Desc.SubpassCount);
+ this->m_Desc.pSubpasses = pSubpasses;
+ for (Uint32 i = 0; i < Desc.SubpassCount; ++i)
{
- auto* pSubpasses =
- ALLOCATE(GetRawAllocator(), "Memory for SubpassDesc array", SubpassDesc, Desc.SubpassCount);
- this->m_Desc.pSubpasses = pSubpasses;
- for (Uint32 i = 0; i < Desc.SubpassCount; ++i)
+ for (Uint32 att = 0; att < Desc.AttachmentCount; ++att)
{
- const auto& SrcSubpass = Desc.pSubpasses[i];
- auto& DstSubpass = pSubpasses[i];
+ SetAttachmentState(i, att, i > 0 ? GetAttachmentState(i - 1, att) : Desc.pAttachments[i].InitialState);
+ }
- DstSubpass = SrcSubpass;
- if (SrcSubpass.InputAttachmentCount != 0)
- {
- DstSubpass.pInputAttachments = pCurrAttachmentRef;
- for (Uint32 input_attachment = 0; input_attachment < SrcSubpass.InputAttachmentCount; ++input_attachment)
- *(pCurrAttachmentRef++) = SrcSubpass.pInputAttachments[input_attachment];
- }
- else
- DstSubpass.pInputAttachments = nullptr;
+ const auto& SrcSubpass = Desc.pSubpasses[i];
+ auto& DstSubpass = pSubpasses[i];
- if (SrcSubpass.RenderTargetAttachmentCount != 0)
+ auto UpdateAttachmentStateAndFirstUseSubpass = [this, i](const AttachmentReference& AttRef) //
+ {
+ if (AttRef.AttachmentIndex != ATTACHMENT_UNUSED)
{
- DstSubpass.pRenderTargetAttachments = pCurrAttachmentRef;
- for (Uint32 rt_attachment = 0; rt_attachment < SrcSubpass.RenderTargetAttachmentCount; ++rt_attachment)
- *(pCurrAttachmentRef++) = SrcSubpass.pRenderTargetAttachments[rt_attachment];
- if (DstSubpass.pResolveAttachments)
- {
- for (Uint32 rslv_attachment = 0; rslv_attachment < SrcSubpass.RenderTargetAttachmentCount; ++rslv_attachment)
- *(pCurrAttachmentRef++) = SrcSubpass.pResolveAttachments[rslv_attachment];
- }
- else
- DstSubpass.pResolveAttachments = nullptr;
+ SetAttachmentState(i, AttRef.AttachmentIndex, AttRef.State);
+ if (m_AttachmentFirstUseSubpass[AttRef.AttachmentIndex] == ATTACHMENT_UNUSED)
+ m_AttachmentFirstUseSubpass[AttRef.AttachmentIndex] = i;
}
- else
+ };
+
+ DstSubpass = SrcSubpass;
+ if (SrcSubpass.InputAttachmentCount != 0)
+ {
+ DstSubpass.pInputAttachments = pCurrAttachmentRef;
+ for (Uint32 input_attachment = 0; input_attachment < SrcSubpass.InputAttachmentCount; ++input_attachment, ++pCurrAttachmentRef)
{
- DstSubpass.pRenderTargetAttachments = nullptr;
- DstSubpass.pResolveAttachments = nullptr;
+ *pCurrAttachmentRef = SrcSubpass.pInputAttachments[input_attachment];
+ UpdateAttachmentStateAndFirstUseSubpass(*pCurrAttachmentRef);
}
+ }
+ else
+ DstSubpass.pInputAttachments = nullptr;
- if (SrcSubpass.pDepthStencilAttachment != nullptr)
+ if (SrcSubpass.RenderTargetAttachmentCount != 0)
+ {
+ DstSubpass.pRenderTargetAttachments = pCurrAttachmentRef;
+ for (Uint32 rt_attachment = 0; rt_attachment < SrcSubpass.RenderTargetAttachmentCount; ++rt_attachment, ++pCurrAttachmentRef)
{
- DstSubpass.pDepthStencilAttachment = pCurrAttachmentRef;
- *(pCurrAttachmentRef++) = *SrcSubpass.pDepthStencilAttachment;
+ *pCurrAttachmentRef = SrcSubpass.pRenderTargetAttachments[rt_attachment];
+ UpdateAttachmentStateAndFirstUseSubpass(*pCurrAttachmentRef);
}
- if (SrcSubpass.PreserveAttachmentCount != 0)
+ if (DstSubpass.pResolveAttachments)
{
- DstSubpass.pPreserveAttachments = pCurrPreserveAttachment;
- for (Uint32 prsv_attachment = 0; prsv_attachment < SrcSubpass.PreserveAttachmentCount; ++prsv_attachment)
- *(pCurrPreserveAttachment++) = SrcSubpass.pPreserveAttachments[prsv_attachment];
+ DstSubpass.pResolveAttachments = pCurrAttachmentRef;
+ for (Uint32 rslv_attachment = 0; rslv_attachment < SrcSubpass.RenderTargetAttachmentCount; ++rslv_attachment, ++pCurrAttachmentRef)
+ {
+ *pCurrAttachmentRef = SrcSubpass.pResolveAttachments[rslv_attachment];
+ UpdateAttachmentStateAndFirstUseSubpass(*pCurrAttachmentRef);
+ }
}
- else
- DstSubpass.pPreserveAttachments = nullptr;
}
+ else
+ {
+ DstSubpass.pRenderTargetAttachments = nullptr;
+ DstSubpass.pResolveAttachments = nullptr;
+ }
+
+ if (SrcSubpass.pDepthStencilAttachment != nullptr)
+ {
+ DstSubpass.pDepthStencilAttachment = pCurrAttachmentRef;
+ *(pCurrAttachmentRef++) = *SrcSubpass.pDepthStencilAttachment;
+ UpdateAttachmentStateAndFirstUseSubpass(*SrcSubpass.pDepthStencilAttachment);
+ }
+
+ if (SrcSubpass.PreserveAttachmentCount != 0)
+ {
+ DstSubpass.pPreserveAttachments = pCurrPreserveAttachment;
+ for (Uint32 prsv_attachment = 0; prsv_attachment < SrcSubpass.PreserveAttachmentCount; ++prsv_attachment)
+ *(pCurrPreserveAttachment++) = SrcSubpass.pPreserveAttachments[prsv_attachment];
+ }
+ else
+ DstSubpass.pPreserveAttachments = nullptr;
}
VERIFY_EXPR(pCurrAttachmentRef - m_pAttachmentReferences == TotalAttachmentReferencesCount);
VERIFY_EXPR(pCurrPreserveAttachment - m_pPreserveAttachments == TotalPreserveAttachmentsCount);
@@ -177,6 +204,18 @@ public:
IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_RenderPass, TDeviceObjectBase)
+ RESOURCE_STATE GetAttachmentState(Uint32 Subpass, Uint32 Attachment) const
+ {
+ VERIFY_EXPR(Attachment < this->m_Desc.AttachmentCount);
+ VERIFY_EXPR(Subpass < this->m_Desc.SubpassCount);
+ return m_AttachmentStates[this->m_Desc.AttachmentCount * Subpass + Attachment];
+ }
+
+ Uint32 GetAttachmentFirstUseSubpass(Uint32 Attachment) const
+ {
+ return m_AttachmentFirstUseSubpass[Attachment];
+ }
+
protected:
static void CountSubpassAttachmentReferences(const RenderPassDesc& Desc,
Uint32& TotalAttachmentReferencesCount,
@@ -198,8 +237,21 @@ protected:
}
private:
+ void SetAttachmentState(Uint32 Subpass, Uint32 Attachment, RESOURCE_STATE State)
+ {
+ VERIFY_EXPR(Attachment < this->m_Desc.AttachmentCount);
+ VERIFY_EXPR(Subpass < this->m_Desc.SubpassCount);
+ m_AttachmentStates[this->m_Desc.AttachmentCount * Subpass + Attachment] = State;
+ }
+
AttachmentReference* m_pAttachmentReferences = nullptr;
Uint32* m_pPreserveAttachments = nullptr;
+
+ // Attachment states during each subpass
+ std::vector<RESOURCE_STATE> m_AttachmentStates;
+
+ // The index of the subpass where the attachment is first used
+ std::vector<Uint32> m_AttachmentFirstUseSubpass;
};
} // namespace Diligent