/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #include #include #include #include #include #include #include #include namespace AZ { namespace RPI { DynamicDrawInterface* DynamicDrawInterface::Get() { return Interface::Get(); } void DynamicDrawSystem::Init(const DynamicDrawSystemDescriptor& descriptor) { m_bufferAlloc = AZStd::make_unique(); if (m_bufferAlloc) { m_bufferAlloc->Init(descriptor.m_dynamicBufferPoolSize); Interface::Register(this); } } void DynamicDrawSystem::Shutdown() { if (m_bufferAlloc) { Interface::Unregister(this); m_bufferAlloc->Shutdown(); m_bufferAlloc = nullptr; } m_dynamicDrawContexts.clear(); } RHI::Ptr DynamicDrawSystem::GetDynamicBuffer(uint32_t size, uint32_t alignment) { AZStd::lock_guard lock(m_mutexBufferAlloc); return m_bufferAlloc->Allocate(size, alignment); } RHI::Ptr DynamicDrawSystem::CreateDynamicDrawContext() { RHI::Ptr drawContext = aznew DynamicDrawContext(); AZStd::lock_guard lock(m_mutexDrawContext); m_dynamicDrawContexts.push_back(drawContext); return drawContext; } // [GFX TODO][ATOM-13184] Add support of draw geometry with material for DynamicDrawSystemInterface void DynamicDrawSystem::DrawGeometry([[maybe_unused]] Data::Instance material, [[maybe_unused]] const GeometryData& geometry, [[maybe_unused]] ScenePtr scene) { AZ_Error("RPI", false, "Unimplemented function"); } void DynamicDrawSystem::AddDrawPacket(Scene* scene, AZStd::unique_ptr drawPacket) { AZStd::lock_guard lock(m_mutexDrawPackets); m_drawPackets[scene].emplace_back(ConstPtr(AZStd::move(drawPacket.get()))); } void DynamicDrawSystem::AddDrawPacket(Scene* scene, ConstPtr drawPacket) { AZStd::lock_guard lock(m_mutexDrawPackets); m_drawPackets[scene].emplace_back(drawPacket); } void DynamicDrawSystem::SubmitDrawData(Scene* scene, AZStd::vector views) { { AZStd::lock_guard lock(m_mutexDrawContext); for (RHI::Ptr drawContext : m_dynamicDrawContexts) { if (drawContext->m_scene == scene) { drawContext->FinalizeDrawList(); for (auto& view : views) { drawContext->SubmitDrawList(view); } } } } { AZStd::lock_guard lock(m_mutexDrawPackets); for (auto& dp : m_drawPackets[scene]) { for (auto& view : views) { view->AddDrawPacket(dp.get()); } } } } AZStd::vector DynamicDrawSystem::GetDrawListsForPass(const RasterPass* pass) { AZStd::vector result; AZStd::lock_guard lock(m_mutexDrawContext); for (RHI::Ptr drawContext : m_dynamicDrawContexts) { if (drawContext->m_pass == pass) { drawContext->FinalizeDrawList(); auto drawListView = drawContext->GetDrawList(); if (drawListView.size() > 0) { result.push_back(drawListView); } } } return result; } void DynamicDrawSystem::FrameEnd() { { AZStd::lock_guard lock(m_mutexBufferAlloc); m_bufferAlloc->FrameEnd(); } // Clean up released dynamic draw contexts (which use count is 1) { AZStd::lock_guard lock(m_mutexDrawContext); auto unused = AZStd::remove_if( m_dynamicDrawContexts.begin(), m_dynamicDrawContexts.end(), [](const RHI::Ptr& drawContext) { return drawContext->use_count() == 1; }); m_dynamicDrawContexts.erase(unused, m_dynamicDrawContexts.end()); // Call FrameEnd for each DynamicDrawContext; AZStd::for_each( m_dynamicDrawContexts.begin(), m_dynamicDrawContexts.end(), [](const RHI::Ptr& drawContext) { drawContext->FrameEnd(); }); } { AZStd::lock_guard lock(m_mutexDrawPackets); m_drawPackets.clear(); } } } }