diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp index 4c036688..c2d4cb77 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp @@ -183,7 +183,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { CreateFrameResources(); } - // Wait fence & Acquire image & Record commands & Submit & Present + // Wait fence & Acquire image & Record commands & Submit void VulkanRenderer::RenderFrame() { if (!Ctx) MOBILEGL_ASSERT(false, "Renderer not initialized"); FrameContext& frame = *Frames[CurrentFrame]; @@ -222,9 +222,26 @@ namespace MobileGL::MG_Backend::DirectVulkan { si.pSignalSemaphores = signalSemaphores; MOBILEGL_ASSERT_VK(vkQueueSubmit(Ctx->GetGraphicsQueue(), 1, &si, frame.InFlightFence), "vkQueueSubmit"); + } + + void VulkanRenderer::Present() { + if (!Ctx) MOBILEGL_ASSERT(false, "Renderer not initialized"); + FrameContext& frame = *Frames[CurrentFrame]; + + // Acquire image + uint32_t imageIndex = 0; + VkResult res = vkAcquireNextImageKHR(Ctx->GetDevice(), Swapchain->GetSwapchain(), UINT64_MAX, + frame.ImageAvailable, VK_NULL_HANDLE, &imageIndex); + if (res == VK_ERROR_OUT_OF_DATE_KHR) { + MGLOG_D("vkAcquireNextImageKHR: OUT_OF_DATE -> recreate"); + RecreateSwapchainIfNeeded(); + return; + } + MOBILEGL_ASSERT_VK(res, "vkAcquireNextImageKHR"); // Present VkPresentInfoKHR pi{VK_STRUCTURE_TYPE_PRESENT_INFO_KHR}; + VkSemaphore signalSemaphores[] = {frame.RenderFinished}; pi.waitSemaphoreCount = 1; pi.pWaitSemaphores = signalSemaphores; VkSwapchainKHR scs[] = {Swapchain->GetSwapchain()}; diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h index 5c9cd75d..bb928139 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h @@ -31,6 +31,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { void Shutdown(); void RenderFrame(); + void Present(); void RegisterRenderCallback(const std::string& name, RenderCallback cb); void UnregisterRenderCallback(const std::string& name); diff --git a/MobileGL/MG_Impl/EGLImpl/EGLForVulkan/EGLForVulkan.cpp b/MobileGL/MG_Impl/EGLImpl/EGLForVulkan/EGLForVulkan.cpp index f221cf1d..17759b3e 100644 --- a/MobileGL/MG_Impl/EGLImpl/EGLForVulkan/EGLForVulkan.cpp +++ b/MobileGL/MG_Impl/EGLImpl/EGLForVulkan/EGLForVulkan.cpp @@ -102,6 +102,11 @@ namespace MobileGL { } EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface draw) { + if (!MG_Backend::DirectVulkan::pVulkanRenderer) { + MGLOG_E("EGLForVulkan::SwapBuffers called but VulkanRenderer is null"); + return EGL_FALSE; + } + MG_Backend::DirectVulkan::pVulkanRenderer->Present(); return EGL_TRUE; }