3
0

DynamicDrawSystem.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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/DynamicDraw/DynamicBufferAllocator.h>
  9. #include <Atom/RPI.Public/DynamicDraw/DynamicBuffer.h>
  10. #include <Atom/RPI.Public/DynamicDraw/DynamicDrawContext.h>
  11. #include <Atom/RPI.Public/DynamicDraw/DynamicDrawSystem.h>
  12. #include <Atom/RPI.Public/RenderPipeline.h>
  13. #include <Atom/RPI.Public/Scene.h>
  14. #include <Atom/RPI.Public/View.h>
  15. #include <AzCore/Interface/Interface.h>
  16. namespace AZ
  17. {
  18. namespace RPI
  19. {
  20. DynamicDrawInterface* DynamicDrawInterface::Get()
  21. {
  22. return Interface<DynamicDrawInterface>::Get();
  23. }
  24. void DynamicDrawSystem::Init(const DynamicDrawSystemDescriptor& descriptor)
  25. {
  26. m_bufferAlloc = AZStd::make_unique<DynamicBufferAllocator>();
  27. if (m_bufferAlloc)
  28. {
  29. m_bufferAlloc->Init(descriptor.m_dynamicBufferPoolSize);
  30. Interface<DynamicDrawInterface>::Register(this);
  31. }
  32. }
  33. void DynamicDrawSystem::Shutdown()
  34. {
  35. if (m_bufferAlloc)
  36. {
  37. Interface<DynamicDrawInterface>::Unregister(this);
  38. m_bufferAlloc->Shutdown();
  39. m_bufferAlloc = nullptr;
  40. }
  41. m_dynamicDrawContexts.clear();
  42. }
  43. RHI::Ptr<DynamicBuffer> DynamicDrawSystem::GetDynamicBuffer(uint32_t size, uint32_t alignment)
  44. {
  45. AZStd::lock_guard<AZStd::mutex> lock(m_mutexBufferAlloc);
  46. return m_bufferAlloc->Allocate(size, alignment);
  47. }
  48. RHI::Ptr<DynamicDrawContext> DynamicDrawSystem::CreateDynamicDrawContext()
  49. {
  50. RHI::Ptr<DynamicDrawContext> drawContext = aznew DynamicDrawContext();
  51. AZStd::lock_guard<AZStd::mutex> lock(m_mutexDrawContext);
  52. m_dynamicDrawContexts.push_back(drawContext);
  53. return drawContext;
  54. }
  55. // [GFX TODO][ATOM-13184] Add support of draw geometry with material for DynamicDrawSystemInterface
  56. void DynamicDrawSystem::DrawGeometry([[maybe_unused]] Data::Instance<Material> material, [[maybe_unused]] const GeometryData& geometry, [[maybe_unused]] ScenePtr scene)
  57. {
  58. AZ_Error("RPI", false, "Unimplemented function");
  59. }
  60. void DynamicDrawSystem::AddDrawPacket(Scene* scene, AZStd::unique_ptr<const RHI::DrawPacket> drawPacket)
  61. {
  62. AZStd::lock_guard<AZStd::mutex> lock(m_mutexDrawPackets);
  63. m_drawPackets[scene].emplace_back(ConstPtr<RHI::DrawPacket>(drawPacket.release()));
  64. }
  65. void DynamicDrawSystem::AddDrawPacket(Scene* scene, ConstPtr<RHI::DrawPacket> drawPacket)
  66. {
  67. AZStd::lock_guard<AZStd::mutex> lock(m_mutexDrawPackets);
  68. m_drawPackets[scene].emplace_back(drawPacket);
  69. }
  70. void DynamicDrawSystem::SubmitDrawData(Scene* scene, AZStd::vector<ViewPtr> views)
  71. {
  72. {
  73. AZStd::lock_guard<AZStd::mutex> lock(m_mutexDrawContext);
  74. for (RHI::Ptr<DynamicDrawContext> drawContext : m_dynamicDrawContexts)
  75. {
  76. if (drawContext->m_scene == scene)
  77. {
  78. drawContext->FinalizeDrawList();
  79. for (auto& view : views)
  80. {
  81. drawContext->SubmitDrawList(view);
  82. }
  83. }
  84. }
  85. }
  86. {
  87. AZStd::lock_guard<AZStd::mutex> lock(m_mutexDrawPackets);
  88. for (auto& dp : m_drawPackets[scene])
  89. {
  90. for (auto& view : views)
  91. {
  92. view->AddDrawPacket(dp.get());
  93. }
  94. }
  95. }
  96. }
  97. AZStd::vector<RHI::DrawListView> DynamicDrawSystem::GetDrawListsForPass(const RasterPass* pass)
  98. {
  99. AZStd::vector<RHI::DrawListView> result;
  100. AZStd::lock_guard<AZStd::mutex> lock(m_mutexDrawContext);
  101. for (RHI::Ptr<DynamicDrawContext> drawContext : m_dynamicDrawContexts)
  102. {
  103. if (drawContext->m_pass == pass)
  104. {
  105. drawContext->FinalizeDrawList();
  106. auto drawListView = drawContext->GetDrawList();
  107. if (drawListView.size() > 0)
  108. {
  109. result.push_back(drawListView);
  110. }
  111. }
  112. }
  113. return result;
  114. }
  115. void DynamicDrawSystem::FrameEnd()
  116. {
  117. // The DynamicDrawSystem::Init function must have been invoked
  118. // for m_bufferAlloc to be non-nullptr
  119. if (m_bufferAlloc != nullptr)
  120. {
  121. AZStd::lock_guard<AZStd::mutex> lock(m_mutexBufferAlloc);
  122. m_bufferAlloc->FrameEnd();
  123. }
  124. // Clean up released dynamic draw contexts (which use count is 1)
  125. {
  126. AZStd::lock_guard<AZStd::mutex> lock(m_mutexDrawContext);
  127. auto unused = AZStd::remove_if(
  128. m_dynamicDrawContexts.begin(), m_dynamicDrawContexts.end(), [](const RHI::Ptr<DynamicDrawContext>& drawContext) {
  129. return drawContext->use_count() == 1;
  130. });
  131. m_dynamicDrawContexts.erase(unused, m_dynamicDrawContexts.end());
  132. // Call FrameEnd for each DynamicDrawContext;
  133. AZStd::for_each(
  134. m_dynamicDrawContexts.begin(), m_dynamicDrawContexts.end(), [](const RHI::Ptr<DynamicDrawContext>& drawContext) {
  135. drawContext->FrameEnd();
  136. });
  137. }
  138. {
  139. AZStd::lock_guard<AZStd::mutex> lock(m_mutexDrawPackets);
  140. m_drawPackets.clear();
  141. }
  142. }
  143. }
  144. }