DynamicDrawSystem.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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(AZStd::move(drawPacket));
  64. }
  65. void DynamicDrawSystem::SubmitDrawData(Scene* scene, AZStd::vector<ViewPtr> views)
  66. {
  67. {
  68. AZStd::lock_guard<AZStd::mutex> lock(m_mutexDrawContext);
  69. for (RHI::Ptr<DynamicDrawContext> drawContext : m_dynamicDrawContexts)
  70. {
  71. if (drawContext->m_scene == scene)
  72. {
  73. drawContext->FinalizeDrawList();
  74. for (auto& view : views)
  75. {
  76. drawContext->SubmitDrawList(view);
  77. }
  78. }
  79. }
  80. }
  81. {
  82. AZStd::lock_guard<AZStd::mutex> lock(m_mutexDrawPackets);
  83. for (auto& dp : m_drawPackets[scene])
  84. {
  85. for (auto& view : views)
  86. {
  87. view->AddDrawPacket(dp.get());
  88. }
  89. }
  90. }
  91. }
  92. AZStd::vector<RHI::DrawListView> DynamicDrawSystem::GetDrawListsForPass(const RasterPass* pass)
  93. {
  94. AZStd::vector<RHI::DrawListView> result;
  95. AZStd::lock_guard<AZStd::mutex> lock(m_mutexDrawContext);
  96. for (RHI::Ptr<DynamicDrawContext> drawContext : m_dynamicDrawContexts)
  97. {
  98. if (drawContext->m_pass == pass)
  99. {
  100. drawContext->FinalizeDrawList();
  101. auto drawListView = drawContext->GetDrawList();
  102. if (drawListView.size() > 0)
  103. {
  104. result.push_back(drawListView);
  105. }
  106. }
  107. }
  108. return result;
  109. }
  110. void DynamicDrawSystem::FrameEnd()
  111. {
  112. {
  113. AZStd::lock_guard<AZStd::mutex> lock(m_mutexBufferAlloc);
  114. m_bufferAlloc->FrameEnd();
  115. }
  116. // Clean up released dynamic draw contexts (which use count is 1)
  117. {
  118. AZStd::lock_guard<AZStd::mutex> lock(m_mutexDrawContext);
  119. auto unused = AZStd::remove_if(
  120. m_dynamicDrawContexts.begin(), m_dynamicDrawContexts.end(), [](const RHI::Ptr<DynamicDrawContext>& drawContext) {
  121. return drawContext->use_count() == 1;
  122. });
  123. m_dynamicDrawContexts.erase(unused, m_dynamicDrawContexts.end());
  124. // Call FrameEnd for each DynamicDrawContext;
  125. AZStd::for_each(
  126. m_dynamicDrawContexts.begin(), m_dynamicDrawContexts.end(), [](const RHI::Ptr<DynamicDrawContext>& drawContext) {
  127. drawContext->FrameEnd();
  128. });
  129. }
  130. {
  131. AZStd::lock_guard<AZStd::mutex> lock(m_mutexDrawPackets);
  132. m_drawPackets.clear();
  133. }
  134. }
  135. }
  136. }