15 changed files with 352 additions and 58 deletions
@ -0,0 +1,123 @@ |
|||||
|
// Copyright 2022 Simon Boyé
|
||||
|
|
||||
|
#include <vk/Fence.h> |
||||
|
#include <vk/Context.h> |
||||
|
|
||||
|
#include <cassert> |
||||
|
|
||||
|
|
||||
|
namespace vk { |
||||
|
|
||||
|
|
||||
|
Fence::Fence() noexcept { |
||||
|
} |
||||
|
|
||||
|
Fence::Fence(Context& context, VkFenceCreateFlags flags) |
||||
|
: m_context(&context) |
||||
|
{ |
||||
|
assert(m_context); |
||||
|
|
||||
|
VkFenceCreateInfo create_info { |
||||
|
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, |
||||
|
.flags = flags, |
||||
|
}; |
||||
|
if(vkCreateFence( |
||||
|
context.device(), |
||||
|
&create_info, |
||||
|
nullptr, |
||||
|
&m_fence |
||||
|
) != VK_SUCCESS) |
||||
|
throw std::runtime_error("failed to create fence"); |
||||
|
} |
||||
|
|
||||
|
Fence::Fence(Fence&& other) noexcept |
||||
|
{ |
||||
|
swap(*this, other); |
||||
|
} |
||||
|
|
||||
|
Fence::~Fence() noexcept { |
||||
|
if(is_valid()) |
||||
|
destroy(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
Fence& Fence::operator=(Fence&& other) noexcept { |
||||
|
swap(*this, other); |
||||
|
if(other) |
||||
|
other.destroy(); |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
VkResult Fence::get_status() const { |
||||
|
assert(m_context); |
||||
|
assert(is_valid()); |
||||
|
|
||||
|
VkResult result = vkGetFenceStatus( |
||||
|
m_context->device(), |
||||
|
m_fence |
||||
|
); |
||||
|
|
||||
|
if(result < 0) |
||||
|
throw std::runtime_error("failed to get fence status"); |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
void Fence::reset() { |
||||
|
assert(m_context); |
||||
|
assert(is_valid()); |
||||
|
|
||||
|
if(vkResetFences( |
||||
|
m_context->device(), |
||||
|
1, |
||||
|
&m_fence |
||||
|
) != VK_SUCCESS) |
||||
|
throw std::runtime_error("failed to reset fence"); |
||||
|
} |
||||
|
|
||||
|
void Fence::wait(uint64_t timeout) const { |
||||
|
assert(m_context); |
||||
|
assert(is_valid()); |
||||
|
|
||||
|
wait_for_fences( |
||||
|
m_context->device(), |
||||
|
ArrayView<VkFence>(1, const_cast<VkFence*>(&m_fence)), |
||||
|
true, |
||||
|
timeout |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void Fence::destroy() noexcept { |
||||
|
assert(is_valid()); |
||||
|
assert(m_context); |
||||
|
|
||||
|
vkDestroyFence( |
||||
|
m_context->device(), |
||||
|
m_fence, |
||||
|
nullptr |
||||
|
); |
||||
|
|
||||
|
m_fence = nullptr; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void wait_for_fences(VkDevice device, ArrayView<VkFence> fences, bool wait_all, uint64_t timeout) { |
||||
|
assert(fences.is_dense()); |
||||
|
|
||||
|
if(fences.size() == 0) |
||||
|
return; |
||||
|
|
||||
|
if(vkWaitForFences( |
||||
|
device, |
||||
|
fences.size(), |
||||
|
fences.data(), |
||||
|
wait_all, |
||||
|
timeout |
||||
|
) != VK_SUCCESS) |
||||
|
throw std::runtime_error("failed to wait for fences"); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,69 @@ |
|||||
|
// Copyright 2022 Simon Boyé
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <core/ArrayView.h> |
||||
|
|
||||
|
#include <vk/forward.h> |
||||
|
|
||||
|
#include <vulkan/vulkan.h> |
||||
|
|
||||
|
|
||||
|
namespace vk { |
||||
|
|
||||
|
|
||||
|
class Fence { |
||||
|
public: |
||||
|
Fence() noexcept; |
||||
|
Fence(Context& context, VkFenceCreateFlags flags=0); |
||||
|
Fence(const Fence&) = delete; |
||||
|
Fence(Fence&& other) noexcept; |
||||
|
~Fence() noexcept; |
||||
|
|
||||
|
Fence& operator=(const Fence&) = delete; |
||||
|
Fence& operator=(Fence&& other) noexcept; |
||||
|
|
||||
|
explicit inline operator bool() const noexcept { |
||||
|
return is_valid(); |
||||
|
} |
||||
|
|
||||
|
inline bool is_valid() const noexcept { |
||||
|
return m_fence != VK_NULL_HANDLE; |
||||
|
} |
||||
|
|
||||
|
inline const Context* context() const noexcept { |
||||
|
return m_context; |
||||
|
} |
||||
|
|
||||
|
inline Context* context() noexcept { |
||||
|
return m_context; |
||||
|
} |
||||
|
|
||||
|
inline operator VkFence() noexcept { |
||||
|
return m_fence; |
||||
|
} |
||||
|
|
||||
|
inline VkFence fence() noexcept { |
||||
|
return m_fence; |
||||
|
} |
||||
|
|
||||
|
VkResult get_status() const; |
||||
|
void reset(); |
||||
|
void wait(uint64_t timeout=UINT64_MAX) const; |
||||
|
|
||||
|
friend inline void swap(Fence& fence_0, Fence& fence_1) noexcept { |
||||
|
using std::swap; |
||||
|
swap(fence_0.m_context, fence_1.m_context); |
||||
|
swap(fence_0.m_fence, fence_1.m_fence); |
||||
|
} |
||||
|
|
||||
|
void destroy() noexcept; |
||||
|
|
||||
|
private: |
||||
|
Context* m_context = nullptr; |
||||
|
VkFence m_fence = VK_NULL_HANDLE; |
||||
|
}; |
||||
|
|
||||
|
void wait_for_fences(VkDevice device, ArrayView<VkFence> fences, bool wait_all=true, uint64_t timeout=UINT64_MAX); |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,63 @@ |
|||||
|
// Copyright 2022 Simon Boyé
|
||||
|
|
||||
|
#include <vk/RenderPass.h> |
||||
|
#include <vk/Context.h> |
||||
|
|
||||
|
#include <cassert> |
||||
|
|
||||
|
|
||||
|
namespace vk { |
||||
|
|
||||
|
|
||||
|
RenderPass::RenderPass() noexcept { |
||||
|
} |
||||
|
|
||||
|
RenderPass::RenderPass(Context& context, const VkRenderPassCreateInfo& create_info) |
||||
|
: m_context(&context) |
||||
|
{ |
||||
|
assert(m_context); |
||||
|
|
||||
|
if(vkCreateRenderPass( |
||||
|
context.device(), |
||||
|
&create_info, |
||||
|
nullptr, |
||||
|
&m_render_pass |
||||
|
) != VK_SUCCESS) |
||||
|
throw std::runtime_error("failed to create render pass"); |
||||
|
} |
||||
|
|
||||
|
RenderPass::RenderPass(RenderPass&& other) noexcept |
||||
|
{ |
||||
|
swap(*this, other); |
||||
|
} |
||||
|
|
||||
|
RenderPass::~RenderPass() noexcept { |
||||
|
if(is_valid()) |
||||
|
destroy(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
RenderPass& RenderPass::operator=(RenderPass&& other) noexcept { |
||||
|
swap(*this, other); |
||||
|
if(other) |
||||
|
other.destroy(); |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void RenderPass::destroy() noexcept { |
||||
|
assert(is_valid()); |
||||
|
assert(m_context); |
||||
|
|
||||
|
vkDestroyRenderPass( |
||||
|
m_context->device(), |
||||
|
m_render_pass, |
||||
|
nullptr |
||||
|
); |
||||
|
|
||||
|
m_render_pass = nullptr; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,53 @@ |
|||||
|
// Copyright 2022 Simon Boyé
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <vk/forward.h> |
||||
|
|
||||
|
#include <vulkan/vulkan.h> |
||||
|
|
||||
|
|
||||
|
namespace vk { |
||||
|
|
||||
|
|
||||
|
class RenderPass { |
||||
|
public: |
||||
|
RenderPass() noexcept; |
||||
|
RenderPass(Context& context, const VkRenderPassCreateInfo& create_info); |
||||
|
RenderPass(const RenderPass&) = delete; |
||||
|
RenderPass(RenderPass&& other) noexcept; |
||||
|
~RenderPass() noexcept; |
||||
|
|
||||
|
RenderPass& operator=(const RenderPass&) = delete; |
||||
|
RenderPass& operator=(RenderPass&& other) noexcept; |
||||
|
|
||||
|
explicit inline operator bool() const noexcept { |
||||
|
return is_valid(); |
||||
|
} |
||||
|
|
||||
|
inline bool is_valid() const noexcept { |
||||
|
return m_render_pass != VK_NULL_HANDLE; |
||||
|
} |
||||
|
|
||||
|
inline operator VkRenderPass() noexcept { |
||||
|
return m_render_pass; |
||||
|
} |
||||
|
|
||||
|
inline VkRenderPass render_pass() noexcept { |
||||
|
return m_render_pass; |
||||
|
} |
||||
|
|
||||
|
friend inline void swap(RenderPass& render_pass_0, RenderPass& render_pass_1) noexcept { |
||||
|
using std::swap; |
||||
|
swap(render_pass_0.m_context, render_pass_1.m_context); |
||||
|
swap(render_pass_0.m_render_pass, render_pass_1.m_render_pass); |
||||
|
} |
||||
|
|
||||
|
void destroy() noexcept; |
||||
|
|
||||
|
private: |
||||
|
Context* m_context = nullptr; |
||||
|
VkRenderPass m_render_pass = VK_NULL_HANDLE; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
} |
||||
Loading…
Reference in new issue