mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
[Fix] (MG_Backend/DirectVulkan): fixing inter-frame swapchain sync?
This commit is contained in:
@@ -53,6 +53,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
for (Uint32 i = 0; i < frameCount; ++i) {
|
||||
DestroySyncObjectsForFrame(device, i);
|
||||
}
|
||||
DestroySwapchainSemaphores(device);
|
||||
if (device != VK_NULL_HANDLE && commandPool != VK_NULL_HANDLE && !m_frames.empty()) {
|
||||
vkFreeCommandBuffers(device, commandPool, frameCount, commandBuffers.data());
|
||||
}
|
||||
@@ -107,6 +108,36 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
frame.hasCommandBufferRecorded = true;
|
||||
}
|
||||
|
||||
VkResult FrameContext::InitializeSwapchainSemaphores(VkDevice device, Uint32 swapchainImageCount) {
|
||||
DestroySwapchainSemaphores(device);
|
||||
if (swapchainImageCount == 0) {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
m_swapchainImageRenderFinishedSemaphores.assign(swapchainImageCount, VK_NULL_HANDLE);
|
||||
VkSemaphoreCreateInfo semaphoreInfo{VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
|
||||
for (Uint32 imageIndex = 0; imageIndex < swapchainImageCount; ++imageIndex) {
|
||||
VkResult result =
|
||||
vkCreateSemaphore(device, &semaphoreInfo, nullptr, &m_swapchainImageRenderFinishedSemaphores[imageIndex]);
|
||||
if (result != VK_SUCCESS) {
|
||||
DestroySwapchainSemaphores(device);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void FrameContext::DestroySwapchainSemaphores(VkDevice device) {
|
||||
if (device != VK_NULL_HANDLE) {
|
||||
for (auto semaphore : m_swapchainImageRenderFinishedSemaphores) {
|
||||
if (semaphore != VK_NULL_HANDLE) {
|
||||
vkDestroySemaphore(device, semaphore, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_swapchainImageRenderFinishedSemaphores.clear();
|
||||
}
|
||||
|
||||
Bool FrameContext::TransitionToPresent(VkImage image, VkImageLayout oldLayout, VkImageLayout presentLayout) {
|
||||
auto& frame = GetCurrent();
|
||||
if (frame.hasCommandBufferRecorded || frame.isCommandRecording || oldLayout == presentLayout ||
|
||||
@@ -137,12 +168,14 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
return true;
|
||||
}
|
||||
|
||||
FrameContext::SubmitInfoPacket FrameContext::GetSubmitInfo(Bool shouldSubmitCommandBuffer) const {
|
||||
FrameContext::SubmitInfoPacket FrameContext::GetSubmitInfo(Bool shouldSubmitCommandBuffer,
|
||||
Uint32 swapchainImageIndex) const {
|
||||
const auto& frame = GetCurrent();
|
||||
MOBILEGL_ASSERT(!frame.isCommandRecording, "GetSubmitInfo called while command buffer recording is still active");
|
||||
AssertValidSwapchainImageIndex(swapchainImageIndex);
|
||||
SubmitInfoPacket packet{};
|
||||
packet.waitSemaphore = frame.imageAvailableSemaphore;
|
||||
packet.signalSemaphore = frame.renderFinishedSemaphore;
|
||||
packet.signalSemaphore = m_swapchainImageRenderFinishedSemaphores[swapchainImageIndex];
|
||||
packet.commandBuffer = frame.commandBuffer;
|
||||
|
||||
packet.submitInfo.waitSemaphoreCount = 1;
|
||||
@@ -156,9 +189,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
}
|
||||
|
||||
FrameContext::PresentInfoPacket FrameContext::GetPresentInfo(VkSwapchainKHR swapchain, const Uint32& imageIndex) const {
|
||||
const auto& frame = GetCurrent();
|
||||
AssertValidSwapchainImageIndex(imageIndex);
|
||||
PresentInfoPacket packet{};
|
||||
packet.waitSemaphore = frame.renderFinishedSemaphore;
|
||||
packet.waitSemaphore = m_swapchainImageRenderFinishedSemaphores[imageIndex];
|
||||
packet.swapchain = swapchain;
|
||||
packet.imageIndex = &imageIndex;
|
||||
|
||||
@@ -200,6 +233,11 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
MOBILEGL_ASSERT(frameIndex < m_frames.size(), "FrameContext index out of range");
|
||||
}
|
||||
|
||||
void FrameContext::AssertValidSwapchainImageIndex(Uint32 imageIndex) const {
|
||||
MOBILEGL_ASSERT(imageIndex < m_swapchainImageRenderFinishedSemaphores.size(),
|
||||
"FrameContext swapchain image index out of range");
|
||||
}
|
||||
|
||||
VkResult FrameContext::CreateSyncObjectsForFrame(VkDevice device, Uint32 frameIndex,
|
||||
const VkSemaphoreCreateInfo& semaphoreInfo,
|
||||
const VkFenceCreateInfo& fenceInfo) {
|
||||
@@ -213,18 +251,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = vkCreateSemaphore(device, &semaphoreInfo, nullptr, &frame.renderFinishedSemaphore);
|
||||
if (result != VK_SUCCESS) {
|
||||
vkDestroySemaphore(device, frame.imageAvailableSemaphore, nullptr);
|
||||
frame.imageAvailableSemaphore = VK_NULL_HANDLE;
|
||||
return result;
|
||||
}
|
||||
|
||||
result = vkCreateFence(device, &fenceInfo, nullptr, &frame.imageInFlightFence);
|
||||
if (result != VK_SUCCESS) {
|
||||
vkDestroySemaphore(device, frame.renderFinishedSemaphore, nullptr);
|
||||
vkDestroySemaphore(device, frame.imageAvailableSemaphore, nullptr);
|
||||
frame.renderFinishedSemaphore = VK_NULL_HANDLE;
|
||||
frame.imageAvailableSemaphore = VK_NULL_HANDLE;
|
||||
return result;
|
||||
}
|
||||
@@ -242,11 +271,6 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
}
|
||||
frame.imageInFlightFence = VK_NULL_HANDLE;
|
||||
|
||||
if (device != VK_NULL_HANDLE && frame.renderFinishedSemaphore != VK_NULL_HANDLE) {
|
||||
vkDestroySemaphore(device, frame.renderFinishedSemaphore, nullptr);
|
||||
}
|
||||
frame.renderFinishedSemaphore = VK_NULL_HANDLE;
|
||||
|
||||
if (device != VK_NULL_HANDLE && frame.imageAvailableSemaphore != VK_NULL_HANDLE) {
|
||||
vkDestroySemaphore(device, frame.imageAvailableSemaphore, nullptr);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
struct FrameData {
|
||||
VkCommandBuffer commandBuffer = VK_NULL_HANDLE;
|
||||
VkSemaphore imageAvailableSemaphore = VK_NULL_HANDLE;
|
||||
VkSemaphore renderFinishedSemaphore = VK_NULL_HANDLE;
|
||||
VkFence imageInFlightFence = VK_NULL_HANDLE;
|
||||
Bool isCommandRecording = false;
|
||||
Bool hasCommandBufferRecorded = false;
|
||||
@@ -49,9 +48,11 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
VkCommandBuffer& BeginCommandRecording(VkCommandBufferUsageFlags flags = 0,
|
||||
const VkCommandBufferInheritanceInfo* pInheritanceInfo = nullptr);
|
||||
void EndCommandRecording();
|
||||
VkResult InitializeSwapchainSemaphores(VkDevice device, Uint32 swapchainImageCount);
|
||||
void DestroySwapchainSemaphores(VkDevice device);
|
||||
Bool TransitionToPresent(VkImage image, VkImageLayout oldLayout,
|
||||
VkImageLayout presentLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||
SubmitInfoPacket GetSubmitInfo(Bool shouldSubmitCommandBuffer) const;
|
||||
SubmitInfoPacket GetSubmitInfo(Bool shouldSubmitCommandBuffer, Uint32 swapchainImageIndex) const;
|
||||
PresentInfoPacket GetPresentInfo(VkSwapchainKHR swapchain, const Uint32& imageIndex) const;
|
||||
VkResult WaitAndAcquireNextImage(VkDevice device, VkSwapchainKHR swapchain, Uint32& outImageIndex,
|
||||
Uint64 timeout = UINT64_MAX, VkFence acquireFence = VK_NULL_HANDLE);
|
||||
@@ -61,6 +62,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
|
||||
private:
|
||||
void AssertValidFrameIndex(Uint32 frameIndex) const;
|
||||
void AssertValidSwapchainImageIndex(Uint32 imageIndex) const;
|
||||
|
||||
VkResult CreateSyncObjectsForFrame(VkDevice device, Uint32 frameIndex,
|
||||
const VkSemaphoreCreateInfo& semaphoreInfo,
|
||||
@@ -68,6 +70,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
void DestroySyncObjectsForFrame(VkDevice device, Uint32 frameIndex);
|
||||
|
||||
Vector<FrameData> m_frames;
|
||||
Vector<VkSemaphore> m_swapchainImageRenderFinishedSemaphores;
|
||||
Uint32 currentFrameIndex = 0;
|
||||
};
|
||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||
|
||||
@@ -103,6 +103,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
void VulkanRenderer::CreateFrameContexts() {
|
||||
VK_VERIFY(m_frameContext.Initialize(m_device, m_commandPool, m_config.MaxFramesInFlight),
|
||||
"CreateFrameContexts");
|
||||
VK_VERIFY(m_frameContext.InitializeSwapchainSemaphores(
|
||||
m_device, static_cast<Uint32>(m_swapchainObject.GetImageCount())),
|
||||
"CreateFrameContexts, InitializeSwapchainSemaphores");
|
||||
MGLOG_I("CreateFrameContexts completed");
|
||||
}
|
||||
|
||||
@@ -688,7 +691,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
const Bool shouldSubmitCommandBuffer = frame.hasCommandBufferRecorded || needsLayoutTransitionForPresent;
|
||||
|
||||
// 1) Submit current frame work.
|
||||
auto submitPacket = m_frameContext.GetSubmitInfo(shouldSubmitCommandBuffer);
|
||||
auto submitPacket = m_frameContext.GetSubmitInfo(shouldSubmitCommandBuffer, m_imageIndexAcquired);
|
||||
VK_VERIFY(vkQueueSubmit(m_graphicsQueue, 1, &submitPacket.submitInfo, frame.imageInFlightFence));
|
||||
frame.isCommandRecording = false;
|
||||
frame.hasCommandBufferRecorded = false;
|
||||
@@ -1399,6 +1402,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
ShutdownSwapchain();
|
||||
|
||||
CreateSwapchain();
|
||||
VK_VERIFY(m_frameContext.InitializeSwapchainSemaphores(
|
||||
m_device, static_cast<Uint32>(m_swapchainObject.GetImageCount())),
|
||||
"RecreateSwapchain, InitializeSwapchainSemaphores");
|
||||
CreateDepthStencilResources();
|
||||
CreateDefaultRenderPass();
|
||||
CreateDefaultFramebuffers();
|
||||
|
||||
Reference in New Issue
Block a user