RenderAttachmentLayout.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <Atom/RHI.Reflect/AttachmentLoadStoreAction.h>
  10. #include <Atom/RHI.Reflect/Format.h>
  11. #include <Atom/RHI.Reflect/Interval.h>
  12. #include <Atom/RHI.Reflect/Limits.h>
  13. #include <AzCore/Utils/TypeHash.h>
  14. #include <AzCore/std/containers/array.h>
  15. #include <AzCore/std/containers/span.h>
  16. #include <AzCore/std/smart_ptr/shared_ptr.h>
  17. namespace AZ
  18. {
  19. class ReflectContext;
  20. }
  21. namespace AZ::RHI
  22. {
  23. static const uint32_t InvalidRenderAttachmentIndex = Limits::Pipeline::RenderAttachmentCountMax;
  24. //! Base class for extra data to be used when building a RenderAttachmentLayout
  25. struct RenderAttachmentExtras
  26. {
  27. AZ_RTTI(RenderAttachmentExtras, "{0A50E3A8-78B6-4B7A-86CD-D0AB0108743E}");
  28. virtual ~RenderAttachmentExtras() = default;
  29. };
  30. //! Describes one render attachment that is part of a layout.
  31. struct RenderAttachmentDescriptor
  32. {
  33. AZ_TYPE_INFO(RenderAttachmentDescriptor, "{2855E1D2-BDA1-45A8-ABB9-5D8FB1E78EF4}");
  34. static void Reflect(ReflectContext* context);
  35. bool IsValid() const;
  36. bool operator==(const RenderAttachmentDescriptor& other) const;
  37. bool operator!=(const RenderAttachmentDescriptor& other) const;
  38. bool IsEqual(const RenderAttachmentDescriptor& other, const bool compareLoadStoreAction) const;
  39. //! Position of the attachment in the layout.
  40. uint32_t m_attachmentIndex = InvalidRenderAttachmentIndex;
  41. //! Position of the resolve attachment in layout (if it resolves).
  42. uint32_t m_resolveAttachmentIndex = InvalidRenderAttachmentIndex;
  43. //! Load and store action of the attachment.
  44. AttachmentLoadStoreAction m_loadStoreAction = AttachmentLoadStoreAction();
  45. //! The following two flags are only relevant when there are more than one subpasses
  46. //! that will be merged.
  47. //! The scope attachment access as defined in the pass template, which will be used
  48. //! to accurately define the subpass dependencies.
  49. AZ::RHI::ScopeAttachmentAccess m_scopeAttachmentAccess = AZ::RHI::ScopeAttachmentAccess::Unknown;
  50. //! The scope attachment stage as defined in the pass template, which will be used
  51. //! to accurately define the subpass dependencies.
  52. AZ::RHI::ScopeAttachmentStage m_scopeAttachmentStage = AZ::RHI::ScopeAttachmentStage::Uninitialized;
  53. //! Extra data that can be passed for platform specific operations.
  54. RenderAttachmentExtras* m_extras = nullptr;
  55. };
  56. //! Describes a subpass input attachment.
  57. struct SubpassInputDescriptor
  58. {
  59. AZ_TYPE_INFO(SubpassInputDescriptor, "{5E5B933D-8209-4722-8AC5-C3FEA1D75BB3}");
  60. static void Reflect(ReflectContext* context);
  61. bool operator==(const SubpassInputDescriptor& other) const;
  62. bool operator!=(const SubpassInputDescriptor& other) const;
  63. //! Attachment index that this subpass input references.
  64. uint32_t m_attachmentIndex = 0;
  65. //! Aspects that are used by the input (needed by some implementations, like Vulkan, when creating a renderpass with a subpass input)
  66. RHI::ImageAspectFlags m_aspectFlags = RHI::ImageAspectFlags::None;
  67. //! The following two flags are only relevant when there are more than one subpasses
  68. //! that will be merged.
  69. //! The scope attachment access as defined in the pass template, which will be used
  70. //! to accurately define the subpass dependencies.
  71. AZ::RHI::ScopeAttachmentAccess m_scopeAttachmentAccess = AZ::RHI::ScopeAttachmentAccess::Unknown;
  72. //! The scope attachment stage as defined in the pass template, which will be used
  73. //! to accurately define the subpass dependencies.
  74. AZ::RHI::ScopeAttachmentStage m_scopeAttachmentStage = AZ::RHI::ScopeAttachmentStage::Uninitialized;
  75. //! Load and store action of the attachment.
  76. AttachmentLoadStoreAction m_loadStoreAction = AttachmentLoadStoreAction();
  77. //! Extra data that can be passed for platform specific operations.
  78. RenderAttachmentExtras* m_extras = nullptr;
  79. };
  80. //! Describes the attachments of one subpass as part of a render target layout.
  81. //! It include descriptions about the render targets, subpass inputs and depth/stencil attachment.
  82. struct SubpassRenderAttachmentLayout
  83. {
  84. AZ_TYPE_INFO(SubpassRenderAttachmentLayout, "{7AF04EC1-D835-4F97-8433-0D445C0D6F5B}");
  85. static void Reflect(ReflectContext* context);
  86. bool operator==(const SubpassRenderAttachmentLayout& other) const;
  87. bool operator!=(const SubpassRenderAttachmentLayout& other) const;
  88. bool IsEqual(const SubpassRenderAttachmentLayout& other, const bool compareLoadStoreAction) const;
  89. //! Number of render targets in the subpass.
  90. uint32_t m_rendertargetCount = 0;
  91. //! Number of subpass input attachments in the subpass.
  92. uint32_t m_subpassInputCount = 0;
  93. //! List of render targets used by the subpass.
  94. AZStd::array<RenderAttachmentDescriptor, Limits::Pipeline::AttachmentColorCountMax> m_rendertargetDescriptors = { {} };
  95. //! List of subpass inputs used by the subpass.
  96. AZStd::array<SubpassInputDescriptor, Limits::Pipeline::AttachmentColorCountMax> m_subpassInputDescriptors = { {} };
  97. //! Descriptor of the depth/stencil attachment. If not used, the attachment index is InvalidRenderAttachmentIndex.
  98. RenderAttachmentDescriptor m_depthStencilDescriptor;
  99. //! Descriptor of the shading rate attachment. If not used, the attachment index is InvalidRenderAttachmentIndex.
  100. RenderAttachmentDescriptor m_shadingRateDescriptor;
  101. };
  102. //! A RenderAttachmentLayout consist of a description of one or more subpasses.
  103. //! Each subpass is a collection of render targets, subpass inputs and depth stencil attachments.
  104. //! Each subpass corresponds to a phase in the rendering of a Pipeline.
  105. //! Subpass outputs can be read by other subpasses as inputs.
  106. //! A RenderAttachmentLayout may be implemented by the platform using native functionality, achieving a
  107. //! performance gain for that specific platform. On other platforms, it may be emulated to achieve the same result
  108. //! but without the performance benefits. For example, Vulkan supports the concept of subpass natively.
  109. class RenderAttachmentLayout
  110. {
  111. public:
  112. AZ_TYPE_INFO(RenderAttachmentLayout, "{5ED96982-BFB0-4EFF-ABBE-1552CECE707D}");
  113. static void Reflect(ReflectContext* context);
  114. HashValue64 GetHash() const;
  115. bool operator==(const RenderAttachmentLayout& other) const;
  116. bool IsEqual(const RenderAttachmentLayout& other, const bool compareLoadStoreAction) const;
  117. //! Number of total attachments in the list.
  118. uint32_t m_attachmentCount = 0;
  119. //! List with all attachments (renderAttachments, resolveAttachments and depth/stencil attachment).
  120. AZStd::array<Format, Limits::Pipeline::RenderAttachmentCountMax> m_attachmentFormats = { {} };
  121. //! Number of subpasses.
  122. uint32_t m_subpassCount = 0;
  123. //! List with the layout of each subpass.
  124. AZStd::array<SubpassRenderAttachmentLayout, Limits::Pipeline::SubpassCountMax> m_subpassLayouts;
  125. };
  126. //! Describes the layout of a collection of subpasses and it defines which of the subpasses this
  127. //! configuration will be using.
  128. struct RenderAttachmentConfiguration
  129. {
  130. AZ_TYPE_INFO(RenderAttachmentConfiguration, "{037F27A5-B568-439B-81D4-928DFA3A74F2}");
  131. static void Reflect(ReflectContext* context);
  132. HashValue64 GetHash() const;
  133. bool operator==(const RenderAttachmentConfiguration& other) const;
  134. bool IsEqual(const RenderAttachmentConfiguration& other, const bool compareLoadStoreAction) const;
  135. //! Returns the format of a render target in the subpass being used.
  136. Format GetRenderTargetFormat(uint32_t index) const;
  137. //! Returns the format of a subpass input in the subpass being used.
  138. Format GetSubpassInputFormat(uint32_t index) const;
  139. //! Returns the format of resolve attachment in the subpass being used.
  140. Format GetRenderTargetResolveFormat(uint32_t index) const;
  141. //! Returns the format of a depth/stencil in the subpass being used.
  142. //! Will return Format::Unkwon if the depth/stencil is not being used.
  143. Format GetDepthStencilFormat() const;
  144. //! Returns the number of render targets in the subpass being used.
  145. uint32_t GetRenderTargetCount() const;
  146. //! Returns the number of subpass inputs in the subpass being used.
  147. uint32_t GetSubpassInputCount() const;
  148. //! Returns true if the render target is resolving in the subpass being used.
  149. bool DoesRenderTargetResolve(uint32_t index) const;
  150. //! Layout of the render target attachments.
  151. RenderAttachmentLayout m_renderAttachmentLayout;
  152. //! Index of the subpass being used.
  153. uint32_t m_subpassIndex = 0;
  154. };
  155. }