VulkanTutorial refactoring.
This commit is contained in:
@@ -43,7 +43,7 @@ void VkExpe::initialize() {
|
||||
}
|
||||
|
||||
void VkExpe::shutdown() {
|
||||
m_vulkan.shutdown();
|
||||
recreate_object(m_vulkan);
|
||||
|
||||
m_window.reset();
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
new(&m_swapchain_states) SwapchainStates();
|
||||
initialize_swapchain_states();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void VulkanTutorial::destroy_swapchain_objects() {
|
||||
if(m_command_pool == VK_NULL_HANDLE)
|
||||
return;
|
||||
|
||||
m_command_buffers.clear();
|
||||
void VulkanTutorial::create_command_pool() {
|
||||
m_command_pool = vk::CommandPool(
|
||||
m_context,
|
||||
m_context.queue_family(GRAPHIC_QUEUE)
|
||||
);
|
||||
}
|
||||
|
||||
for(auto& buffer: m_uniform_buffers)
|
||||
buffer.destroy();
|
||||
m_uniform_buffers.clear();
|
||||
m_uniform_buffer_memory.free();
|
||||
|
||||
m_descriptor_pool.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);
|
||||
}
|
||||
|
||||
m_framebuffers.clear();
|
||||
|
||||
m_pipeline.destroy();
|
||||
m_pipeline_layout.destroy();
|
||||
m_render_pass.destroy();
|
||||
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,74 +546,49 @@ 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(
|
||||
|
||||
void VulkanTutorial::initialize_image_states(size_t image_index) {
|
||||
auto& image_states = m_image_states[image_index];
|
||||
image_states.m_image_index = image_index;
|
||||
|
||||
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_framebuffer(ImageStates& image_states) {
|
||||
auto view = m_swapchain.image_view(image_states.m_image_index);
|
||||
image_states.m_framebuffer = vk::Framebuffer(
|
||||
m_context,
|
||||
m_render_pass,
|
||||
&view,
|
||||
m_swapchain.extent()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanTutorial::create_command_pool() {
|
||||
if(!m_command_pool.is_null())
|
||||
return;
|
||||
|
||||
m_command_pool = vk::CommandPool(
|
||||
m_context,
|
||||
m_context.queue_family(GRAPHIC_QUEUE)
|
||||
);
|
||||
}
|
||||
void VulkanTutorial::create_uniform_buffer(ImageStates& image_states) {
|
||||
const auto image_index = image_states.m_image_index;
|
||||
|
||||
void VulkanTutorial::create_vertex_buffer() {
|
||||
if(m_vertex_buffer)
|
||||
return;
|
||||
|
||||
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() {
|
||||
if(m_index_buffer)
|
||||
return;
|
||||
|
||||
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::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(
|
||||
image_states.m_uniform_buffer = vk::Buffer(
|
||||
m_context,
|
||||
sizeof(Uniforms),
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
|
||||
);
|
||||
}
|
||||
auto& buffer = image_states.m_uniform_buffer;
|
||||
|
||||
if(!m_uniform_buffer_memory) {
|
||||
VkMemoryRequirements memory_requirements =
|
||||
m_uniform_buffers[0].memory_requirements();
|
||||
buffer.memory_requirements();
|
||||
|
||||
m_uniform_buffer_memory = m_context.allocator().allocate(
|
||||
memory_requirements.size * m_swapchain.image_count(),
|
||||
@@ -597,44 +597,32 @@ void VulkanTutorial::create_uniform_buffer() {
|
||||
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
||||
);
|
||||
|
||||
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(
|
||||
for (size_t index = 0; index < m_swapchain.image_count(); index += 1)
|
||||
m_image_states[index].m_uniform_buffer_offset =
|
||||
index * memory_requirements.size;
|
||||
}
|
||||
|
||||
buffer.bind_memory(
|
||||
m_uniform_buffer_memory,
|
||||
m_uniform_buffer_offsets[index]
|
||||
image_states.m_uniform_buffer_offset
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanTutorial::create_descriptor_pool() {
|
||||
VkDescriptorPoolSize pool_sizes[] {
|
||||
{
|
||||
.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,
|
||||
uint32_t(m_swapchain.image_count()),
|
||||
pool_sizes
|
||||
m_swapchain_states.m_descriptor_pool,
|
||||
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 {
|
||||
.buffer = m_uniform_buffers[index],
|
||||
.buffer = image_states.m_uniform_buffer,
|
||||
.offset = 0,
|
||||
.range = sizeof(Uniforms),
|
||||
};
|
||||
|
||||
VkWriteDescriptorSet write {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = m_descriptor_sets[index],
|
||||
.dstSet = image_states.m_descriptor_set,
|
||||
.dstBinding = 0,
|
||||
.dstArrayElement = 0,
|
||||
.descriptorCount = 1,
|
||||
@@ -646,14 +634,10 @@ void VulkanTutorial::create_descriptor_sets() {
|
||||
1, &write,
|
||||
0, nullptr
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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];
|
||||
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,
|
||||
@@ -661,10 +645,11 @@ void VulkanTutorial::create_command_buffers() {
|
||||
.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(
|
||||
command_buffer,
|
||||
image_states.m_command_buffer,
|
||||
&begin_info
|
||||
) != VK_SUCCESS)
|
||||
throw std::runtime_error("failed to begin command buffer");
|
||||
@@ -678,7 +663,7 @@ void VulkanTutorial::create_command_buffers() {
|
||||
VkRenderPassBeginInfo pass_info {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
.renderPass = m_render_pass,
|
||||
.framebuffer = m_framebuffers[index],
|
||||
.framebuffer = image_states.m_framebuffer,
|
||||
.renderArea = {
|
||||
.offset = { 0, 0 },
|
||||
.extent = m_swapchain.extent(),
|
||||
@@ -688,15 +673,15 @@ void VulkanTutorial::create_command_buffers() {
|
||||
};
|
||||
|
||||
vkCmdBeginRenderPass(
|
||||
command_buffer,
|
||||
image_states.m_command_buffer,
|
||||
&pass_info,
|
||||
VK_SUBPASS_CONTENTS_INLINE
|
||||
);
|
||||
|
||||
vkCmdBindPipeline(
|
||||
command_buffer,
|
||||
image_states.m_command_buffer,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
m_pipeline
|
||||
m_swapchain_states.m_pipeline
|
||||
);
|
||||
|
||||
VkBuffer vertex_buffers[] = {
|
||||
@@ -706,7 +691,7 @@ void VulkanTutorial::create_command_buffers() {
|
||||
0,
|
||||
};
|
||||
vkCmdBindVertexBuffers(
|
||||
command_buffer,
|
||||
image_states.m_command_buffer,
|
||||
0,
|
||||
1,
|
||||
vertex_buffers,
|
||||
@@ -714,17 +699,17 @@ void VulkanTutorial::create_command_buffers() {
|
||||
);
|
||||
|
||||
vkCmdBindIndexBuffer(
|
||||
command_buffer,
|
||||
image_states.m_command_buffer,
|
||||
m_index_buffer,
|
||||
0,
|
||||
VK_INDEX_TYPE_UINT32
|
||||
);
|
||||
|
||||
VkDescriptorSet descriptor_sets[] {
|
||||
m_descriptor_sets[index],
|
||||
image_states.m_descriptor_set,
|
||||
};
|
||||
vkCmdBindDescriptorSets(
|
||||
command_buffer,
|
||||
image_states.m_command_buffer,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
m_pipeline_layout,
|
||||
0, 1, descriptor_sets,
|
||||
@@ -732,7 +717,7 @@ void VulkanTutorial::create_command_buffers() {
|
||||
);
|
||||
|
||||
vkCmdDrawIndexed(
|
||||
command_buffer,
|
||||
image_states.m_command_buffer,
|
||||
uint32_t(indices.size()),
|
||||
1,
|
||||
0,
|
||||
@@ -740,9 +725,8 @@ void VulkanTutorial::create_command_buffers() {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::Swapchain m_swapchain;
|
||||
|
||||
struct SwapchainStates {
|
||||
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::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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -324,7 +324,7 @@ void Swapchain::create() {
|
||||
}
|
||||
|
||||
for(auto& callback: m_creation_callbacks)
|
||||
callback(image_count);
|
||||
callback();
|
||||
}
|
||||
|
||||
void Swapchain::destroy() {
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user