From 61a2e9367b8013983a378d6aa05d1a8ba7779fd7 Mon Sep 17 00:00:00 2001 From: Mars Date: Sun, 6 Oct 2024 18:14:15 -0400 Subject: [PATCH] ok i guess we do need exceptions --- meson.build | 2 +- src/main.cpp | 283 +++++++++------------------------------------------ 2 files changed, 49 insertions(+), 236 deletions(-) diff --git a/meson.build b/meson.build index f6dcb6e..6686362 100644 --- a/meson.build +++ b/meson.build @@ -2,7 +2,7 @@ project( 'graphics-test', 'cpp', version: '0.1.0', - default_options: ['cpp_std=c++20', 'warning_level=everything', 'buildtype=debugoptimized'], + default_options: ['cpp_std=c++20', 'warning_level=everything', 'buildtype=debug'], ) cpp = meson.get_compiler('cpp') diff --git a/src/main.cpp b/src/main.cpp index 937c00c..08d7e08 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,7 +6,6 @@ #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 #define VK_ENABLE_BETA_EXTENSIONS #define VULKAN_HPP_NO_CONSTRUCTORS -#define VULKAN_HPP_NO_EXCEPTIONS #include VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE @@ -151,10 +150,7 @@ class VulkanApp { drawFrame(); } - auto result = mDevice->waitIdle(); - - if (result != vk::Result::eSuccess) - throw std::runtime_error("Failed to wait for idle!"); + mDevice->waitIdle(); } fn cleanupSwapChain() -> void { @@ -175,10 +171,7 @@ class VulkanApp { vkfw::waitEvents(); } - auto result = mDevice->waitIdle(); - - if (result != vk::Result::eSuccess) - throw std::runtime_error("Failed to wait for idle!"); + mDevice->waitIdle(); cleanupSwapChain(); @@ -226,15 +219,7 @@ class VulkanApp { for (const char* extension : extensions) fmt::println("\t{}", extension); #endif - vk::Result instanceResult = vk::Result::eSuccess; - vk::UniqueInstance instanceValue; - - std::tie(instanceResult, instanceValue) = vk::createInstanceUnique(createInfo).asTuple(); - - if (instanceResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to create instance!"); - - mInstance = std::move(instanceValue); + mInstance = vk::createInstanceUnique(createInfo); VULKAN_HPP_DEFAULT_DISPATCHER.init(mInstance.get()); } @@ -253,36 +238,22 @@ class VulkanApp { .pfnUserCallback = debugCallback, }; - vk::Result debugMessengerResult = vk::Result::eSuccess; - vk::UniqueDebugUtilsMessengerEXT debugMessengerValue; - - std::tie(debugMessengerResult, debugMessengerValue) = - mInstance->createDebugUtilsMessengerEXTUnique(messengerCreateInfo, nullptr).asTuple(); - - if (debugMessengerResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to set up debug messenger!"); - - mDebugMessenger = std::move(debugMessengerValue); + mDebugMessenger = mInstance->createDebugUtilsMessengerEXTUnique(messengerCreateInfo, nullptr); } fn createSurface() -> void { mSurface = vkfw::createWindowSurfaceUnique(mInstance.get(), mWindow.get()); } fn pickPhysicalDevice() -> void { - vk::Result devicesResult = vk::Result::eSuccess; - std::vector devicesValue; - std::tie(devicesResult, devicesValue) = mInstance->enumeratePhysicalDevices(); + std::vector devices = mInstance->enumeratePhysicalDevices(); - if (devicesResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to enumerate physical devices!"); - - if (devicesValue.empty()) + if (devices.empty()) throw std::runtime_error("Failed to find GPUs with Vulkan support!"); #ifndef NDEBUG fmt::println("Available devices:"); #endif - for (const vk::PhysicalDevice& device : devicesValue) { + for (const vk::PhysicalDevice& device : devices) { #ifndef NDEBUG vk::PhysicalDeviceProperties properties = device.getProperties(); fmt::println("\t{}", properties.deviceName.data()); @@ -322,17 +293,7 @@ class VulkanApp { .ppEnabledExtensionNames = deviceExtensions.data(), .pEnabledFeatures = &deviceFeatures }; - vk::Result createDeviceResult = vk::Result::eSuccess; - vk::UniqueDevice createDeviceValue; - - std::tie(createDeviceResult, createDeviceValue) = - mPhysicalDevice.createDeviceUnique(createInfo).asTuple(); - - if (createDeviceResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to create logical device!"); - - mDevice = std::move(createDeviceValue); - + mDevice = mPhysicalDevice.createDeviceUnique(createInfo); mGraphicsQueue = mDevice->getQueue(indices.graphics_family.value(), 0); mPresentQueue = mDevice->getQueue(indices.present_family.value(), 0); } @@ -374,24 +335,9 @@ class VulkanApp { .oldSwapchain = nullptr, }; - vk::Result swapChainResult = vk::Result::eSuccess; - vk::UniqueSwapchainKHR swapChainValue; + mSwapChain = mDevice->createSwapchainKHRUnique(createInfo); - std::tie(swapChainResult, swapChainValue) = mDevice->createSwapchainKHRUnique(createInfo).asTuple(); - - if (swapChainResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to create swap chain!"); - - mSwapChain = std::move(swapChainValue); - - vk::Result swapChainImagesResult = vk::Result::eSuccess; - std::vector mSwapChainImagesValue; - std::tie(swapChainImagesResult, mSwapChainImagesValue) = mDevice->getSwapchainImagesKHR(mSwapChain.get()); - - if (swapChainImagesResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to get swap chain images!"); - - mSwapChainImages = std::move(mSwapChainImagesValue); + mSwapChainImages = mDevice->getSwapchainImagesKHR(mSwapChain.get()); mSwapChainImageFormat = surfaceFormat.format; mSwapChainExtent = extent; } @@ -417,15 +363,7 @@ class VulkanApp { // clang-format on }; - vk::Result createImageViewResult = vk::Result::eSuccess; - vk::UniqueImageView imageViewValue; - - std::tie(createImageViewResult, imageViewValue) = mDevice->createImageViewUnique(createInfo).asTuple(); - - if (createImageViewResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to create image views!"); - - mSwapChainImageViews[i] = std::move(imageViewValue); + mSwapChainImageViews[i] = mDevice->createImageViewUnique(createInfo); } } @@ -459,15 +397,7 @@ class VulkanApp { .pSubpasses = &subpass, }; - vk::Result renderPassResult = vk::Result::eSuccess; - vk::UniqueRenderPass renderPassValue; - - std::tie(renderPassResult, renderPassValue) = mDevice->createRenderPassUnique(renderPassInfo).asTuple(); - - if (renderPassResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to create render pass!"); - - mRenderPass = std::move(renderPassValue); + mRenderPass = mDevice->createRenderPassUnique(renderPassInfo); } fn createGraphicsPipeline() -> void { @@ -549,16 +479,7 @@ class VulkanApp { .pushConstantRangeCount = 0, }; - vk::Result pipelineLayoutResult = vk::Result::eSuccess; - vk::UniquePipelineLayout pipelineLayoutValue; - - std::tie(pipelineLayoutResult, pipelineLayoutValue) = - mDevice->createPipelineLayoutUnique(pipelineLayoutInfo).asTuple(); - - if (pipelineLayoutResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to create pipeline layout!"); - - mPipelineLayout = std::move(pipelineLayoutValue); + mPipelineLayout = mDevice->createPipelineLayoutUnique(pipelineLayoutInfo); vk::GraphicsPipelineCreateInfo pipelineInfo { .stageCount = static_cast(shaderStages.size()), @@ -600,16 +521,7 @@ class VulkanApp { .layers = 1, }; - vk::Result framebufferResult = vk::Result::eSuccess; - vk::UniqueFramebuffer framebufferValue; - - std::tie(framebufferResult, framebufferValue) = - mDevice->createFramebufferUnique(framebufferInfo).asTuple(); - - if (framebufferResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to create framebuffer!"); - - mSwapChainFramebuffers[i] = std::move(framebufferValue); + mSwapChainFramebuffers[i] = mDevice->createFramebufferUnique(framebufferInfo); } } @@ -621,15 +533,7 @@ class VulkanApp { .queueFamilyIndex = queueFamilyIndices.graphics_family.value(), }; - vk::Result commandPoolResult = vk::Result::eSuccess; - vk::UniqueCommandPool commandPoolValue; - - std::tie(commandPoolResult, commandPoolValue) = mDevice->createCommandPoolUnique(poolInfo).asTuple(); - - if (commandPoolResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to create command pool!"); - - mCommandPool = std::move(commandPoolValue); + mCommandPool = mDevice->createCommandPoolUnique(poolInfo); } fn createCommandBuffers() -> void { @@ -640,25 +544,13 @@ class VulkanApp { .commandBufferCount = static_cast(mCommandBuffers.size()) }; - vk::Result commandBufferResult = vk::Result::eSuccess; - std::vector commandBufferValue; - - std::tie(commandBufferResult, commandBufferValue) = - mDevice->allocateCommandBuffersUnique(allocInfo).asTuple(); - - if (commandBufferResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to allocate command buffers!"); - - mCommandBuffers = std::move(commandBufferValue); + mCommandBuffers = mDevice->allocateCommandBuffersUnique(allocInfo); } fn recordCommandBuffer(vk::CommandBuffer commandBuffer, u32 imageIndex) -> void { vk::CommandBufferBeginInfo beginInfo {}; - vk::Result beginResult = commandBuffer.begin(beginInfo); - - if (beginResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to begin command buffer!"); + commandBuffer.begin(beginInfo); vk::ClearValue clearColor { .color = { .float32 = std::array { 0.0F, 0.0F, 0.0F, 1.0F } } }; @@ -693,10 +585,7 @@ class VulkanApp { commandBuffer.endRenderPass(); - vk::Result endResult = commandBuffer.end(); - - if (endResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to end command buffer!"); + commandBuffer.end(); } fn createSyncObjects() -> void { @@ -708,37 +597,9 @@ class VulkanApp { vk::FenceCreateInfo fenceInfo { .flags = vk::FenceCreateFlagBits::eSignaled }; for (usize idx = 0; idx < MAX_FRAMES_IN_FLIGHT; idx++) { - vk::Result imageAvailableSemaphoreResult = vk::Result::eSuccess; - vk::UniqueSemaphore imageAvailableSemaphoreValue; - - std::tie(imageAvailableSemaphoreResult, imageAvailableSemaphoreValue) = - mDevice->createSemaphoreUnique(semaphoreInfo).asTuple(); - - if (imageAvailableSemaphoreResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to create semaphores!"); - - mImageAvailableSemaphores[idx] = std::move(imageAvailableSemaphoreValue); - - vk::Result renderFinishedSemaphoreResult = vk::Result::eSuccess; - vk::UniqueSemaphore renderFinishedSemaphoreValue; - - std::tie(renderFinishedSemaphoreResult, renderFinishedSemaphoreValue) = - mDevice->createSemaphoreUnique(semaphoreInfo).asTuple(); - - if (imageAvailableSemaphoreResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to create semaphores!"); - - mRenderFinishedSemaphores[idx] = std::move(renderFinishedSemaphoreValue); - - vk::Result fenceResult = vk::Result::eSuccess; - vk::UniqueFence fenceValue; - - std::tie(fenceResult, fenceValue) = mDevice->createFenceUnique(fenceInfo).asTuple(); - - if (fenceResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to create fences!"); - - mInFlightFences[idx] = std::move(fenceValue); + mImageAvailableSemaphores[idx] = mDevice->createSemaphoreUnique(semaphoreInfo); + mRenderFinishedSemaphores[idx] = mDevice->createSemaphoreUnique(semaphoreInfo); + mInFlightFences[idx] = mDevice->createFenceUnique(fenceInfo); } } @@ -781,10 +642,7 @@ class VulkanApp { .pSignalSemaphores = &mRenderFinishedSemaphores[mCurrentFrame].get(), }; - vk::Result submitResult = mGraphicsQueue.submit(submitInfo, mInFlightFences[mCurrentFrame].get()); - - if (submitResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to submit draw command buffer!"); + mGraphicsQueue.submit(submitInfo, mInFlightFences[mCurrentFrame].get()); vk::PresentInfoKHR presentInfo { .waitSemaphoreCount = 1, @@ -794,32 +652,33 @@ class VulkanApp { .pImageIndices = &imageIndexValue, }; - vk::Result presentResult = mPresentQueue.presentKHR(presentInfo); + try { + vk::Result presentResult = mPresentQueue.presentKHR(presentInfo); - if (presentResult == vk::Result::eErrorOutOfDateKHR || presentResult == vk::Result::eSuboptimalKHR || - mFramebufferResized) { + fmt::println("Present result: {}", vk::to_string(presentResult)); + + if (presentResult == vk::Result::eErrorOutOfDateKHR || presentResult == vk::Result::eSuboptimalKHR || + mFramebufferResized) { + mFramebufferResized = false; + recreateSwapChain(); + } else if (presentResult != vk::Result::eSuccess) { + throw std::runtime_error("Failed to present swap chain image!"); + } + + mCurrentFrame = (mCurrentFrame + 1) % MAX_FRAMES_IN_FLIGHT; + } catch (vk::OutOfDateKHRError& err) { + fmt::println("Caught OutOfDateKHRError: {}", err.what()); mFramebufferResized = false; recreateSwapChain(); - } else if (presentResult != vk::Result::eSuccess) { - throw std::runtime_error("Failed to present swap chain image!"); + return; } - - mCurrentFrame = (mCurrentFrame + 1) % MAX_FRAMES_IN_FLIGHT; } fn createShaderModule(const std::vector& code) -> vk::UniqueShaderModule { vk::ShaderModuleCreateInfo createInfo { .codeSize = code.size(), .pCode = std::bit_cast(code.data()) }; - vk::Result shaderModuleResult = vk::Result::eSuccess; - vk::UniqueShaderModule shaderModuleValue; - - std::tie(shaderModuleResult, shaderModuleValue) = mDevice->createShaderModuleUnique(createInfo).asTuple(); - - if (shaderModuleResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to create shader module!"); - - return shaderModuleValue; + return mDevice->createShaderModuleUnique(createInfo); } static fn chooseSwapSurfaceFormat(const std::vector& availableFormats @@ -861,36 +720,9 @@ class VulkanApp { fn querySwapChainSupport(vk::PhysicalDevice device) -> SwapChainSupportDetails { SwapChainSupportDetails details; - vk::Result surfaceCapabilitiesResult = vk::Result::eSuccess; - vk::SurfaceCapabilitiesKHR surfaceCapabilitiesValue; - - std::tie(surfaceCapabilitiesResult, surfaceCapabilitiesValue) = - device.getSurfaceCapabilitiesKHR(mSurface.get()); - - if (surfaceCapabilitiesResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to get surface capabilities!"); - - details.capabilities = surfaceCapabilitiesValue; - - vk::Result surfaceFormatsResult = vk::Result::eSuccess; - std::vector surfaceFormatsValue; - - std::tie(surfaceFormatsResult, surfaceFormatsValue) = device.getSurfaceFormatsKHR(mSurface.get()); - - if (surfaceFormatsResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to get surface formats!"); - - details.formats = surfaceFormatsValue; - - vk::Result presentModesResult = vk::Result::eSuccess; - std::vector presentModesValue; - - std::tie(presentModesResult, presentModesValue) = device.getSurfacePresentModesKHR(mSurface.get()); - - if (presentModesResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to get surface present modes!"); - - details.present_modes = presentModesValue; + details.capabilities = device.getSurfaceCapabilitiesKHR(mSurface.get()); + details.formats = device.getSurfaceFormatsKHR(mSurface.get()); + details.present_modes = device.getSurfacePresentModesKHR(mSurface.get()); return details; } @@ -911,18 +743,11 @@ class VulkanApp { } static fn checkDeviceExtensionSupport(vk::PhysicalDevice device) -> bool { - vk::Result availableExtensionsResult = vk::Result::eSuccess; - std::vector availableExtensionsValue; - - std::tie(availableExtensionsResult, availableExtensionsValue) = - device.enumerateDeviceExtensionProperties(); - - if (availableExtensionsResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to enumerate device extensions!"); + std::vector availableExtensions = device.enumerateDeviceExtensionProperties(); std::set requiredExtensions(deviceExtensions.begin(), deviceExtensions.end()); - for (const vk::ExtensionProperties& extension : availableExtensionsValue) + for (const vk::ExtensionProperties& extension : availableExtensions) requiredExtensions.erase(extension.extensionName); return requiredExtensions.empty(); @@ -937,16 +762,9 @@ class VulkanApp { if (queueFamilies[i].queueFlags & vk::QueueFlagBits::eGraphics) indices.graphics_family = i; - vk::Result queuePresentSupportResult = vk::Result::eSuccess; - vk::Bool32 queuePresentSupportValue = 0; + vk::Bool32 queuePresentSupport = device.getSurfaceSupportKHR(i, mSurface.get()); - std::tie(queuePresentSupportResult, queuePresentSupportValue) = - device.getSurfaceSupportKHR(i, mSurface.get()); - - if (queuePresentSupportResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to get surface support!"); - - if (queuePresentSupportValue) + if (queuePresentSupport) indices.present_family = i; if (indices.isComplete()) @@ -968,17 +786,12 @@ class VulkanApp { } static fn checkValidationLayerSupport() -> bool { - vk::Result availableLayersResult = vk::Result::eSuccess; - std::vector availableLayersValue; - std::tie(availableLayersResult, availableLayersValue) = vk::enumerateInstanceLayerProperties(); - - if (availableLayersResult != vk::Result::eSuccess) - throw std::runtime_error("Failed to enumerate validation layers!"); + std::vector availableLayers = vk::enumerateInstanceLayerProperties(); for (const char* layerName : validationLayers) { bool layerFound = false; - for (const vk::LayerProperties& layerProperties : availableLayersValue) + for (const vk::LayerProperties& layerProperties : availableLayers) if (strcmp(layerName, layerProperties.layerName) == 0) { layerFound = true; break;