Browse Source

Semaphore wrapper.

master
Draklaw 4 years ago
parent
commit
c73d773845
  1. 1
      CMakeLists.txt
  2. 26
      src/VulkanTutorial.cpp
  3. 9
      src/VulkanTutorial.h
  4. 65
      src/vk/Semaphore.cpp
  5. 61
      src/vk/Semaphore.h
  6. 29
      src/vk/Swapchain.cpp
  7. 5
      src/vk/Swapchain.h

1
CMakeLists.txt

@ -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

26
src/VulkanTutorial.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");
} }
} }

9
src/VulkanTutorial.h

@ -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

@ -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

@ -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;
};
}

29
src/vk/Swapchain.cpp

@ -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();

5
src/vk/Swapchain.h

@ -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;
}; };

Loading…
Cancel
Save