UE5 Mac Os Assertion failed: Backing.Buffer.GetStorageMode() == Mode

Mac OS M1 chip.
When I open a level map , UE5 will crash.
Thanks!

Assertion failed: Backing.Buffer.GetStorageMode() == Mode [File:/Users/build/Build/++UE5/Sync/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalVertexBuffer.cpp] [Line: 287]

FMetalRHIBuffer::FMetalRHIBuffer(unsigned int, EBufferUsageFlags, EMetalBufferUsage, ERHIResourceType) Address = 0x19478d945 (filename not found) [in UnrealEditor-MetalRHI.dylib]

FMetalResourceMultiBuffer::FMetalResourceMultiBuffer(unsigned int, EBufferUsageFlags, EMetalBufferUsage, unsigned int, FResourceArrayInterface*, ERHIResourceType) Address = 0x194793c32 (filename not found) [in UnrealEditor-MetalRHI.dylib]

FMetalDynamicRHI::CreateBuffer_RenderThread(FRHICommandListImmediate&, unsigned int, EBufferUsageFlags, unsigned int, ERHIAccess, FRHIResourceCreateInfo&) Address = 0x194794f8c (filename not found) [in UnrealEditor-MetalRHI.dylib]

FScatterUploadBuffer::Init(unsigned int, unsigned int, bool, char16_t const*) Address = 0x112155f34 (filename not found) [in UnrealEditor-RenderCore.dylib]

void FGPUScene::UploadGeneral(FRHICommandListImmediate&, FScene*, FUploadDataSourceAdapterScenePrimitives const&, FGPUSceneBufferState const&) Address = 0x1469db4bf (filename not found) [in UnrealEditor-Renderer.dylib]

TRDGLambdaPass<FEmptyShaderParameters, FGPUScene::UpdateInternal(FRDGBuilder&, FScene&)::$_54>::Execute(FRHIComputeCommandList&) Address = 0x1469d76aa (filename not found) [in UnrealEditor-Renderer.dylib]

FRDGBuilder::ExecutePass(FRDGPass*, FRHIComputeCommandList&) Address = 0x111f7ee20 (filename not found) [in UnrealEditor-RenderCore.dylib]

FRDGBuilder::Execute() Address = 0x111f4cd1a (filename not found) [in UnrealEditor-RenderCore.dylib]

CaptureSceneToScratchCubemap(FRHICommandListImmediate&, FSceneRenderer*, ECubeFace, int, bool, bool, FLinearColor const&, bool) Address = 0x1473162c8 (filename not found) [in UnrealEditor-Renderer.dylib]

TEnqueueUniqueRenderCommandType<CaptureSceneIntoScratchCubemap(FScene*, UE::Math::TVector, int, bool, bool, float, bool, bool, FLinearColor const&, bool)::CaptureCommandName, CaptureSceneIntoScratchCubemap(FScene*, UE::Math::TVector, int, bool, bool, float, bool, bool, FLinearColor const&, bool)::$_12>::DoTask(ENamedThreads::Type, TRefCountPtr const&) Address = 0x1473bf868 (filename not found) [in UnrealEditor-Renderer.dylib]

TGraphTask<TEnqueueUniqueRenderCommandType<CaptureSceneIntoScratchCubemap(FScene*, UE::Math::TVector, int, bool, bool, float, bool, bool, FLinearColor const&, bool)::CaptureCommandName, CaptureSceneIntoScratchCubemap(FScene*, UE::Math::TVector, int, bool, bool, float, bool, bool, FLinearColor const&, bool)::$_12> >::ExecuteTask(TArray<FBaseGraphTask*, TSizedDefaultAllocator<32> >&, ENamedThreads::Type, bool) Address = 0x1473bfce4 (filename not found) [in UnrealEditor-Renderer.dylib]

FNamedTaskThread::ProcessTasksNamedThread(int, bool) Address = 0x10c906449 (filename not found) [in UnrealEditor-Core.dylib]

FNamedTaskThread::ProcessTasksUntilQuit(int) Address = 0x10c904a00 (filename not found) [in UnrealEditor-Core.dylib]

FTaskGraphCompatibilityImplementation::ProcessThreadUntilRequestReturn(ENamedThreads::Type) Address = 0x10c90320f (filename not found) [in UnrealEditor-Core.dylib]

RenderingThreadMain(FEvent*) Address = 0x11203a9d4 (filename not found) [in UnrealEditor-RenderCore.dylib]

FRenderingThread::Run() Address = 0x112065e57 (filename not found) [in UnrealEditor-RenderCore.dylib]

FRunnableThreadPThread::Run() Address = 0x10ca8afc4 (filename not found) [in UnrealEditor-Core.dylib]

FRunnableThreadPThread::_ThreadProc(void*) Address = 0x10c9eb3b4 (filename not found) [in UnrealEditor-Core.dylib]

_pthread_start Address = 0x7ff8092894e1 (filename not found) [in libsystem_pthread.dylib]

thread_start Address = 0x7ff809284f6b (filename not found) [in libsystem_pthread.dylib]

1 Like

Hahaļ¼I fixed itļ¼

Edit /Config/DefaultEngine.ini (In your project folder)
Find line contains ā€œDefaultGraphicsRHIā€
Set value to ā€œDefaultGraphicsRHIā€ like below

DefaultGraphicsRHI=DefaultGraphicsRHI_Default

3 Likes

This method only works on macOS. (UE5)

It seems that the problem still exists in other mapsļ¼Œ :sleeping:

I am getting this a lot. Your fix did not work for me unfortunately
Yes it seems to be only on certain maps.
If its a default map I just move it in Finder to force the project to open a blank level so I can at least get in the Project

