Browse Source

VulkanTutorial refactoring.

master
Draklaw 4 years ago
parent
commit
5b363a8c57
  1. 2
      src/VkExpe.cpp
  2. 300
      src/VulkanTutorial.cpp
  3. 72
      src/VulkanTutorial.h
  4. 8
      src/core/utils.h
  5. 4
      src/vk/Buffer.cpp
  6. 8
      src/vk/Memory.cpp
  7. 2
      src/vk/Swapchain.cpp
  8. 2
      src/vk/Swapchain.h

2
src/VkExpe.cpp

@ -43,7 +43,7 @@ void VkExpe::initialize() {
} }
void VkExpe::shutdown() { void VkExpe::shutdown() {
m_vulkan.shutdown(); recreate_object(m_vulkan);
m_window.reset(); m_window.reset();

300
src/VulkanTutorial.cpp

@ -100,9 +100,7 @@ struct Uniforms {
VulkanTutorial::VulkanTutorial() { VulkanTutorial::VulkanTutorial() {
m_swapchain.register_creation_callback( m_swapchain.register_creation_callback(
std::bind(&VulkanTutorial::create_swapchain_objects, this, std::placeholders::_1)); std::bind(&VulkanTutorial::create_swapchain_objects, this));
m_swapchain.register_destruction_callback(
std::bind(&VulkanTutorial::destroy_swapchain_objects, this));
auto const subdiv_count = 4; auto const subdiv_count = 4;
@ -154,9 +152,11 @@ VulkanTutorial::VulkanTutorial() {
} }
VulkanTutorial::~VulkanTutorial() { VulkanTutorial::~VulkanTutorial() {
shutdown(); if(m_context)
vkDeviceWaitIdle(m_context.device());
} }
void VulkanTutorial::initialize(SDL_Window* window) { void VulkanTutorial::initialize(SDL_Window* window) {
auto const context_settings = vk::ContextSettings() auto const context_settings = vk::ContextSettings()
#if defined(VKEXPE_ENABLE_VALIDATION) || !defined(NDEBUG) #if defined(VKEXPE_ENABLE_VALIDATION) || !defined(NDEBUG)
@ -167,7 +167,13 @@ void VulkanTutorial::initialize(SDL_Window* window) {
m_context.initialize(context_settings); m_context.initialize(context_settings);
create_command_pool(); create_command_pool();
create_descriptor_set_layout(); create_descriptor_set_layout();
create_pipeline_layout();
create_render_pass();
// m_uniform_buffer_memory is allocated when uniform buffer is first created.
create_vertex_buffer(); create_vertex_buffer();
create_index_buffer(); create_index_buffer();
@ -176,24 +182,6 @@ void VulkanTutorial::initialize(SDL_Window* window) {
m_swapchain.initialize(swapchain_settings); m_swapchain.initialize(swapchain_settings);
} }
void VulkanTutorial::shutdown() {
if(!m_context.instance())
return;
vkDeviceWaitIdle(m_context.device());
destroy_swapchain_objects();
m_command_pool.destroy();
m_index_buffer.destroy();
m_vertex_buffer.destroy();
m_descriptor_set_layout.destroy();
m_render_done.clear();
m_swapchain.shutdown();
m_context.shutdown();
}
void VulkanTutorial::set_camera(const Vector3& camera_position, const Vector3& camera_z, const Vector3& camera_y) { void VulkanTutorial::set_camera(const Vector3& camera_position, const Vector3& camera_z, const Vector3& camera_y) {
m_camera_position = camera_position; m_camera_position = camera_position;
@ -201,9 +189,11 @@ void VulkanTutorial::set_camera(const Vector3& camera_position, const Vector3& c
m_camera_y = camera_y; m_camera_y = camera_y;
} }
void VulkanTutorial::draw_frame() { void VulkanTutorial::draw_frame() {
m_swapchain.begin_frame(); m_swapchain.begin_frame();
auto const image_index = m_swapchain.current_image_index(); const auto image_index = m_swapchain.current_image_index();
auto& image_states = m_image_states[image_index];
const auto now = Clock::now(); const auto now = Clock::now();
if(m_last_frame_time.time_since_epoch() != Duration(0)) { if(m_last_frame_time.time_since_epoch() != Duration(0)) {
@ -245,7 +235,7 @@ void VulkanTutorial::draw_frame() {
void* uniform_buffer = m_uniform_buffer_memory.map( void* uniform_buffer = m_uniform_buffer_memory.map(
m_context, m_context,
m_uniform_buffer_offsets[image_index], image_states.m_uniform_buffer_offset,
sizeof(Uniforms) sizeof(Uniforms)
); );
std::memcpy(uniform_buffer, &uniforms, sizeof(Uniforms)); std::memcpy(uniform_buffer, &uniforms, sizeof(Uniforms));
@ -255,13 +245,13 @@ void VulkanTutorial::draw_frame() {
m_swapchain.ready_to_render(), m_swapchain.ready_to_render(),
}; };
VkSemaphore done_semaphores[] = { VkSemaphore done_semaphores[] = {
m_render_done[image_index], image_states.m_render_done,
}; };
VkPipelineStageFlags stages[] = { VkPipelineStageFlags stages[] = {
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
}; };
VkCommandBuffer command_buffers[] = { VkCommandBuffer command_buffers[] = {
m_command_buffers[image_index], image_states.m_command_buffer,
}; };
VkSubmitInfo submit_info { VkSubmitInfo submit_info {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
@ -288,39 +278,45 @@ void VulkanTutorial::invalidate_swapchain() {
m_swapchain.invalidate(); m_swapchain.invalidate();
} }
void VulkanTutorial::create_swapchain_objects(uint32_t image_count) {
create_render_pass();
create_framebuffers();
create_uniform_buffer();
create_descriptor_pool();
create_descriptor_sets();
create_graphic_pipeline();
create_command_buffers();
m_render_done.clear(); void VulkanTutorial::create_swapchain_objects() {
for(size_t index = 0; index < m_swapchain.image_count(); index += 1) { m_image_states.clear();
m_render_done.emplace_back(m_context); m_swapchain_states.~SwapchainStates();
}
}
void VulkanTutorial::destroy_swapchain_objects() { new(&m_swapchain_states) SwapchainStates();
if(m_command_pool == VK_NULL_HANDLE) initialize_swapchain_states();
return;
m_command_buffers.clear(); m_image_states.resize(m_swapchain.image_count());
for(size_t image_index = 0; image_index < m_image_states.size(); image_index += 1)
initialize_image_states(image_index);
}
for(auto& buffer: m_uniform_buffers)
buffer.destroy();
m_uniform_buffers.clear();
m_uniform_buffer_memory.free();
m_descriptor_pool.destroy(); void VulkanTutorial::create_command_pool() {
m_command_pool = vk::CommandPool(
m_context,
m_context.queue_family(GRAPHIC_QUEUE)
);
}
m_framebuffers.clear();
m_pipeline.destroy(); void VulkanTutorial::create_descriptor_set_layout() {
m_pipeline_layout.destroy(); VkDescriptorSetLayoutBinding binding[] {
m_render_pass.destroy(); {
.binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT,
}
};
m_descriptor_set_layout = vk::DescriptorSetLayout(m_context, binding);
}
void VulkanTutorial::create_pipeline_layout() {
VkDescriptorSetLayout set_layouts[] {
m_descriptor_set_layout,
};
m_pipeline_layout = vk::PipelineLayout(m_context, set_layouts);
} }
void VulkanTutorial::create_render_pass() { void VulkanTutorial::create_render_pass() {
@ -368,17 +364,51 @@ void VulkanTutorial::create_render_pass() {
m_render_pass = vk::RenderPass(m_context, render_pass_info); m_render_pass = vk::RenderPass(m_context, render_pass_info);
} }
void VulkanTutorial::create_descriptor_set_layout() {
VkDescriptorSetLayoutBinding binding[] { void VulkanTutorial::create_vertex_buffer() {
VkDeviceSize size = sizeof(vertices[0]) * vertices.size();
m_vertex_buffer = vk::Buffer(
m_context,
size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
| VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
);
m_vertex_buffer.upload(size, vertices.data(), m_context.queue_family(GRAPHIC_QUEUE));
}
void VulkanTutorial::create_index_buffer() {
VkDeviceSize size = sizeof(indices[0]) * indices.size();
m_index_buffer = vk::Buffer(
m_context,
size,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT
| VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
);
m_index_buffer.upload(size, indices.data(), m_context.queue_family(GRAPHIC_QUEUE));
}
void VulkanTutorial::initialize_swapchain_states() {
create_descriptor_pool();
create_graphic_pipeline();
}
void VulkanTutorial::create_descriptor_pool() {
VkDescriptorPoolSize pool_sizes[] {
{ {
.binding = 0, .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorCount = uint32_t(m_swapchain.image_count()),
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT,
} }
}; };
m_descriptor_set_layout = vk::DescriptorSetLayout(m_context, binding); m_swapchain_states.m_descriptor_pool = vk::DescriptorPool(
m_context,
uint32_t(m_swapchain.image_count()),
pool_sizes
);
} }
void VulkanTutorial::create_graphic_pipeline() { void VulkanTutorial::create_graphic_pipeline() {
@ -497,11 +527,6 @@ void VulkanTutorial::create_graphic_pipeline() {
.blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f }, .blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f },
}; };
VkDescriptorSetLayout set_layouts[] {
m_descriptor_set_layout,
};
m_pipeline_layout = vk::PipelineLayout(m_context, set_layouts);
VkGraphicsPipelineCreateInfo pipeline_info { VkGraphicsPipelineCreateInfo pipeline_info {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.stageCount = 3, .stageCount = 3,
@ -521,74 +546,49 @@ void VulkanTutorial::create_graphic_pipeline() {
.basePipelineIndex = -1, .basePipelineIndex = -1,
}; };
m_pipeline = vk::Pipeline(m_context, pipeline_info); m_swapchain_states.m_pipeline = vk::Pipeline(m_context, pipeline_info);
} }
void VulkanTutorial::create_framebuffers() {
m_framebuffers.clear();
for(size_t index = 0; index < m_swapchain.image_count(); index += 1) {
VkImageView view = m_swapchain.image_view(index);
m_framebuffers.emplace_back(
m_context,
m_render_pass,
&view,
m_swapchain.extent()
);
}
}
void VulkanTutorial::create_command_pool() { void VulkanTutorial::initialize_image_states(size_t image_index) {
if(!m_command_pool.is_null()) auto& image_states = m_image_states[image_index];
return; image_states.m_image_index = image_index;
m_command_pool = vk::CommandPool( create_framebuffer(image_states);
m_context,
m_context.queue_family(GRAPHIC_QUEUE)
);
}
void VulkanTutorial::create_vertex_buffer() { create_uniform_buffer(image_states);
if(m_vertex_buffer) create_descriptor_set(image_states);
return;
VkDeviceSize size = sizeof(vertices[0]) * vertices.size(); create_command_buffer(image_states);
m_vertex_buffer = vk::Buffer(
m_context, image_states.m_render_done = vk::Semaphore(m_context);
size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
| VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
);
m_vertex_buffer.upload(size, vertices.data(), m_context.queue_family(GRAPHIC_QUEUE));
} }
void VulkanTutorial::create_index_buffer() {
if(m_index_buffer)
return;
VkDeviceSize size = sizeof(indices[0]) * indices.size(); void VulkanTutorial::create_framebuffer(ImageStates& image_states) {
m_index_buffer = vk::Buffer( auto view = m_swapchain.image_view(image_states.m_image_index);
image_states.m_framebuffer = vk::Framebuffer(
m_context, m_context,
size, m_render_pass,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT &view,
| VK_BUFFER_USAGE_TRANSFER_DST_BIT, m_swapchain.extent()
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
); );
m_index_buffer.upload(size, indices.data(), m_context.queue_family(GRAPHIC_QUEUE));
} }
void VulkanTutorial::create_uniform_buffer() {
m_uniform_buffers.resize(m_swapchain.image_count()); void VulkanTutorial::create_uniform_buffer(ImageStates& image_states) {
for(size_t index = 0; index < m_uniform_buffers.size(); index += 1) { const auto image_index = image_states.m_image_index;
m_uniform_buffers[index] = vk::Buffer(
image_states.m_uniform_buffer = vk::Buffer(
m_context, m_context,
sizeof(Uniforms), sizeof(Uniforms),
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
); );
} auto& buffer = image_states.m_uniform_buffer;
if(!m_uniform_buffer_memory) {
VkMemoryRequirements memory_requirements = VkMemoryRequirements memory_requirements =
m_uniform_buffers[0].memory_requirements(); buffer.memory_requirements();
m_uniform_buffer_memory = m_context.allocator().allocate( m_uniform_buffer_memory = m_context.allocator().allocate(
memory_requirements.size * m_swapchain.image_count(), memory_requirements.size * m_swapchain.image_count(),
@ -597,44 +597,32 @@ void VulkanTutorial::create_uniform_buffer() {
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
); );
m_uniform_buffer_offsets.resize(m_uniform_buffers.size()); for (size_t index = 0; index < m_swapchain.image_count(); index += 1)
for(size_t index = 0; index < m_uniform_buffers.size(); index += 1) { m_image_states[index].m_uniform_buffer_offset =
m_uniform_buffer_offsets[index] = index * memory_requirements.size; index * memory_requirements.size;
m_uniform_buffers[index].bind_memory(
m_uniform_buffer_memory,
m_uniform_buffer_offsets[index]
);
}
} }
void VulkanTutorial::create_descriptor_pool() { buffer.bind_memory(
VkDescriptorPoolSize pool_sizes[] { m_uniform_buffer_memory,
{ image_states.m_uniform_buffer_offset
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, );
.descriptorCount = uint32_t(m_swapchain.image_count()),
} }
};
m_descriptor_pool = vk::DescriptorPool( void VulkanTutorial::create_descriptor_set(ImageStates& image_states) {
image_states.m_descriptor_set = vk::DescriptorSet(
m_context, m_context,
uint32_t(m_swapchain.image_count()), m_swapchain_states.m_descriptor_pool,
pool_sizes m_descriptor_set_layout
); );
}
void VulkanTutorial::create_descriptor_sets() {
m_descriptor_sets.clear();
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 = image_states.m_uniform_buffer,
.offset = 0, .offset = 0,
.range = sizeof(Uniforms), .range = sizeof(Uniforms),
}; };
VkWriteDescriptorSet write { VkWriteDescriptorSet write {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = m_descriptor_sets[index], .dstSet = image_states.m_descriptor_set,
.dstBinding = 0, .dstBinding = 0,
.dstArrayElement = 0, .dstArrayElement = 0,
.descriptorCount = 1, .descriptorCount = 1,
@ -647,13 +635,9 @@ void VulkanTutorial::create_descriptor_sets() {
0, nullptr 0, nullptr
); );
} }
}
void VulkanTutorial::create_command_buffers() { void VulkanTutorial::create_command_buffer(ImageStates& image_states) {
m_command_buffers.clear(); image_states.m_command_buffer = vk::CommandBuffer(m_context, m_command_pool);
for(size_t index = 0; index < m_framebuffers.size(); index += 1) {
m_command_buffers.emplace_back(m_context, m_command_pool);
VkCommandBuffer command_buffer = m_command_buffers[index];
VkCommandBufferBeginInfo begin_info { VkCommandBufferBeginInfo begin_info {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
@ -661,10 +645,11 @@ void VulkanTutorial::create_command_buffers() {
.pInheritanceInfo = nullptr, .pInheritanceInfo = nullptr,
}; };
logger.debug() << "record command buffer " << index << " (" << command_buffer << ")"; logger.debug() << "record command buffer " << image_states.m_image_index
<< " (" << image_states.m_command_buffer << ")";
if(vkBeginCommandBuffer( if(vkBeginCommandBuffer(
command_buffer, image_states.m_command_buffer,
&begin_info &begin_info
) != VK_SUCCESS) ) != VK_SUCCESS)
throw std::runtime_error("failed to begin command buffer"); throw std::runtime_error("failed to begin command buffer");
@ -678,7 +663,7 @@ void VulkanTutorial::create_command_buffers() {
VkRenderPassBeginInfo pass_info { VkRenderPassBeginInfo pass_info {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = m_render_pass, .renderPass = m_render_pass,
.framebuffer = m_framebuffers[index], .framebuffer = image_states.m_framebuffer,
.renderArea = { .renderArea = {
.offset = { 0, 0 }, .offset = { 0, 0 },
.extent = m_swapchain.extent(), .extent = m_swapchain.extent(),
@ -688,15 +673,15 @@ void VulkanTutorial::create_command_buffers() {
}; };
vkCmdBeginRenderPass( vkCmdBeginRenderPass(
command_buffer, image_states.m_command_buffer,
&pass_info, &pass_info,
VK_SUBPASS_CONTENTS_INLINE VK_SUBPASS_CONTENTS_INLINE
); );
vkCmdBindPipeline( vkCmdBindPipeline(
command_buffer, image_states.m_command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_pipeline m_swapchain_states.m_pipeline
); );
VkBuffer vertex_buffers[] = { VkBuffer vertex_buffers[] = {
@ -706,7 +691,7 @@ void VulkanTutorial::create_command_buffers() {
0, 0,
}; };
vkCmdBindVertexBuffers( vkCmdBindVertexBuffers(
command_buffer, image_states.m_command_buffer,
0, 0,
1, 1,
vertex_buffers, vertex_buffers,
@ -714,17 +699,17 @@ void VulkanTutorial::create_command_buffers() {
); );
vkCmdBindIndexBuffer( vkCmdBindIndexBuffer(
command_buffer, image_states.m_command_buffer,
m_index_buffer, m_index_buffer,
0, 0,
VK_INDEX_TYPE_UINT32 VK_INDEX_TYPE_UINT32
); );
VkDescriptorSet descriptor_sets[] { VkDescriptorSet descriptor_sets[] {
m_descriptor_sets[index], image_states.m_descriptor_set,
}; };
vkCmdBindDescriptorSets( vkCmdBindDescriptorSets(
command_buffer, image_states.m_command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_pipeline_layout, m_pipeline_layout,
0, 1, descriptor_sets, 0, 1, descriptor_sets,
@ -732,7 +717,7 @@ void VulkanTutorial::create_command_buffers() {
); );
vkCmdDrawIndexed( vkCmdDrawIndexed(
command_buffer, image_states.m_command_buffer,
uint32_t(indices.size()), uint32_t(indices.size()),
1, 1,
0, 0,
@ -740,9 +725,8 @@ void VulkanTutorial::create_command_buffers() {
0 0
); );
vkCmdEndRenderPass(command_buffer); vkCmdEndRenderPass(image_states.m_command_buffer);
if(vkEndCommandBuffer(command_buffer) != VK_SUCCESS) if(vkEndCommandBuffer(image_states.m_command_buffer) != VK_SUCCESS)
throw("failed to record command buffer"); throw("failed to record command buffer");
} }
}

72
src/VulkanTutorial.h

@ -50,7 +50,6 @@ public:
VulkanTutorial& operator=(const VulkanTutorial&) = delete; VulkanTutorial& operator=(const VulkanTutorial&) = delete;
void initialize(SDL_Window* window); void initialize(SDL_Window* window);
void shutdown();
void set_camera(const Vector3& camera_position, const Vector3& camera_z, const Vector3& camera_y); void set_camera(const Vector3& camera_position, const Vector3& camera_z, const Vector3& camera_y);
@ -58,42 +57,71 @@ public:
void invalidate_swapchain(); void invalidate_swapchain();
private: private:
void create_swapchain_objects(uint32_t image_count); struct SwapchainStates;
void destroy_swapchain_objects(); struct ImageStates;
private:
void create_swapchain_objects();
void create_render_pass();
void create_descriptor_set_layout();
void create_graphic_pipeline();
void create_framebuffers();
void create_command_pool(); void create_command_pool();
void create_descriptor_set_layout();
void create_pipeline_layout();
void create_render_pass();
void create_vertex_buffer(); void create_vertex_buffer();
void create_index_buffer(); void create_index_buffer();
void create_uniform_buffer();
void initialize_swapchain_states();
void create_descriptor_pool(); void create_descriptor_pool();
void create_descriptor_sets(); void create_graphic_pipeline();
void create_command_buffers();
void initialize_image_states(size_t image_index);
void create_framebuffer(ImageStates& image_states);
void create_uniform_buffer(ImageStates& image_states);
void create_descriptor_set(ImageStates& image_states);
void create_command_buffer(ImageStates& image_states);
private: private:
vk::Context m_context; vk::Context m_context;
vk::Swapchain m_swapchain;
VkQueue m_graphic_queue = nullptr;
VkQueue m_presentation_queue = nullptr;
vk::RenderPass m_render_pass; vk::CommandPool m_command_pool;
vk::DescriptorSetLayout m_descriptor_set_layout; vk::DescriptorSetLayout m_descriptor_set_layout;
vk::PipelineLayout m_pipeline_layout; vk::PipelineLayout m_pipeline_layout;
vk::Pipeline m_pipeline; vk::RenderPass m_render_pass;
std::vector<vk::Framebuffer> m_framebuffers;
vk::CommandPool m_command_pool;
vk::Buffer m_vertex_buffer; vk::Buffer m_vertex_buffer;
vk::Buffer m_index_buffer; vk::Buffer m_index_buffer;
std::vector<vk::Buffer> m_uniform_buffers;
std::vector<VkDeviceSize> m_uniform_buffer_offsets;
vk::MemoryBlock m_uniform_buffer_memory; vk::MemoryBlock m_uniform_buffer_memory;
vk::Swapchain m_swapchain;
struct SwapchainStates {
vk::DescriptorPool m_descriptor_pool; vk::DescriptorPool m_descriptor_pool;
std::vector<vk::DescriptorSet> m_descriptor_sets; vk::Pipeline m_pipeline;
std::vector<vk::CommandBuffer> m_command_buffers; };
std::vector<vk::Semaphore> m_render_done; SwapchainStates m_swapchain_states;
struct ImageStates {
size_t m_image_index;
vk::Framebuffer m_framebuffer;
vk::Buffer m_uniform_buffer;
VkDeviceSize m_uniform_buffer_offset;
vk::DescriptorSet m_descriptor_set;
vk::CommandBuffer m_command_buffer;
vk::Semaphore m_render_done;
};
std::vector<ImageStates> m_image_states;
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);

8
src/core/utils.h

@ -33,6 +33,14 @@ Guard<T> make_guard(T&& teardown) {
} }
template<typename T>
T& recreate_object(T& object) {
object.~T();
new(&object) T;
return object;
}
template<typename... Args> template<typename... Args>
std::string cat(Args&&... args) { std::string cat(Args&&... args) {
std::ostringstream ostream; std::ostringstream ostream;

4
src/vk/Buffer.cpp

@ -56,11 +56,9 @@ Buffer::Buffer(Buffer&& other) noexcept {
} }
Buffer::~Buffer() noexcept { Buffer::~Buffer() noexcept {
if(!is_null()) { if(!is_null())
logger.warning() << "Buffer deleted before being destroyed";
destroy(); destroy();
} }
}
Buffer& Buffer::operator=(Buffer&& other) noexcept { Buffer& Buffer::operator=(Buffer&& other) noexcept {
swap(other); swap(other);

8
src/vk/Memory.cpp

@ -42,11 +42,9 @@ MemoryBlock::MemoryBlock(MemoryBlock&& other) noexcept
} }
MemoryBlock::~MemoryBlock() noexcept { MemoryBlock::~MemoryBlock() noexcept {
if(!is_null()) { if(!is_null())
logger.warning() << "MemoryBlock deleted before being freed";
free(); free();
} }
}
MemoryBlock& MemoryBlock::operator=(MemoryBlock&& other) noexcept { MemoryBlock& MemoryBlock::operator=(MemoryBlock&& other) noexcept {
if(&other != this) { if(&other != this) {
@ -176,6 +174,8 @@ MemoryBlock MemoryPage::allocate(VkDeviceSize size) noexcept {
if(block_it == m_blocks.end()) if(block_it == m_blocks.end())
return MemoryBlock(); return MemoryBlock();
const auto offset = block_it->offset;
block_it[0].is_free = false; block_it[0].is_free = false;
if (block_it[0].offset != block_it[1].offset) { if (block_it[0].offset != block_it[1].offset) {
m_blocks.emplace(std::next(block_it), Block{ m_blocks.emplace(std::next(block_it), Block{
@ -183,7 +183,7 @@ MemoryBlock MemoryPage::allocate(VkDeviceSize size) noexcept {
}); });
} }
return MemoryBlock(m_device_memory, size, block_it[0].offset, this, m_memory_type); return MemoryBlock(m_device_memory, size, offset, this, m_memory_type);
} }
void MemoryPage::p_free(MemoryBlock& block) noexcept { void MemoryPage::p_free(MemoryBlock& block) noexcept {

2
src/vk/Swapchain.cpp

@ -324,7 +324,7 @@ void Swapchain::create() {
} }
for(auto& callback: m_creation_callbacks) for(auto& callback: m_creation_callbacks)
callback(image_count); callback();
} }
void Swapchain::destroy() { void Swapchain::destroy() {

2
src/vk/Swapchain.h

@ -42,7 +42,7 @@ public:
static constexpr uint32_t CURRENT_IMAGE_INDEX = UINT32_MAX; static constexpr uint32_t CURRENT_IMAGE_INDEX = UINT32_MAX;
static constexpr uint32_t MAX_FRAMES_IN_FLIGHT = 2; static constexpr uint32_t MAX_FRAMES_IN_FLIGHT = 2;
using CreationCallback = std::function<void(uint32_t)>; using CreationCallback = std::function<void()>;
using DestructionCallback = std::function<void()>; using DestructionCallback = std::function<void()>;
public: public:

Loading…
Cancel
Save