Caleb Cornett пре 15 часа
родитељ
комит
3561f81400
1 измењених фајлова са 14 додато и 27 уклоњено
  1. 14 27
      src/gpu/metal/SDL_gpu_metal.m

+ 14 - 27
src/gpu/metal/SDL_gpu_metal.m

@@ -454,8 +454,7 @@ typedef struct MetalTextureContainer
 
 typedef struct MetalFence
 {
-    // can be NULL if the command buffer was recycled
-    MetalCommandBuffer *commandBuffer;
+    id<MTLCommandBuffer> commandBuffer;
     SDL_AtomicInt referenceCount;
 } MetalFence;
 
@@ -2137,7 +2136,7 @@ static bool METAL_INTERNAL_AcquireFence(
 
     // Associate the fence with the command buffer
     commandBuffer->fence = fence;
-    fence->commandBuffer = commandBuffer;
+    fence->commandBuffer = commandBuffer->handle;
     (void)SDL_AtomicIncRef(&commandBuffer->fence->referenceCount);
 
     return true;
@@ -3407,6 +3406,7 @@ static void METAL_ReleaseFence(
     SDL_GPUFence *fence)
 {
     MetalFence *metalFence = (MetalFence *)fence;
+    metalFence->commandBuffer = nil;
     if (SDL_AtomicDecRef(&metalFence->referenceCount)) {
         METAL_INTERNAL_ReleaseFenceToPool(
             (MetalRenderer *)driverData,
@@ -3518,8 +3518,6 @@ static void METAL_INTERNAL_CleanCommandBuffer(
         METAL_ReleaseFence(
             (SDL_GPURenderer *)renderer,
             (SDL_GPUFence *)commandBuffer->fence);
-    } else {
-        commandBuffer->fence->commandBuffer = NULL;
     }
 
     // Return command buffer to pool
@@ -3593,11 +3591,7 @@ static void METAL_INTERNAL_PerformPendingDestroys(
 static bool METAL_INTERNAL_IsFenceBusy(
         MetalFence *fence
 ) {
-    if (!fence->commandBuffer) {
-        return false; // command buffer was recycled
-    }
-
-    MTLCommandBufferStatus status = fence->commandBuffer->handle.status;
+    MTLCommandBufferStatus status = fence->commandBuffer.status;
     return status == MTLCommandBufferStatusCommitted || status == MTLCommandBufferStatusScheduled;
 }
 
@@ -3613,25 +3607,19 @@ static bool METAL_WaitForFences(
         if (waitAll) {
             for (Uint32 i = 0; i < numFences; i += 1) {
                 MetalFence *fence = (MetalFence *)fences[i];
-                if (METAL_INTERNAL_IsFenceBusy(fence)) {
-                    [fence->commandBuffer->handle waitUntilCompleted];
-                }
+                [fence->commandBuffer waitUntilCompleted];
             }
         } else {
-            dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
-            for (Uint32 i = 0; i < numFences; i += 1) {
-                MetalFence *fence = (MetalFence *)fences[i];
-                // command buffer has completed and been recycled
-                if(!fence->commandBuffer)
-                    return true;
-
-                // even if it's completed, the handle will call back straight away
-                [fence->commandBuffer->handle addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
-                    dispatch_semaphore_signal(semaphore);
-                }];
+            bool waiting = true;
+            while (waiting) {
+                for (Uint32 i = 0; i < numFences; i += 1) {
+                    MetalFence *fence = (MetalFence *)fences[i];
+                    if (!METAL_INTERNAL_IsFenceBusy(fence)) {
+                        waiting = false;
+                        break;
+                    }
+                }
             }
-
-            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
         }
 
         METAL_INTERNAL_PerformPendingDestroys(renderer);
@@ -4125,7 +4113,6 @@ static bool METAL_Submit(
 
         // Check if we can perform any cleanups
         for (Sint32 i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) {
-
             if (!METAL_INTERNAL_IsFenceBusy(renderer->submittedCommandBuffers[i]->fence)) {
                 METAL_INTERNAL_CleanCommandBuffer(
                     renderer,