From 0495fd870ae88b22d28a32e2f86d75dec5375c3b Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Thu, 4 Aug 2022 17:23:08 +0000 Subject: [PATCH] Work --- include/Orange/Core/Result.h | 21 +++++++++ include/Orange/Render/RenderContext.h | 11 +++-- include/Orange/Render/Swapchain.h | 15 ++++++- include/Orange/Render/VulkanHelpers.h | 10 +++++ src/Apps/Tools/CubeTest.cpp | 8 ++-- src/Orange/Render/RenderContext_Init.cpp | 57 ++++++++++++++---------- src/Orange/Render/Swapchain.cpp | 37 ++++++++++----- 7 files changed, 115 insertions(+), 44 deletions(-) diff --git a/include/Orange/Core/Result.h b/include/Orange/Core/Result.h index ae18424..8167bec 100644 --- a/include/Orange/Core/Result.h +++ b/include/Orange/Core/Result.h @@ -58,6 +58,20 @@ namespace orange return res; } + template + static Result PrintError(const char* message, Args&&... args) + { + log::err(message, Forward(args)...); + return Error(); + } + + template + static Result PrintError(ErrorCode code, const char* message, Args&&... args) + { + log::err(message, Forward(args)...); + return Error(code); + } + template static Result Success(Args&&... args) { @@ -75,6 +89,13 @@ namespace orange return Error(x.Code()); } + template + static Result PrintForwardError(OtherResult& x, const char* message, Args&&... args) + { + log::err(message, Forward(args)...); + return Error(x.Code()); + } + protected: Result() = default; diff --git a/include/Orange/Render/RenderContext.h b/include/Orange/Render/RenderContext.h index 6ffcd79..67e243d 100644 --- a/include/Orange/Render/RenderContext.h +++ b/include/Orange/Render/RenderContext.h @@ -16,20 +16,23 @@ namespace orange public: ~RenderContext(); - static Result Create(const char *appName); + static VulkanResult Create(const char *appName); VkInstance Instance() const { return m_instance; } VkPhysicalDevice PhysicalDevice() const { return m_physicalDevice; } VkDevice Device() const { return m_device; } VkQueue Queue() const { return m_queue; } protected: - friend class Result; - RenderContext(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device, VkQueue queue) - : m_instance{ instance }, m_physicalDevice{ physicalDevice }, m_device{ device }, m_queue{ queue } {} + friend VulkanResult; + RenderContext(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device, + VkQueue queue, VkCommandPool commandPool) + : m_instance{ instance }, m_physicalDevice{ physicalDevice }, m_device{ device } + , m_queue{ queue }, m_commandPool{ commandPool } {} private: VkInstance m_instance = VK_NULL_HANDLE; VkPhysicalDevice m_physicalDevice = VK_NULL_HANDLE; VkDevice m_device = VK_NULL_HANDLE; VkQueue m_queue = VK_NULL_HANDLE; + VkCommandPool m_commandPool = VK_NULL_HANDLE; }; } \ No newline at end of file diff --git a/include/Orange/Render/Swapchain.h b/include/Orange/Render/Swapchain.h index 900e080..720311f 100644 --- a/include/Orange/Render/Swapchain.h +++ b/include/Orange/Render/Swapchain.h @@ -16,13 +16,24 @@ namespace orange static Result Create(RenderContext& context, VkSurfaceKHR surface); protected: friend class Result; - Swapchain(VkDevice device, VkSurfaceKHR surface, VkExtent2D extent, VkSwapchainKHR swapchain); + Swapchain(VkDevice device, VkSurfaceKHR surface, VkFormat format, VkExtent2D extent, VkSwapchainKHR swapchain, + Span images, Span imageViews) + : m_device { device } + , m_surface { surface } + , m_format { format } + , m_extent { extent } + , m_swapchain { swapchain } + , m_images { images } + , m_imageViews{ imageViews } + {} private: VkDevice m_device; VkSurfaceKHR m_surface; + VkFormat m_format; VkExtent2D m_extent; VkSwapchainKHR m_swapchain; - SmallVector m_images; + SmallVector m_images; + SmallVector m_imageViews; }; } \ No newline at end of file diff --git a/include/Orange/Render/VulkanHelpers.h b/include/Orange/Render/VulkanHelpers.h index 74c3db0..f3b818b 100644 --- a/include/Orange/Render/VulkanHelpers.h +++ b/include/Orange/Render/VulkanHelpers.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace orange { @@ -17,4 +18,13 @@ namespace orange function(Forward(arguments)..., &count, outArray.Data()); return count; } + + static constexpr VkImageSubresourceRange FirstMipSubresourceRange = + { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + }; } diff --git a/src/Apps/Tools/CubeTest.cpp b/src/Apps/Tools/CubeTest.cpp index 0d408c5..01886b3 100644 --- a/src/Apps/Tools/CubeTest.cpp +++ b/src/Apps/Tools/CubeTest.cpp @@ -10,19 +10,19 @@ int main(int argc, char** argv) { (void)argc; (void)argv; - Result r_window = Window::Create(); + auto r_window = Window::Create(); if (!r_window) return 1; - Result r_renderContext = RenderContext::Create("Cube Test"); + auto r_renderContext = RenderContext::Create("Cube Test"); if (!r_renderContext) return 1; - Result r_surface = r_window->CreateSurface(r_renderContext->Instance()); + auto r_surface = r_window->CreateSurface(r_renderContext->Instance()); if (!r_surface) return 1; - Result r_swapchain = Swapchain::Create(*r_renderContext, *r_surface); + auto r_swapchain = Swapchain::Create(*r_renderContext, *r_surface); if (!r_swapchain) return 1; diff --git a/src/Orange/Render/RenderContext_Init.cpp b/src/Orange/Render/RenderContext_Init.cpp index 277e709..c0291f8 100644 --- a/src/Orange/Render/RenderContext_Init.cpp +++ b/src/Orange/Render/RenderContext_Init.cpp @@ -13,13 +13,12 @@ namespace orange { auto r_tempWindow = Window::Create(); if (!r_tempWindow) - { - log::err("Failed to create temporary window for grabbing instance extensions: %s", Window::GetError()); - return VulkanResult::Error(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR); - } + return VulkanResult::PrintError( + "Failed to create temporary window for grabbing instance extensions: %s", Window::GetError()); if (!VkEnumerate(Window::GetInstanceExtensions, instanceExtensions, *r_tempWindow)) - return VulkanResult::Error(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR); + return VulkanResult::PrintError( + "Failed to get required instance extensions: %s", Window::GetError()); } VkApplicationInfo appInfo = @@ -36,17 +35,14 @@ namespace orange { .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .pApplicationInfo = &appInfo, - .enabledExtensionCount = instanceExtensions.Size(), + .enabledExtensionCount = uint32_t(instanceExtensions.Size()), .ppEnabledExtensionNames = instanceExtensions.Data(), }; VkResult result = VK_SUCCESS; VkInstance instance = VK_NULL_HANDLE; if ((result = vkCreateInstance(&instanceInfo, nullptr, &instance)) != VK_SUCCESS) - { - log::err("Failed to create Vulkan instance."); - return VulkanResult::Error(result); - } + return VulkanResult::PrintError(result, "Failed to create Vulkan instance."); return VulkanResult::Success(instance); } @@ -100,10 +96,7 @@ namespace orange } if (!bestPhysicalDevice) - { - log::err("Failed to find a suitable physical device"); - return Result::Error(BasicErrorCode::Failed); - } + return Result::PrintError("Failed to find a suitable physical device"); return Result::Success(bestPhysicalDevice); } @@ -139,34 +132,52 @@ namespace orange VkDevice device = VK_NULL_HANDLE; VkResult result; if ((result = vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &device)) != VK_SUCCESS) - { - log::err("Failed to create Vulkan logical device"); - return VulkanResult::Error(result); - } + return VulkanResult::PrintError(result, "Failed to create Vulkan logical device"); return VulkanResult::Success(device); } - Result RenderContext::Create(const char *appName) + static VulkanResult CreateVkCommandPool(VkDevice device, uint32_t graphicsQueueFamilyIndex) + { + VkCommandPoolCreateInfo poolInfo = + { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + .queueFamilyIndex = graphicsQueueFamilyIndex, + }; + + VkResult res = VK_SUCCESS; + VkCommandPool commandPool = VK_NULL_HANDLE; + if ((res = vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool)) != VK_SUCCESS) + return VulkanResult::PrintError(res, "Failed to create command pool"); + + return VulkanResult::Success(commandPool); + } + + VulkanResult RenderContext::Create(const char *appName) { auto r_instance = CreateVkInstance(appName); if (!r_instance) - return Result::Error(BasicErrorCode::Failed); + return VulkanResult::ForwardError(r_instance); auto r_physicalDevice = PickPhysicalDevice(*r_instance); if (!r_physicalDevice) - return Result::Error(BasicErrorCode::Failed); + return VulkanResult::Error(); uint32_t graphicsQueueFamilyIndex = *PickQueueFamilyIndex(*r_physicalDevice); auto r_device = CreateVkDevice(*r_physicalDevice, graphicsQueueFamilyIndex); if (!r_device) - return Result::Error(BasicErrorCode::Failed); + return VulkanResult::ForwardError(r_device); + + auto r_commandPool = CreateVkCommandPool(*r_device, graphicsQueueFamilyIndex); + if (!r_commandPool) + return VulkanResult::ForwardError(r_commandPool); VkQueue queue = VK_NULL_HANDLE; vkGetDeviceQueue(*r_device, graphicsQueueFamilyIndex, 0, &queue); - return Result::Success(*r_instance, *r_physicalDevice, *r_device, queue); + return VulkanResult::Success(*r_instance, *r_physicalDevice, *r_device, queue, *r_commandPool); } RenderContext::~RenderContext() diff --git a/src/Orange/Render/Swapchain.cpp b/src/Orange/Render/Swapchain.cpp index 8fecdcd..eea4f7e 100644 --- a/src/Orange/Render/Swapchain.cpp +++ b/src/Orange/Render/Swapchain.cpp @@ -70,7 +70,7 @@ namespace orange Result r_format = ChooseSwapChainFormat(context.PhysicalDevice(), surface); if (!r_format) - return Result::ForwardError(r_format); + return Result::PrintForwardError(r_format, "Failed to pick swapchain format"); const VkExtent2D extent = ChooseSwapExtent(capabilities); @@ -89,27 +89,42 @@ namespace orange .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, .presentMode = ChoosePresentMode(context.PhysicalDevice(), surface), .clipped = VK_TRUE, - .oldSwapchain = VK_NULL_HANDLE, // TODO + .oldSwapchain = VK_NULL_HANDLE, // TODO }; VkSwapchainKHR swapchain = VK_NULL_HANDLE; if (vkCreateSwapchainKHR(context.Device(), &swapchainInfo, nullptr, &swapchain) != VK_SUCCESS) + return Result::PrintError("Failed to create swapchain"); + + SmallVector swapchainImages; + if (!VkEnumerate(vkGetSwapchainImagesKHR, swapchainImages, context.Device(), swapchain)) + return Result::PrintError("Failed to get swapchain images"); + + SmallVector swapchainImageViews{ swapchainImages.Size() }; + for (size_t i = 0; i < swapchainImages.Size(); i++) { - log::err("Failed to create swapchain"); - return Result::Error(); + VkImageViewCreateInfo imageViewInfo = + { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = swapchainImages[i], + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = r_format->format, + .subresourceRange = FirstMipSubresourceRange, + }; + + if (vkCreateImageView(context.Device(), &imageViewInfo, nullptr, &swapchainImageViews[i]) != VK_SUCCESS) + return Result::PrintError("Failed to get swapchain image view"); } - return Result::Success(context.Device(), surface, extent, swapchain); - } - - Swapchain::Swapchain(VkDevice device, VkSurfaceKHR surface, VkExtent2D extent, VkSwapchainKHR swapchain) - : m_device{ device }, m_surface{ surface }, m_extent{ extent }, m_swapchain{ swapchain } - { - VkEnumerate(vkGetSwapchainImagesKHR, m_images, m_device, m_swapchain); + return Result::Success( + context.Device(), surface, r_format->format, extent, swapchain, + swapchainImages, swapchainImageViews); } Swapchain::~Swapchain() { + for (const auto& imageView : m_imageViews) + vkDestroyImageView(m_device, imageView, nullptr); vkDestroySwapchainKHR(m_device, m_swapchain, nullptr); } } \ No newline at end of file