3
0

RasterPass.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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. #include <Atom/RHI/CommandList.h>
  9. #include <Atom/RHI/DrawListTagRegistry.h>
  10. #include <Atom/RHI/RHISystemInterface.h>
  11. #include <Atom/RHI/ShaderResourceGroup.h>
  12. #include <Atom/RPI.Public/DynamicDraw/DynamicDrawInterface.h>
  13. #include <Atom/RPI.Public/Pass/RasterPass.h>
  14. #include <Atom/RPI.Public/RenderPipeline.h>
  15. #include <Atom/RPI.Public/RPISystemInterface.h>
  16. #include <Atom/RPI.Public/Scene.h>
  17. #include <Atom/RPI.Public/View.h>
  18. #include <Atom/RPI.Reflect/Asset/AssetUtils.h>
  19. #include <Atom/RPI.Reflect/Pass/RasterPassData.h>
  20. namespace AZ
  21. {
  22. namespace RPI
  23. {
  24. // --- Creation & Initialization ---
  25. Ptr<RasterPass> RasterPass::Create(const PassDescriptor& descriptor)
  26. {
  27. Ptr<RasterPass> pass = aznew RasterPass(descriptor);
  28. return pass;
  29. }
  30. RasterPass::RasterPass(const PassDescriptor& descriptor)
  31. : RenderPass(descriptor)
  32. {
  33. const RasterPassData* rasterData = PassUtils::GetPassData<RasterPassData>(descriptor);
  34. // If we successfully retrieved our custom data, use it to set the DrawListTag
  35. if (rasterData == nullptr)
  36. {
  37. return;
  38. }
  39. SetDrawListTag(rasterData->m_drawListTag);
  40. m_drawListSortType = rasterData->m_drawListSortType;
  41. // Get the shader asset that contains the SRG Layout.
  42. Data::Asset<ShaderAsset> shaderAsset;
  43. if (rasterData->m_passSrgShaderReference.m_assetId.IsValid())
  44. {
  45. shaderAsset = AssetUtils::LoadAssetById<ShaderAsset>(rasterData->m_passSrgShaderReference.m_assetId, AssetUtils::TraceLevel::Error);
  46. }
  47. else if (!rasterData->m_passSrgShaderReference.m_filePath.empty())
  48. {
  49. shaderAsset = AssetUtils::LoadAssetByProductPath<ShaderAsset>(
  50. rasterData->m_passSrgShaderReference.m_filePath.c_str(), AssetUtils::TraceLevel::Error);
  51. }
  52. if (shaderAsset)
  53. {
  54. const auto srgLayout = shaderAsset->FindShaderResourceGroupLayout(SrgBindingSlot::Pass);
  55. if (srgLayout)
  56. {
  57. m_shaderResourceGroup = ShaderResourceGroup::Create(shaderAsset, srgLayout->GetName());
  58. AZ_Assert(
  59. m_shaderResourceGroup, "[RasterPass '%s']: Failed to create SRG from shader asset '%s'", GetPathName().GetCStr(),
  60. rasterData->m_passSrgShaderReference.m_filePath.data());
  61. PassUtils::BindDataMappingsToSrg(descriptor, m_shaderResourceGroup.get());
  62. }
  63. }
  64. if (!rasterData->m_overrideScissor.IsNull())
  65. {
  66. m_scissorState = rasterData->m_overrideScissor;
  67. m_overrideScissorSate = true;
  68. }
  69. if (!rasterData->m_overrideViewport.IsNull())
  70. {
  71. m_viewportState = rasterData->m_overrideViewport;
  72. m_overrideViewportState = true;
  73. }
  74. m_viewportAndScissorTargetOutputIndex = rasterData->m_viewportAndScissorTargetOutputIndex;
  75. }
  76. RasterPass::~RasterPass()
  77. {
  78. if (m_drawListTag != RHI::DrawListTag::Null)
  79. {
  80. RHI::RHISystemInterface* rhiSystem = RHI::RHISystemInterface::Get();
  81. rhiSystem->GetDrawListTagRegistry()->ReleaseTag(m_drawListTag);
  82. }
  83. }
  84. void RasterPass::SetDrawListTag(Name drawListName)
  85. {
  86. // Use AcquireTag to register a draw list tag if it doesn't exist.
  87. RHI::RHISystemInterface* rhiSystem = RHI::RHISystemInterface::Get();
  88. m_drawListTag = rhiSystem->GetDrawListTagRegistry()->AcquireTag(drawListName);
  89. m_flags.m_hasDrawListTag = true;
  90. }
  91. void RasterPass::SetPipelineStateDataIndex(uint32_t index)
  92. {
  93. m_pipelineStateDataIndex.m_index = index;
  94. }
  95. ShaderResourceGroup* RasterPass::GetShaderResourceGroup()
  96. {
  97. return m_shaderResourceGroup.get();
  98. }
  99. uint32_t RasterPass::GetDrawItemCount()
  100. {
  101. return m_drawItemCount;
  102. }
  103. // --- Pass behaviour overrides ---
  104. void RasterPass::Validate(PassValidationResults& validationResults)
  105. {
  106. AZ_RPI_PASS_ERROR(m_drawListTag.IsValid(), "DrawListTag for RasterPass [%s] is invalid", GetPathName().GetCStr());
  107. AZ_RPI_PASS_ERROR(!GetPipelineViewTag().IsEmpty(), "ViewTag for RasterPass [%s] is invalid", GetPathName().GetCStr());
  108. RenderPass::Validate(validationResults);
  109. }
  110. void RasterPass::FrameBeginInternal(FramePrepareParams params)
  111. {
  112. if (m_viewportAndScissorTargetOutputIndex >= 0)
  113. {
  114. PassAttachmentBinding& target = GetOutputBinding(m_viewportAndScissorTargetOutputIndex);
  115. u32 targetWidth = target.GetAttachment()->m_descriptor.m_image.m_size.m_width;
  116. u32 targetHeight = target.GetAttachment()->m_descriptor.m_image.m_size.m_height;
  117. m_scissorState = RHI::Scissor(0, 0, targetWidth, targetHeight);
  118. m_viewportState = RHI::Viewport(0, static_cast<float>(targetWidth), 0, static_cast<float>(targetHeight));
  119. }
  120. else
  121. {
  122. if (!m_overrideScissorSate)
  123. {
  124. m_scissorState = params.m_scissorState;
  125. }
  126. if (!m_overrideViewportState)
  127. {
  128. m_viewportState = params.m_viewportState;
  129. }
  130. }
  131. UpdateDrawList();
  132. RenderPass::FrameBeginInternal(params);
  133. }
  134. void RasterPass::UpdateDrawList()
  135. {
  136. // DrawLists from dynamic draw
  137. AZStd::vector<RHI::DrawListView> drawLists = DynamicDrawInterface::Get()->GetDrawListsForPass(this);
  138. // Get DrawList from view
  139. const AZStd::vector<ViewPtr>& views = m_pipeline->GetViews(GetPipelineViewTag());
  140. RHI::DrawListView viewDrawList;
  141. if (!views.empty())
  142. {
  143. const ViewPtr& view = views.front();
  144. // Assert the view has our draw list (the view's DrawlistTags are collected from passes using its viewTag)
  145. AZ_Assert(view->HasDrawListTag(m_drawListTag), "View's DrawListTags out of sync with pass'. ");
  146. // Draw List
  147. viewDrawList = view->GetDrawList(m_drawListTag);
  148. }
  149. // clean up data
  150. m_drawListView = {};
  151. m_combinedDrawList.clear();
  152. m_drawItemCount = 0;
  153. // draw list from view was sorted and if it's the only draw list then we can use it directly
  154. if (viewDrawList.size() > 0 && drawLists.size() == 0)
  155. {
  156. m_drawListView = viewDrawList;
  157. m_drawItemCount += static_cast<uint32_t>(viewDrawList.size());
  158. PassSystemInterface::Get()->IncrementFrameDrawItemCount(m_drawItemCount);
  159. return;
  160. }
  161. // add view's draw list to drawLists too
  162. drawLists.push_back(viewDrawList);
  163. // combine draw items from mutiple draw lists to one draw list and sort it.
  164. for (auto drawList : drawLists)
  165. {
  166. m_drawItemCount += static_cast<uint32_t>(drawList.size());
  167. }
  168. PassSystemInterface::Get()->IncrementFrameDrawItemCount(m_drawItemCount);
  169. m_combinedDrawList.resize(m_drawItemCount);
  170. RHI::DrawItemProperties* currentBuffer = m_combinedDrawList.data();
  171. for (auto drawList : drawLists)
  172. {
  173. memcpy(currentBuffer, drawList.data(), drawList.size()*sizeof(RHI::DrawItemProperties));
  174. currentBuffer += drawList.size();
  175. }
  176. SortDrawList(m_combinedDrawList);
  177. // have the final draw list point to the combined draw list.
  178. m_drawListView = m_combinedDrawList;
  179. }
  180. // --- DrawList and PipelineView Tags ---
  181. RHI::DrawListTag RasterPass::GetDrawListTag() const
  182. {
  183. return m_drawListTag;
  184. }
  185. // --- Scope producer functions ---
  186. void RasterPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph)
  187. {
  188. RenderPass::SetupFrameGraphDependencies(frameGraph);
  189. frameGraph.SetEstimatedItemCount(static_cast<uint32_t>(m_drawListView.size()));
  190. }
  191. void RasterPass::CompileResources(const RHI::FrameGraphCompileContext& context)
  192. {
  193. if (m_shaderResourceGroup == nullptr)
  194. {
  195. return;
  196. }
  197. BindPassSrg(context, m_shaderResourceGroup);
  198. m_shaderResourceGroup->Compile();
  199. }
  200. void RasterPass::SubmitDrawItems(const RHI::FrameGraphExecuteContext& context, uint32_t startIndex, uint32_t endIndex, uint32_t indexOffset) const
  201. {
  202. RHI::CommandList* commandList = context.GetCommandList();
  203. uint32_t clampedEndIndex = AZStd::GetMin<uint32_t>(endIndex, static_cast<uint32_t>(m_drawListView.size()));
  204. for (uint32_t index = startIndex; index < clampedEndIndex; ++index)
  205. {
  206. const RHI::DrawItemProperties& drawItemProperties = m_drawListView[index];
  207. if (drawItemProperties.m_drawFilterMask & m_pipeline->GetDrawFilterMask())
  208. {
  209. commandList->Submit(*drawItemProperties.m_item, index + indexOffset);
  210. }
  211. }
  212. }
  213. void RasterPass::BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context)
  214. {
  215. RHI::CommandList* commandList = context.GetCommandList();
  216. if (context.GetSubmitRange().m_startIndex != context.GetSubmitRange().m_endIndex)
  217. {
  218. commandList->SetViewport(m_viewportState);
  219. commandList->SetScissor(m_scissorState);
  220. SetSrgsForDraw(commandList);
  221. SubmitDrawItems(context, context.GetSubmitRange().m_startIndex, context.GetSubmitRange().m_endIndex, 0);
  222. }
  223. }
  224. } // namespace RPI
  225. } // namespace AZ