Browse Source

DescriptorSet related wrappers.

master
Draklaw 4 years ago
parent
commit
8358558ddb
  1. 7
      CMakeLists.txt
  2. 99
      src/VulkanTutorial.cpp
  3. 12
      src/VulkanTutorial.h
  4. 74
      src/vk/DescriptorPool.cpp
  5. 68
      src/vk/DescriptorPool.h
  6. 76
      src/vk/DescriptorSet.cpp
  7. 79
      src/vk/DescriptorSet.h
  8. 67
      src/vk/DescriptorSetLayout.cpp
  9. 63
      src/vk/DescriptorSetLayout.h
  10. 73
      src/vk/PipelineLayout.cpp
  11. 67
      src/vk/PipelineLayout.h
  12. 48
      src/vk/Wrapper.cpp
  13. 56
      src/vk/Wrapper.h

7
CMakeLists.txt

@ -36,19 +36,24 @@ add_executable(vk_expe
src/core/utils.cpp src/core/utils.cpp
src/core/Logger.cpp src/core/Logger.cpp
src/vk/Wrapper.cpp
src/vk/Context.cpp src/vk/Context.cpp
src/vk/CommandPool.cpp src/vk/CommandPool.cpp
src/vk/CommandBuffer.cpp src/vk/CommandBuffer.cpp
src/vk/Fence.cpp src/vk/Fence.cpp
src/vk/Semaphore.cpp src/vk/Semaphore.cpp
src/vk/RenderPass.cpp
src/vk/Framebuffer.cpp src/vk/Framebuffer.cpp
src/vk/ShaderModule.cpp src/vk/ShaderModule.cpp
src/vk/Pipeline.cpp src/vk/Pipeline.cpp
src/vk/Memory.cpp src/vk/Memory.cpp
src/vk/Buffer.cpp src/vk/Buffer.cpp
src/vk/ImageView.cpp src/vk/ImageView.cpp
src/vk/DescriptorSetLayout.cpp
src/vk/PipelineLayout.cpp
src/vk/DescriptorPool.cpp
src/vk/DescriptorSet.cpp
src/vk/Swapchain.cpp src/vk/Swapchain.cpp
src/vk/RenderPass.cpp
src/main.cpp src/main.cpp
src/Simplex.cpp src/Simplex.cpp

99
src/VulkanTutorial.cpp

@ -187,7 +187,7 @@ void VulkanTutorial::shutdown() {
m_command_pool.destroy(); m_command_pool.destroy();
m_index_buffer.destroy(); m_index_buffer.destroy();
m_vertex_buffer.destroy(); m_vertex_buffer.destroy();
m_context.destroy_descriptor_set_layout(m_descriptor_set_layout); m_descriptor_set_layout.destroy();
m_render_done.clear(); m_render_done.clear();
@ -314,12 +314,12 @@ void VulkanTutorial::destroy_swapchain_objects() {
m_uniform_buffers.clear(); m_uniform_buffers.clear();
m_uniform_buffer_memory.free(); m_uniform_buffer_memory.free();
m_context.destroy_descriptor_pool(m_descriptor_pool); m_descriptor_pool.destroy();
m_framebuffers.clear(); m_framebuffers.clear();
m_pipeline.destroy(); m_pipeline.destroy();
m_context.destroy_pipeline_layout(m_pipeline_layout); m_pipeline_layout.destroy();
m_render_pass.destroy(); m_render_pass.destroy();
} }
@ -369,25 +369,16 @@ void VulkanTutorial::create_render_pass() {
} }
void VulkanTutorial::create_descriptor_set_layout() { void VulkanTutorial::create_descriptor_set_layout() {
VkDescriptorSetLayoutBinding binding { VkDescriptorSetLayoutBinding binding[] {
.binding = 0, {
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .binding = 0,
.descriptorCount = 1, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT, .descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT,
}
}; };
VkDescriptorSetLayoutCreateInfo layout_info { m_descriptor_set_layout = vk::DescriptorSetLayout(m_context, binding);
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = 1,
.pBindings = &binding,
};
if(vkCreateDescriptorSetLayout(
m_context.device(),
&layout_info,
nullptr,
&m_descriptor_set_layout
) != VK_SUCCESS)
throw std::runtime_error("failed to create descriptor set layout");
} }
void VulkanTutorial::create_graphic_pipeline() { void VulkanTutorial::create_graphic_pipeline() {
@ -506,21 +497,10 @@ void VulkanTutorial::create_graphic_pipeline() {
.blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f }, .blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f },
}; };
VkPipelineLayoutCreateInfo layout_info = { VkDescriptorSetLayout set_layouts[] {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, m_descriptor_set_layout,
.setLayoutCount = 1,
.pSetLayouts = &m_descriptor_set_layout,
.pushConstantRangeCount = 0,
.pPushConstantRanges = nullptr,
}; };
m_pipeline_layout = vk::PipelineLayout(m_context, set_layouts);
if(vkCreatePipelineLayout(
m_context.device(),
&layout_info,
nullptr,
&m_pipeline_layout
) != VK_SUCCESS)
throw std::runtime_error("failed to create pipeline layout");
VkGraphicsPipelineCreateInfo pipeline_info { VkGraphicsPipelineCreateInfo pipeline_info {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
@ -628,46 +608,24 @@ void VulkanTutorial::create_uniform_buffer() {
} }
void VulkanTutorial::create_descriptor_pool() { void VulkanTutorial::create_descriptor_pool() {
VkDescriptorPoolSize pool_size { VkDescriptorPoolSize pool_sizes[] {
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, {
.descriptorCount = uint32_t(m_swapchain.image_count()), .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = uint32_t(m_swapchain.image_count()),
}
}; };
VkDescriptorPoolCreateInfo pool_info { m_descriptor_pool = vk::DescriptorPool(
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, m_context,
.maxSets = uint32_t(m_swapchain.image_count()), uint32_t(m_swapchain.image_count()),
.poolSizeCount = 1, pool_sizes
.pPoolSizes = &pool_size, );
};
if(vkCreateDescriptorPool(
m_context.device(),
&pool_info,
nullptr,
&m_descriptor_pool
) != VK_SUCCESS)
throw std::runtime_error("failed to create descriptor pool");
} }
void VulkanTutorial::create_descriptor_sets() { void VulkanTutorial::create_descriptor_sets() {
const std::vector<VkDescriptorSetLayout> layouts( m_descriptor_sets.clear();
m_swapchain.image_count(), m_descriptor_set_layout);
VkDescriptorSetAllocateInfo alloc_info {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = m_descriptor_pool,
.descriptorSetCount = uint32_t(layouts.size()),
.pSetLayouts = layouts.data(),
};
m_descriptor_sets.resize(m_swapchain.image_count());
if(vkAllocateDescriptorSets(
m_context.device(),
&alloc_info,
m_descriptor_sets.data()
) != VK_SUCCESS)
throw std::runtime_error("failed to allocate descriptor sets");
for(size_t index = 0; index < m_swapchain.image_count(); index += 1) { for(size_t index = 0; index < m_swapchain.image_count(); index += 1) {
m_descriptor_sets.emplace_back(m_context, m_descriptor_pool, m_descriptor_set_layout);
VkDescriptorBufferInfo buffer_info { VkDescriptorBufferInfo buffer_info {
.buffer = m_uniform_buffers[index], .buffer = m_uniform_buffers[index],
.offset = 0, .offset = 0,
@ -762,11 +720,14 @@ void VulkanTutorial::create_command_buffers() {
VK_INDEX_TYPE_UINT32 VK_INDEX_TYPE_UINT32
); );
VkDescriptorSet descriptor_sets[] {
m_descriptor_sets[index],
};
vkCmdBindDescriptorSets( vkCmdBindDescriptorSets(
command_buffer, command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_pipeline_layout, m_pipeline_layout,
0, 1, &m_descriptor_sets[index], 0, 1, descriptor_sets,
0, nullptr 0, nullptr
); );

12
src/VulkanTutorial.h

@ -2,6 +2,10 @@
#pragma once #pragma once
#include <vk/Swapchain.h> #include <vk/Swapchain.h>
#include <vk/DescriptorSet.h>
#include <vk/DescriptorPool.h>
#include <vk/PipelineLayout.h>
#include <vk/DescriptorSetLayout.h>
#include <vk/Buffer.h> #include <vk/Buffer.h>
#include <vk/Pipeline.h> #include <vk/Pipeline.h>
#include <vk/Framebuffer.h> #include <vk/Framebuffer.h>
@ -76,8 +80,8 @@ private:
VkQueue m_presentation_queue = nullptr; VkQueue m_presentation_queue = nullptr;
vk::RenderPass m_render_pass; vk::RenderPass m_render_pass;
VkDescriptorSetLayout m_descriptor_set_layout = VK_NULL_HANDLE; vk::DescriptorSetLayout m_descriptor_set_layout;
VkPipelineLayout m_pipeline_layout = VK_NULL_HANDLE; vk::PipelineLayout m_pipeline_layout;
vk::Pipeline m_pipeline; vk::Pipeline m_pipeline;
std::vector<vk::Framebuffer> m_framebuffers; std::vector<vk::Framebuffer> m_framebuffers;
vk::CommandPool m_command_pool; vk::CommandPool m_command_pool;
@ -86,8 +90,8 @@ private:
std::vector<vk::Buffer> m_uniform_buffers; std::vector<vk::Buffer> m_uniform_buffers;
std::vector<VkDeviceSize> m_uniform_buffer_offsets; std::vector<VkDeviceSize> m_uniform_buffer_offsets;
vk::MemoryBlock m_uniform_buffer_memory; vk::MemoryBlock m_uniform_buffer_memory;
VkDescriptorPool m_descriptor_pool = VK_NULL_HANDLE; vk::DescriptorPool m_descriptor_pool;
std::vector<VkDescriptorSet> m_descriptor_sets; std::vector<vk::DescriptorSet> m_descriptor_sets;
std::vector<vk::CommandBuffer> m_command_buffers; std::vector<vk::CommandBuffer> m_command_buffers;
std::vector<vk::Semaphore> m_render_done; std::vector<vk::Semaphore> m_render_done;

74
src/vk/DescriptorPool.cpp

@ -0,0 +1,74 @@
// Copyright 2022 Simon Boyé
#include <vk/DescriptorPool.h>
#include <vk/Context.h>
#include <cassert>
namespace vk {
DescriptorPool::DescriptorPool() noexcept {
}
DescriptorPool::DescriptorPool(
Context& context,
uint32_t max_sets,
Array<const VkDescriptorPoolSize> pool_sizes,
VkDescriptorPoolCreateFlags flags
)
: m_context(&context)
{
assert(m_context);
VkDescriptorPoolCreateInfo create_info {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.flags = flags,
.maxSets = max_sets,
.poolSizeCount = uint32_t(pool_sizes.size()),
.pPoolSizes = pool_sizes.data(),
};
if(vkCreateDescriptorPool(
context.device(),
&create_info,
nullptr,
&m_descriptor_pool
) != VK_SUCCESS)
throw std::runtime_error("failed to create descriptor pool");
}
DescriptorPool::DescriptorPool(DescriptorPool&& other) noexcept
{
swap(*this, other);
}
DescriptorPool::~DescriptorPool() noexcept {
if(!is_null())
destroy();
}
DescriptorPool& DescriptorPool::operator=(DescriptorPool&& other) noexcept {
swap(*this, other);
if(other)
other.destroy();
return *this;
}
void DescriptorPool::destroy() noexcept {
assert(!is_null());
assert(m_context);
vkDestroyDescriptorPool(
m_context->device(),
m_descriptor_pool,
nullptr
);
m_descriptor_pool = nullptr;
}
}

68
src/vk/DescriptorPool.h

@ -0,0 +1,68 @@
// Copyright 2022 Simon Boyé
#pragma once
#include <core/utils.h>
#include <vk/forward.h>
#include <vulkan/vulkan.h>
namespace vk {
class DescriptorPool {
public:
DescriptorPool() noexcept;
DescriptorPool(
Context& context,
uint32_t max_sets,
Array<const VkDescriptorPoolSize> pool_sizes,
VkDescriptorPoolCreateFlags flags=0
);
DescriptorPool(const DescriptorPool&) = delete;
DescriptorPool(DescriptorPool&& other) noexcept;
~DescriptorPool() noexcept;
DescriptorPool& operator=(const DescriptorPool&) = delete;
DescriptorPool& operator=(DescriptorPool&& other) noexcept;
explicit inline operator bool() const noexcept {
return !is_null();
}
inline bool is_null() const noexcept {
return m_descriptor_pool == VK_NULL_HANDLE;
}
inline const Context* context() const noexcept {
return m_context;
}
inline Context* context() noexcept {
return m_context;
}
inline operator VkDescriptorPool() noexcept {
return m_descriptor_pool;
}
inline VkDescriptorPool descriptor_pool() noexcept {
return m_descriptor_pool;
}
friend inline void swap(DescriptorPool& descriptor_pool_0, DescriptorPool& descriptor_pool_1) noexcept {
using std::swap;
swap(descriptor_pool_0.m_context, descriptor_pool_1.m_context);
swap(descriptor_pool_0.m_descriptor_pool, descriptor_pool_1.m_descriptor_pool);
}
void destroy() noexcept;
private:
Context* m_context = nullptr;
VkDescriptorPool m_descriptor_pool = VK_NULL_HANDLE;
};
}

76
src/vk/DescriptorSet.cpp

@ -0,0 +1,76 @@
// Copyright 2022 Simon Boyé
#include <vk/DescriptorSet.h>
#include <vk/Context.h>
#include <cassert>
namespace vk {
DescriptorSet::DescriptorSet() noexcept {
}
DescriptorSet::DescriptorSet(
Context& context,
VkDescriptorPool descriptor_pool,
const VkDescriptorSetLayout& set_layout
)
: Wrapper(context, 0)
, m_descriptor_pool(descriptor_pool)
{
assert(m_descriptor_pool != VK_NULL_HANDLE);
VkDescriptorSetAllocateInfo create_info {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = m_descriptor_pool,
.descriptorSetCount = 1,
.pSetLayouts = &set_layout,
};
if(vkAllocateDescriptorSets(
context.device(),
&create_info,
&m_descriptor_set
) != VK_SUCCESS)
throw std::runtime_error("failed to create descriptor_set");
}
DescriptorSet::DescriptorSet(DescriptorSet&& other) noexcept
{
swap(other);
}
DescriptorSet::~DescriptorSet() noexcept {
if(!is_null())
destroy();
}
DescriptorSet& DescriptorSet::operator=(DescriptorSet&& other) noexcept {
swap(other);
if(other)
other.destroy();
return *this;
}
void DescriptorSet::destroy() noexcept {
assert(!is_null());
assert(m_context);
if (!own_underlying_object())
return;
vkFreeDescriptorSets(
m_context->device(),
m_descriptor_pool,
1,
&m_descriptor_set
);
m_descriptor_set = nullptr;
}
}

79
src/vk/DescriptorSet.h

@ -0,0 +1,79 @@
// Copyright 2022 Simon Boyé
#pragma once
#include <vk/forward.h>
#include <vk/Wrapper.h>
#include <vulkan/vulkan.h>
namespace vk {
class DescriptorSet: public Wrapper {
public:
DescriptorSet() noexcept;
DescriptorSet(
Context& context,
VkDescriptorPool descriptor_pool,
const VkDescriptorSetLayout& set_layout
);
DescriptorSet(const DescriptorSet&) = delete;
DescriptorSet(DescriptorSet&& other) noexcept;
~DescriptorSet() noexcept;
DescriptorSet& operator=(const DescriptorSet&) = delete;
DescriptorSet& operator=(DescriptorSet&& other) noexcept;
explicit inline operator bool() const noexcept {
return !is_null();
}
inline bool is_null() const noexcept {
return m_descriptor_set == VK_NULL_HANDLE;
}
inline const Context* context() const noexcept {
return m_context;
}
inline Context* context() noexcept {
return m_context;
}
inline const VkDescriptorPool descriptor_pool() const noexcept {
return m_descriptor_pool;
}
inline VkDescriptorPool descriptor_pool() noexcept {
return m_descriptor_pool;
}
inline operator VkDescriptorSet() noexcept {
return m_descriptor_set;
}
inline VkDescriptorSet descriptor_set() noexcept {
return m_descriptor_set;
}
inline void swap(DescriptorSet& other) noexcept {
using std::swap;
swap(m_context, other.m_context);
swap(m_descriptor_pool, other.m_descriptor_pool);
swap(m_descriptor_set, other.m_descriptor_set);
}
friend inline void swap(DescriptorSet& descriptor_set_0, DescriptorSet& descriptor_set_1) noexcept {
descriptor_set_0.swap(descriptor_set_1);
}
void destroy() noexcept;
private:
VkDescriptorPool m_descriptor_pool = VK_NULL_HANDLE;
VkDescriptorSet m_descriptor_set = VK_NULL_HANDLE;
};
}

67
src/vk/DescriptorSetLayout.cpp

@ -0,0 +1,67 @@
// Copyright 2022 Simon Boyé
#include <vk/DescriptorSetLayout.h>
#include <vk/Context.h>
#include <cassert>
namespace vk {
DescriptorSetLayout::DescriptorSetLayout() noexcept {
}
DescriptorSetLayout::DescriptorSetLayout(Context& context, Array<const VkDescriptorSetLayoutBinding> bindings)
: m_context(&context)
{
assert(m_context);
VkDescriptorSetLayoutCreateInfo create_info {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = uint32_t(bindings.size()),
.pBindings = bindings.data(),
};
if(vkCreateDescriptorSetLayout(
context.device(),
&create_info,
nullptr,
&m_descriptor_set_layout
) != VK_SUCCESS)
throw std::runtime_error("failed to create descriptor set layout");
}
DescriptorSetLayout::DescriptorSetLayout(DescriptorSetLayout&& other) noexcept
{
swap(*this, other);
}
DescriptorSetLayout::~DescriptorSetLayout() noexcept {
if(!is_null())
destroy();
}
DescriptorSetLayout& DescriptorSetLayout::operator=(DescriptorSetLayout&& other) noexcept {
swap(*this, other);
if(other)
other.destroy();
return *this;
}
void DescriptorSetLayout::destroy() noexcept {
assert(!is_null());
assert(m_context);
vkDestroyDescriptorSetLayout(
m_context->device(),
m_descriptor_set_layout,
nullptr
);
m_descriptor_set_layout = nullptr;
}
}

63
src/vk/DescriptorSetLayout.h

@ -0,0 +1,63 @@
// Copyright 2022 Simon Boyé
#pragma once
#include <core/utils.h>
#include <vk/forward.h>
#include <vulkan/vulkan.h>
namespace vk {
class DescriptorSetLayout {
public:
DescriptorSetLayout() noexcept;
DescriptorSetLayout(Context& context, Array<const VkDescriptorSetLayoutBinding> bindings);
DescriptorSetLayout(const DescriptorSetLayout&) = delete;
DescriptorSetLayout(DescriptorSetLayout&& other) noexcept;
~DescriptorSetLayout() noexcept;
DescriptorSetLayout& operator=(const DescriptorSetLayout&) = delete;
DescriptorSetLayout& operator=(DescriptorSetLayout&& other) noexcept;
explicit inline operator bool() const noexcept {
return !is_null();
}
inline bool is_null() const noexcept {
return m_descriptor_set_layout == VK_NULL_HANDLE;
}
inline const Context* context() const noexcept {
return m_context;
}
inline Context* context() noexcept {
return m_context;
}
inline operator VkDescriptorSetLayout() noexcept {
return m_descriptor_set_layout;
}
inline VkDescriptorSetLayout descriptor_set_layout() noexcept {
return m_descriptor_set_layout;
}
friend inline void swap(DescriptorSetLayout& descriptor_set_layout_0, DescriptorSetLayout& descriptor_set_layout_1) noexcept {
using std::swap;
swap(descriptor_set_layout_0.m_context, descriptor_set_layout_1.m_context);
swap(descriptor_set_layout_0.m_descriptor_set_layout, descriptor_set_layout_1.m_descriptor_set_layout);
}
void destroy() noexcept;
private:
Context* m_context = nullptr;
VkDescriptorSetLayout m_descriptor_set_layout = VK_NULL_HANDLE;
};
}

73
src/vk/PipelineLayout.cpp

@ -0,0 +1,73 @@
// Copyright 2022 Simon Boyé
#include <vk/PipelineLayout.h>
#include <vk/Context.h>
#include <cassert>
namespace vk {
PipelineLayout::PipelineLayout() noexcept {
}
PipelineLayout::PipelineLayout(
Context& context,
Array<const VkDescriptorSetLayout> set_layouts,
Array<const VkPushConstantRange> push_constant_ranges
)
: m_context(&context)
{
assert(m_context);
VkPipelineLayoutCreateInfo create_info {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = uint32_t(set_layouts.size()),
.pSetLayouts = set_layouts.data(),
.pushConstantRangeCount = uint32_t(push_constant_ranges.size()),
.pPushConstantRanges = push_constant_ranges.data(),
};
if(vkCreatePipelineLayout(
context.device(),
&create_info,
nullptr,
&m_pipeline_layout
) != VK_SUCCESS)
throw std::runtime_error("failed to create pipeline layout");
}
PipelineLayout::PipelineLayout(PipelineLayout&& other) noexcept
{
swap(*this, other);
}
PipelineLayout::~PipelineLayout() noexcept {
if(!is_null())
destroy();
}
PipelineLayout& PipelineLayout::operator=(PipelineLayout&& other) noexcept {
swap(*this, other);
if(other)
other.destroy();
return *this;
}
void PipelineLayout::destroy() noexcept {
assert(!is_null());
assert(m_context);
vkDestroyPipelineLayout(
m_context->device(),
m_pipeline_layout,
nullptr
);
m_pipeline_layout = nullptr;
}
}

67
src/vk/PipelineLayout.h

@ -0,0 +1,67 @@
// Copyright 2022 Simon Boyé
#pragma once
#include <core/utils.h>
#include <vk/forward.h>
#include <vulkan/vulkan.h>
namespace vk {
class PipelineLayout {
public:
PipelineLayout() noexcept;
PipelineLayout(
Context& context,
Array<const VkDescriptorSetLayout> set_layouts,
Array<const VkPushConstantRange> push_constant_ranges={}
);
PipelineLayout(const PipelineLayout&) = delete;
PipelineLayout(PipelineLayout&& other) noexcept;
~PipelineLayout() noexcept;
PipelineLayout& operator=(const PipelineLayout&) = delete;
PipelineLayout& operator=(PipelineLayout&& other) noexcept;
explicit inline operator bool() const noexcept {
return !is_null();
}
inline bool is_null() const noexcept {
return m_pipeline_layout == VK_NULL_HANDLE;
}
inline const Context* context() const noexcept {
return m_context;
}
inline Context* context() noexcept {
return m_context;
}
inline operator VkPipelineLayout() noexcept {
return m_pipeline_layout;
}
inline VkPipelineLayout pipeline_layout() noexcept {
return m_pipeline_layout;
}
friend inline void swap(PipelineLayout& pipeline_layout_0, PipelineLayout& pipeline_layout_1) noexcept {
using std::swap;
swap(pipeline_layout_0.m_context, pipeline_layout_1.m_context);
swap(pipeline_layout_0.m_pipeline_layout, pipeline_layout_1.m_pipeline_layout);
}
void destroy() noexcept;
private:
Context* m_context = nullptr;
VkPipelineLayout m_pipeline_layout = VK_NULL_HANDLE;
};
}

48
src/vk/Wrapper.cpp

@ -0,0 +1,48 @@
// Copyright 2022 Simon Boyé
#include <vk/Wrapper.h>
#include <vk/Context.h>
#include <cassert>
namespace vk {
Wrapper::Wrapper() noexcept {
}
Wrapper::Wrapper(Context& context, Flags flags) noexcept
: m_context(&context)
, m_flags(flags)
{
assert(m_context);
}
Wrapper::Wrapper(const Wrapper& other) noexcept
: m_context(other.m_context)
{}
Wrapper::Wrapper(Wrapper&& other) noexcept
{
swap(other);
}
Wrapper::~Wrapper() noexcept {
}
Wrapper& Wrapper::operator=(const Wrapper& other) noexcept {
if (&other != this) {
m_context = other.m_context;
}
return *this;
}
Wrapper& Wrapper::operator=(Wrapper&& other) noexcept {
swap(other);
return *this;
}
}

56
src/vk/Wrapper.h

@ -0,0 +1,56 @@
// Copyright 2022 Simon Boyé
#pragma once
#include <vk/forward.h>
#include <vulkan/vulkan.h>
namespace vk {
class Wrapper {
public:
enum Flag {
OwnUnderlyingObject = 0x01,
};
using Flags = unsigned;
public:
Wrapper() noexcept;
Wrapper(Context& context, Flags flags=OwnUnderlyingObject) noexcept;
Wrapper(const Wrapper& other) noexcept;
Wrapper(Wrapper&& other) noexcept;
~Wrapper() noexcept;
Wrapper& operator=(const Wrapper& other) noexcept;
Wrapper& operator=(Wrapper&& other) noexcept;
inline const Context* context() const noexcept {
return m_context;
}
inline Context* context() noexcept {
return m_context;
}
inline bool own_underlying_object() const noexcept {
return (m_flags & Flags(OwnUnderlyingObject)) != 0;
}
inline void swap(Wrapper& other) noexcept {
using std::swap;
swap(m_context, other.m_context);
}
friend inline void swap(Wrapper& wrapper_0, Wrapper& wrapper_1) noexcept {
wrapper_0.swap(wrapper_1);
}
protected:
Context* m_context = nullptr;
Flags m_flags = 0;
};
}
Loading…
Cancel
Save