We are experiencing a crash in FGPUSkinCache::GetPositionBuffer which is called by FSkeletalMeshObjectGPUSkin::GetCachedGeometry. This is due to Niagara’s “Skeletal Mesh Location” Module on a character. The crash happens when the LOD level of the character changes (e.g. when you are moving back and forth). It does have about a 25% repro rate.
I think this is due to a race condition.
This is the crash in the debugger:
[Image Removed]
The Entry parameter seems to be stale which you can easily tell by the Mode value.
[Image Removed]
It is interesting, that the skin cache entry is perfectly fine if you go one line down in the callstack. You can see that the pointer is not the same. Compare the pointer inside the GetPositionBuffer function …
[Image Removed]
… and the pointer in the calling GetGeometryCache:
[Image Removed]
Note that the pointer in GetGeometryCache is a class field, whereas the pointer in the GetPositionBuffer function is a copy of it. I think, the field gets changed by another thread while AddAsyncComputeWait is waiting for it to finish.
A data breakpoint shows that the entry gets deleted and reassigned on a worker thread due to a LOD change:
[Image Removed]
however, GetGeometryCache is called on the render thread which you can easily see from the crashing callstack! I think this is because skinning runs on UE::RenderCommandPipe::SkeletalMesh.
My understanding is that AddAsyncComputeWait is waiting until the parallel render threads are finished. So you can probably fix the problem by moving the wait up into the GetGeometryCache function before it accesses the entry. The problem is just, AddAsyncComputeWait is a FGPUSkinCache function and the skin cache object is only available through the FGPUSkinCacheEntry pointer. So you’d somehow have to make the FGPUSkinCache object accessible without going through the FGPUSkinCacheEntry pointer. Even something like
if (Entry)
{
Entry->SkinCache->AddAsyncComputeWait(GraphBuilder);
}
is not safe because Entry is not atomic and the thread could be interrupted between the null check and the access.
I hope this helps to provide a fix soon as we currently only have a workaround which is not 100% reliable. Thank you!
PS: The crashing callstack is:
Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0xffffffffffffffff
(0x1896123) UnrealEditor-Engine.dll!FGPUSkinCache::GetPositionBuffer() [D:\TRS_Perforce\Game\Engine\Source\Runtime\Engine\Private\GPUSkinCache.cpp:2567]
(0x2c0aa9d) UnrealEditor-Engine.dll!FSkeletalMeshObjectGPUSkin::GetCachedGeometry() [D:\TRS_Perforce\Game\Engine\Source\Runtime\Engine\Private\SkeletalRenderGPUSkin.cpp:2468]
(0xa6607d) UnrealEditor-Niagara.dll!UNiagaraDataInterfaceSkeletalMesh::SetShaderParameters() [D:\TRS_Perforce\Game\Engine\Plugins\FX\Niagara\Source\Niagara\Private\NiagaraDataInterfaceSkeletalMesh.cpp:3384]
(0xbc17b4) UnrealEditor-Niagara.dll!FNiagaraGpuComputeDispatch::SetDataInterfaceParameters() [D:\TRS_Perforce\Game\Engine\Plugins\FX\Niagara\Source\Niagara\Private\NiagaraGpuComputeDispatch.cpp:2460]
(0xb76d6c) UnrealEditor-Niagara.dll!FNiagaraGpuComputeDispatch::DispatchStage() [D:\TRS_Perforce\Game\Engine\Plugins\FX\Niagara\Source\Niagara\Private\NiagaraGpuComputeDispatch.cpp:1701]
(0xb89b3d) UnrealEditor-Niagara.dll!FNiagaraGpuComputeDispatch::ExecuteTicks() [D:\TRS_Perforce\Game\Engine\Plugins\FX\Niagara\Source\Niagara\Private\NiagaraGpuComputeDispatch.cpp:1288]
(0xbb00f7) UnrealEditor-Niagara.dll!FNiagaraGpuComputeDispatch::PreInitViews() [D:\TRS_Perforce\Game\Engine\Plugins\FX\Niagara\Source\Niagara\Private\NiagaraGpuComputeDispatch.cpp:2008]
(0x2191425) UnrealEditor-Engine.dll!FFXSystemSet::PreInitViews() [D:\TRS_Perforce\Game\Engine\Source\Runtime\Engine\Private\Particles\FXSystemSet.cpp:131]
(0x15c72bb) UnrealEditor-Renderer.dll!FSceneRenderer::PreVisibilityFrameSetup() [D:\TRS_Perforce\Game\Engine\Source\Runtime\Renderer\Private\SceneVisibility.cpp:4863]
(0x159a837) UnrealEditor-Renderer.dll!FDeferredShadingSceneRenderer::BeginInitViews() [D:\TRS_Perforce\Game\Engine\Source\Runtime\Renderer\Private\SceneVisibility.cpp:5750]
(0x31cb93) UnrealEditor-Renderer.dll!FDeferredShadingSceneRenderer::Render() [D:\TRS_Perforce\Game\Engine\Source\Runtime\Renderer\Private\DeferredShadingRenderer.cpp:1737]
(0x155728f) UnrealEditor-Renderer.dll!RenderViewFamily_RenderThread() [D:\TRS_Perforce\Game\Engine\Source\Runtime\Renderer\Private\SceneRendering.cpp:4873]
(0x14dd030) UnrealEditor-Renderer.dll!`FRendererModule::BeginRenderingViewFamilies’::`116’::<lambda_4>::<lambda_invoker_cdecl>() [D:\TRS_Perforce\Game\Engine\Source\Runtime\Renderer\Private\SceneRendering.cpp:5163]
(0x150c8eb) UnrealEditor-Renderer.dll!`FSceneRenderProcessor::Execute’::`30’::<lambda_4>::operator()() [D:\TRS_Perforce\Game\Engine\Source\Runtime\Renderer\Private\SceneRenderBuilder.cpp:916]
(0x1bd71f) UnrealEditor-RenderCore.dll!`FRenderThreadCommandPipe::EnqueueAndLaunch’::`5’::<lambda_1>::operator()() [D:\TRS_Perforce\Game\Engine\Source\Runtime\RenderCore\Private\RenderingThread.cpp:1554]
(0x1e4698) UnrealEditor-RenderCore.dll!TGraphTask<TFunctionGraphTaskImpl<void __cdecl(void),1> >::ExecuteTask() [D:\TRS_Perforce\Game\Engine\Source\Runtime\Core\Public\Async\TaskGraphInterfaces.h:708]
(0x129fb2) UnrealEditor-Core.dll!UE::Tasks::Private::FTaskBase::TryExecuteTask() [D:\TRS_Perforce\Game\Engine\Source\Runtime\Core\Public\Tasks\TaskPrivate.h:527]
(0x1109bf) UnrealEditor-Core.dll!FNamedTaskThread::ProcessTasksNamedThread() [D:\TRS_Perforce\Game\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:784]
(0x1110be) UnrealEditor-Core.dll!FNamedTaskThread::ProcessTasksUntilQuit() [D:\TRS_Perforce\Game\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:672]
(0x2092f9) UnrealEditor-RenderCore.dll!RenderingThreadMain() [D:\TRS_Perforce\Game\Engine\Source\Runtime\RenderCore\Private\RenderingThread.cpp:321]
(0x20a3a4) UnrealEditor-RenderCore.dll!FRenderingThread::Run() [D:\TRS_Perforce\Game\Engine\Source\Runtime\RenderCore\Private\RenderingThread.cpp:454]
(0x849504) UnrealEditor-Core.dll!FRunnableThreadWin::Run() [D:\TRS_Perforce\Game\Engine\Source\Runtime\Core\Private\Windows\WindowsRunnableThread.cpp:165]
(0x841e1f) UnrealEditor-Core.dll!FRunnableThreadWin::GuardedRun() [D:\TRS_Perforce\Game\Engine\Source\Runtime\Core\Private\Windows\WindowsRunnableThread.cpp:83]
(0x2e8d7) KERNEL32.DLL!UnknownFunction