SDL: testffmpeg_vulkan: fixed usage of timeline semaphores

From 6ce3d843fc4eef3374878c094ac5d33ce415c9a6 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 10 Jul 2026 09:26:36 -0700
Subject: [PATCH] testffmpeg_vulkan: fixed usage of timeline semaphores

---
 src/render/vulkan/SDL_render_vulkan.c |  3 ++
 test/testffmpeg.c                     | 13 +++---
 test/testffmpeg_vulkan.c              | 64 ---------------------------
 3 files changed, 10 insertions(+), 70 deletions(-)

diff --git a/src/render/vulkan/SDL_render_vulkan.c b/src/render/vulkan/SDL_render_vulkan.c
index de93c3a2c7dc1..9312401a0cada 100644
--- a/src/render/vulkan/SDL_render_vulkan.c
+++ b/src/render/vulkan/SDL_render_vulkan.c
@@ -4070,6 +4070,9 @@ static void VULKAN_InvalidateCachedState(SDL_Renderer *renderer)
     VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->internal;
     rendererData->currentPipelineState = NULL;
     rendererData->cliprectDirty = true;
+
+    // Make sure pending drawing is submitted to the GPU
+    VULKAN_IssueBatch(rendererData);
 }
 
 static bool VULKAN_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
diff --git a/test/testffmpeg.c b/test/testffmpeg.c
index a68fc09916026..22f5879a5233a 100644
--- a/test/testffmpeg.c
+++ b/test/testffmpeg.c
@@ -1087,6 +1087,10 @@ static void DisplayVideoTexture(AVFrame *frame)
         return;
     }
 
+    if (BeginFrameRendering(frame) < 0) {
+        return;
+    }
+
     SDL_FRect src;
     src.x = 0.0f;
     src.y = 0.0f;
@@ -1097,6 +1101,9 @@ static void DisplayVideoTexture(AVFrame *frame)
     } else {
         SDL_RenderTexture(renderer, video_texture, &src, NULL);
     }
+    SDL_FlushRenderer(renderer);
+
+    FinishFrameRendering(frame);
 }
 
 static void DisplayVideoFrame(AVFrame *frame)
@@ -1115,10 +1122,6 @@ static void HandleVideoFrame(AVFrame *frame, double pts)
         SDL_DelayPrecise((Uint64)((pts - now) * SDL_NS_PER_SECOND));
     }
 
-    if (BeginFrameRendering(frame) < 0) {
-        return;
-    }
-
     SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
     SDL_RenderClear(renderer);
 
@@ -1128,8 +1131,6 @@ static void HandleVideoFrame(AVFrame *frame, double pts)
     MoveSprite();
 
     SDL_RenderPresent(renderer);
-
-    FinishFrameRendering(frame);
 }
 
 static AVCodecContext *OpenAudioStream(AVFormatContext *ic, int stream, const AVCodec *codec)
diff --git a/test/testffmpeg_vulkan.c b/test/testffmpeg_vulkan.c
index c6f34c251655a..77ef13ba609c3 100644
--- a/test/testffmpeg_vulkan.c
+++ b/test/testffmpeg_vulkan.c
@@ -78,10 +78,6 @@ struct VulkanVideoContext
     VkCommandBuffer *commandBuffers;
     uint32_t commandBufferCount;
     uint32_t commandBufferIndex;
-    VkSemaphore *waitSemaphores;
-    uint32_t waitSemaphoreCount;
-    VkSemaphore *signalSemaphores;
-    uint32_t signalSemaphoreCount;
 
     const char **instanceExtensions;
     int instanceExtensionsCount;
