|
|
@ -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( |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
buffer.bind_memory( |
|
|
m_uniform_buffer_memory, |
|
|
m_uniform_buffer_memory, |
|
|
m_uniform_buffer_offsets[index] |
|
|
image_states.m_uniform_buffer_offset |
|
|
); |
|
|
); |
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void VulkanTutorial::create_descriptor_pool() { |
|
|
void VulkanTutorial::create_descriptor_set(ImageStates& image_states) { |
|
|
VkDescriptorPoolSize pool_sizes[] { |
|
|
image_states.m_descriptor_set = vk::DescriptorSet( |
|
|
{ |
|
|
|
|
|
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, |
|
|
|
|
|
.descriptorCount = uint32_t(m_swapchain.image_count()), |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
m_descriptor_pool = vk::DescriptorPool( |
|
|
|
|
|
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, |
|
|
@ -646,14 +634,10 @@ void VulkanTutorial::create_descriptor_sets() { |
|
|
1, &write, |
|
|
1, &write, |
|
|
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"); |
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
|