This commit is contained in:
Joshua Ashton 2022-08-04 20:00:53 +01:00
parent 0495fd870a
commit 6009d3178f
6 changed files with 117 additions and 19 deletions

View File

@ -22,6 +22,10 @@ namespace orange
VkPhysicalDevice PhysicalDevice() const { return m_physicalDevice; }
VkDevice Device() const { return m_device; }
VkQueue Queue() const { return m_queue; }
VkCommandPool CommandPool() const { return m_commandPool; }
VulkanResult<VkFence> CreateFence(bool signalled);
VulkanResult<VkSemaphore> CreateSemaphore();
protected:
friend VulkanResult<RenderContext>;
RenderContext(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device,

View File

@ -5,35 +5,56 @@
#include <Orange/Core/SmallVector.h>
#include <Orange/Render/RenderContext.h>
#include <vulkan/vulkan_core.h>
namespace orange
{
static constexpr uint32_t MaxFramesInFlight = 4;
class Swapchain
{
public:
~Swapchain();
static Result<Swapchain> Create(RenderContext& context, VkSurfaceKHR surface);
VkCommandBuffer CommandBuffer() const { return m_commandBuffers[m_currentImage]; }
protected:
friend class Result<Swapchain>;
Swapchain(VkDevice device, VkSurfaceKHR surface, VkFormat format, VkExtent2D extent, VkSwapchainKHR swapchain,
Span<VkImage> images, Span<VkImageView> imageViews)
: m_device { device }
, m_surface { surface }
, m_format { format }
, m_extent { extent }
, m_swapchain { swapchain }
, m_images { images }
, m_imageViews{ imageViews }
Swapchain(RenderContext& context, VkSurfaceKHR surface, VkFormat format, VkExtent2D extent, VkSwapchainKHR swapchain,
Span<VkImage> images, Span<VkImageView> imageViews, Span<VkCommandBuffer> commandBuffers,
Span<VkSemaphore> imageAvailableSemaphores, Span<VkSemaphore> renderFinishedSemaphores, Span<VkFence> inFlightFences,
uint32_t currentImage)
: m_ctx { context }
, m_surface { surface }
, m_format { format }
, m_extent { extent }
, m_swapchain { swapchain }
, m_images { images }
, m_imageViews { imageViews }
, m_commandBuffers { commandBuffers }
, m_imageAvailableSemaphores { imageAvailableSemaphores }
, m_renderFinishedSemaphores { renderFinishedSemaphores }
, m_inFlightFences { inFlightFences }
, m_currentImage { currentImage }
{}
private:
VkDevice m_device;
RenderContext& m_ctx;
VkSurfaceKHR m_surface;
VkFormat m_format;
VkExtent2D m_extent;
VkSwapchainKHR m_swapchain;
SmallVector<VkImage, 8> m_images;
SmallVector<VkImageView, 8> m_imageViews;
SmallVector<VkImage, 6> m_images;
SmallVector<VkImageView, 6> m_imageViews;
SmallVector<VkCommandBuffer, MaxFramesInFlight> m_commandBuffers;
SmallVector<VkSemaphore, MaxFramesInFlight> m_imageAvailableSemaphores;
SmallVector<VkSemaphore, MaxFramesInFlight> m_renderFinishedSemaphores;
SmallVector<VkFence, MaxFramesInFlight> m_inFlightFences;
uint32_t m_currentFrame = 0;
uint32_t m_currentImage = 0;
};
}

View File

@ -182,6 +182,7 @@ namespace orange
RenderContext::~RenderContext()
{
vkDestroyCommandPool(m_device, m_commandPool, nullptr);
vkDestroyDevice(m_device, nullptr);
vkDestroyInstance(m_instance, nullptr);
}

View File

@ -0,0 +1,36 @@
#include <Orange/Render/RenderContext.h>
#include <vulkan/vulkan_core.h>
namespace orange
{
VulkanResult<VkFence> RenderContext::CreateFence(bool signalled)
{
VkFenceCreateInfo fenceInfo =
{
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
.flags = signalled ? VK_FENCE_CREATE_SIGNALED_BIT : 0u,
};
VkFence fence = VK_NULL_HANDLE;
VkResult res = VK_SUCCESS;
if ((res = vkCreateFence(m_device, &fenceInfo, nullptr, &fence)) != VK_SUCCESS)
return VulkanResult<VkFence>::Error(res);
return VulkanResult<VkFence>::Success(fence);
}
VulkanResult<VkSemaphore> RenderContext::CreateSemaphore()
{
VkSemaphoreCreateInfo semaphoreInfo =
{
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
};
VkSemaphore semaphore = VK_NULL_HANDLE;
VkResult res = VK_SUCCESS;
if ((res = vkCreateSemaphore(m_device, &semaphoreInfo, nullptr, &semaphore)) != VK_SUCCESS)
return VulkanResult<VkSemaphore>::Error(res);
return VulkanResult<VkSemaphore>::Success(semaphore);
}
}

View File

@ -3,9 +3,12 @@
#include <Orange/Render/Swapchain.h>
#include <Orange/Render/VulkanHelpers.h>
#include <Orange/Render/Window.h>
#include <vulkan/vulkan_core.h>
namespace orange
{
static constexpr uint32_t DefaultFramesInFlight = 2;
static Result<VkSurfaceFormatKHR> ChooseSwapChainFormat(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
{
SmallVector<VkSurfaceFormatKHR, 32> surfaceFormats;
@ -96,11 +99,11 @@ namespace orange
if (vkCreateSwapchainKHR(context.Device(), &swapchainInfo, nullptr, &swapchain) != VK_SUCCESS)
return Result<Swapchain>::PrintError("Failed to create swapchain");
SmallVector<VkImage, 8> swapchainImages;
SmallVector<VkImage, 6> swapchainImages;
if (!VkEnumerate(vkGetSwapchainImagesKHR, swapchainImages, context.Device(), swapchain))
return Result<Swapchain>::PrintError("Failed to get swapchain images");
SmallVector<VkImageView, 8> swapchainImageViews{ swapchainImages.Size() };
SmallVector<VkImageView, 6> swapchainImageViews{ swapchainImages.Size() };
for (size_t i = 0; i < swapchainImages.Size(); i++)
{
VkImageViewCreateInfo imageViewInfo =
@ -116,15 +119,47 @@ namespace orange
return Result<Swapchain>::PrintError("Failed to get swapchain image view");
}
return Result<Swapchain>::Success(
context.Device(), surface, r_format->format, extent, swapchain,
swapchainImages, swapchainImageViews);
SmallVector<VkCommandBuffer, 6> commandBuffers{ DefaultFramesInFlight };
{
VkCommandBufferAllocateInfo commandBufferInfo =
{
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.commandPool = context.CommandPool(),
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
.commandBufferCount = DefaultFramesInFlight,
};
if (vkAllocateCommandBuffers(context.Device(), &commandBufferInfo, commandBuffers.Data()) != VK_SUCCESS)
return Result<Swapchain>::PrintError("Failed to get swapchain image view");
}
SmallVector<VkSemaphore, MaxFramesInFlight> imageAvailableSemaphores{ DefaultFramesInFlight };
SmallVector<VkSemaphore, MaxFramesInFlight> renderFinishedSemaphores{ DefaultFramesInFlight };
SmallVector<VkFence, MaxFramesInFlight> inFlightFences { DefaultFramesInFlight };
for (uint32_t i = 0; i < DefaultFramesInFlight; i++)
{
auto r_fence = context.CreateFence(true);
if (!r_fence) return Result<Swapchain>::PrintError("Failed to create fence for swapchain");
inFlightFences[i] = *r_fence;
auto r_imageSem = context.CreateSemaphore();
if (!r_imageSem) return Result<Swapchain>::PrintError("Failed to create semaphore for swapchain");
imageAvailableSemaphores[i] = *r_imageSem;
auto r_renderSem = context.CreateSemaphore();
if (!r_renderSem) return Result<Swapchain>::PrintError("Failed to create semaphore for swapchain");
renderFinishedSemaphores[i] = *r_renderSem;
}
// TODO: Handle failure
uint32_t imageIndex;
vkAcquireNextImageKHR(context.Device(), swapchain, ~0u, imageAvailableSemaphores[0], VK_NULL_HANDLE, &imageIndex);
}
Swapchain::~Swapchain()
{
for (const auto& imageView : m_imageViews)
vkDestroyImageView(m_device, imageView, nullptr);
vkDestroySwapchainKHR(m_device, m_swapchain, nullptr);
vkDestroyImageView(m_ctx.Device(), imageView, nullptr);
vkDestroySwapchainKHR(m_ctx.Device(), m_swapchain, nullptr);
}
}

View File

@ -2,6 +2,7 @@ orange_src = [
'Core/Log.cpp',
'Render/RenderContext_Init.cpp',
'Render/RenderContext_Util.cpp',
'Render/Swapchain.cpp',
'Render/Window.cpp',
]