Fix editor hang on level load (#6323)
Make View::SortFinalizedDrawLists use child jobs so they don't block the worker thread from doing other work while waiting. Implement a TaskGraph version of the view draw list sort. Fix a misc bug where the scene was waiting on a task graph event twice and so hanging. Enable MeshFeatureProcessor::Simulate to be able to use jobs when no parent job is specified because the parent job is a task. Signed-off-by: rgba16f <82187279+rgba16f@users.noreply.github.com>
This commit is contained in:
@@ -123,11 +123,26 @@ namespace AZ
|
||||
}
|
||||
};
|
||||
Job* executeGroupJob = aznew JobFunction<decltype(jobLambda)>(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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Jobs/JobCompletion.h>
|
||||
#include <AzCore/Jobs/JobFunction.h>
|
||||
#include <AzCore/Task/TaskGraph.h>
|
||||
#include <Atom_RPI_Traits_Platform.h>
|
||||
|
||||
#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<decltype(jobLambda)>(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)
|
||||
|
||||
Reference in New Issue
Block a user