Browse Source

Framebuffer wrapper.

master
Draklaw 4 years ago
parent
commit
db9fdf5a7f
  1. 1
      CMakeLists.txt
  2. 33
      src/VulkanTutorial.cpp
  3. 3
      src/VulkanTutorial.h
  4. 1
      src/core/utils.cpp
  5. 11
      src/core/utils.h
  6. 86
      src/vk/Framebuffer.cpp
  7. 74
      src/vk/Framebuffer.h

1
CMakeLists.txt

@ -39,6 +39,7 @@ add_executable(vk_expe
src/vk/Context.cpp
src/vk/Fence.cpp
src/vk/Semaphore.cpp
src/vk/Framebuffer.cpp
src/vk/Swapchain.cpp
src/vk/Memory.cpp
src/vk/Buffer.cpp

33
src/VulkanTutorial.cpp

@ -276,7 +276,7 @@ void VulkanTutorial::draw_frame() {
))
throw std::runtime_error("failed to submit draw command buffer");
m_swapchain.swap_buffers({1, done_semaphores});
m_swapchain.swap_buffers(done_semaphores);
}
void VulkanTutorial::invalidate_swapchain() {
@ -317,8 +317,6 @@ void VulkanTutorial::destroy_swapchain_objects() {
m_context.destroy_descriptor_pool(m_descriptor_pool);
for(VkFramebuffer framebuffer: m_framebuffers)
m_context.destroy_framebuffer(framebuffer);
m_framebuffers.clear();
m_context.destroy_pipeline(m_pipeline);
@ -569,28 +567,15 @@ void VulkanTutorial::create_graphic_pipeline() {
}
void VulkanTutorial::create_framebuffers() {
m_framebuffers.resize(m_swapchain.image_count());
for(size_t index = 0; index < m_framebuffers.size(); index += 1) {
m_framebuffers.clear();
for(size_t index = 0; index < m_swapchain.image_count(); index += 1) {
VkImageView view = m_swapchain.image_view(index);
VkFramebufferCreateInfo framebuffer_info {
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
.renderPass = m_render_pass,
.attachmentCount = 1,
.pAttachments = &view,
.width = m_swapchain.extent().width,
.height = m_swapchain.extent().height,
.layers = 1,
};
if(vkCreateFramebuffer(
m_context.device(),
&framebuffer_info,
nullptr,
&m_framebuffers[index]
) != VK_SUCCESS)
throw std::runtime_error("failed to create framebuffer");
m_framebuffers.emplace_back(
m_context,
m_render_pass,
&view,
m_swapchain.extent()
);
}
}

3
src/VulkanTutorial.h

@ -1,6 +1,7 @@
// Copyright 2022 Simon Boyé
#pragma once
#include <vk/Framebuffer.h>
#include <vk/Semaphore.h>
#include <vk/RenderPass.h>
#include <vk/Buffer.h>
@ -75,7 +76,7 @@ private:
VkDescriptorSetLayout m_descriptor_set_layout = VK_NULL_HANDLE;
VkPipelineLayout m_pipeline_layout = VK_NULL_HANDLE;
VkPipeline m_pipeline = VK_NULL_HANDLE;
std::vector<VkFramebuffer> m_framebuffers;
std::vector<vk::Framebuffer> m_framebuffers;
VkCommandPool m_command_pool = VK_NULL_HANDLE;
vk::Buffer m_vertex_buffer;
vk::Buffer m_index_buffer;

1
src/core/utils.cpp

@ -24,4 +24,3 @@ std::vector<char> read_binary_file(const char* path) {
return buffer;
}

11
src/core/utils.h

@ -57,6 +57,17 @@ public:
assert((size == 0 && m_data == nullptr) || (size != 0 && m_data != nullptr));
}
Array(T* item)
: m_size(1)
, m_data(item)
{}
template<size_t Size>
Array(T (&array)[Size])
: m_size(Size)
, m_data(array)
{}
Array(const std::vector<T>& vector)
: m_size(vector.size())
, m_data(vector.data())

86
src/vk/Framebuffer.cpp

@ -0,0 +1,86 @@
// Copyright 2022 Simon Boyé
#include <vk/Framebuffer.h>
#include <vk/Context.h>
#include <cassert>
namespace vk {
Framebuffer::Framebuffer() noexcept {
}
Framebuffer::Framebuffer(
Context& context,
VkRenderPass render_pass,
Array<VkImageView> attachments,
uint32_t width, uint32_t height, uint32_t layers
)
: m_context(&context)
{
assert(m_context);
assert(render_pass);
VkFramebufferCreateInfo create_info {
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
.renderPass = render_pass,
.attachmentCount = uint32_t(attachments.size()),
.pAttachments = attachments.data(),
.width = width,
.height = height,
.layers = layers,
};
if(vkCreateFramebuffer(
context.device(),
&create_info,
nullptr,
&m_framebuffer
) != VK_SUCCESS)
throw std::runtime_error("failed to create framebuffer");
}
Framebuffer::Framebuffer(
Context& context,
VkRenderPass render_pass,
Array<VkImageView> attachments,
VkExtent2D extent, uint32_t layers
)
: Framebuffer(context, render_pass, attachments, extent.width, extent.height, layers)
{}
Framebuffer::Framebuffer(Framebuffer&& other) noexcept
{
swap(*this, other);
}
Framebuffer::~Framebuffer() noexcept {
if(!is_null())
destroy();
}
Framebuffer& Framebuffer::operator=(Framebuffer&& other) noexcept {
swap(*this, other);
if(other)
other.destroy();
return *this;
}
void Framebuffer::destroy() noexcept {
assert(!is_null());
assert(m_context);
vkDestroyFramebuffer(
m_context->device(),
m_framebuffer,
nullptr
);
m_framebuffer = nullptr;
}
}

74
src/vk/Framebuffer.h

@ -0,0 +1,74 @@
// Copyright 2022 Simon Boyé
#pragma once
#include <core/utils.h>
#include <vk/forward.h>
#include <vulkan/vulkan.h>
namespace vk {
class Framebuffer {
public:
Framebuffer() noexcept;
Framebuffer(
Context& context,
VkRenderPass render_pass,
Array<VkImageView> attachments,
uint32_t width, uint32_t height, uint32_t layers=1
);
Framebuffer(
Context& context,
VkRenderPass render_pass,
Array<VkImageView> attachments,
VkExtent2D extent, uint32_t layers=1
);
Framebuffer(const Framebuffer&) = delete;
Framebuffer(Framebuffer&& other) noexcept;
~Framebuffer() noexcept;
Framebuffer& operator=(const Framebuffer&) = delete;
Framebuffer& operator=(Framebuffer&& other) noexcept;
explicit inline operator bool() const noexcept {
return !is_null();
}
inline bool is_null() const noexcept {
return m_framebuffer == VK_NULL_HANDLE;
}
inline const Context* context() const noexcept {
return m_context;
}
inline Context* context() noexcept {
return m_context;
}
inline operator VkFramebuffer() noexcept {
return m_framebuffer;
}
inline VkFramebuffer framebuffer() noexcept {
return m_framebuffer;
}
friend inline void swap(Framebuffer& framebuffer_0, Framebuffer& framebuffer_1) noexcept {
using std::swap;
swap(framebuffer_0.m_context, framebuffer_1.m_context);
swap(framebuffer_0.m_framebuffer, framebuffer_1.m_framebuffer);
}
void destroy() noexcept;
private:
Context* m_context = nullptr;
VkFramebuffer m_framebuffer = VK_NULL_HANDLE;
};
}
Loading…
Cancel
Save