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);