diff --git a/src/gpu/metal/SDL_gpu_metal.m b/src/gpu/metal/SDL_gpu_metal.m index 3a02f8fd3a..f6d6d30f96 100644 --- a/src/gpu/metal/SDL_gpu_metal.m +++ b/src/gpu/metal/SDL_gpu_metal.m @@ -4063,8 +4063,9 @@ static bool METAL_SetAllowedFramesInFlight( // Submission -static bool METAL_Submit( - SDL_GPUCommandBuffer *commandBuffer) +static bool METAL_INTERNAL_Submit( + SDL_GPUCommandBuffer *commandBuffer, + SDL_GPUFence **fence) { @autoreleasepool { MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer; @@ -4077,6 +4078,12 @@ static bool METAL_Submit( return false; } + // Return the fence while submitLock is held, another thread could + // recycle this command buffer as soon as the lock is released. + if (fence) { + *fence = (SDL_GPUFence *)metalCommandBuffer->fence; + } + // Enqueue present requests, if applicable for (Uint32 i = 0; i < metalCommandBuffer->windowDataCount; i += 1) { MetalWindowData *windowData = metalCommandBuffer->windowDatas[i]; @@ -4123,15 +4130,22 @@ static bool METAL_Submit( } } +static bool METAL_Submit( + SDL_GPUCommandBuffer *commandBuffer) +{ + return METAL_INTERNAL_Submit(commandBuffer, NULL); +} + static SDL_GPUFence *METAL_SubmitAndAcquireFence( SDL_GPUCommandBuffer *commandBuffer) { MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer; + SDL_GPUFence *fence = NULL; metalCommandBuffer->autoReleaseFence = false; - if (!METAL_Submit(commandBuffer)) { + if (!METAL_INTERNAL_Submit(commandBuffer, &fence)) { return NULL; } - return (SDL_GPUFence *)metalCommandBuffer->fence; + return fence; } static bool METAL_Cancel(