From e39af3b9408801fcfd4f21760c368598f8e57b5d Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Sun, 8 Feb 2026 15:39:26 +0800 Subject: [PATCH] [Fix|Refactor] (MG_Backend/DirectVulkan): Fix incorrect vkAcquireNextImageKHR call. MOBILEGL_ASSERT_VK -> VK_VERIFY. --- .../DirectVulkan/Renderer/FrameContext.cpp | 13 +++-- .../DirectVulkan/Renderer/FrameContext.h | 1 + .../DirectVulkan/Renderer/PipelineManager.cpp | 11 ++-- .../Renderer/SwapchainManager.cpp | 19 ++++--- .../DirectVulkan/Renderer/SwapchainManager.h | 3 ++ .../DirectVulkan/Renderer/VulkanContext.cpp | 19 ++++--- .../DirectVulkan/Renderer/VulkanContext.h | 8 ++- .../DirectVulkan/Renderer/VulkanRenderer.cpp | 51 +++++++++---------- .../DirectVulkan/Renderer/VulkanRenderer.h | 2 +- 9 files changed, 66 insertions(+), 61 deletions(-) diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.cpp index b96b07fd..802c5ddf 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.cpp @@ -18,20 +18,19 @@ namespace MobileGL::MG_Backend::DirectVulkan { abci.commandPool = pool; abci.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; abci.commandBufferCount = 1; - MOBILEGL_ASSERT_VK(vkAllocateCommandBuffers(ctx.GetDevice(), &abci, &CommandBuffer), - "vkAllocateCommandBuffers"); + VK_VERIFY(vkAllocateCommandBuffers(ctx.GetDevice(), &abci, &CommandBuffer), "vkAllocateCommandBuffers"); // semaphores VkSemaphoreCreateInfo sci{VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO}; - MOBILEGL_ASSERT_VK(vkCreateSemaphore(ctx.GetDevice(), &sci, nullptr, &ImageAvailable), - "vkCreateSemaphore ImageAvailable"); - MOBILEGL_ASSERT_VK(vkCreateSemaphore(ctx.GetDevice(), &sci, nullptr, &RenderFinished), - "vkCreateSemaphore RenderFinished"); + VK_VERIFY(vkCreateSemaphore(ctx.GetDevice(), &sci, nullptr, &ImageAvailable), + "vkCreateSemaphore ImageAvailable"); + VK_VERIFY(vkCreateSemaphore(ctx.GetDevice(), &sci, nullptr, &RenderFinished), + "vkCreateSemaphore RenderFinished"); // fence (start signaled) VkFenceCreateInfo fci{VK_STRUCTURE_TYPE_FENCE_CREATE_INFO}; fci.flags = VK_FENCE_CREATE_SIGNALED_BIT; - MOBILEGL_ASSERT_VK(vkCreateFence(ctx.GetDevice(), &fci, nullptr, &InFlightFence), "vkCreateFence"); + VK_VERIFY(vkCreateFence(ctx.GetDevice(), &fci, nullptr, &InFlightFence), "vkCreateFence"); } void FrameContext::Cleanup(VulkanContext& ctx) { diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.h index 7b581cf5..39a12136 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.h @@ -23,5 +23,6 @@ namespace MobileGL::MG_Backend::DirectVulkan { VkSemaphore ImageAvailable = VK_NULL_HANDLE; VkSemaphore RenderFinished = VK_NULL_HANDLE; VkFence InFlightFence = VK_NULL_HANDLE; + Uint32 CurrentImageIndex = 0; }; } // namespace MobileGL::MG_Backend::DirectVulkan \ No newline at end of file diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/PipelineManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/PipelineManager.cpp index 12804e1e..13c784b8 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/PipelineManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/PipelineManager.cpp @@ -18,8 +18,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { void PipelineManager::EnsurePipelineLayout() { if (PipelineLayout != VK_NULL_HANDLE) return; VkPipelineLayoutCreateInfo plci{VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO}; - MOBILEGL_ASSERT_VK(vkCreatePipelineLayout(Ctx.GetDevice(), &plci, nullptr, &PipelineLayout), - "vkCreatePipelineLayout"); + VK_VERIFY(vkCreatePipelineLayout(Ctx.GetDevice(), &plci, nullptr, &PipelineLayout), "vkCreatePipelineLayout"); } VkPipeline PipelineManager::CreateGraphicsPipelineFromSpv(const std::string& key, @@ -36,12 +35,12 @@ namespace MobileGL::MG_Backend::DirectVulkan { smci.codeSize = vsSpv.size() * sizeof(uint32_t); smci.pCode = vsSpv.data(); VkShaderModule vs; - MOBILEGL_ASSERT_VK(vkCreateShaderModule(Ctx.GetDevice(), &smci, nullptr, &vs), "vkCreateShaderModule VS"); + VK_VERIFY(vkCreateShaderModule(Ctx.GetDevice(), &smci, nullptr, &vs), "vkCreateShaderModule VS"); smci.codeSize = fsSpv.size() * sizeof(uint32_t); smci.pCode = fsSpv.data(); VkShaderModule fs; - MOBILEGL_ASSERT_VK(vkCreateShaderModule(Ctx.GetDevice(), &smci, nullptr, &fs), "vkCreateShaderModule FS"); + VK_VERIFY(vkCreateShaderModule(Ctx.GetDevice(), &smci, nullptr, &fs), "vkCreateShaderModule FS"); VkPipelineShaderStageCreateInfo stages[2]{}; stages[0] = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO}; @@ -105,8 +104,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { gpi.subpass = 0; VkPipeline pipeline; - MOBILEGL_ASSERT_VK(vkCreateGraphicsPipelines(Ctx.GetDevice(), VK_NULL_HANDLE, 1, &gpi, nullptr, &pipeline), - "vkCreateGraphicsPipelines"); + VK_VERIFY(vkCreateGraphicsPipelines(Ctx.GetDevice(), VK_NULL_HANDLE, 1, &gpi, nullptr, &pipeline), + "vkCreateGraphicsPipelines"); vkDestroyShaderModule(Ctx.GetDevice(), vs, nullptr); vkDestroyShaderModule(Ctx.GetDevice(), fs, nullptr); diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainManager.cpp index 656936bd..ede0e280 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainManager.cpp @@ -18,6 +18,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { void SwapchainManager::Initialize() { CreateSwapchainInternal(); CreateImageViews(); + ImagesInFlight.resize(Images.size(), VK_NULL_HANDLE); } void SwapchainManager::Recreate() { @@ -28,6 +29,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { } CreateSwapchainInternal(); CreateImageViews(); + ImagesInFlight.resize(Images.size(), VK_NULL_HANDLE); + Framebuffers.clear(); MGLOG_D("Swapchain recreated"); } @@ -72,8 +75,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { void SwapchainManager::CreateSwapchainInternal() { VkSurfaceCapabilitiesKHR caps; - MOBILEGL_ASSERT_VK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Ctx.GetPhysicalDevice(), Ctx.GetSurface(), &caps), - "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"); + VK_VERIFY(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Ctx.GetPhysicalDevice(), Ctx.GetSurface(), &caps), + "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"); Extent = caps.currentExtent; ImageFormat = VK_FORMAT_R8G8B8A8_UNORM; @@ -91,14 +94,14 @@ namespace MobileGL::MG_Backend::DirectVulkan { sci.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; sci.presentMode = QueryPossiblePresentMode(); - MOBILEGL_ASSERT_VK(vkCreateSwapchainKHR(Ctx.GetDevice(), &sci, nullptr, &Swapchain), "vkCreateSwapchainKHR"); + VK_VERIFY(vkCreateSwapchainKHR(Ctx.GetDevice(), &sci, nullptr, &Swapchain), "vkCreateSwapchainKHR"); uint32_t count = 0; - MOBILEGL_ASSERT_VK(vkGetSwapchainImagesKHR(Ctx.GetDevice(), Swapchain, &count, nullptr), - "vkGetSwapchainImagesKHR count"); + VK_VERIFY(vkGetSwapchainImagesKHR(Ctx.GetDevice(), Swapchain, &count, nullptr), + "vkGetSwapchainImagesKHR count"); Images.resize(count); - MOBILEGL_ASSERT_VK(vkGetSwapchainImagesKHR(Ctx.GetDevice(), Swapchain, &count, Images.data()), - "vkGetSwapchainImagesKHR images"); + VK_VERIFY(vkGetSwapchainImagesKHR(Ctx.GetDevice(), Swapchain, &count, Images.data()), + "vkGetSwapchainImagesKHR images"); MGLOG_D("Swapchain created (%u images)", count); } @@ -117,7 +120,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { ivci.subresourceRange.levelCount = 1; ivci.subresourceRange.baseArrayLayer = 0; ivci.subresourceRange.layerCount = 1; - MOBILEGL_ASSERT_VK(vkCreateImageView(Ctx.GetDevice(), &ivci, nullptr, &ImageViews[i]), "vkCreateImageView"); + VK_VERIFY(vkCreateImageView(Ctx.GetDevice(), &ivci, nullptr, &ImageViews[i]), "vkCreateImageView"); } MGLOG_D("ImageViews created"); } diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainManager.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainManager.h index b0af3fd1..9a46b7f1 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainManager.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainManager.h @@ -26,6 +26,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { VkExtent2D GetExtent() const { return Extent; } const std::vector& GetImageViews() const { return ImageViews; } const std::vector& GetFramebuffers() const { return Framebuffers; } + const std::vector& GetImages() const { return Images; } + std::vector& GetImagesInFlight() { return ImagesInFlight; } void SetFramebuffers(std::vector&& fbs); @@ -36,6 +38,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { VkExtent2D Extent{0, 0}; std::vector Images; std::vector ImageViews; + std::vector ImagesInFlight; std::vector Framebuffers; void CreateSwapchainInternal(); diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanContext.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanContext.cpp index 5cd454d4..a80bc516 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanContext.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanContext.cpp @@ -59,20 +59,19 @@ namespace MobileGL::MG_Backend::DirectVulkan { ci.enabledExtensionCount = 2; ci.ppEnabledExtensionNames = exts; - MOBILEGL_ASSERT_VK(vkCreateInstance(&ci, nullptr, &Instance), "vkCreateInstance failed"); + VK_VERIFY(vkCreateInstance(&ci, nullptr, &Instance), "vkCreateInstance failed"); } void VulkanContext::CreateSurface(NativeWindowType window) { #if __ANDROID__ - if (!Instance) MOBILEGL_ASSERT(false, "Instance not created"); + if (!Instance) throw RuntimeError("Instance not created"); auto* nativeWindow = static_cast(window); - if (!nativeWindow) MOBILEGL_ASSERT(false, "ANativeWindowType is null"); + if (!nativeWindow) throw RuntimeError("ANativeWindowType is null"); VkAndroidSurfaceCreateInfoKHR sci{VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR}; sci.window = nativeWindow; - MOBILEGL_ASSERT_VK(vkCreateAndroidSurfaceKHR(Instance, &sci, nullptr, &Surface), - "vkCreateAndroidSurfaceKHR failed"); + VK_VERIFY(vkCreateAndroidSurfaceKHR(Instance, &sci, nullptr, &Surface), "vkCreateAndroidSurfaceKHR failed"); #else MGLOG_W("VulkanRenderer::Initialize called on a platform which is not supported yet"); // TODO: support more // platforms @@ -81,10 +80,10 @@ namespace MobileGL::MG_Backend::DirectVulkan { void VulkanContext::PickPhysicalDevice() { uint32_t count = 0; - MOBILEGL_ASSERT_VK(vkEnumeratePhysicalDevices(Instance, &count, nullptr), "vkEnumeratePhysicalDevices count"); - if (count == 0) MOBILEGL_ASSERT(false, "No physical devices"); + VK_VERIFY(vkEnumeratePhysicalDevices(Instance, &count, nullptr), "vkEnumeratePhysicalDevices count"); + if (count == 0) throw RuntimeError("No physical devices"); std::vector devs(count); - MOBILEGL_ASSERT_VK(vkEnumeratePhysicalDevices(Instance, &count, devs.data()), "vkEnumeratePhysicalDevices"); + VK_VERIFY(vkEnumeratePhysicalDevices(Instance, &count, devs.data()), "vkEnumeratePhysicalDevices"); for (auto d : devs) { uint32_t qcount = 0; @@ -102,7 +101,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } } } - MOBILEGL_ASSERT(false, "No suitable physical device"); + throw RuntimeError("No suitable physical device"); } void VulkanContext::CreateLogicalDevice() { @@ -120,7 +119,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { dci.enabledExtensionCount = 1; dci.ppEnabledExtensionNames = devExts; - MOBILEGL_ASSERT_VK(vkCreateDevice(PhysicalDevice, &dci, nullptr, &Device), "vkCreateDevice failed"); + VK_VERIFY(vkCreateDevice(PhysicalDevice, &dci, nullptr, &Device), "vkCreateDevice failed"); vkGetDeviceQueue(Device, GraphicsQueueFamily, 0, &GraphicsQueue); MGLOG_D("Logical device created"); } diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanContext.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanContext.h index 149b7780..fc9283d2 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanContext.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanContext.h @@ -9,7 +9,13 @@ #pragma once #include -#define MOBILEGL_ASSERT_VK(exp, ...) MOBILEGL_ASSERT((exp) == VK_SUCCESS, __VA_ARGS__) +#define VK_VERIFY(expr, ...) \ + do { \ + VkResult _vk_verify_result = (expr); \ + if (_vk_verify_result != VK_SUCCESS) { \ + MGLOG_E("Vulkan error %d at %s:%d" __VA_OPT__(" - ") __VA_ARGS__, _vk_verify_result, __FILE__, __LINE__); \ + } \ + } while (0) namespace MobileGL::MG_Backend::DirectVulkan { class VulkanContext { diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp index c2d4cb77..376c23cb 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp @@ -82,7 +82,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { rpci.subpassCount = 1; rpci.pSubpasses = ⊂ - MOBILEGL_ASSERT_VK(vkCreateRenderPass(Ctx->GetDevice(), &rpci, nullptr, &RenderPass), "vkCreateRenderPass"); + VK_VERIFY(vkCreateRenderPass(Ctx->GetDevice(), &rpci, nullptr, &RenderPass), "vkCreateRenderPass"); // Create framebuffers now (use swapchain imageviews) const auto& imageViews = Swapchain->GetImageViews(); @@ -98,7 +98,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { fbci.height = Swapchain->GetExtent().height; fbci.layers = 1; VkFramebuffer fb; - MOBILEGL_ASSERT_VK(vkCreateFramebuffer(Ctx->GetDevice(), &fbci, nullptr, &fb), "vkCreateFramebuffer"); + VK_VERIFY(vkCreateFramebuffer(Ctx->GetDevice(), &fbci, nullptr, &fb), "vkCreateFramebuffer"); fbs.push_back(fb); } Swapchain->SetFramebuffers(std::move(fbs)); @@ -116,7 +116,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { VkCommandPoolCreateInfo cpci{VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO}; cpci.queueFamilyIndex = Ctx->GetGraphicsQueueFamily(); cpci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - MOBILEGL_ASSERT_VK(vkCreateCommandPool(Ctx->GetDevice(), &cpci, nullptr, &CommandPool), "vkCreateCommandPool"); + VK_VERIFY(vkCreateCommandPool(Ctx->GetDevice(), &cpci, nullptr, &CommandPool), "vkCreateCommandPool"); } void VulkanRenderer::DestroyCommandPool() { @@ -128,7 +128,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { void VulkanRenderer::CreateFrameResources() { uint32_t imageCount = static_cast(Swapchain->GetImageViews().size()); - if (imageCount == 0) MOBILEGL_ASSERT(false, "Swapchain has zero images"); + if (imageCount == 0) throw RuntimeError("Swapchain has zero images"); uint32_t frames = std::min(Config.MaxFramesInFlight, imageCount); Frames.clear(); for (uint32_t i = 0; i < frames; ++i) { @@ -150,7 +150,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { void VulkanRenderer::RecordFrameCommandBuffer(FrameContext& frame, uint32_t imageIndex) { // Begin VkCommandBufferBeginInfo bi{VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO}; - MOBILEGL_ASSERT_VK(vkBeginCommandBuffer(frame.CommandBuffer, &bi), "vkBeginCommandBuffer"); + VK_VERIFY(vkBeginCommandBuffer(frame.CommandBuffer, &bi), "vkBeginCommandBuffer"); VkClearValue clear{}; clear.color = {{0.0f, 0.0f, 0.0f, 1.0f}}; @@ -171,7 +171,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } vkCmdEndRenderPass(frame.CommandBuffer); - MOBILEGL_ASSERT_VK(vkEndCommandBuffer(frame.CommandBuffer), "vkEndCommandBuffer"); + VK_VERIFY(vkEndCommandBuffer(frame.CommandBuffer), "vkEndCommandBuffer"); } void VulkanRenderer::RecreateSwapchainIfNeeded() { @@ -185,28 +185,33 @@ namespace MobileGL::MG_Backend::DirectVulkan { // Wait fence & Acquire image & Record commands & Submit void VulkanRenderer::RenderFrame() { - if (!Ctx) MOBILEGL_ASSERT(false, "Renderer not initialized"); + if (!Ctx) throw RuntimeError("Renderer not initialized"); FrameContext& frame = *Frames[CurrentFrame]; // Wait fence and reset - MOBILEGL_ASSERT_VK(vkWaitForFences(Ctx->GetDevice(), 1, &frame.InFlightFence, VK_TRUE, UINT64_MAX), - "vkWaitForFences"); - MOBILEGL_ASSERT_VK(vkResetFences(Ctx->GetDevice(), 1, &frame.InFlightFence), "vkResetFences"); + VK_VERIFY(vkWaitForFences(Ctx->GetDevice(), 1, &frame.InFlightFence, VK_TRUE, UINT64_MAX), "vkWaitForFences"); + VK_VERIFY(vkResetFences(Ctx->GetDevice(), 1, &frame.InFlightFence), "vkResetFences"); // Acquire image - uint32_t imageIndex = 0; + auto& imagesInFlight = Swapchain->GetImagesInFlight(); + Uint32 imageIndex = 0; VkResult res = vkAcquireNextImageKHR(Ctx->GetDevice(), Swapchain->GetSwapchain(), UINT64_MAX, frame.ImageAvailable, VK_NULL_HANDLE, &imageIndex); + if (imagesInFlight[imageIndex] != VK_NULL_HANDLE) { + vkWaitForFences(Ctx->GetDevice(), 1, &imagesInFlight[imageIndex], VK_TRUE, UINT64_MAX); + } + imagesInFlight[imageIndex] = frame.InFlightFence; + frame.CurrentImageIndex = imageIndex; if (res == VK_ERROR_OUT_OF_DATE_KHR) { MGLOG_D("vkAcquireNextImageKHR: OUT_OF_DATE -> recreate"); RecreateSwapchainIfNeeded(); return; } - MOBILEGL_ASSERT_VK(res, "vkAcquireNextImageKHR"); + VK_VERIFY(res, "vkAcquireNextImageKHR"); // Record commands - MOBILEGL_ASSERT_VK(vkResetCommandBuffer(frame.CommandBuffer, 0), "vkResetCommandBuffer"); - RecordFrameCommandBuffer(frame, imageIndex); + VK_VERIFY(vkResetCommandBuffer(frame.CommandBuffer, 0), "vkResetCommandBuffer"); + RecordFrameCommandBuffer(frame, frame.CurrentImageIndex); // Submit VkSubmitInfo si{VK_STRUCTURE_TYPE_SUBMIT_INFO}; @@ -221,23 +226,13 @@ namespace MobileGL::MG_Backend::DirectVulkan { si.signalSemaphoreCount = 1; si.pSignalSemaphores = signalSemaphores; - MOBILEGL_ASSERT_VK(vkQueueSubmit(Ctx->GetGraphicsQueue(), 1, &si, frame.InFlightFence), "vkQueueSubmit"); + VK_VERIFY(vkQueueSubmit(Ctx->GetGraphicsQueue(), 1, &si, frame.InFlightFence), "vkQueueSubmit"); } void VulkanRenderer::Present() { - if (!Ctx) MOBILEGL_ASSERT(false, "Renderer not initialized"); + if (!Ctx) throw RuntimeError("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"); + const Uint32& imageIndex = frame.CurrentImageIndex; // Present VkPresentInfoKHR pi{VK_STRUCTURE_TYPE_PRESENT_INFO_KHR}; @@ -253,7 +248,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { MGLOG_D("vkQueuePresentKHR: out_of_date/suboptimal -> recreate"); RecreateSwapchainIfNeeded(); } else { - MOBILEGL_ASSERT_VK(pres, "vkQueuePresentKHR"); + VK_VERIFY(pres, "vkQueuePresentKHR"); } CurrentFrame = (CurrentFrame + 1) % Frames.size(); diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h index bb928139..f582bca9 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h @@ -55,7 +55,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { VkCommandPool CommandPool = VK_NULL_HANDLE; std::vector> Frames; - uint32_t CurrentFrame = 0; + Uint32 CurrentFrame = 0; // Render callbacks map std::vector> RenderCallbacks;