3
0

EditorStatePassSystemUtils.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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 <Pass/State/EditorStateBufferCopyPassData.h>
  9. #include <Pass/State/EditorStateBufferCopyPass.h>
  10. #include <Pass/State/EditorStateParentPassData.h>
  11. #include <Pass/EditorStatePassSystem.h>
  12. #include <Pass/EditorStatePassSystemUtils.h>
  13. #include <Atom/RPI.Reflect/Pass/RasterPassData.h>
  14. namespace AZ::Render
  15. {
  16. Name GetMaskPassTemplateNameForDrawList(const Name& drawList)
  17. {
  18. return Name(AZStd::string(drawList.GetStringView()) + "_EditorModeMaskTemplate");
  19. }
  20. Name GetMaskPassNameForDrawList(const Name& drawList)
  21. {
  22. return Name(AZStd::string(drawList.GetStringView()) + "_EntityMaskPass");
  23. }
  24. Name GetBufferCopyPassTemplateName(const EditorStateBase& state)
  25. {
  26. return Name(state.GetStateName() + "BufferCopyTemplate");
  27. }
  28. Name GetBufferCopyPassNameForState(const EditorStateBase& state)
  29. {
  30. return Name(state.GetStateName() + "BufferCopyPass");
  31. }
  32. void CreateAndAddStateParentPassTemplate(const EditorStateBase& state)
  33. {
  34. const auto templateName = state.GetPassTemplateName();
  35. if (RPI::PassSystemInterface::Get()->GetPassTemplate(templateName))
  36. {
  37. // Template was created by another pipeline, do not to create again
  38. return;
  39. }
  40. auto stateParentPassTemplate = AZStd::make_shared<RPI::PassTemplate>();
  41. stateParentPassTemplate->m_name = templateName;
  42. stateParentPassTemplate->m_passClass = StatePassTemplatePassClassName;
  43. // Input depth slot
  44. {
  45. RPI::PassSlot slot;
  46. slot.m_name = Name("InputDepth");
  47. slot.m_slotType = RPI::PassSlotType::Input;
  48. stateParentPassTemplate->AddSlot(slot);
  49. }
  50. // Input entity mask slot
  51. {
  52. RPI::PassSlot slot;
  53. slot.m_name = Name("InputEntityMask");
  54. slot.m_slotType = RPI::PassSlotType::Input;
  55. stateParentPassTemplate->AddSlot(slot);
  56. }
  57. // Input color slot
  58. {
  59. RPI::PassSlot slot;
  60. slot.m_name = Name("InputColor");
  61. slot.m_slotType = RPI::PassSlotType::Input;
  62. stateParentPassTemplate->AddSlot(slot);
  63. }
  64. // Output color slot
  65. {
  66. RPI::PassSlot slot;
  67. slot.m_name = Name("OutputColor");
  68. slot.m_slotType = RPI::PassSlotType::Output;
  69. stateParentPassTemplate->AddSlot(slot);
  70. }
  71. // Fallback connections
  72. {
  73. RPI::PassFallbackConnection fallbackConnection;
  74. fallbackConnection.m_inputSlotName = Name("InputColor");
  75. fallbackConnection.m_outputSlotName = Name("OutputColor");
  76. stateParentPassTemplate->m_fallbackConnections.push_back(fallbackConnection);
  77. }
  78. // Pass data
  79. {
  80. auto passData = AZStd::make_shared<RPI::EditorStateParentPassData>();
  81. passData->editorStatePass = &state;
  82. stateParentPassTemplate->m_passData = passData;
  83. }
  84. // Child passes
  85. auto previousOutput = AZStd::make_pair(Name("Parent"), Name("InputColor"));
  86. AZ::u32 passCount = 0;
  87. for (const auto& childPassTemplate : state.GetChildPassNameList())
  88. {
  89. auto childPassName = state.GetGeneratedChildPassName(passCount);
  90. RPI::PassRequest pass;
  91. pass.m_passName = childPassName;
  92. pass.m_templateName = childPassTemplate;
  93. // Input depth
  94. {
  95. RPI::PassConnection connection;
  96. connection.m_localSlot = Name("InputDepth");
  97. connection.m_attachmentRef = { Name("Parent"), Name("InputDepth") };
  98. pass.AddInputConnection(connection);
  99. }
  100. // Input entity mask
  101. {
  102. RPI::PassConnection connection;
  103. connection.m_localSlot = Name("InputEntityMask");
  104. connection.m_attachmentRef = { Name("Parent"), Name("InputEntityMask") };
  105. pass.AddInputConnection(connection);
  106. }
  107. // Input color
  108. {
  109. RPI::PassConnection connection;
  110. connection.m_localSlot = Name("InputColor");
  111. connection.m_attachmentRef = { previousOutput.first, previousOutput.second };
  112. pass.AddInputConnection(connection);
  113. }
  114. stateParentPassTemplate->AddPassRequest(pass);
  115. previousOutput = { pass.m_passName, Name("OutputColor") };
  116. passCount++;
  117. }
  118. // Connections
  119. {
  120. RPI::PassConnection connection;
  121. connection.m_localSlot = Name("OutputColor");
  122. connection.m_attachmentRef.m_pass = previousOutput.first;
  123. connection.m_attachmentRef.m_attachment = previousOutput.second;
  124. stateParentPassTemplate->AddOutputConnection(connection);
  125. }
  126. RPI::PassSystemInterface::Get()->AddPassTemplate(stateParentPassTemplate->m_name, stateParentPassTemplate);
  127. }
  128. void CreateAndAddBufferCopyPassTemplate(const EditorStateBase& state)
  129. {
  130. const auto templateName = GetBufferCopyPassTemplateName(state);
  131. if (RPI::PassSystemInterface::Get()->GetPassTemplate(templateName))
  132. {
  133. // Template was created by another pipeline, do not to create again
  134. return;
  135. }
  136. auto passTemplate = AZStd::make_shared<RPI::PassTemplate>();
  137. passTemplate->m_name = templateName;
  138. passTemplate->m_passClass = BufferCopyStatePassTemplatePassClassName;
  139. // Input color slot
  140. {
  141. RPI::PassSlot slot;
  142. slot.m_name = Name("InputColor");
  143. slot.m_slotType = RPI::PassSlotType::Input;
  144. slot.m_shaderInputName = Name("m_framebuffer");
  145. slot.m_scopeAttachmentUsage = RHI::ScopeAttachmentUsage::Shader;
  146. passTemplate->AddSlot(slot);
  147. }
  148. // Output color slot
  149. {
  150. RPI::PassSlot slot;
  151. slot.m_name = Name("OutputColor");
  152. slot.m_slotType = RPI::PassSlotType::Output;
  153. slot.m_scopeAttachmentUsage = RHI::ScopeAttachmentUsage::RenderTarget;
  154. slot.m_loadStoreAction.m_loadAction = RHI::AttachmentLoadAction::DontCare;
  155. passTemplate->AddSlot(slot);
  156. }
  157. // Connections
  158. {
  159. RPI::PassConnection connection;
  160. connection.m_localSlot = Name("OutputColor");
  161. connection.m_attachmentRef.m_pass = Name("Parent");
  162. connection.m_attachmentRef.m_attachment = Name("ColorInputOutput");
  163. passTemplate->AddOutputConnection(connection);
  164. }
  165. // Fallback connections
  166. {
  167. RPI::PassFallbackConnection fallbackConnection;
  168. passTemplate->m_fallbackConnections.push_back({ Name("InputColor"), Name("OutputColor") });
  169. }
  170. // Pass data
  171. {
  172. const auto shaderFilePath = "shaders/editormodebuffercopy.azshader";
  173. Data::AssetId shaderAssetId;
  174. Data::AssetCatalogRequestBus::BroadcastResult(
  175. shaderAssetId, &Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, shaderFilePath, azrtti_typeid<RPI::ShaderAsset>(),
  176. false);
  177. if (!shaderAssetId.IsValid())
  178. {
  179. AZ_Assert(false, "[DisplayMapperPass] Unable to obtain asset id for %s.", shaderFilePath);
  180. return;
  181. }
  182. auto passData = AZStd::make_shared<RPI::EditorStateBufferCopyPassData>();
  183. passData->m_pipelineViewTag = "MainCamera";
  184. passData->m_shaderAsset.m_filePath = shaderFilePath;
  185. passData->m_shaderAsset.m_assetId = shaderAssetId;
  186. passData->editorStatePass = &state;
  187. passTemplate->m_passData = passData;
  188. }
  189. RPI::PassSystemInterface::Get()->AddPassTemplate(passTemplate->m_name, passTemplate);
  190. }
  191. void CreateAndAddMaskPassTemplate(const Name& drawList)
  192. {
  193. const auto templateName = GetMaskPassTemplateNameForDrawList(drawList);
  194. if (RPI::PassSystemInterface::Get()->GetPassTemplate(templateName))
  195. {
  196. // Template was created by another pipeline, do not to create again
  197. return;
  198. }
  199. auto maskPassTemplate = AZStd::make_shared<RPI::PassTemplate>();
  200. maskPassTemplate->m_name = templateName;
  201. maskPassTemplate->m_passClass = Name("RasterPass");
  202. // Input depth slot
  203. {
  204. RPI::PassSlot slot;
  205. slot.m_name = Name("InputDepth");
  206. slot.m_slotType = RPI::PassSlotType::Input;
  207. slot.m_shaderInputName = Name("m_existingDepth");
  208. slot.m_scopeAttachmentUsage = RHI::ScopeAttachmentUsage::Shader;
  209. slot.m_shaderImageDimensionsName = Name("m_existingDepthDimensions");
  210. slot.m_imageViewDesc = AZStd::make_shared<RHI::ImageViewDescriptor>();
  211. slot.m_imageViewDesc->m_aspectFlags = RHI::ImageAspectFlags::Depth;
  212. maskPassTemplate->AddSlot(slot);
  213. }
  214. // Output entity mask slot
  215. {
  216. RPI::PassSlot slot;
  217. slot.m_name = Name("OutputEntityMask");
  218. slot.m_slotType = RPI::PassSlotType::Output;
  219. slot.m_scopeAttachmentUsage = RHI::ScopeAttachmentUsage::RenderTarget;
  220. slot.m_loadStoreAction.m_loadAction = RHI::AttachmentLoadAction::Clear;
  221. slot.m_loadStoreAction.m_clearValue = RHI::ClearValue::CreateVector4Float(0.0, 0.0, 0.0, 0.0);
  222. maskPassTemplate->AddSlot(slot);
  223. }
  224. // Output entity mask attachment
  225. RPI::PassImageAttachmentDesc imageAttachment;
  226. imageAttachment.m_name = Name("OutputEntityMaskAttachment");
  227. imageAttachment.m_sizeSource.m_source.m_pass = Name("This");
  228. imageAttachment.m_sizeSource.m_source.m_attachment = Name("InputDepth");
  229. imageAttachment.m_imageDescriptor.m_format = RHI::Format::R8G8_UNORM;
  230. imageAttachment.m_imageDescriptor.m_sharedQueueMask = RHI::HardwareQueueClassMask::Graphics;
  231. maskPassTemplate->AddImageAttachment(imageAttachment);
  232. // Output entity mask
  233. RPI::PassConnection connection;
  234. connection.m_localSlot = Name("OutputEntityMask");
  235. connection.m_attachmentRef = { Name("This"), Name("OutputEntityMaskAttachment") };
  236. maskPassTemplate->AddOutputConnection(connection);
  237. // Pass data
  238. {
  239. auto passData = AZStd::make_shared<RPI::RasterPassData>();
  240. passData->m_drawListTag = Name(drawList);
  241. passData->m_passSrgShaderReference.m_filePath = "shaders/editormodemask.azshader";
  242. passData->m_pipelineViewTag = "MainCamera";
  243. maskPassTemplate->m_passData = passData;
  244. }
  245. RPI::PassSystemInterface::Get()->AddPassTemplate(maskPassTemplate->m_name, maskPassTemplate);
  246. }
  247. AZStd::unordered_set<Name> CreateMaskPassTemplatesFromEditorStates(
  248. const EditorStateList& editorStates)
  249. {
  250. AZStd::unordered_set<Name> drawLists;
  251. for (const auto& state : editorStates)
  252. {
  253. if (const auto drawList = state->GetEntityMaskDrawList();
  254. !drawLists.contains(drawList))
  255. {
  256. CreateAndAddMaskPassTemplate(drawList);
  257. drawLists.insert(drawList);
  258. }
  259. }
  260. return drawLists;
  261. }
  262. } // namespace AZ::Render