Semaphore wrapper.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Copyright 2022 Simon Boyé
|
||||
#pragma once
|
||||
|
||||
#include <vk/Context.h>
|
||||
#include <vk/Swapchain.h>
|
||||
#include <vk/Buffer.h>
|
||||
#include <vk/Semaphore.h>
|
||||
#include <vk/RenderPass.h>
|
||||
#include <vk/Buffer.h>
|
||||
#include <vk/Swapchain.h>
|
||||
#include <vk/Context.h>
|
||||
|
||||
#include <core/math.h>
|
||||
|
||||
@@ -84,7 +85,7 @@ private:
|
||||
VkDescriptorPool m_descriptor_pool = VK_NULL_HANDLE;
|
||||
std::vector<VkDescriptorSet> m_descriptor_sets;
|
||||
std::vector<VkCommandBuffer> m_command_buffers;
|
||||
std::vector<VkSemaphore> m_render_done;
|
||||
std::vector<vk::Semaphore> 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);
|
||||
|
||||
65
src/vk/Semaphore.cpp
Normal file
65
src/vk/Semaphore.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright 2022 Simon Boyé
|
||||
|
||||
#include <vk/Semaphore.h>
|
||||
#include <vk/Context.h>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
61
src/vk/Semaphore.h
Normal file
61
src/vk/Semaphore.h
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright 2022 Simon Boyé
|
||||
#pragma once
|
||||
|
||||
#include <vk/forward.h>
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2022 Simon Boyé
|
||||
#pragma once
|
||||
|
||||
#include <vk/Semaphore.h>
|
||||
#include <vk/Context.h>
|
||||
|
||||
#include <core/utils.h>
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user