PassTree.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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/RPI.Public/Pass/PassTree.h>
  9. #include <Atom/RPI.Public/Pass/PassUtils.h>
  10. namespace AZ::RPI
  11. {
  12. void PassTree::EraseFromLists(AZStd::function<bool(const RHI::Ptr<Pass>&)> predicate)
  13. {
  14. AZStd::erase_if(m_removePassList, predicate);
  15. AZStd::erase_if(m_buildPassList, predicate);
  16. AZStd::erase_if(m_initializePassList, predicate);
  17. }
  18. void PassTree::ClearQueues()
  19. {
  20. m_removePassList.clear();
  21. m_buildPassList.clear();
  22. m_initializePassList.clear();
  23. }
  24. void PassTree::RemovePasses()
  25. {
  26. AZ_PROFILE_SCOPE(RPI, "PassTree::RemovePasses");
  27. m_state = PassTreeState::RemovingPasses;
  28. if (!m_removePassList.empty())
  29. {
  30. PassUtils::SortPassListDescending(m_removePassList);
  31. for (const Ptr<Pass>& pass : m_removePassList)
  32. {
  33. pass->RemoveFromParent();
  34. }
  35. m_removePassList.clear();
  36. }
  37. m_state = PassTreeState::Idle;
  38. }
  39. void PassTree::BuildPasses()
  40. {
  41. AZ_PROFILE_SCOPE(RPI, "PassTree::BuildPasses");
  42. m_state = PassTreeState::BuildingPasses;
  43. m_passesChangedThisFrame = m_passesChangedThisFrame || !m_buildPassList.empty();
  44. // While loop is for the event in which passes being built add more pass to m_buildPassList
  45. while (!m_buildPassList.empty())
  46. {
  47. AZ_Assert(m_removePassList.empty(), "Passes shouldn't be queued removal during build attachment process");
  48. // Copy the list and clear it, so that further passes can be queue during this phase
  49. AZStd::vector< Ptr<Pass> > buildListCopy = m_buildPassList;
  50. m_buildPassList.clear();
  51. // Erase passes which were removed from pass tree already (which parent is empty)
  52. AZStd::erase_if(buildListCopy, [](const RHI::Ptr<Pass>& currentPass) {
  53. return !currentPass->m_flags.m_partOfHierarchy;
  54. });
  55. PassUtils::SortPassListAscending(buildListCopy);
  56. for (const Ptr<Pass>& pass : buildListCopy)
  57. {
  58. pass->Reset();
  59. }
  60. for (const Ptr<Pass>& pass : buildListCopy)
  61. {
  62. pass->Build(true);
  63. }
  64. }
  65. if (m_passesChangedThisFrame)
  66. {
  67. #if AZ_RPI_ENABLE_PASS_DEBUGGING
  68. AZ_Printf("PassTree", "\nFinished building passes:\n");
  69. m_rootPass->DebugPrint();
  70. #endif
  71. }
  72. m_state = PassTreeState::Idle;
  73. }
  74. void PassTree::InitializePasses()
  75. {
  76. AZ_PROFILE_SCOPE(RPI, "PassTree::InitializePasses");
  77. m_state = PassTreeState::InitializingPasses;
  78. m_passesChangedThisFrame = m_passesChangedThisFrame || !m_initializePassList.empty();
  79. while (!m_initializePassList.empty())
  80. {
  81. // Copy the list and clear it, so that further passes can be queue during this phase
  82. AZStd::vector< Ptr<Pass> > initListCopy = m_initializePassList;
  83. m_initializePassList.clear();
  84. // Erase passes which were removed from pass tree already (which parent is empty)
  85. AZStd::erase_if(initListCopy, [](const RHI::Ptr<Pass>& currentPass) {
  86. return !currentPass->m_flags.m_partOfHierarchy;
  87. });
  88. PassUtils::SortPassListAscending(initListCopy);
  89. for (const Ptr<Pass>& pass : initListCopy)
  90. {
  91. pass->Initialize();
  92. }
  93. }
  94. if (m_passesChangedThisFrame)
  95. {
  96. // Signal all passes that we have finished initialization
  97. m_rootPass->OnInitializationFinished();
  98. }
  99. m_state = PassTreeState::Idle;
  100. }
  101. void PassTree::Validate()
  102. {
  103. m_state = PassTreeState::ValidatingPasses;
  104. if (PassValidation::IsEnabled())
  105. {
  106. if (!m_passesChangedThisFrame)
  107. {
  108. return;
  109. }
  110. AZ_PROFILE_SCOPE(RPI, "PassSystem: Validate");
  111. PassValidationResults validationResults;
  112. m_rootPass->Validate(validationResults);
  113. validationResults.PrintValidationIfError();
  114. }
  115. m_state = PassTreeState::Idle;
  116. }
  117. bool PassTree::ProcessQueuedChanges()
  118. {
  119. RemovePasses();
  120. BuildPasses();
  121. InitializePasses();
  122. Validate();
  123. bool changedThisFrame = m_passesChangedThisFrame;
  124. m_passesChangedThisFrame = false;
  125. return changedThisFrame;
  126. }
  127. }