From c73d773845387b6c644be57f2cd5ca15863b102c Mon Sep 17 00:00:00 2001 From: Draklaw Date: Thu, 3 Mar 2022 22:20:37 +0100 Subject: [PATCH] Semaphore wrapper. --- CMakeLists.txt | 1 + src/VulkanTutorial.cpp | 26 ++++++----------- src/VulkanTutorial.h | 9 +++--- src/vk/Semaphore.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++ src/vk/Semaphore.h | 61 +++++++++++++++++++++++++++++++++++++++ src/vk/Swapchain.cpp | 29 +++++-------------- src/vk/Swapchain.h | 5 ++-- 7 files changed, 150 insertions(+), 46 deletions(-) create mode 100644 src/vk/Semaphore.cpp create mode 100644 src/vk/Semaphore.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 03c71be..ff0d299 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,7 @@ add_executable(vk_expe src/vk/Context.cpp src/vk/Fence.cpp + src/vk/Semaphore.cpp src/vk/Swapchain.cpp src/vk/Memory.cpp src/vk/Buffer.cpp diff --git a/src/VulkanTutorial.cpp b/src/VulkanTutorial.cpp index 71ea733..f98ba2a 100644 --- a/src/VulkanTutorial.cpp +++ b/src/VulkanTutorial.cpp @@ -187,8 +187,6 @@ void VulkanTutorial::shutdown() { m_vertex_buffer.destroy(); m_context.destroy_descriptor_set_layout(m_descriptor_set_layout); - for(VkSemaphore semaphore: m_render_done) - m_context.destroy_semaphore(semaphore); m_render_done.clear(); m_swapchain.shutdown(); @@ -254,6 +252,9 @@ void VulkanTutorial::draw_frame() { VkSemaphore wait_semaphores[] = { m_swapchain.ready_to_render(), }; + VkSemaphore done_semaphores[] = { + m_render_done[image_index], + }; VkPipelineStageFlags stages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, }; @@ -265,7 +266,7 @@ void VulkanTutorial::draw_frame() { .commandBufferCount = 1, .pCommandBuffers = &m_command_buffers[image_index], .signalSemaphoreCount = 1, - .pSignalSemaphores = &m_render_done[image_index], + .pSignalSemaphores = done_semaphores, }; if(vkQueueSubmit( @@ -275,7 +276,7 @@ void VulkanTutorial::draw_frame() { )) throw std::runtime_error("failed to submit draw command buffer"); - m_swapchain.swap_buffers({1, &m_render_done[image_index]}); + m_swapchain.swap_buffers({1, done_semaphores}); } void VulkanTutorial::invalidate_swapchain() { @@ -291,20 +292,9 @@ void VulkanTutorial::create_swapchain_objects(uint32_t image_count) { create_graphic_pipeline(); create_command_buffers(); - m_render_done.resize(m_swapchain.image_count()); - - VkSemaphoreCreateInfo semaphore_info { - .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, - }; - - for(size_t index = 0; index < m_render_done.size(); index += 1) { - if(vkCreateSemaphore( - m_context.device(), - &semaphore_info, - nullptr, - &m_render_done[index] - ) != VK_SUCCESS) - throw std::runtime_error("failed to create semaphore"); + m_render_done.clear(); + for(size_t index = 0; index < m_swapchain.image_count(); index += 1) { + m_render_done.emplace_back(m_context); } } diff --git a/src/VulkanTutorial.h b/src/VulkanTutorial.h index 9f0f67b..d178cd3 100644 --- a/src/VulkanTutorial.h +++ b/src/VulkanTutorial.h @@ -1,10 +1,11 @@ // Copyright 2022 Simon Boyé #pragma once -#include -#include -#include +#include #include +#include +#include +#include #include @@ -84,7 +85,7 @@ private: VkDescriptorPool m_descriptor_pool = VK_NULL_HANDLE; std::vector m_descriptor_sets; std::vector m_command_buffers; - std::vector m_render_done; + std::vector m_render_done; Vector3 m_camera_position = Vector3(0.0f, 0.0f, -3.0f); Vector3 m_camera_z = Vector3(0.0f, 0.0f, 1.0f); diff --git a/src/vk/Semaphore.cpp b/src/vk/Semaphore.cpp new file mode 100644 index 0000000..0c84ca7 --- /dev/null +++ b/src/vk/Semaphore.cpp @@ -0,0 +1,65 @@ +// Copyright 2022 Simon Boyé + +#include +#include + +#include + + +namespace vk { + + +Semaphore::Semaphore() noexcept { +} + +Semaphore::Semaphore(Context& context) + : m_context(&context) +{ + assert(m_context); + + VkSemaphoreCreateInfo create_info { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + }; + if(vkCreateSemaphore( + context.device(), + &create_info, + nullptr, + &m_semaphore + ) != VK_SUCCESS) + throw std::runtime_error("failed to create semaphore"); +} + +Semaphore::Semaphore(Semaphore&& other) noexcept +{ + swap(*this, other); +} + +Semaphore::~Semaphore() noexcept { + if(!is_null()) + destroy(); +} + + +Semaphore& Semaphore::operator=(Semaphore&& other) noexcept { + swap(*this, other); + if(other) + other.destroy(); + return *this; +} + + +void Semaphore::destroy() noexcept { + assert(!is_null()); + assert(m_context); + + vkDestroySemaphore( + m_context->device(), + m_semaphore, + nullptr + ); + + m_semaphore = nullptr; +} + + +} diff --git a/src/vk/Semaphore.h b/src/vk/Semaphore.h new file mode 100644 index 0000000..c7a280f --- /dev/null +++ b/src/vk/Semaphore.h @@ -0,0 +1,61 @@ +// Copyright 2022 Simon Boyé +#pragma once + +#include + +#include + + +namespace vk { + + +class Semaphore { +public: + Semaphore() noexcept; + Semaphore(Context& context); + Semaphore(const Semaphore&) = delete; + Semaphore(Semaphore&& other) noexcept; + ~Semaphore() noexcept; + + Semaphore& operator=(const Semaphore&) = delete; + Semaphore& operator=(Semaphore&& other) noexcept; + + explicit inline operator bool() const noexcept { + return !is_null(); + } + + inline bool is_null() const noexcept { + return m_semaphore == VK_NULL_HANDLE; + } + + inline const Context* context() const noexcept { + return m_context; + } + + inline Context* context() noexcept { + return m_context; + } + + inline operator VkSemaphore() noexcept { + return m_semaphore; + } + + inline VkSemaphore semaphore() noexcept { + return m_semaphore; + } + + friend inline void swap(Semaphore& semaphore_0, Semaphore& semaphore_1) noexcept { + using std::swap; + swap(semaphore_0.m_context, semaphore_1.m_context); + swap(semaphore_0.m_semaphore, semaphore_1.m_semaphore); + } + + void destroy() noexcept; + +private: + Context* m_context = nullptr; + VkSemaphore m_semaphore = VK_NULL_HANDLE; +}; + + +} diff --git a/src/vk/Swapchain.cpp b/src/vk/Swapchain.cpp index f1d595c..889c370 100644 --- a/src/vk/Swapchain.cpp +++ b/src/vk/Swapchain.cpp @@ -80,7 +80,7 @@ VkImageView Swapchain::image_view(size_t image_index) { return m_image_resources[image_index].view; } -VkSemaphore Swapchain::ready_to_render() { +Semaphore& Swapchain::ready_to_render() { return m_frame_resources[m_frame_resources_index].ready_to_render; } @@ -325,22 +325,11 @@ void Swapchain::create() { image_resources.render_done = Fence(*m_context, VK_FENCE_CREATE_SIGNALED_BIT); } - m_frame_resources.resize(MAX_FRAMES_IN_FLIGHT, {}); - - int index = 0; - for(auto& frame_resources: m_frame_resources) { - VkSemaphoreCreateInfo semaphore_info { - .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, - }; - if(vkCreateSemaphore( - m_context->device(), - &semaphore_info, - nullptr, - &frame_resources.ready_to_render - ) != VK_SUCCESS) - throw std::runtime_error("failed to create semaphore"); - - index += 1; + m_frame_resources.clear(); + for(int index = 0; index < MAX_FRAMES_IN_FLIGHT; index += 1) { + m_frame_resources.emplace_back(FrameResources { + .ready_to_render = Semaphore(*m_context), + }); } for(auto& callback: m_creation_callbacks) @@ -351,11 +340,7 @@ void Swapchain::destroy() { for(auto& callback: m_destruction_callbacks) callback(); - for(auto& frame_resources: m_frame_resources) { - m_context->destroy_semaphore(frame_resources.ready_to_render); - // This is a reference to an ImageResources.render_done - frame_resources.render_done = nullptr; - } + m_frame_resources.clear(); for(auto& image_resources: m_image_resources) { image_resources.render_done.destroy(); diff --git a/src/vk/Swapchain.h b/src/vk/Swapchain.h index 8f09689..dff401b 100644 --- a/src/vk/Swapchain.h +++ b/src/vk/Swapchain.h @@ -1,6 +1,7 @@ // Copyright 2022 Simon Boyé #pragma once +#include #include #include @@ -58,7 +59,7 @@ public: VkImage image(size_t image_index); VkImageView image_view(); VkImageView image_view(size_t image_index); - VkSemaphore ready_to_render(); + Semaphore& ready_to_render(); Fence& render_done(); void initialize(const SwapchainSettings& settings); @@ -80,7 +81,7 @@ private: }; struct FrameResources { - VkSemaphore ready_to_render = VK_NULL_HANDLE; + Semaphore ready_to_render; Fence* render_done = nullptr; };