From 35e53f76a9fc8f22be3909558def87474aa3de71 Mon Sep 17 00:00:00 2001 From: d-musique <119169473+d-musique@users.noreply.github.com> Date: Tue, 29 Oct 2024 17:35:13 +0100 Subject: [PATCH] metal: check success of device creation (#11367) When macOS runs under a virtual environment, it is possible that MTLCreateSystemDefaultDevice() does not succeed. Not checking this failure results in a crash down the road. This change allows to skip GPU renderer and use an adequate fallback. Co-authored-by: D.musique --- src/gpu/metal/SDL_gpu_metal.m | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/gpu/metal/SDL_gpu_metal.m b/src/gpu/metal/SDL_gpu_metal.m index 3792d80327abf..04a5bff59692e 100644 --- a/src/gpu/metal/SDL_gpu_metal.m +++ b/src/gpu/metal/SDL_gpu_metal.m @@ -4166,33 +4166,40 @@ static void METAL_INTERNAL_DestroyBlitResources( { @autoreleasepool { MetalRenderer *renderer; - - // Allocate and zero out the renderer - renderer = (MetalRenderer *)SDL_calloc(1, sizeof(MetalRenderer)); + id device = NULL; // Create the Metal device and command queue #ifdef SDL_PLATFORM_MACOS if (preferLowPower) { NSArray> *devices = MTLCopyAllDevices(); - for (id device in devices) { - if (device.isLowPower) { - renderer->device = device; + for (id candidate in devices) { + if (candidate.isLowPower) { + device = candidate; break; } } } #endif - if (renderer->device == NULL) { - renderer->device = MTLCreateSystemDefaultDevice(); + if (device == NULL) { + device = MTLCreateSystemDefaultDevice(); + if (device == NULL) { + SDL_SetError("Failed to create Metal device"); + return NULL; + } } - renderer->queue = [renderer->device newCommandQueue]; + + // Allocate and zero out the renderer + renderer = (MetalRenderer *)SDL_calloc(1, sizeof(MetalRenderer)); + + renderer->device = device; + renderer->queue = [device newCommandQueue]; // Print driver info SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: Metal"); SDL_LogInfo( SDL_LOG_CATEGORY_GPU, "Metal Device: %s", - [renderer->device.name UTF8String]); + [device.name UTF8String]); // Remember debug mode renderer->debugMode = debugMode;