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