mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[Fix] (Magma): readback before the first acquire no longer submits a signaled slot fence
This commit is contained in:
@@ -4421,6 +4421,27 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A SLOT THAT HAS NOT ACQUIRED STILL HOLDS ITS FENCE SIGNALED. The slot fences are created
|
||||||
|
// signaled and only WaitAndAcquireNextImage resets them, so while the first acquire is
|
||||||
|
// deferred (no swapchain yet: a zero-area or hidden window, which is what an offscreen
|
||||||
|
// context created through a helper window is) the current slot's fence is still signaled
|
||||||
|
// here. Submitting it in that state is invalid (VUID-vkQueueSubmit-fence-00063), and in
|
||||||
|
// practice the wait below then returns at once - before the copy has run - so the readback
|
||||||
|
// hands back the buffer's initial zeros. The late signal from that submission could also
|
||||||
|
// land after the reset below, leaving the NEXT readback to submit a signaled fence again.
|
||||||
|
//
|
||||||
|
// Such a fence is unsignaled before the submit, and handed back signaled afterwards: the
|
||||||
|
// deferred acquire (Present) waits on it with no submission of its own, and a fence this
|
||||||
|
// readback reset and left unsignaled would never signal for that wait.
|
||||||
|
const Bool slotFenceIdle = vkGetFenceStatus(m_device, frame.imageInFlightFence) == VK_SUCCESS;
|
||||||
|
if (slotFenceIdle) {
|
||||||
|
const VkResult resetResult = vkResetFences(m_device, 1, &frame.imageInFlightFence);
|
||||||
|
if (resetResult != VK_SUCCESS) {
|
||||||
|
MGLOG_E_ONCE("DirectVulkan readback: vkResetFences on the idle slot fence returned %d", resetResult);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!SubmitPendingCommandBuffer(frame, frame.imageInFlightFence, /*pooledFence=*/false)) {
|
if (!SubmitPendingCommandBuffer(frame, frame.imageInFlightFence, /*pooledFence=*/false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -4468,10 +4489,12 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
OnSubmitsCompletedUpTo(frame.lastSubmitIndex);
|
OnSubmitsCompletedUpTo(frame.lastSubmitIndex);
|
||||||
result = vkResetFences(m_device, 1, &frame.imageInFlightFence);
|
if (!slotFenceIdle) {
|
||||||
if (result != VK_SUCCESS) {
|
result = vkResetFences(m_device, 1, &frame.imageInFlightFence);
|
||||||
MGLOG_E_ONCE("DirectVulkan readback: vkResetFences returned %d", result);
|
if (result != VK_SUCCESS) {
|
||||||
return false;
|
MGLOG_E_ONCE("DirectVulkan readback: vkResetFences returned %d", result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
frame.hasCommandBufferRecorded = false;
|
frame.hasCommandBufferRecorded = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user