diff --git a/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp index c11d223458..dfb2b3fe6b 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Mesh/MeshFeatureProcessor.cpp @@ -123,11 +123,26 @@ namespace AZ } }; Job* executeGroupJob = aznew JobFunction(jobLambda, true, nullptr); // Auto-deletes - parentJob->StartAsChild(executeGroupJob); + if (parentJob) + { + parentJob->StartAsChild(executeGroupJob); + } + else + { + executeGroupJob->SetDependent(&jobCompletion); + executeGroupJob->Start(); + } } { AZ_PROFILE_SCOPE(AzRender, "MeshFeatureProcessor: Simulate: WaitForChildren"); - parentJob->WaitForChildren(); + if (parentJob) + { + parentJob->WaitForChildren(); + } + else + { + jobCompletion.StartAndWaitForCompletion(); + } } m_forceRebuildDrawPackets = false; diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h index 92b9ad695a..ed0124b82b 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/View.h @@ -24,6 +24,9 @@ class MaskedOcclusionCulling; namespace AZ { + // forward declares + class Job; + class TaskGraphEvent; namespace RHI { class FrameScheduler; @@ -102,7 +105,8 @@ namespace AZ //! Finalize draw lists in this view. This function should only be called when all //! draw packets for current frame are added. - void FinalizeDrawLists(); + void FinalizeDrawListsJob(AZ::Job* parentJob); + void FinalizeDrawListsTG(AZ::TaskGraphEvent& finalizeDrawListsTGEvent); bool HasDrawListTag(RHI::DrawListTag drawListTag); @@ -142,7 +146,8 @@ namespace AZ View(const AZ::Name& name, UsageFlags usage); //! Sorts the finalized draw lists in this view - void SortFinalizedDrawLists(); + void SortFinalizedDrawListsJob(AZ::Job* parentJob); + void SortFinalizedDrawListsTG(AZ::TaskGraphEvent& finalizeDrawListsTGEvent); //! Sorts a drawList using the sort function from a pass with the corresponding drawListTag void SortDrawList(RHI::DrawList& drawList, RHI::DrawListTag tag); diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp index a21b0bfecd..1b5110e327 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Scene.cpp @@ -114,6 +114,7 @@ namespace AZ if (m_taskGraphActive) { WaitAndCleanTGEvent(AZStd::move(m_simulationFinishedTGEvent)); + m_simulationFinishedTGEvent.reset(); } else { @@ -383,7 +384,9 @@ namespace AZ simulationTGDesc, [this, featureProcessor]() { - featureProcessor->Simulate(m_simulatePacket); + FeatureProcessor::SimulatePacket jobPacket = m_simulatePacket; + jobPacket.m_parentJob = nullptr; + featureProcessor->Simulate(jobPacket); }); } simulationTG.Detach(); @@ -423,6 +426,7 @@ namespace AZ if (m_taskGraphActive) { WaitAndCleanTGEvent(AZStd::move(m_simulationFinishedTGEvent)); + m_simulationFinishedTGEvent.reset(); } else { @@ -609,9 +613,9 @@ namespace AZ { finalizeDrawListsTG.AddTask( finalizeDrawListsTGDesc, - [view]() + [view, &finalizeDrawListsTGEvent]() { - view->FinalizeDrawLists(); + view->FinalizeDrawListsTG(finalizeDrawListsTGEvent); }); } finalizeDrawListsTG.Submit(&finalizeDrawListsTGEvent); @@ -623,9 +627,9 @@ namespace AZ AZ::JobCompletion* finalizeDrawListsCompletion = aznew AZ::JobCompletion(); for (auto& view : m_renderPacket.m_views) { - const auto finalizeDrawListsLambda = [view]() + const auto finalizeDrawListsLambda = [view](AZ::Job& job) { - view->FinalizeDrawLists(); + view->FinalizeDrawListsJob(&job); }; AZ::Job* finalizeDrawListsJob = AZ::CreateJobFunction(AZStd::move(finalizeDrawListsLambda), true, nullptr); //auto-deletes @@ -642,6 +646,7 @@ namespace AZ if (m_taskGraphActive) { WaitAndCleanTGEvent(AZStd::move(m_simulationFinishedTGEvent)); + m_simulationFinishedTGEvent.reset(); } else { @@ -743,7 +748,7 @@ namespace AZ { for (auto& view : m_renderPacket.m_views) { - view->FinalizeDrawLists(); + view->FinalizeDrawListsJob(nullptr); } } else diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp index e1d564c8ac..091664b9e8 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/View.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #if AZ_TRAIT_MASKED_OCCLUSION_CULLING_SUPPORTED @@ -253,14 +254,45 @@ namespace AZ return m_drawListContext.GetList(drawListTag); } - void View::FinalizeDrawLists() + void View::FinalizeDrawListsTG(AZ::TaskGraphEvent& finalizeDrawListsTGEvent) { AZ_PROFILE_SCOPE(RPI, "View: FinalizeDrawLists"); m_drawListContext.FinalizeLists(); - SortFinalizedDrawLists(); + SortFinalizedDrawListsTG(finalizeDrawListsTGEvent); + } + void View::FinalizeDrawListsJob(AZ::Job* parentJob) + { + AZ_PROFILE_SCOPE(RPI, "View: FinalizeDrawLists"); + m_drawListContext.FinalizeLists(); + SortFinalizedDrawListsJob(parentJob); } - void View::SortFinalizedDrawLists() + void View::SortFinalizedDrawListsTG(AZ::TaskGraphEvent& finalizeDrawListsTGEvent) + { + AZ_PROFILE_SCOPE(RPI, "View: SortFinalizedDrawLists"); + RHI::DrawListsByTag& drawListsByTag = m_drawListContext.GetMergedDrawListsByTag(); + + AZ::TaskGraph drawListSortTG; + AZ::TaskDescriptor drawListSortTGDescriptor{"RPI_View_SortFinalizedDrawLists", "Graphics"}; + for (size_t idx = 0; idx < drawListsByTag.size(); ++idx) + { + if (drawListsByTag[idx].size() > 1) + { + drawListSortTG.AddTask(drawListSortTGDescriptor, [this, &drawListsByTag, idx]() + { + AZ_PROFILE_SCOPE(RPI, "View: SortDrawList Task"); + SortDrawList(drawListsByTag[idx], RHI::DrawListTag(idx)); + }); + } + } + if (!drawListSortTG.IsEmpty()) + { + drawListSortTG.Detach(); + drawListSortTG.Submit(&finalizeDrawListsTGEvent); + } + } + + void View::SortFinalizedDrawListsJob(AZ::Job* parentJob) { AZ_PROFILE_SCOPE(RPI, "View: SortFinalizedDrawLists"); RHI::DrawListsByTag& drawListsByTag = m_drawListContext.GetMergedDrawListsByTag(); @@ -276,11 +308,25 @@ namespace AZ SortDrawList(drawListsByTag[idx], RHI::DrawListTag(idx)); }; Job* jobSortDrawList = aznew JobFunction(jobLambda, true, nullptr); // Auto-deletes - jobSortDrawList->SetDependent(&jobCompletion); - jobSortDrawList->Start(); + if (parentJob) + { + parentJob->StartAsChild(jobSortDrawList); + } + else + { + jobSortDrawList->SetDependent(&jobCompletion); + jobSortDrawList->Start(); + } } } - jobCompletion.StartAndWaitForCompletion(); + if (parentJob) + { + parentJob->WaitForChildren(); + } + else + { + jobCompletion.StartAndWaitForCompletion(); + } } void View::SortDrawList(RHI::DrawList& drawList, RHI::DrawListTag tag)