Description

Context: Some ActorComponents can schedule end-of-frame work which UWorld executes later in the frame in UWorld::SendAllEndOfFrameUpdates(). By-design it appears that it's not allowed to schedule more end-of-frame work while executing such work. As a consequence of that contract, no code executed should defer to generic task graph tasks since an arbitrary task may schedule more end-of-frame work.

User reported repro: When launching a map via automation or commandline that has a UHierarchicalInstancedStaticMeshComponent, the assertion

check(!bPostTickComponentUpdate); // can't call this while we are doing the updates 

fails with the attached callstack. From the callstack it appears that the destructor

~FStaticMeshComponentBulkReregisterContext() 

which is executing in an end-of-frame update indirectly causes 

FD3D12DynamicRHI::ProcessInterruptQueueUntil() 

to be called which lets TaskGraph work on arbitrary tasks. Letting end-of-frame work defer to TaskGraph to execute arbitrary tasks is bound to cause issues like this assertion so should be fixed somewhere within the callstack between ~FStaticMeshComponentBulkReregisterContext() and FD3D12DynamicRHI::ProcessInterruptQueueUntil().

Steps to Reproduce

See UDN.

Callstack

KERNELBASE!RaiseException() [:-1]
UnrealEditor_Core!ReportAssert(wchar_t* ErrorMessage, void* ProgramCounter) [WindowsPlatformCrashContext.cpp:1834]
UnrealEditor_Core!FWindowsErrorOutputDevice::Serialize(wchar_t* Msg, ELogVerbosity::Type Verbosity = 0n-112 (No matching enumerant), FName* Category) [WindowsErrorOutputDevice.cpp:84]
UnrealEditor_Core!FOutputDevice::LogfImpl(wchar_t* Fmt) [OutputDevice.cpp:70]
UnrealEditor_Core!FOutputDevice::Logf() [OutputDevice.h:250]
UnrealEditor_Core!AssertFailedImplV(char* Expr, char* File, int Line = 0n889, void* ProgramCounter, wchar_t* Format, char* Args) [AssertionMacros.cpp:148]
UnrealEditor_Core!FDebug::CheckVerifyFailedImpl2(char* Expr, char* File, int Line = 0n889, wchar_t* Format) [AssertionMacros.cpp:649]
UnrealEditor_Engine!UWorld::MarkActorComponentForNeededEndOfFrameUpdate(UActorComponent* Component, bool bForceGameThread = false) [LevelTick.cpp:889]
UnrealEditor_Engine!FPrimitiveInstanceDataManager::MarkComponentRenderInstancesDirty() [ISMInstanceDataManager.cpp:908]
UnrealEditor_Engine!FPrimitiveInstanceDataManager::MarkForRebuildFromLegacy(TUniquePtr<FStaticMeshInstanceData,TDefaultDelete<FStaticMeshInstanceData>>* InLegacyInstanceData, TArray<int,TSizedDefaultAllocator<32>>* InstanceReorderTable, TArray<TRefCountPtr<HHitProxy>,TSizedDefaultAllocator<32>>* HitProxies) [ISMInstanceDataManager.cpp:1047]
UnrealEditor_Engine!UHierarchicalInstancedStaticMeshComponent::ApplyBuildTree(UHierarchicalInstancedStaticMeshComponent::FClusterBuilder* Builder, bool bWasAsyncBuild = true) [HierarchicalInstancedStaticMesh.cpp:2733]
UnrealEditor_Engine!UHierarchicalInstancedStaticMeshComponent::ApplyBuildTreeAsync(ENamedThreads::Type CurrentThread = 0n-2147258240 (No matching enumerant), TRefCountPtr<FGraphEvent>* MyCompletionGraphEvent, TSharedRef<UHierarchicalInstancedStaticMeshComponent::FClusterBuilder,1>* Builder, double StartTime = 19144969.470916200429) [HierarchicalInstancedStaticMesh.cpp:2671]
UnrealEditor_Engine!Invoke() [Invoke.h:66]
UnrealEditor_Engine!UE::Core::Private::Tuple::TTupleBase<TIntegerSequence<unsigned int,0,1>,TSharedRef<UHierarchicalInstancedStaticMeshComponent::FClusterBuilder,1>,double>::ApplyAfter() [Tuple.h:309]
UnrealEditor_Engine!TBaseUObjectMethodDelegateInstance<0,UHierarchicalInstancedStaticMeshComponent,void __cdecl(ENamedThreads::Type <Params_0> = GameThread (0n1), TRefCountPtr<FGraphEvent>* <Params_1>) [DelegateInstancesImpl.h:667]
UnrealEditor_Engine!TDelegate<void __cdecl() [DelegateSignatureImpl.inl:570]
UnrealEditor_Engine!FDelegateGraphTask::DoTask() [TaskGraphInterfaces.h:1645]
UnrealEditor_Engine!TGraphTask<FDelegateGraphTask>::ExecuteTask(TArray<FBaseGraphTask*,TSizedDefaultAllocator<32>>* NewTasks, ENamedThreads::Type CurrentThread = GameThread (0n1), bool bDeleteOnCompletion = true) [TaskGraphInterfaces.h:1235]
UnrealEditor_Core!FBaseGraphTask::Execute(ENamedThreads::Type CurrentThread = GameThread (0n1)) [TaskGraphInterfaces.h:840]
UnrealEditor_Core!FNamedTaskThread::ProcessTasksNamedThread(int QueueIndex = 0n0, bool bAllowStall = false) [TaskGraph.cpp:760]
UnrealEditor_Core!FNamedTaskThread::ProcessTasksUntilQuit(int QueueIndex = 0n0) [TaskGraph.cpp:651]
UnrealEditor_Core!FTaskGraphCompatibilityImplementation::ProcessThreadUntilRequestReturn() [TaskGraph.cpp:2072]
UnrealEditor_Core!FTaskGraphCompatibilityImplementation::WaitUntilTasksComplete(TArray<TRefCountPtr<FGraphEvent>,TSizedInlineAllocator<4,32,TSizedDefaultAllocator<32>>>* Tasks, ENamedThreads::Type CurrentThreadIfKnown) [TaskGraph.cpp:2126]
UnrealEditor_D3D12RHI!FTaskGraphInterface::WaitUntilTaskCompletes() [TaskGraphInterfaces.h:410]
UnrealEditor_D3D12RHI!FGraphEvent::Wait(ENamedThreads::Type CurrentThreadIfKnown = AnyThread (0n255)) [TaskGraphInterfaces.h:974]
UnrealEditor_D3D12RHI!FD3D12DynamicRHI::ProcessInterruptQueueUntil() [D3D12Submission.cpp:950]
UnrealEditor_D3D12RHI!FD3D12SyncPoint::Wait() [D3D12Submission.cpp:938]
UnrealEditor_D3D12RHI!FD3D12Device::BlockUntilIdle() [D3D12Device.cpp:578]
UnrealEditor_D3D12RHI!FD3D12Adapter::BlockUntilIdle() [D3D12Adapter.cpp:1950]
UnrealEditor_D3D12RHI!FD3D12Viewport::Resize(unsigned int InSizeX = 8, unsigned int InSizeY = 8, bool bInIsFullscreen = false, EPixelFormat PreferredPixelFormat = PF_A2B10G10R10 (0n18)) [D3D12Viewport.cpp:402]
UnrealEditor_D3D12RHI!FD3D12Viewport::Init() [WindowsD3D12Viewport.cpp:225]
UnrealEditor_D3D12RHI!FD3D12DynamicRHI::RHICreateViewport(void* WindowHandle, unsigned int SizeX = 8, unsigned int SizeY = 8, bool bIsFullscreen = false, EPixelFormat PreferredPixelFormat = PF_A2B10G10R10 (0n18)) [D3D12Viewport.cpp:831]
UnrealEditor_SlateRHIRenderer!RHICreateViewport(void* WindowHandle, EPixelFormat PreferredPixelFormat = PF_Unknown (0n0)) [DynamicRHI.h:1352]
UnrealEditor_SlateRHIRenderer!FSlateRHIRenderer::CreateViewport(TSharedRef<SWindow,1>* Window) [SlateRHIRenderer.cpp:459]
UnrealEditor_SlateCore!SWindow::ShowWindow() [SWindow.cpp:1412]
UnrealEditor_Slate!FSlateApplication::AddWindowAsNativeChild(TSharedRef<SWindow,1>* InSlateWindow, TSharedRef<SWindow,1>* InParentWindow, bool bShowImmediately = true) [SlateApplication.cpp:2187]
UnrealEditor_Slate!FSlateNotificationManager::CreateStackForArea(FSlateRect* InRectangle, TSharedPtr<SWindow,1>* Window) [NotificationManager.cpp:157]
UnrealEditor_Slate!FSlateNotificationManager::AddNotification(FNotificationInfo* Info) [NotificationManager.cpp:217]
UnrealEditor_Engine!UMaterial::SetMaterialUsage(bool* bNeedsRecompile, EMaterialUsage Usage = MATUSAGE_Nanite (0n18), UMaterialInterface* MaterialInstance) [Material.cpp:1951]
UnrealEditor_Engine!UMaterial::CheckMaterialUsage(EMaterialUsage Usage = MATUSAGE_Nanite (0n18)) [Material.cpp:1772]
UnrealEditor_Engine!UMaterial::CheckMaterialUsage_Concurrent(EMaterialUsage Usage = MATUSAGE_Nanite (0n18)) [Material.cpp:1784]
UnrealEditor_Engine!Nanite::AuditMaterialsImp<UStaticMeshComponent>(UStaticMeshComponent* InProxyDesc, Nanite::FMaterialAudit* Audit, bool bSetMaterialUsage = true) [NaniteResources.cpp:2343]
UnrealEditor_Engine!Nanite::ShouldCreateNaniteProxy<UStaticMeshComponent>(UStaticMeshComponent* Component, Nanite::FMaterialAudit* OutNaniteMaterials) [StaticMeshRender.cpp:2714]
UnrealEditor_Engine!UStaticMeshComponent::ShouldCreateNaniteProxy() [StaticMeshRender.cpp:2735]
UnrealEditor_Engine!UStaticMeshComponent::CreateSceneProxy() [StaticMeshRender.cpp:2869]
UnrealEditor_Engine!FActorPrimitiveComponentInterface::CreateSceneProxy() [PrimitiveComponent.cpp:5316]
UnrealEditor_Renderer!FScene::BatchAddPrimitivesInternal<UPrimitiveComponent>(TArrayView<UPrimitiveComponent*,int>* InPrimitives) [RendererScene.cpp:2131]
UnrealEditor_Renderer!FScene::BatchAddPrimitives(TArrayView<UPrimitiveComponent*,int>* InPrimitives) [RendererScene.cpp:2198]
UnrealEditor_Engine!FStaticMeshComponentBulkReregisterContext::~FStaticMeshComponentBulkReregisterContext() [StaticMeshResources.cpp:163]
UnrealEditor_Engine!`UWorld::SendAllEndOfFrameUpdates'::`2'::<lambda_3>::operator()() [LevelTick.cpp:1133]
UnrealEditor_Engine!UWorld::SendAllEndOfFrameUpdates() [LevelTick.cpp:1149]
UnrealEditor_Engine!UEngine::SendWorldEndOfFrameUpdates() [UnrealEngine.cpp:1686]
UnrealEditor_Engine!UEngine::PreGarbageCollect() [UnrealEngine.cpp:1698]
UnrealEditor_Engine!Invoke() [Invoke.h:47]
UnrealEditor_Engine!UE::Core::Private::Tuple::TTupleBase<TIntegerSequence<unsigned int> >::ApplyAfter() [Tuple.h:309]
UnrealEditor_Engine!TBaseStaticDelegateInstance<void __cdecl() [DelegateInstancesImpl.h:777]
UnrealEditor_CoreUObject!TMulticastDelegateBase<FDefaultDelegateUserPolicy>::Broadcast() [MulticastDelegateBase.h:254]
UnrealEditor_CoreUObject!TMulticastDelegate<void __cdecl() [DelegateSignatureImpl.inl:956]
UnrealEditor_CoreUObject!UE::GC::PreCollectGarbageImpl<1>(EObjectFlags KeepFlags = RF_Public (0n1)) [GarbageCollection.cpp:5493]
UnrealEditor_CoreUObject!UE::GC::FReachabilityAnalysisState::PerformReachabilityAnalysisAndConditionallyPurgeGarbage(bool bReachabilityUsingTimeLimit = false) [GarbageCollection.cpp:5745]
UnrealEditor_CoreUObject!UE::GC::CollectGarbageInternal() [GarbageCollection.cpp:5423]
UnrealEditor_CoreUObject!CollectGarbage(EObjectFlags KeepFlags = RF_Standalone (0n2), bool bPerformFullPurge = true) [GarbageCollection.cpp:6088]
UnrealEditor_UnrealEd!UEditorEngine::Map_Load(wchar_t* Str, FOutputDevice* Ar) [EditorServer.cpp:2794]
UnrealEditor_UnrealEd!UEditorEngine::HandleMapCommand(wchar_t* Str, FOutputDevice* Ar, UWorld* InWorld) [EditorServer.cpp:6200]
UnrealEditor_UnrealEd!UEditorEngine::Exec_Editor(UWorld* InWorld, wchar_t* Stream, FOutputDevice* Ar) [EditorServer.cpp:5661]
UnrealEditor_Core!FExec::Exec(UWorld* InWorld, wchar_t* Cmd, FOutputDevice* Ar) [Exec.cpp:18]
UnrealEditor_Engine!UEngine::Exec(UWorld* InWorld, wchar_t* Cmd, FOutputDevice* Ar) [UnrealEngine.cpp:4848]
UnrealEditor_UnrealEd!UUnrealEdEngine::Exec(UWorld* InWorld, wchar_t* Stream, FOutputDevice* Ar) [UnrealEdSrv.cpp:662]
UnrealEditor_GbxGameEditor!UGbxGameUnrealEdEngine::Exec(UWorld* InWorld, wchar_t* Cmd, FOutputDevice* Ar) [GbxGameUnrealEdEngine.cpp:122]
UnrealEditor_UnrealEd!FEditorFileUtils::LoadMap(FString* InFilename, bool LoadAsTemplate = false, bool bShowProgress = false) [FileHelpers.cpp:2962]
UnrealEditor_UnrealEd!FAutomationEditorCommonUtils::LoadMap() [AutomationEditorCommon.cpp:672]
UnrealEditor_UnrealEd!FEditorLoadMap::Update() [AutomationEditorCommon.cpp:868]
UnrealEditor_Core!IAutomationLatentCommand::InternalUpdate() [AutomationTest.h:525]
UnrealEditor_Core!FAutomationTestFramework::ExecuteLatentCommands() [AutomationTest.cpp:566]
UnrealEditor_AutomationWorker!FAutomationWorkerModule::ExecuteLatentCommands() [AutomationWorkerModule.cpp:116]
UnrealEditor_AutomationWorker!FAutomationWorkerModule::Tick() [AutomationWorkerModule.cpp:69]
UnrealEditor!FEngineLoop::Tick() [LaunchEngineLoop.cpp:6350]
UnrealEditor!EngineTick() [Launch.cpp:64]
UnrealEditor!GuardedMain(wchar_t* CmdLine) [Launch.cpp:198]

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-220009 in the post.

1
Login to Vote

Fixed
ComponentUE - Gameplay - Components
Affects Versions5.4
Target Fix5.5
Fix Commit34524771
CreatedJul 23, 2024
ResolvedJul 24, 2024
UpdatedAug 8, 2024
View Jira Issue