From 55020a1e861faed5462ef9a6b78df0dd883db62a Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Sun, 8 Feb 2026 14:48:04 +0800 Subject: [PATCH] [Improvement] (MG_Backend/DirectVulkan): Unify error handling. --- .../DirectVulkan/Renderer/FrameContext.cpp | 13 +++++---- .../DirectVulkan/Renderer/PipelineManager.cpp | 12 ++++---- .../Renderer/SwapchainManager.cpp | 16 +++++------ .../DirectVulkan/Renderer/VulkanContext.cpp | 19 +++++++------ .../DirectVulkan/Renderer/VulkanContext.h | 7 +---- .../DirectVulkan/Renderer/VulkanRenderer.cpp | 28 +++++++++---------- 6 files changed, 46 insertions(+), 49 deletions(-) diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.cpp index 65a4838d..b96b07fd 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.cpp @@ -18,19 +18,20 @@ namespace MobileGL::MG_Backend::DirectVulkan { abci.commandPool = pool; abci.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; abci.commandBufferCount = 1; - ThrowIfFailed(vkAllocateCommandBuffers(ctx.GetDevice(), &abci, &CommandBuffer), "vkAllocateCommandBuffers"); + MOBILEGL_ASSERT_VK(vkAllocateCommandBuffers(ctx.GetDevice(), &abci, &CommandBuffer), + "vkAllocateCommandBuffers"); // semaphores VkSemaphoreCreateInfo sci{VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO}; - ThrowIfFailed(vkCreateSemaphore(ctx.GetDevice(), &sci, nullptr, &ImageAvailable), - "vkCreateSemaphore ImageAvailable"); - ThrowIfFailed(vkCreateSemaphore(ctx.GetDevice(), &sci, nullptr, &RenderFinished), - "vkCreateSemaphore RenderFinished"); + MOBILEGL_ASSERT_VK(vkCreateSemaphore(ctx.GetDevice(), &sci, nullptr, &ImageAvailable), + "vkCreateSemaphore ImageAvailable"); + MOBILEGL_ASSERT_VK(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; - ThrowIfFailed(vkCreateFence(ctx.GetDevice(), &fci, nullptr, &InFlightFence), "vkCreateFence"); + MOBILEGL_ASSERT_VK(vkCreateFence(ctx.GetDevice(), &fci, nullptr, &InFlightFence), "vkCreateFence"); } void FrameContext::Cleanup(VulkanContext& ctx) { diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/PipelineManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/PipelineManager.cpp index 05173cf2..12804e1e 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/PipelineManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/PipelineManager.cpp @@ -18,8 +18,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { void PipelineManager::EnsurePipelineLayout() { if (PipelineLayout != VK_NULL_HANDLE) return; VkPipelineLayoutCreateInfo plci{VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO}; - ThrowIfFailed(vkCreatePipelineLayout(Ctx.GetDevice(), &plci, nullptr, &PipelineLayout), - "vkCreatePipelineLayout"); + MOBILEGL_ASSERT_VK(vkCreatePipelineLayout(Ctx.GetDevice(), &plci, nullptr, &PipelineLayout), + "vkCreatePipelineLayout"); } VkPipeline PipelineManager::CreateGraphicsPipelineFromSpv(const std::string& key, @@ -36,12 +36,12 @@ namespace MobileGL::MG_Backend::DirectVulkan { smci.codeSize = vsSpv.size() * sizeof(uint32_t); smci.pCode = vsSpv.data(); VkShaderModule vs; - ThrowIfFailed(vkCreateShaderModule(Ctx.GetDevice(), &smci, nullptr, &vs), "vkCreateShaderModule VS"); + MOBILEGL_ASSERT_VK(vkCreateShaderModule(Ctx.GetDevice(), &smci, nullptr, &vs), "vkCreateShaderModule VS"); smci.codeSize = fsSpv.size() * sizeof(uint32_t); smci.pCode = fsSpv.data(); VkShaderModule fs; - ThrowIfFailed(vkCreateShaderModule(Ctx.GetDevice(), &smci, nullptr, &fs), "vkCreateShaderModule FS"); + MOBILEGL_ASSERT_VK(vkCreateShaderModule(Ctx.GetDevice(), &smci, nullptr, &fs), "vkCreateShaderModule FS"); VkPipelineShaderStageCreateInfo stages[2]{}; stages[0] = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO}; @@ -105,8 +105,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { gpi.subpass = 0; VkPipeline pipeline; - ThrowIfFailed(vkCreateGraphicsPipelines(Ctx.GetDevice(), VK_NULL_HANDLE, 1, &gpi, nullptr, &pipeline), - "vkCreateGraphicsPipelines"); + MOBILEGL_ASSERT_VK(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 de6396c4..656936bd 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainManager.cpp @@ -72,8 +72,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { void SwapchainManager::CreateSwapchainInternal() { VkSurfaceCapabilitiesKHR caps; - ThrowIfFailed(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Ctx.GetPhysicalDevice(), Ctx.GetSurface(), &caps), - "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"); + MOBILEGL_ASSERT_VK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Ctx.GetPhysicalDevice(), Ctx.GetSurface(), &caps), + "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"); Extent = caps.currentExtent; ImageFormat = VK_FORMAT_R8G8B8A8_UNORM; @@ -91,14 +91,14 @@ namespace MobileGL::MG_Backend::DirectVulkan { sci.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; sci.presentMode = QueryPossiblePresentMode(); - ThrowIfFailed(vkCreateSwapchainKHR(Ctx.GetDevice(), &sci, nullptr, &Swapchain), "vkCreateSwapchainKHR"); + MOBILEGL_ASSERT_VK(vkCreateSwapchainKHR(Ctx.GetDevice(), &sci, nullptr, &Swapchain), "vkCreateSwapchainKHR"); uint32_t count = 0; - ThrowIfFailed(vkGetSwapchainImagesKHR(Ctx.GetDevice(), Swapchain, &count, nullptr), - "vkGetSwapchainImagesKHR count"); + MOBILEGL_ASSERT_VK(vkGetSwapchainImagesKHR(Ctx.GetDevice(), Swapchain, &count, nullptr), + "vkGetSwapchainImagesKHR count"); Images.resize(count); - ThrowIfFailed(vkGetSwapchainImagesKHR(Ctx.GetDevice(), Swapchain, &count, Images.data()), - "vkGetSwapchainImagesKHR images"); + MOBILEGL_ASSERT_VK(vkGetSwapchainImagesKHR(Ctx.GetDevice(), Swapchain, &count, Images.data()), + "vkGetSwapchainImagesKHR images"); MGLOG_D("Swapchain created (%u images)", count); } @@ -117,7 +117,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { ivci.subresourceRange.levelCount = 1; ivci.subresourceRange.baseArrayLayer = 0; ivci.subresourceRange.layerCount = 1; - ThrowIfFailed(vkCreateImageView(Ctx.GetDevice(), &ivci, nullptr, &ImageViews[i]), "vkCreateImageView"); + MOBILEGL_ASSERT_VK(vkCreateImageView(Ctx.GetDevice(), &ivci, nullptr, &ImageViews[i]), "vkCreateImageView"); } MGLOG_D("ImageViews created"); } diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanContext.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanContext.cpp index fc09c89b..5cd454d4 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanContext.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanContext.cpp @@ -59,19 +59,20 @@ namespace MobileGL::MG_Backend::DirectVulkan { ci.enabledExtensionCount = 2; ci.ppEnabledExtensionNames = exts; - ThrowIfFailed(vkCreateInstance(&ci, nullptr, &Instance), "vkCreateInstance failed"); + MOBILEGL_ASSERT_VK(vkCreateInstance(&ci, nullptr, &Instance), "vkCreateInstance failed"); } void VulkanContext::CreateSurface(NativeWindowType window) { #if __ANDROID__ - if (!Instance) throw MobileGL::RuntimeError("Instance not created"); + if (!Instance) MOBILEGL_ASSERT(false, "Instance not created"); auto* nativeWindow = static_cast(window); - if (!nativeWindow) throw MobileGL::RuntimeError("ANativeWindowType is null"); + if (!nativeWindow) MOBILEGL_ASSERT(false, "ANativeWindowType is null"); VkAndroidSurfaceCreateInfoKHR sci{VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR}; sci.window = nativeWindow; - ThrowIfFailed(vkCreateAndroidSurfaceKHR(Instance, &sci, nullptr, &Surface), "vkCreateAndroidSurfaceKHR failed"); + MOBILEGL_ASSERT_VK(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 @@ -80,10 +81,10 @@ namespace MobileGL::MG_Backend::DirectVulkan { void VulkanContext::PickPhysicalDevice() { uint32_t count = 0; - ThrowIfFailed(vkEnumeratePhysicalDevices(Instance, &count, nullptr), "vkEnumeratePhysicalDevices count"); - if (count == 0) throw MobileGL::RuntimeError("No physical devices"); + MOBILEGL_ASSERT_VK(vkEnumeratePhysicalDevices(Instance, &count, nullptr), "vkEnumeratePhysicalDevices count"); + if (count == 0) MOBILEGL_ASSERT(false, "No physical devices"); std::vector devs(count); - ThrowIfFailed(vkEnumeratePhysicalDevices(Instance, &count, devs.data()), "vkEnumeratePhysicalDevices"); + MOBILEGL_ASSERT_VK(vkEnumeratePhysicalDevices(Instance, &count, devs.data()), "vkEnumeratePhysicalDevices"); for (auto d : devs) { uint32_t qcount = 0; @@ -101,7 +102,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } } } - throw MobileGL::RuntimeError("No suitable physical device"); + MOBILEGL_ASSERT(false, "No suitable physical device"); } void VulkanContext::CreateLogicalDevice() { @@ -119,7 +120,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { dci.enabledExtensionCount = 1; dci.ppEnabledExtensionNames = devExts; - ThrowIfFailed(vkCreateDevice(PhysicalDevice, &dci, nullptr, &Device), "vkCreateDevice failed"); + MOBILEGL_ASSERT_VK(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 afb7d275..149b7780 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanContext.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanContext.h @@ -9,12 +9,7 @@ #pragma once #include -static inline void ThrowIfFailed(VkResult r, const char* msg) { - if (r != VK_SUCCESS) { - MGLOG_E("%s (VkResult=%d)", msg, int(r)); - throw MobileGL::RuntimeError(msg); - } -} +#define MOBILEGL_ASSERT_VK(exp, ...) MOBILEGL_ASSERT((exp) == VK_SUCCESS, __VA_ARGS__) 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 cb3bbe00..4c036688 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 = ⊂ - ThrowIfFailed(vkCreateRenderPass(Ctx->GetDevice(), &rpci, nullptr, &RenderPass), "vkCreateRenderPass"); + MOBILEGL_ASSERT_VK(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; - ThrowIfFailed(vkCreateFramebuffer(Ctx->GetDevice(), &fbci, nullptr, &fb), "vkCreateFramebuffer"); + MOBILEGL_ASSERT_VK(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; - ThrowIfFailed(vkCreateCommandPool(Ctx->GetDevice(), &cpci, nullptr, &CommandPool), "vkCreateCommandPool"); + MOBILEGL_ASSERT_VK(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) throw MobileGL::RuntimeError("Swapchain has zero images"); + if (imageCount == 0) MOBILEGL_ASSERT(false, "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}; - ThrowIfFailed(vkBeginCommandBuffer(frame.CommandBuffer, &bi), "vkBeginCommandBuffer"); + MOBILEGL_ASSERT_VK(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); - ThrowIfFailed(vkEndCommandBuffer(frame.CommandBuffer), "vkEndCommandBuffer"); + MOBILEGL_ASSERT_VK(vkEndCommandBuffer(frame.CommandBuffer), "vkEndCommandBuffer"); } void VulkanRenderer::RecreateSwapchainIfNeeded() { @@ -185,13 +185,13 @@ namespace MobileGL::MG_Backend::DirectVulkan { // Wait fence & Acquire image & Record commands & Submit & Present void VulkanRenderer::RenderFrame() { - if (!Ctx) throw MobileGL::RuntimeError("Renderer not initialized"); + if (!Ctx) MOBILEGL_ASSERT(false, "Renderer not initialized"); FrameContext& frame = *Frames[CurrentFrame]; // Wait fence and reset - ThrowIfFailed(vkWaitForFences(Ctx->GetDevice(), 1, &frame.InFlightFence, VK_TRUE, UINT64_MAX), - "vkWaitForFences"); - ThrowIfFailed(vkResetFences(Ctx->GetDevice(), 1, &frame.InFlightFence), "vkResetFences"); + MOBILEGL_ASSERT_VK(vkWaitForFences(Ctx->GetDevice(), 1, &frame.InFlightFence, VK_TRUE, UINT64_MAX), + "vkWaitForFences"); + MOBILEGL_ASSERT_VK(vkResetFences(Ctx->GetDevice(), 1, &frame.InFlightFence), "vkResetFences"); // Acquire image uint32_t imageIndex = 0; @@ -202,10 +202,10 @@ namespace MobileGL::MG_Backend::DirectVulkan { RecreateSwapchainIfNeeded(); return; } - ThrowIfFailed(res, "vkAcquireNextImageKHR"); + MOBILEGL_ASSERT_VK(res, "vkAcquireNextImageKHR"); // Record commands - ThrowIfFailed(vkResetCommandBuffer(frame.CommandBuffer, 0), "vkResetCommandBuffer"); + MOBILEGL_ASSERT_VK(vkResetCommandBuffer(frame.CommandBuffer, 0), "vkResetCommandBuffer"); RecordFrameCommandBuffer(frame, imageIndex); // Submit @@ -221,7 +221,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { si.signalSemaphoreCount = 1; si.pSignalSemaphores = signalSemaphores; - ThrowIfFailed(vkQueueSubmit(Ctx->GetGraphicsQueue(), 1, &si, frame.InFlightFence), "vkQueueSubmit"); + MOBILEGL_ASSERT_VK(vkQueueSubmit(Ctx->GetGraphicsQueue(), 1, &si, frame.InFlightFence), "vkQueueSubmit"); // Present VkPresentInfoKHR pi{VK_STRUCTURE_TYPE_PRESENT_INFO_KHR}; @@ -236,7 +236,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { MGLOG_D("vkQueuePresentKHR: out_of_date/suboptimal -> recreate"); RecreateSwapchainIfNeeded(); } else { - ThrowIfFailed(pres, "vkQueuePresentKHR"); + MOBILEGL_ASSERT_VK(pres, "vkQueuePresentKHR"); } CurrentFrame = (CurrentFrame + 1) % Frames.size();