Metal: Pace frames via presented handler.

This commit is contained in:
Бранимир Караџић
2026-06-06 21:43:05 -07:00
parent 9dc9749b53
commit 60e357e69d
2 changed files with 35 additions and 1 deletions

View File

@@ -1728,11 +1728,14 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
if (!needPresent)
{
m_cmd.m_paceSemaphore.post();
return;
}
MTL::CommandBuffer* presentCommandBuffer = m_cmd.alloc();
bool pacePosted = false;
for (uint32_t ii = 0, num = m_numWindows; ii < num; ++ii)
{
FrameBufferMtl& frameBuffer = ii == 0 ? m_mainFrameBuffer : m_frameBuffers[m_windows[ii].idx];
@@ -1744,12 +1747,30 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
if (NULL != frameBuffer.m_swapChain->m_drawable)
{
presentCommandBuffer->presentDrawable( (MTL::Drawable*)frameBuffer.m_swapChain->m_drawable);
MTL::Drawable* drawable = (MTL::Drawable*)frameBuffer.m_swapChain->m_drawable;
presentCommandBuffer->presentDrawable(drawable);
if (!pacePosted)
{
pacePosted = true;
CommandQueueMtl* cmdQueue = &m_cmd;
drawable->addPresentedHandler(
MTL::DrawablePresentedHandlerFunction(
[cmdQueue](MTL::Drawable*) { cmdQueue->m_paceSemaphore.post(); }
)
);
}
MTL_RELEASE_I(frameBuffer.m_swapChain->m_drawable);
}
}
}
if (!pacePosted)
{
m_cmd.m_paceSemaphore.post();
}
m_cmd.kick(false, false);
}
@@ -4395,6 +4416,8 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
, BGFX_CONFIG_MAX_FRAME_LATENCY
);
m_framesSemaphore.post(m_maxFrameLatency);
const uint32_t paceLatency = bx::max<uint32_t>(m_maxFrameLatency - 1, 1);
m_paceSemaphore.post(paceLatency);
}
void CommandQueueMtl::shutdown()
@@ -4471,12 +4494,20 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
: m_maxFrameLatency
;
const uint32_t paceCount = bx::min<uint32_t>(count, bx::max<uint32_t>(m_maxFrameLatency - 1, 1) );
for (uint32_t ii = 0; ii < count; ++ii)
{
consume();
}
for (uint32_t ii = 0; ii < paceCount; ++ii)
{
m_paceSemaphore.wait();
}
m_framesSemaphore.post(count);
m_paceSemaphore.post(paceCount);
}
else
{
@@ -4711,6 +4742,8 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
void RendererContextMtl::submit(Frame* _render, const ClearQuad& _clearQuad, const MipGen& /*_mipGen*/, TextVideoMemBlitter& _textVideoMemBlitter)
{
m_cmd.m_paceSemaphore.wait();
m_cmd.finish(false);
if (NULL == m_commandBuffer)

View File

@@ -584,6 +584,7 @@ namespace bgfx { namespace mtl
void consume();
bx::Semaphore m_framesSemaphore;
bx::Semaphore m_paceSemaphore;
MTL::CommandQueue* m_commandQueue;
MTL::CommandBuffer* m_activeCommandBuffer;