Browse Source

VulkanTutorial refactoring.

master
Draklaw 4 years ago
parent
commit
5b363a8c57
  1. 2
      src/VkExpe.cpp
  2. 492
      src/VulkanTutorial.cpp
  3. 74
      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() {
m_vulkan.shutdown();
recreate_object(m_vulkan);
m_window.reset();

492
src/VulkanTutorial.cpp

@ -100,9 +100,7 @@ struct Uniforms {
VulkanTutorial::VulkanTutorial() {
m_swapchain.register_creation_callback(
std::bind(&VulkanTutorial::create_swapchain_objects, this, std::placeholders::_1));
m_swapchain.register_destruction_callback(
std::bind(&VulkanTutorial::destroy_swapchain_objects, this));
std::bind(&VulkanTutorial::create_swapchain_objects, this));
auto const subdiv_count = 4;
@ -154,9 +152,11 @@ VulkanTutorial::VulkanTutorial() {
}
VulkanTutorial::~VulkanTutorial() {
shutdown();
if(m_context)
vkDeviceWaitIdle(m_context.device());
}
void VulkanTutorial::initialize(SDL_Window* window) {
auto const context_settings = vk::ContextSettings()
#if defined(VKEXPE_ENABLE_VALIDATION) || !defined(NDEBUG)
@ -167,7 +167,13 @@ void VulkanTutorial::initialize(SDL_Window* window) {
m_context.initialize(context_settings);
create_command_pool();
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_index_buffer();
@ -176,24 +182,6 @@ void VulkanTutorial::initialize(SDL_Window* window) {
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) {
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;
}
void VulkanTutorial::draw_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();
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(
m_context,
m_uniform_buffer_offsets[image_index],
image_states.m_uniform_buffer_offset,
sizeof(Uniforms)
);
std::memcpy(uniform_buffer, &uniforms, sizeof(Uniforms));
@ -255,13 +245,13 @@ void VulkanTutorial::draw_frame() {
m_swapchain.ready_to_render(),
};
VkSemaphore done_semaphores[] = {
m_render_done[image_index],
image_states.m_render_done,
};
VkPipelineStageFlags stages[] = {
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
};
VkCommandBuffer command_buffers[] = {
m_command_buffers[image_index],
image_states.m_command_buffer,
};
VkSubmitInfo submit_info {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
@ -288,39 +278,45 @@ void VulkanTutorial::invalidate_swapchain() {
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();
for(size_t index = 0; index < m_swapchain.image_count(); index += 1) {
m_render_done.emplace_back(m_context);
}
}
void VulkanTutorial::create_swapchain_objects() {
m_image_states.clear();
m_swapchain_states.~SwapchainStates();
void VulkanTutorial::destroy_swapchain_objects() {
if(m_command_pool == VK_NULL_HANDLE)
return;
new(&m_swapchain_states) SwapchainStates();
initialize_swapchain_states();
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();
m_pipeline_layout.destroy();
m_render_pass.destroy();
void VulkanTutorial::create_descriptor_set_layout() {
VkDescriptorSetLayoutBinding binding[] {
{
.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() {
@ -368,17 +364,51 @@ void VulkanTutorial::create_render_pass() {
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,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT,
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = uint32_t(m_swapchain.image_count()),
}
};
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() {
@ -497,11 +527,6 @@ void VulkanTutorial::create_graphic_pipeline() {
.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 {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.stageCount = 3,
@ -521,228 +546,187 @@ void VulkanTutorial::create_graphic_pipeline() {
.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() {
if(!m_command_pool.is_null())
return;
void VulkanTutorial::initialize_image_states(size_t image_index) {
auto& image_states = m_image_states[image_index];
image_states.m_image_index = image_index;
m_command_pool = vk::CommandPool(
m_context,
m_context.queue_family(GRAPHIC_QUEUE)
);
create_framebuffer(image_states);
create_uniform_buffer(image_states);
create_descriptor_set(image_states);
create_command_buffer(image_states);
image_states.m_render_done = vk::Semaphore(m_context);
}
void VulkanTutorial::create_vertex_buffer() {
if(m_vertex_buffer)
return;
VkDeviceSize size = sizeof(vertices[0]) * vertices.size();
m_vertex_buffer = vk::Buffer(
void VulkanTutorial::create_framebuffer(ImageStates& image_states) {
auto view = m_swapchain.image_view(image_states.m_image_index);
image_states.m_framebuffer = vk::Framebuffer(
m_context,
size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
| VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
m_render_pass,
&view,
m_swapchain.extent()
);
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();
m_index_buffer = vk::Buffer(
void VulkanTutorial::create_uniform_buffer(ImageStates& image_states) {
const auto image_index = image_states.m_image_index;
image_states.m_uniform_buffer = vk::Buffer(
m_context,
size,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT
| VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
sizeof(Uniforms),
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
);
m_index_buffer.upload(size, indices.data(), m_context.queue_family(GRAPHIC_QUEUE));
}
auto& buffer = image_states.m_uniform_buffer;
if(!m_uniform_buffer_memory) {
VkMemoryRequirements memory_requirements =
buffer.memory_requirements();
void VulkanTutorial::create_uniform_buffer() {
m_uniform_buffers.resize(m_swapchain.image_count());
for(size_t index = 0; index < m_uniform_buffers.size(); index += 1) {
m_uniform_buffers[index] = vk::Buffer(
m_context,
sizeof(Uniforms),
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
m_uniform_buffer_memory = m_context.allocator().allocate(
memory_requirements.size * m_swapchain.image_count(),
memory_requirements.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
);
for (size_t index = 0; index < m_swapchain.image_count(); index += 1)
m_image_states[index].m_uniform_buffer_offset =
index * memory_requirements.size;
}
VkMemoryRequirements memory_requirements =
m_uniform_buffers[0].memory_requirements();
buffer.bind_memory(
m_uniform_buffer_memory,
image_states.m_uniform_buffer_offset
);
}
m_uniform_buffer_memory = m_context.allocator().allocate(
memory_requirements.size * m_swapchain.image_count(),
memory_requirements.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
void VulkanTutorial::create_descriptor_set(ImageStates& image_states) {
image_states.m_descriptor_set = vk::DescriptorSet(
m_context,
m_swapchain_states.m_descriptor_pool,
m_descriptor_set_layout
);
m_uniform_buffer_offsets.resize(m_uniform_buffers.size());
for(size_t index = 0; index < m_uniform_buffers.size(); index += 1) {
m_uniform_buffer_offsets[index] = index * memory_requirements.size;
m_uniform_buffers[index].bind_memory(
m_uniform_buffer_memory,
m_uniform_buffer_offsets[index]
);
}
VkDescriptorBufferInfo buffer_info {
.buffer = image_states.m_uniform_buffer,
.offset = 0,
.range = sizeof(Uniforms),
};
VkWriteDescriptorSet write {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = image_states.m_descriptor_set,
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.pBufferInfo = &buffer_info,
};
vkUpdateDescriptorSets(
m_context.device(),
1, &write,
0, nullptr
);
}
void VulkanTutorial::create_descriptor_pool() {
VkDescriptorPoolSize pool_sizes[] {
{
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = uint32_t(m_swapchain.image_count()),
}
void VulkanTutorial::create_command_buffer(ImageStates& image_states) {
image_states.m_command_buffer = vk::CommandBuffer(m_context, m_command_pool);
VkCommandBufferBeginInfo begin_info {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.flags = 0,
.pInheritanceInfo = nullptr,
};
m_descriptor_pool = vk::DescriptorPool(
m_context,
uint32_t(m_swapchain.image_count()),
pool_sizes
);
}
logger.debug() << "record command buffer " << image_states.m_image_index
<< " (" << image_states.m_command_buffer << ")";
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 {
.buffer = m_uniform_buffers[index],
.offset = 0,
.range = sizeof(Uniforms),
};
VkWriteDescriptorSet write {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = m_descriptor_sets[index],
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.pBufferInfo = &buffer_info,
};
vkUpdateDescriptorSets(
m_context.device(),
1, &write,
0, nullptr
);
}
}
if(vkBeginCommandBuffer(
image_states.m_command_buffer,
&begin_info
) != VK_SUCCESS)
throw std::runtime_error("failed to begin command buffer");
void VulkanTutorial::create_command_buffers() {
m_command_buffers.clear();
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 {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.flags = 0,
.pInheritanceInfo = nullptr,
};
logger.debug() << "record command buffer " << index << " (" << command_buffer << ")";
if(vkBeginCommandBuffer(
command_buffer,
&begin_info
) != VK_SUCCESS)
throw std::runtime_error("failed to begin command buffer");
VkClearValue clear_color = {
.color = {
.float32 = { 0.0f, 0.0f, 0.0f, 1.0f }
}
};
VkRenderPassBeginInfo pass_info {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = m_render_pass,
.framebuffer = m_framebuffers[index],
.renderArea = {
.offset = { 0, 0 },
.extent = m_swapchain.extent(),
},
.clearValueCount = 1,
.pClearValues = &clear_color,
};
vkCmdBeginRenderPass(
command_buffer,
&pass_info,
VK_SUBPASS_CONTENTS_INLINE
);
VkClearValue clear_color = {
.color = {
.float32 = { 0.0f, 0.0f, 0.0f, 1.0f }
}
};
vkCmdBindPipeline(
command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
m_pipeline
);
VkRenderPassBeginInfo pass_info {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = m_render_pass,
.framebuffer = image_states.m_framebuffer,
.renderArea = {
.offset = { 0, 0 },
.extent = m_swapchain.extent(),
},
.clearValueCount = 1,
.pClearValues = &clear_color,
};
VkBuffer vertex_buffers[] = {
m_vertex_buffer,
};
VkDeviceSize offsets[] = {
0,
};
vkCmdBindVertexBuffers(
command_buffer,
0,
1,
vertex_buffers,
offsets
);
vkCmdBeginRenderPass(
image_states.m_command_buffer,
&pass_info,
VK_SUBPASS_CONTENTS_INLINE
);
vkCmdBindIndexBuffer(
command_buffer,
m_index_buffer,
0,
VK_INDEX_TYPE_UINT32
);
vkCmdBindPipeline(
image_states.m_command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
m_swapchain_states.m_pipeline
);
VkDescriptorSet descriptor_sets[] {
m_descriptor_sets[index],
};
vkCmdBindDescriptorSets(
command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
m_pipeline_layout,
0, 1, descriptor_sets,
0, nullptr
);
VkBuffer vertex_buffers[] = {
m_vertex_buffer,
};
VkDeviceSize offsets[] = {
0,
};
vkCmdBindVertexBuffers(
image_states.m_command_buffer,
0,
1,
vertex_buffers,
offsets
);
vkCmdDrawIndexed(
command_buffer,
uint32_t(indices.size()),
1,
0,
0,
0
);
vkCmdBindIndexBuffer(
image_states.m_command_buffer,
m_index_buffer,
0,
VK_INDEX_TYPE_UINT32
);
VkDescriptorSet descriptor_sets[] {
image_states.m_descriptor_set,
};
vkCmdBindDescriptorSets(
image_states.m_command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
m_pipeline_layout,
0, 1, descriptor_sets,
0, nullptr
);
vkCmdEndRenderPass(command_buffer);
vkCmdDrawIndexed(
image_states.m_command_buffer,
uint32_t(indices.size()),
1,
0,
0,
0
);
if(vkEndCommandBuffer(command_buffer) != VK_SUCCESS)
throw("failed to record command buffer");
}
vkCmdEndRenderPass(image_states.m_command_buffer);
if(vkEndCommandBuffer(image_states.m_command_buffer) != VK_SUCCESS)
throw("failed to record command buffer");
}

74
src/VulkanTutorial.h

@ -50,7 +50,6 @@ public:
VulkanTutorial& operator=(const VulkanTutorial&) = delete;
void initialize(SDL_Window* window);
void shutdown();
void set_camera(const Vector3& camera_position, const Vector3& camera_z, const Vector3& camera_y);
@ -58,42 +57,71 @@ public:
void invalidate_swapchain();
private:
void create_swapchain_objects(uint32_t image_count);
void destroy_swapchain_objects();
struct SwapchainStates;
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_descriptor_set_layout();
void create_pipeline_layout();
void create_render_pass();
void create_vertex_buffer();
void create_index_buffer();
void create_uniform_buffer();
void initialize_swapchain_states();
void create_descriptor_pool();
void create_descriptor_sets();
void create_command_buffers();
void create_graphic_pipeline();
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:
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::PipelineLayout m_pipeline_layout;
vk::Pipeline m_pipeline;
std::vector<vk::Framebuffer> m_framebuffers;
vk::CommandPool m_command_pool;
vk::RenderPass m_render_pass;
vk::Buffer m_vertex_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::DescriptorPool m_descriptor_pool;
std::vector<vk::DescriptorSet> m_descriptor_sets;
std::vector<vk::CommandBuffer> m_command_buffers;
std::vector<vk::Semaphore> m_render_done;
vk::Swapchain m_swapchain;
struct SwapchainStates {
vk::DescriptorPool m_descriptor_pool;
vk::Pipeline m_pipeline;
};
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_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>
std::string cat(Args&&... args) {
std::ostringstream ostream;

4
src/vk/Buffer.cpp

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

8
src/vk/Memory.cpp

@ -42,10 +42,8 @@ MemoryBlock::MemoryBlock(MemoryBlock&& other) noexcept
}
MemoryBlock::~MemoryBlock() noexcept {
if(!is_null()) {
logger.warning() << "MemoryBlock deleted before being freed";
if(!is_null())
free();
}
}
MemoryBlock& MemoryBlock::operator=(MemoryBlock&& other) noexcept {
@ -176,6 +174,8 @@ MemoryBlock MemoryPage::allocate(VkDeviceSize size) noexcept {
if(block_it == m_blocks.end())
return MemoryBlock();
const auto offset = block_it->offset;
block_it[0].is_free = false;
if (block_it[0].offset != block_it[1].offset) {
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 {

2
src/vk/Swapchain.cpp

@ -324,7 +324,7 @@ void Swapchain::create() {
}
for(auto& callback: m_creation_callbacks)
callback(image_count);
callback();
}
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 MAX_FRAMES_IN_FLIGHT = 2;
using CreationCallback = std::function<void(uint32_t)>;
using CreationCallback = std::function<void()>;
using DestructionCallback = std::function<void()>;
public:

Loading…
Cancel
Save