diff options
Diffstat (limited to 'Graphics/GraphicsEngine')
| -rw-r--r-- | Graphics/GraphicsEngine/include/RenderPassBase.hpp | 91 | ||||
| -rw-r--r-- | Graphics/GraphicsEngine/interface/RenderPass.h | 142 | ||||
| -rw-r--r-- | Graphics/GraphicsEngine/src/RenderPassBase.cpp | 20 |
3 files changed, 251 insertions, 2 deletions
diff --git a/Graphics/GraphicsEngine/include/RenderPassBase.hpp b/Graphics/GraphicsEngine/include/RenderPassBase.hpp index 03fecd78..a8d73dc2 100644 --- a/Graphics/GraphicsEngine/include/RenderPassBase.hpp +++ b/Graphics/GraphicsEngine/include/RenderPassBase.hpp @@ -76,6 +76,20 @@ public: } } + Uint32 TotalAttachmentReferencesCount = 0; + Uint32 TotalPreserveAttachmentsCount = 0; + CountSubpassAttachmentReferences(Desc, TotalAttachmentReferencesCount, TotalPreserveAttachmentsCount); + if (TotalAttachmentReferencesCount != 0) + { + m_pAttachmentReferences = ALLOCATE(GetRawAllocator(), "Memory for subpass attachment references array", AttachmentReference, TotalAttachmentReferencesCount); + } + if (TotalPreserveAttachmentsCount != 0) + { + m_pPreserveAttachments = ALLOCATE(GetRawAllocator(), "Memory for subpass preserve attachments array", Uint32, TotalPreserveAttachmentsCount); + } + + auto* pCurrAttachmentRef = m_pAttachmentReferences; + auto* pCurrPreserveAttachment = m_pPreserveAttachments; if (Desc.SubpassCount != 0) { auto* pSubpasses = @@ -83,9 +97,56 @@ public: this->m_Desc.pSubpasses = pSubpasses; for (Uint32 i = 0; i < Desc.SubpassCount; ++i) { - pSubpasses[i] = Desc.pSubpasses[i]; + const auto& SrcSubpass = Desc.pSubpasses[i]; + auto& DstSubpass = pSubpasses[i]; + + 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; + + if (SrcSubpass.RenderTargetAttachmentCount != 0) + { + 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; + } + else + { + DstSubpass.pRenderTargetAttachments = nullptr; + DstSubpass.pResolveAttachments = nullptr; + } + + if (SrcSubpass.pDepthStencilAttachment != nullptr) + { + DstSubpass.pDepthStencilAttachment = pCurrAttachmentRef; + *(pCurrAttachmentRef++) = *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); if (Desc.DependencyCount != 0) { @@ -108,9 +169,37 @@ public: RawAllocator.Free(const_cast<SubpassDesc*>(this->m_Desc.pSubpasses)); if (this->m_Desc.pDependencies != nullptr) RawAllocator.Free(const_cast<SubpassDependencyDesc*>(this->m_Desc.pDependencies)); + if (m_pAttachmentReferences != nullptr) + RawAllocator.Free(m_pAttachmentReferences); + if (m_pPreserveAttachments != nullptr) + RawAllocator.Free(m_pPreserveAttachments); } IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_RenderPass, TDeviceObjectBase) + +protected: + static void CountSubpassAttachmentReferences(const RenderPassDesc& Desc, + Uint32& TotalAttachmentReferencesCount, + Uint32& TotalPreserveAttachmentsCount) + { + TotalAttachmentReferencesCount = 0; + TotalPreserveAttachmentsCount = 0; + for (Uint32 i = 0; i < Desc.SubpassCount; ++i) + { + const auto& Subpass = Desc.pSubpasses[i]; + TotalAttachmentReferencesCount += Subpass.InputAttachmentCount; + TotalAttachmentReferencesCount += Subpass.RenderTargetAttachmentCount; + if (Subpass.pResolveAttachments != nullptr) + TotalAttachmentReferencesCount += Subpass.RenderTargetAttachmentCount; + if (Subpass.pDepthStencilAttachment != nullptr) + TotalAttachmentReferencesCount += 1; + TotalPreserveAttachmentsCount += Subpass.PreserveAttachmentCount; + } + } + +private: + AttachmentReference* m_pAttachmentReferences = nullptr; + Uint32* m_pPreserveAttachments = nullptr; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngine/interface/RenderPass.h b/Graphics/GraphicsEngine/interface/RenderPass.h index 36cfc46c..3ac3e3ce 100644 --- a/Graphics/GraphicsEngine/interface/RenderPass.h +++ b/Graphics/GraphicsEngine/interface/RenderPass.h @@ -124,11 +124,151 @@ struct RenderPassAttachmentDesc }; typedef struct RenderPassAttachmentDesc RenderPassAttachmentDesc; +#define ATTACHMENT_UNUSED (~0U) + +/// Attachment reference description. +struct AttachmentReference +{ + /// Either an integer value identifying an attachment at the corresponding index in RenderPassDesc::pAttachments, + /// or ATTACHMENT_UNUSED to signify that this attachment is not used. + Uint32 AttachmentIndex DEFAULT_INITIALIZER(0); + + /// The state of the attachment during the subpass. + RESOURCE_STATE State DEFAULT_INITIALIZER(RESOURCE_STATE_UNKNOWN); + +#if DILIGENT_CPP_INTERFACE + AttachmentReference()noexcept{} + + AttachmentReference(Uint32 _AttachmentIndex, + RESOURCE_STATE _State)noexcept : + AttachmentIndex{_AttachmentIndex}, + State {_State} + {} + + /// Tests if two structures are equivalent + + /// \param [in] RHS - reference to the structure to perform comparison with + /// \return + /// - True if all members of the two structures are equal. + /// - False otherwise + bool operator == (const AttachmentReference& RHS) const + { + return AttachmentIndex == RHS.AttachmentIndex && + State == RHS.State; + } + + bool operator != (const AttachmentReference& RHS) const + { + return !(*this == RHS); + } +#endif +}; +typedef struct AttachmentReference AttachmentReference; + /// Render pass subpass decription. struct SubpassDesc { - int Dummy; + /// The number of input attachments the subpass uses. + Uint32 InputAttachmentCount DEFAULT_INITIALIZER(0); + + /// Pointer to the array of input attachments, see Diligent::AttachmentReference. + const AttachmentReference* pInputAttachments DEFAULT_INITIALIZER(nullptr); + + /// The number of color render target attachments. + Uint32 RenderTargetAttachmentCount DEFAULT_INITIALIZER(0); + + /// Pointer to the array of color render target attachments, see Diligent::AttachmentReference. + + /// Each element of the pRenderTargetAttachments array corresponds to an output in the pixel shader, + /// i.e. if the shader declares an output variable decorated with a render target index X, then it uses + /// the attachment provided in pRenderTargetAttachments[X]. If the attachment index is ATTACHMENT_UNUSED, + /// writes to this render target are ignored. + const AttachmentReference* pRenderTargetAttachments DEFAULT_INITIALIZER(nullptr); + + /// Pointer to the array of resolve attachments, see Diligent::AttachmentReference. + + /// If pResolveAttachments is not NULL, each of its elements corresponds to a render target attachment + /// (the element in pRenderTargetAttachments at the same index), and a multisample resolve operation is + /// defined for each attachment. At the end of each subpass, multisample resolve operations read the subpass's + /// color attachments, and resolve the samples for each pixel within the render area to the same pixel location + /// in the corresponding resolve attachments, unless the resolve attachment index is ATTACHMENT_UNUSED. + const AttachmentReference* pResolveAttachments DEFAULT_INITIALIZER(nullptr); + + /// Pointer to the depth-stencil attachment, see Diligent::AttachmentReference. + const AttachmentReference* pDepthStencilAttachment DEFAULT_INITIALIZER(nullptr); + + /// The number of preserve attachments. + Uint32 PreserveAttachmentCount DEFAULT_INITIALIZER(0); + + /// Pointer to the array of preserve attachments, see Diligent::AttachmentReference. + const Uint32* pPreserveAttachments DEFAULT_INITIALIZER(nullptr); + +#if DILIGENT_CPP_INTERFACE + /// Tests if two structures are equivalent + + /// \param [in] RHS - reference to the structure to perform comparison with + /// \return + /// - True if all members of the two structures are equal. + /// - False otherwise + bool operator == (const SubpassDesc& RHS)const + { + if (InputAttachmentCount != RHS.InputAttachmentCount || + RenderTargetAttachmentCount != RHS.RenderTargetAttachmentCount || + PreserveAttachmentCount != RHS.PreserveAttachmentCount) + return false; + + for(Uint32 i=0; i < InputAttachmentCount; ++i) + { + if (pInputAttachments[i] != RHS.pInputAttachments[i]) + return false; + } + + for(Uint32 i=0; i < RenderTargetAttachmentCount; ++i) + { + if (pRenderTargetAttachments[i] != RHS.pRenderTargetAttachments[i]) + return false; + } + + if ((pResolveAttachments == nullptr && RHS.pResolveAttachments != nullptr) || + (pResolveAttachments != nullptr && RHS.pResolveAttachments == nullptr)) + return false; + + if (pResolveAttachments != nullptr && RHS.pResolveAttachments != nullptr) + { + for(Uint32 i=0; i < RenderTargetAttachmentCount; ++i) + { + if (pResolveAttachments[i] != RHS.pResolveAttachments[i]) + return false; + } + } + + if ((pDepthStencilAttachment == nullptr && RHS.pDepthStencilAttachment != nullptr) || + (pDepthStencilAttachment != nullptr && RHS.pDepthStencilAttachment == nullptr)) + return false; + + if (pDepthStencilAttachment != nullptr && RHS.pDepthStencilAttachment != nullptr) + { + if (*pDepthStencilAttachment != *RHS.pDepthStencilAttachment) + return false; + } + + if ((pPreserveAttachments == nullptr && RHS.pPreserveAttachments != nullptr) || + (pPreserveAttachments != nullptr && RHS.pPreserveAttachments == nullptr)) + return false; + + if (pPreserveAttachments != nullptr && RHS.pPreserveAttachments != nullptr) + { + for(Uint32 i=0; i < PreserveAttachmentCount; ++i) + { + if (pPreserveAttachments[i] != RHS.pPreserveAttachments[i]) + return false; + } + } + + return true; + } +#endif }; typedef struct SubpassDesc SubpassDesc; diff --git a/Graphics/GraphicsEngine/src/RenderPassBase.cpp b/Graphics/GraphicsEngine/src/RenderPassBase.cpp index 4c4e0abd..782e950f 100644 --- a/Graphics/GraphicsEngine/src/RenderPassBase.cpp +++ b/Graphics/GraphicsEngine/src/RenderPassBase.cpp @@ -94,6 +94,26 @@ void ValidateRenderPassDesc(const RenderPassDesc& Desc) } } } + + for (Uint32 i = 0; i < Desc.SubpassCount; ++i) + { + const auto& Subpass = Desc.pSubpasses[i]; + if (Subpass.InputAttachmentCount != 0 && Subpass.pInputAttachments == nullptr) + { + LOG_RENDER_PASS_ERROR_AND_THROW("the input attachment count (", Subpass.InputAttachmentCount, ") of subpass ", i, + " is not zero, while pInputAttachments is null"); + } + if (Subpass.RenderTargetAttachmentCount != 0 && Subpass.pRenderTargetAttachments == nullptr) + { + LOG_RENDER_PASS_ERROR_AND_THROW("the render target attachment count (", Subpass.RenderTargetAttachmentCount, ") of subpass ", i, + " is not zero, while pRenderTargetAttachments is null"); + } + if (Subpass.PreserveAttachmentCount != 0 && Subpass.pPreserveAttachments == nullptr) + { + LOG_RENDER_PASS_ERROR_AND_THROW("the preserve attachment count (", Subpass.PreserveAttachmentCount, ") of subpass ", i, + " is not zero, while pPreserveAttachments is null"); + } + } } } // namespace Diligent |