Happen to me a lot, not just when loading the map. Havenā€™t been able to find a pattern to it yet. :frowning:

The problem persists and I didnā€™t fix it. :sweat:
Now I have to work on WIN OS ,dx11.
dx12 will crash too!

If you fix it, please let me know how.

Any update on this? I am experiencing this issue as well on latest Mac OS and UE 5.0.1

I have the same problem on latest Mac OS with UE 5.0.1

Edit: I have reinstalled UE 5.0.1 and this has fixed the problem for me.

Did you have to do anything with your current UE5.0.1 Project Files?

No, I only deleted the intermediate, binaries and saved folders and opened with the fresh installed Unreal editor

I get this same error, was anyone able to fix it?

Currently re-installing 5.0.1 as suggested

I confirm this is not the solution

Still no solution here. Might be UE5 issue with M1 Chips/Metal GPU Rendering???

I can say that if you start the level simulation in a new window it doesnā€™t crash. If you simulate in the current viewport, issues arise.

I can also say that I am using an ultra wide screen with my Mac. When simulating in a new window that appears on the Mac screen side, no crashes happen.

+1 here on M1 Mac. Hope there will be a solution.

I built 5.0.1 from source so I could debug this and I believe I finally know the cause.

I added some logging to MetalVertexBuffer, MetalBuffer to see what was going on.

Here was can see 2 buffer creations, one with StorageMode = 2 (Private), the other with StorageMode = 1 (Managed):

FMetalRHIBuffer::FMetalRHIBuffer - Size = 2200000, Usage = 16386
FMetalRHIBuffer::FMetalRHIBuffer - Creating Pooled Vertex Buffer 0 with Usage = 16386, Mode = 2
FMetalBufferPoolPolicyData::CreateResource - Allocated new pool buffer with StorageMode = 2, NewBuf.GetStorageMode() = 2
...
FMetalRHIBuffer::FMetalRHIBuffer - Size = 2764800, Usage = 16388
FMetalRHIBuffer::FMetalRHIBuffer - Creating Pooled Vertex Buffer 0 with Usage = 16388, Mode = 1
FMetalBufferPoolPolicyData::CreateResource - Allocated new pool buffer with StorageMode = 1, NewBuf.GetStorageMode() = 1

Now, in FMetalBufferPoolPolicyData definition (see MetalBuffer.h), we can see that the pool has buckets for different buffer sizes:

NumPoolBuckets = NumPoolBucketSizes, /** Number of pool bucket sizes - all entries must use consistent ResourceOptions */

The comment highlights that buffers in the buckets should be consistent wrt ResourceOptions, but there is currently no mechanism to enforce that.

In FMetalBufferPoolPolicyData::GetPoolBucketIndex only the buffer Size is used to determine the index, so both buffers above go in the same pool bucket even though the StorageMode differs.

Eventually, a reused buffer will have StorageMode = 2 instead of the requested 1, or vice versa.

Unfortunately I donā€™t have a minimal reproducible case yet, it breaks in my project all the time but not in a starter project for some reason.

Iā€™m not sure yet when StorageMode 1 or 2 is or should be used so itā€™s possible there is another bug which is mixing modes up.

Unless, someone has additional knowledge I will create a bug report for the buffer pooling issue.

2 Likes

I believe the issue here may be a bug in the FMetalRHIBuffer::UsePrivateMemory method:

bool FMetalRHIBuffer::UsePrivateMemory() const
{
	return (FMetalCommandQueue::SupportsFeature(EMetalFeaturesEfficientBufferBlits) && EnumHasAnyFlags(Usage, BUF_Dynamic|BUF_Static))
	|| (FMetalCommandQueue::SupportsFeature(EMetalFeaturesIABs) && EnumHasAnyFlags(Usage, BUF_ShaderResource|BUF_UnorderedAccess)) && !FMetalCommandQueue::IsUMASystem();
}

I believe the intention here was that UMA systems (M1) should not use private memory since the static CanUsePrivateMemory function:

static bool CanUsePrivateMemory()
{
	return (FMetalCommandQueue::SupportsFeature(EMetalFeaturesEfficientBufferBlits) || FMetalCommandQueue::SupportsFeature(EMetalFeaturesIABs)) && !FMetalCommandQueue::IsUMASystem();
}

Indicates that UMA systems cannot use private memory.

That doesnā€™t seem to line up with Choosing a Resource Storage Mode for Apple GPUs Select an appropriate storage mode for your textures and buffers on Apple GPUs. but there may be reasons for it.

In any case, the way these function are used allows the result of UsePrivateMemory to override that of CanUsePrivateMemory:

	Mode = UsePrivateMemory() ? mtlpp::StorageMode::Private : BUFFER_STORAGE_MODE;
	Mode = CanUsePrivateMemory() ? mtlpp::StorageMode::Private : Mode;

By wrapping the || in UsePrivateMemory in parenthesis,

	return ((FMetalCommandQueue::SupportsFeature(EMetalFeaturesEfficientBufferBlits) && EnumHasAnyFlags(Usage, BUF_Dynamic|BUF_Static))
	|| (FMetalCommandQueue::SupportsFeature(EMetalFeaturesIABs) && EnumHasAnyFlags(Usage, BUF_ShaderResource|BUF_UnorderedAccess))) && !FMetalCommandQueue::IsUMASystem();

mtlpp::StorageMode::Private is never used for UMA systems and the pooling issue I previously discussed doesnā€™t arise.

Iā€™ll file a bug report and open a pull-request if possible.

7 Likes

Anyone at Epic Games can follow up on this? Itā€™s getting impossible to do anything in a Mac

3 Likes