Semaphore wrapper.
This commit is contained in:
@@ -38,6 +38,7 @@ add_executable(vk_expe
|
|||||||
|
|
||||||
src/vk/Context.cpp
|
src/vk/Context.cpp
|
||||||
src/vk/Fence.cpp
|
src/vk/Fence.cpp
|
||||||
|
src/vk/Semaphore.cpp
|
||||||
src/vk/Swapchain.cpp
|
src/vk/Swapchain.cpp
|
||||||
src/vk/Memory.cpp
|
src/vk/Memory.cpp
|
||||||
src/vk/Buffer.cpp
|
src/vk/Buffer.cpp
|
||||||
|
|||||||
@@ -187,8 +187,6 @@ void VulkanTutorial::shutdown() {
|
|||||||
m_vertex_buffer.destroy();
|
m_vertex_buffer.destroy();
|
||||||
m_context.destroy_descriptor_set_layout(m_descriptor_set_layout);
|
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_render_done.clear();
|
||||||
|
|
||||||
m_swapchain.shutdown();
|
m_swapchain.shutdown();
|
||||||
@@ -254,6 +252,9 @@ void VulkanTutorial::draw_frame() {
|
|||||||
VkSemaphore wait_semaphores[] = {
|
VkSemaphore wait_semaphores[] = {
|
||||||
m_swapchain.ready_to_render(),
|
m_swapchain.ready_to_render(),
|
||||||
};
|
};
|
||||||
|
VkSemaphore done_semaphores[] = {
|
||||||
|
m_render_done[image_index],
|
||||||
|
};
|
||||||
VkPipelineStageFlags stages[] = {
|
VkPipelineStageFlags stages[] = {
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
};
|
};
|
||||||
@@ -265,7 +266,7 @@ void VulkanTutorial::draw_frame() {
|
|||||||
.commandBufferCount = 1,
|
.commandBufferCount = 1,
|
||||||
.pCommandBuffers = &m_command_buffers[image_index],
|
.pCommandBuffers = &m_command_buffers[image_index],
|
||||||
.signalSemaphoreCount = 1,
|
.signalSemaphoreCount = 1,
|
||||||
.pSignalSemaphores = &m_render_done[image_index],
|
.pSignalSemaphores = done_semaphores,
|
||||||
};
|
};
|
||||||
|
|
||||||
if(vkQueueSubmit(
|
if(vkQueueSubmit(
|
||||||
@@ -275,7 +276,7 @@ void VulkanTutorial::draw_frame() {
|
|||||||
))
|
))
|
||||||
throw std::runtime_error("failed to submit draw command buffer");
|
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() {
|
void VulkanTutorial::invalidate_swapchain() {
|
||||||
@@ -291,20 +292,9 @@ void VulkanTutorial::create_swapchain_objects(uint32_t image_count) {
|
|||||||
create_graphic_pipeline();
|
create_graphic_pipeline();
|
||||||
create_command_buffers();
|
create_command_buffers();
|
||||||
|
|
||||||
m_render_done.resize(m_swapchain.image_count());
|
m_render_done.clear();
|
||||||
|
for(size_t index = 0; index < m_swapchain.image_count(); index += 1) {
|
||||||
VkSemaphoreCreateInfo semaphore_info {
|
m_render_done.emplace_back(m_context);
|
||||||
.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");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
// Copyright 2022 Simon Boyé
|
// Copyright 2022 Simon Boyé
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vk/Context.h>
|
#include <vk/Semaphore.h>
|
||||||
#include <vk/Swapchain.h>
|
|
||||||
#include <vk/Buffer.h>
|
|
||||||
#include <vk/RenderPass.h>
|
#include <vk/RenderPass.h>
|
||||||
|
#include <vk/Buffer.h>
|
||||||
|
#include <vk/Swapchain.h>
|
||||||
|
#include <vk/Context.h>
|
||||||
|
|
||||||
#include <core/math.h>
|
#include <core/math.h>
|
||||||
|
|
||||||
@@ -84,7 +85,7 @@ private:
|
|||||||
VkDescriptorPool m_descriptor_pool = VK_NULL_HANDLE;
|
VkDescriptorPool m_descriptor_pool = VK_NULL_HANDLE;
|
||||||
std::vector<VkDescriptorSet> m_descriptor_sets;
|
std::vector<VkDescriptorSet> m_descriptor_sets;
|
||||||
std::vector<VkCommandBuffer> m_command_buffers;
|
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_position = Vector3(0.0f, 0.0f, -3.0f);
|
||||||
Vector3 m_camera_z = Vector3(0.0f, 0.0f, 1.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;
|
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;
|
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);
|
image_resources.render_done = Fence(*m_context, VK_FENCE_CREATE_SIGNALED_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_frame_resources.resize(MAX_FRAMES_IN_FLIGHT, {});
|
m_frame_resources.clear();
|
||||||
|
for(int index = 0; index < MAX_FRAMES_IN_FLIGHT; index += 1) {
|
||||||
int index = 0;
|
m_frame_resources.emplace_back(FrameResources {
|
||||||
for(auto& frame_resources: m_frame_resources) {
|
.ready_to_render = Semaphore(*m_context),
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto& callback: m_creation_callbacks)
|
for(auto& callback: m_creation_callbacks)
|
||||||
@@ -351,11 +340,7 @@ void Swapchain::destroy() {
|
|||||||
for(auto& callback: m_destruction_callbacks)
|
for(auto& callback: m_destruction_callbacks)
|
||||||
callback();
|
callback();
|
||||||
|
|
||||||
for(auto& frame_resources: m_frame_resources) {
|
m_frame_resources.clear();
|
||||||
m_context->destroy_semaphore(frame_resources.ready_to_render);
|
|
||||||
// This is a reference to an ImageResources.render_done
|
|
||||||
frame_resources.render_done = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto& image_resources: m_image_resources) {
|
for(auto& image_resources: m_image_resources) {
|
||||||
image_resources.render_done.destroy();
|
image_resources.render_done.destroy();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright 2022 Simon Boyé
|
// Copyright 2022 Simon Boyé
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <vk/Semaphore.h>
|
||||||
#include <vk/Context.h>
|
#include <vk/Context.h>
|
||||||
|
|
||||||
#include <core/utils.h>
|
#include <core/utils.h>
|
||||||
@@ -58,7 +59,7 @@ public:
|
|||||||
VkImage image(size_t image_index);
|
VkImage image(size_t image_index);
|
||||||
VkImageView image_view();
|
VkImageView image_view();
|
||||||
VkImageView image_view(size_t image_index);
|
VkImageView image_view(size_t image_index);
|
||||||
VkSemaphore ready_to_render();
|
Semaphore& ready_to_render();
|
||||||
Fence& render_done();
|
Fence& render_done();
|
||||||
|
|
||||||
void initialize(const SwapchainSettings& settings);
|
void initialize(const SwapchainSettings& settings);
|
||||||
@@ -80,7 +81,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct FrameResources {
|
struct FrameResources {
|
||||||
VkSemaphore ready_to_render = VK_NULL_HANDLE;
|
Semaphore ready_to_render;
|
||||||
Fence* render_done = nullptr;
|
Fence* render_done = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user