@@ -723,44 +719,6 @@ static int CreateCommandBuffers(VulkanVideoContext *context, SDL_Renderer *rende
 {
     uint32_t commandBufferCount = (uint32_t)SDL_GetNumberProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_VULKAN_SWAPCHAIN_IMAGE_COUNT_NUMBER, 1);
 
-    if (commandBufferCount > context->waitSemaphoreCount) {
-        VkSemaphore *semaphores = (VkSemaphore *)SDL_realloc(context->waitSemaphores, commandBufferCount * sizeof(*semaphores));
-        if (!semaphores) {
-            return -1;
-        }
-        context->waitSemaphores = semaphores;
-
-        VkSemaphoreCreateInfo semaphoreCreateInfo = { 0 };
-        semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
-        while (context->waitSemaphoreCount < commandBufferCount) {
-            VkResult result = context->vkCreateSemaphore(context->device, &semaphoreCreateInfo, NULL, &context->waitSemaphores[context->waitSemaphoreCount]);
-            if (result != VK_SUCCESS) {
-                SDL_SetError("vkCreateSemaphore(): %s", getVulkanResultString(result));
-                return -1;
-            }
-            ++context->waitSemaphoreCount;
-        }
-    }
-
-    if (commandBufferCount > context->signalSemaphoreCount) {
-        VkSemaphore *semaphores = (VkSemaphore *)SDL_realloc(context->signalSemaphores, commandBufferCount * sizeof(*semaphores));
-        if (!semaphores) {
-            return -1;
-        }
-        context->signalSemaphores = semaphores;
-
-        VkSemaphoreCreateInfo semaphoreCreateInfo = { 0 };
-        semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
-        while (context->signalSemaphoreCount < commandBufferCount) {
-            VkResult result = context->vkCreateSemaphore(context->device, &semaphoreCreateInfo, NULL, &context->signalSemaphores[context->signalSemaphoreCount]);
-            if (result != VK_SUCCESS) {
-                SDL_SetError("vkCreateSemaphore(): %s", getVulkanResultString(result));
-                return -1;
-            }
-            ++context->signalSemaphoreCount;
-        }
-    }
-
     if (commandBufferCount > context->commandBufferCount) {
         uint32_t needed = (commandBufferCount - context->commandBufferCount);
         VkCommandBuffer *commandBuffers = (VkCommandBuffer *)SDL_realloc(context->commandBuffers, commandBufferCount * sizeof(*commandBuffers));
@@ -808,8 +766,6 @@ int BeginVulkanFrameRendering(VulkanVideoContext *context, AVFrame *frame, SDL_R
     submitInfo.waitSemaphoreCount = 1;
     submitInfo.pWaitSemaphores = pVkFrame->sem;
     submitInfo.pWaitDstStageMask = &pipelineStageMask;
-    submitInfo.signalSemaphoreCount = 1;
-    submitInfo.pSignalSemaphores = &context->waitSemaphores[context->commandBufferIndex];
     submitInfo.pNext = &timeline;
 
     if (pVkFrame->layout[0] != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
@@ -858,8 +814,6 @@ int BeginVulkanFrameRendering(VulkanVideoContext *context, AVFrame *frame, SDL_R
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION , "vkQueueSubmit(): %s", getVulkanResultString(result));
     }
 
-    SDL_AddVulkanRenderSemaphores(renderer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (Sint64)context->waitSemaphores[context->commandBufferIndex], (Sint64)context->signalSemaphores[context->commandBufferIndex]);
-
     return 0;
 }
 
@@ -877,12 +831,8 @@ int FinishVulkanFrameRendering(VulkanVideoContext *context, AVFrame *frame, SDL_
     timeline.signalSemaphoreValueCount = 1;
     timeline.pSignalSemaphoreValues = pVkFrame->sem_value;
 
-    VkPipelineStageFlags pipelineStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
     VkSubmitInfo submitInfo = { 0 };
     submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-    submitInfo.waitSemaphoreCount = 1;
-    submitInfo.pWaitSemaphores = &context->signalSemaphores[context->commandBufferIndex];
-    submitInfo.pWaitDstStageMask = &pipelineStageMask;
     submitInfo.signalSemaphoreCount = 1;
     submitInfo.pSignalSemaphores = pVkFrame->sem;
     submitInfo.pNext = &timeline;
@@ -940,20 +890,6 @@ void DestroyVulkanVideoContext(VulkanVideoContext *context)
         }
         SDL_free(context->instanceExtensions);
         SDL_free(context->deviceExtensions);
-        if (context->waitSemaphores) {
-            for (uint32_t i = 0; i < context->waitSemaphoreCount; ++i) {
-                context->vkDestroySemaphore(context->device, context->waitSemaphores[i], NULL);
-            }
-            SDL_free(context->waitSemaphores);
-            context->waitSemaphores = NULL;
-        }
-        if (context->signalSemaphores) {
-            for (uint32_t i = 0; i < context->signalSemaphoreCount; ++i) {
-                context->vkDestroySemaphore(context->device, context->signalSemaphores[i], NULL);
-            }
-            SDL_free(context->signalSemaphores);
-            context->signalSemaphores = NULL;
-        }
         if (context->commandBuffers) {
             context->vkFreeCommandBuffers(context->device, context->commandPool, context->commandBufferCount, context->commandBuffers);
             SDL_free(context->commandBuffers);