From 6a5163c0d8d85de0bdfe4eb3ace3353085134332 Mon Sep 17 00:00:00 2001 From: Benjamin Doherty Date: Wed, 17 Sep 2025 16:21:18 -0700 Subject: [PATCH] Metal: log command buffer errors --- filament/backend/src/metal/MetalContext.mm | 7 ++++- filament/backend/src/metal/MetalEnums.h | 32 ++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/filament/backend/src/metal/MetalContext.mm b/filament/backend/src/metal/MetalContext.mm index 587316edf8fa..0ed35df845a0 100644 --- a/filament/backend/src/metal/MetalContext.mm +++ b/filament/backend/src/metal/MetalContext.mm @@ -102,7 +102,7 @@ void initializeSupportedGpuFamilies(MetalContext* context) { context->pendingCommandBuffer = [context->commandQueue commandBuffer]; // It's safe for this block to capture the context variable. MetalDriver::terminate will ensure // all frames and their completion handlers finish before context is deallocated. - uint64_t thisCommandBufferId = context->pendingCommandBufferId; + const uint64_t thisCommandBufferId = context->pendingCommandBufferId; [context->pendingCommandBuffer addCompletedHandler:^(id buffer) { context->resourceTracker.clearResources((__bridge void*) buffer); @@ -118,6 +118,11 @@ void initializeSupportedGpuFamilies(MetalContext* context) { context->memorylessLimitsReached = true; } } + + if (UTILS_UNLIKELY(errorCode != MTLCommandBufferErrorNone)) { + LOG(ERROR) << "Filament Metal command buffer errored with code: " << errorCode << " (" + << stringifyMTLCommandBufferError(errorCode) << ")."; + } }]; FILAMENT_CHECK_POSTCONDITION(context->pendingCommandBuffer) << "Could not obtain command buffer."; diff --git a/filament/backend/src/metal/MetalEnums.h b/filament/backend/src/metal/MetalEnums.h index 77a24525a4dd..950e42e08973 100644 --- a/filament/backend/src/metal/MetalEnums.h +++ b/filament/backend/src/metal/MetalEnums.h @@ -451,6 +451,38 @@ inline MTLTextureSwizzleChannels getSwizzleChannels(TextureSwizzle r, TextureSwi getSwizzle(a)); } +inline const char* stringifyMTLCommandBufferError(MTLCommandBufferError error) { +#if !defined(FILAMENT_IOS) + if (error == MTLCommandBufferErrorDeviceRemoved) { + return "MTLCommandBufferErrorDeviceRemoved"; + } +#endif + switch (error) { + case MTLCommandBufferErrorNone: + return "MTLCommandBufferErrorNone"; + case MTLCommandBufferErrorInternal: + return "MTLCommandBufferErrorInternal"; + case MTLCommandBufferErrorTimeout: + return "MTLCommandBufferErrorTimeout"; + case MTLCommandBufferErrorPageFault: + return "MTLCommandBufferErrorPageFault"; + case MTLCommandBufferErrorAccessRevoked: + return "MTLCommandBufferErrorAccessRevoked"; + case MTLCommandBufferErrorNotPermitted: + return "MTLCommandBufferErrorNotPermitted"; + case MTLCommandBufferErrorOutOfMemory: + return "MTLCommandBufferErrorOutOfMemory"; + case MTLCommandBufferErrorInvalidResource: + return "MTLCommandBufferErrorInvalidResource"; + case MTLCommandBufferErrorMemoryless: + return "MTLCommandBufferErrorMemoryless"; + case MTLCommandBufferErrorStackOverflow: + return "MTLCommandBufferErrorStackOverflow"; + default: + return "Unknown"; + } +} + } // namespace backend } // namespace filament