From 4f101d98be95071d39433dfe11ca9707df74e8c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Fri, 19 Jun 2026 12:39:42 -0700 Subject: [PATCH] Don't present BGFX_FRAME_FLUSH frames. Fixed D3D12/VK flush sync. (#3771) --- src/bgfx.cpp | 4 +++- src/bgfx_p.h | 2 ++ src/renderer_d3d12.cpp | 1 + src/renderer_vk.cpp | 18 +++++++++++++----- src/renderer_vk.h | 1 + 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/bgfx.cpp b/src/bgfx.cpp index dc45a4874..93e9606aa 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -2778,7 +2778,7 @@ namespace bgfx if (!m_flipAfterRender) { - if (!m_render->m_flush) + if (!m_flushPrevFrame) { BGFX_PROFILER_SCOPE("bgfx/flip", kColorSubmit); flip(); @@ -2825,6 +2825,8 @@ namespace bgfx flip(); } } + + m_flushPrevFrame = m_render->m_flush; } else { diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 03b6ae3e1..4fe7413ce 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -3928,6 +3928,7 @@ namespace bgfx , m_exit(false) , m_flipAfterRender(false) , m_singleThreaded(false) + , m_flushPrevFrame(false) { } @@ -6209,6 +6210,7 @@ namespace bgfx bool m_flipAfterRender; bool m_singleThreaded; bool m_flipped; + bool m_flushPrevFrame; typedef UpdateBatchT<256> TextureUpdateBatch; BX_ALIGN_DECL_CACHE_LINE(TextureUpdateBatch m_textureUpdateBatch); diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 763e1f115..4de3c50cb 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -7248,6 +7248,7 @@ namespace bgfx { namespace d3d12 D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle; ScratchBufferD3D12& scratchBuffer = m_scratchBuffer[m_backBufferColorIdx]; + m_cmd.finish(m_backBufferColorFence[m_backBufferColorIdx]); scratchBuffer.reset(gpuHandle); m_uniformScratchBuffer.begin(); diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index 0353b6f70..3b9129873 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -8384,6 +8384,9 @@ VK_DESTROY m_lastImageRenderedSemaphore = m_renderDoneSemaphore[m_backBufferColorIdx]; m_needPresent = true; + + s_renderVK->m_cmd.addWaitSemaphore(m_lastImageAcquiredSemaphore, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); + m_lastImageAcquiredSemaphore = VK_NULL_HANDLE; } return true; @@ -8903,15 +8906,20 @@ VK_DESTROY return result; } + void CommandQueueVK::addWaitSemaphore(VkSemaphore _semaphore, VkPipelineStageFlags _waitStage) + { + BX_ASSERT(m_numWaitSemaphores < BX_COUNTOF(m_waitSemaphores), "Too many wait semaphores."); + + m_waitSemaphores[m_numWaitSemaphores] = _semaphore; + m_waitSemaphoreStages[m_numWaitSemaphores] = _waitStage; + m_numWaitSemaphores++; + } + void CommandQueueVK::addSwapChain(SwapChainVK& _swapChain) { if (VK_NULL_HANDLE != _swapChain.m_lastImageAcquiredSemaphore) { - BX_ASSERT(m_numWaitSemaphores < BX_COUNTOF(m_waitSemaphores), "Too many wait semaphores."); - - m_waitSemaphores[m_numWaitSemaphores] = _swapChain.m_lastImageAcquiredSemaphore; - m_waitSemaphoreStages[m_numWaitSemaphores] = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; - m_numWaitSemaphores++; + addWaitSemaphore(_swapChain.m_lastImageAcquiredSemaphore, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); _swapChain.m_lastImageAcquiredSemaphore = VK_NULL_HANDLE; } diff --git a/src/renderer_vk.h b/src/renderer_vk.h index 646e75a65..0a0e80c44 100644 --- a/src/renderer_vk.h +++ b/src/renderer_vk.h @@ -912,6 +912,7 @@ VK_DESTROY_FUNC(DescriptorSet); void shutdown(); VkResult alloc(VkCommandBuffer* _outCommandBuffer); + void addWaitSemaphore(VkSemaphore _semaphore, VkPipelineStageFlags _waitStage); void addSwapChain(SwapChainVK& _swapChain); void kick(bool _wait = false); void finish(bool _finishAll = false);