|
|
|
@@ -4,6 +4,7 @@
|
|
|
|
|
#include <set>
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <chrono>
|
|
|
|
|
|
|
|
|
|
#include "Core/CoreInstance.hpp"
|
|
|
|
|
#include "Log/Log.hpp"
|
|
|
|
@@ -518,6 +519,90 @@ void RenderEngine::create_render_pass()
|
|
|
|
|
VK_CHECK(vkCreateRenderPass(device_, &render_pass_info, nullptr, &render_pass_));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RenderEngine::create_description_set_layout()
|
|
|
|
|
{
|
|
|
|
|
VkDescriptorSetLayoutBinding ubo_layout_binding{};
|
|
|
|
|
ubo_layout_binding.binding = 0;
|
|
|
|
|
ubo_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
|
|
|
|
ubo_layout_binding.descriptorCount = 1;
|
|
|
|
|
ubo_layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
|
|
|
|
ubo_layout_binding.pImmutableSamplers = nullptr;
|
|
|
|
|
|
|
|
|
|
VkDescriptorSetLayoutCreateInfo ubo_layout_info{};
|
|
|
|
|
ubo_layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
|
|
|
|
ubo_layout_info.bindingCount = 1;
|
|
|
|
|
ubo_layout_info.pBindings = &ubo_layout_binding;
|
|
|
|
|
|
|
|
|
|
VK_CHECK(vkCreateDescriptorSetLayout(device_, &ubo_layout_info, nullptr, &ubo_layout_binding_));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RenderEngine::create_uniform_buffers()
|
|
|
|
|
{
|
|
|
|
|
uniform_buffers_.resize(swapchain_images_.size());
|
|
|
|
|
uniform_buffers_memory_.resize(swapchain_images_.size());
|
|
|
|
|
uniform_buffers_mapped_.resize(swapchain_images_.size());
|
|
|
|
|
|
|
|
|
|
std::vector<uint32_t> arr_indices = get_unique_family_indices(find_queue_family_indices(physical_device_, surface_));
|
|
|
|
|
for (size_t i = 0; i < swapchain_images_.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
const VkDeviceSize size = sizeof(UniformBufferObject);
|
|
|
|
|
create_buffer(size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, &uniform_buffers_[i], arr_indices);
|
|
|
|
|
allocate_memory(uniform_buffers_[i], VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &uniform_buffers_memory_[i]);
|
|
|
|
|
vkBindBufferMemory(device_, uniform_buffers_[i], uniform_buffers_memory_[i], 0);
|
|
|
|
|
|
|
|
|
|
vkMapMemory(device_, uniform_buffers_memory_[i], 0, size, 0, &uniform_buffers_mapped_[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RenderEngine::create_descriptor_pool()
|
|
|
|
|
{
|
|
|
|
|
VkDescriptorPoolSize pool_size{};
|
|
|
|
|
pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
|
|
|
|
pool_size.descriptorCount = static_cast<uint32_t>(swapchain_images_.size());
|
|
|
|
|
|
|
|
|
|
VkDescriptorPoolCreateInfo descriptor_pool_info{};
|
|
|
|
|
descriptor_pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
|
|
|
|
descriptor_pool_info.poolSizeCount = 1;
|
|
|
|
|
descriptor_pool_info.pPoolSizes = &pool_size;
|
|
|
|
|
descriptor_pool_info.maxSets = static_cast<uint32_t>(swapchain_images_.size());
|
|
|
|
|
|
|
|
|
|
VK_CHECK(vkCreateDescriptorPool(device_, &descriptor_pool_info, nullptr, &descriptor_pool_));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RenderEngine::create_descriptor_sets()
|
|
|
|
|
{
|
|
|
|
|
std::vector<VkDescriptorSetLayout> layouts(swapchain_images_.size(), ubo_layout_binding_);
|
|
|
|
|
VkDescriptorSetAllocateInfo descriptor_set_allocate_info{};
|
|
|
|
|
descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
|
|
|
|
descriptor_set_allocate_info.descriptorPool = descriptor_pool_;
|
|
|
|
|
descriptor_set_allocate_info.descriptorSetCount = static_cast<uint32_t>(swapchain_images_.size());
|
|
|
|
|
descriptor_set_allocate_info.pSetLayouts = layouts.data();
|
|
|
|
|
|
|
|
|
|
descriptor_sets_.resize(swapchain_images_.size());
|
|
|
|
|
VK_CHECK(vkAllocateDescriptorSets(device_, &descriptor_set_allocate_info, descriptor_sets_.data()));
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < swapchain_images_.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
VkDescriptorBufferInfo buffer_info{};
|
|
|
|
|
buffer_info.buffer = uniform_buffers_[i];
|
|
|
|
|
buffer_info.offset = 0;
|
|
|
|
|
buffer_info.range = sizeof(UniformBufferObject);
|
|
|
|
|
|
|
|
|
|
VkWriteDescriptorSet write_descriptor_set{};
|
|
|
|
|
write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
|
|
|
write_descriptor_set.dstSet = descriptor_sets_[i];
|
|
|
|
|
write_descriptor_set.dstBinding = 0;
|
|
|
|
|
write_descriptor_set.dstArrayElement = 0;
|
|
|
|
|
write_descriptor_set.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
|
|
|
|
write_descriptor_set.descriptorCount = 1;
|
|
|
|
|
write_descriptor_set.pBufferInfo = &buffer_info;
|
|
|
|
|
write_descriptor_set.pImageInfo = nullptr;
|
|
|
|
|
write_descriptor_set.pTexelBufferView = nullptr;
|
|
|
|
|
|
|
|
|
|
vkUpdateDescriptorSets(device_, 1, &write_descriptor_set, 0, nullptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RenderEngine::create_graphics_pipeline()
|
|
|
|
|
{
|
|
|
|
|
std::ifstream vertex_shader_file("Shaders/vertex.spv", std::ios::binary);
|
|
|
|
@@ -601,7 +686,7 @@ void RenderEngine::create_graphics_pipeline()
|
|
|
|
|
rasterization_info.polygonMode = VK_POLYGON_MODE_FILL;
|
|
|
|
|
rasterization_info.lineWidth = 1.0f;
|
|
|
|
|
rasterization_info.cullMode = VK_CULL_MODE_BACK_BIT;
|
|
|
|
|
rasterization_info.frontFace = VK_FRONT_FACE_CLOCKWISE;
|
|
|
|
|
rasterization_info.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
|
|
|
|
rasterization_info.depthBiasEnable = VK_FALSE;
|
|
|
|
|
|
|
|
|
|
VkPipelineMultisampleStateCreateInfo multisample_info{};
|
|
|
|
@@ -631,6 +716,8 @@ void RenderEngine::create_graphics_pipeline()
|
|
|
|
|
|
|
|
|
|
VkPipelineLayoutCreateInfo pipeline_layout_info{};
|
|
|
|
|
pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
|
|
|
|
pipeline_layout_info.setLayoutCount = 1;
|
|
|
|
|
pipeline_layout_info.pSetLayouts = &ubo_layout_binding_;
|
|
|
|
|
|
|
|
|
|
VK_CHECK(vkCreatePipelineLayout(device_, &pipeline_layout_info, nullptr, &pipeline_layout_));
|
|
|
|
|
|
|
|
|
@@ -703,18 +790,26 @@ uint32_t RenderEngine::find_memory_type(uint32_t typeFilter, VkMemoryPropertyFla
|
|
|
|
|
throw std::runtime_error("failed to find suitable memory type!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RenderEngine::allocate_vertex_buffer()
|
|
|
|
|
std::vector<uint32_t> RenderEngine::get_unique_family_indices(const QueueFamilyIndices& indices)
|
|
|
|
|
{
|
|
|
|
|
QueueFamilyIndices indices = find_queue_family_indices(physical_device_, surface_);
|
|
|
|
|
std::set<uint32_t> set_indices = {indices.graphics_family.value(),
|
|
|
|
|
indices.present_family.value(),
|
|
|
|
|
indices.transfer_family.value()};
|
|
|
|
|
|
|
|
|
|
std::vector<uint32_t> arr_indices;
|
|
|
|
|
std::vector<uint32_t> transfer_index = {indices.transfer_family.value()};
|
|
|
|
|
arr_indices.reserve(set_indices.size());
|
|
|
|
|
for (auto& i : set_indices)
|
|
|
|
|
arr_indices.push_back(i);
|
|
|
|
|
return arr_indices;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RenderEngine::allocate_vertex_buffer()
|
|
|
|
|
{
|
|
|
|
|
QueueFamilyIndices indices = find_queue_family_indices(physical_device_, surface_);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<uint32_t> arr_indices = get_unique_family_indices(indices);
|
|
|
|
|
std::vector<uint32_t> transfer_index = {indices.transfer_family.value()};
|
|
|
|
|
|
|
|
|
|
VkBuffer staging_buffer = VK_NULL_HANDLE;
|
|
|
|
|
VkDeviceMemory staging_buffer_memory = VK_NULL_HANDLE;
|
|
|
|
@@ -746,11 +841,9 @@ void RenderEngine::allocate_index_buffer()
|
|
|
|
|
std::set<uint32_t> set_indices = {indices.graphics_family.value(),
|
|
|
|
|
indices.present_family.value(),
|
|
|
|
|
indices.transfer_family.value()};
|
|
|
|
|
std::vector<uint32_t> arr_indices;
|
|
|
|
|
|
|
|
|
|
std::vector<uint32_t> arr_indices = get_unique_family_indices(indices);
|
|
|
|
|
std::vector<uint32_t> transfer_index = {indices.transfer_family.value()};
|
|
|
|
|
arr_indices.reserve(set_indices.size());
|
|
|
|
|
for (auto& i : set_indices)
|
|
|
|
|
arr_indices.push_back(i);
|
|
|
|
|
|
|
|
|
|
VkBuffer staging_buffer = VK_NULL_HANDLE;
|
|
|
|
|
VkDeviceMemory staging_buffer_memory = VK_NULL_HANDLE;
|
|
|
|
@@ -875,6 +968,9 @@ void RenderEngine::record_command_buffer(VkCommandBuffer command_buffer, uint32_
|
|
|
|
|
VkBuffer vertex_buffers[] = {vertex_buffer_};
|
|
|
|
|
VkDeviceSize offset[] = {0};
|
|
|
|
|
vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, offset);
|
|
|
|
|
|
|
|
|
|
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout_, 0, 1, &descriptor_sets_[current_frame_], 0, nullptr);
|
|
|
|
|
|
|
|
|
|
vkCmdBindIndexBuffer(command_buffer, index_buffer_, 0, VK_INDEX_TYPE_UINT16);
|
|
|
|
|
|
|
|
|
|
VkViewport viewport;
|
|
|
|
@@ -891,13 +987,25 @@ void RenderEngine::record_command_buffer(VkCommandBuffer command_buffer, uint32_
|
|
|
|
|
scissor.extent = swapchain_extent_;
|
|
|
|
|
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
|
|
|
|
|
|
|
|
|
//vkCmdDraw(command_buffer, static_cast<uint32_t>(vertices_.size()), 1, 0, 0);
|
|
|
|
|
vkCmdDrawIndexed(command_buffer, static_cast<uint32_t>(indices_.size()), 1, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
vkCmdEndRenderPass(command_buffer);
|
|
|
|
|
VK_CHECK(vkEndCommandBuffer(command_buffer));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RenderEngine::update_uniform_buffer(uint32_t current_frame)
|
|
|
|
|
{
|
|
|
|
|
static auto start_time = std::chrono::high_resolution_clock::now();
|
|
|
|
|
auto current_time = std::chrono::high_resolution_clock::now();
|
|
|
|
|
float time = std::chrono::duration_cast<std::chrono::duration<float>>(current_time - start_time).count();
|
|
|
|
|
UniformBufferObject ubo{};
|
|
|
|
|
ubo.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(45.0f), glm::vec3(0.0f, 0.0f, 1.0f));
|
|
|
|
|
ubo.view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f));
|
|
|
|
|
ubo.proj = glm::perspective(glm::radians(45.0f), static_cast<float>(swapchain_extent_.width) / static_cast<float>(swapchain_extent_.height), 0.1f, 256.0f);
|
|
|
|
|
ubo.proj[1][1] *= -1;
|
|
|
|
|
memcpy(uniform_buffers_mapped_[current_frame], &ubo, sizeof(ubo));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RenderEngine::draw_frame()
|
|
|
|
|
{
|
|
|
|
|
vkWaitForFences(device_, 1, &in_flight_fences_[current_frame_], VK_TRUE, UINT64_MAX);
|
|
|
|
@@ -908,6 +1016,8 @@ void RenderEngine::draw_frame()
|
|
|
|
|
|
|
|
|
|
vkResetCommandBuffer(command_buffers_[current_frame_], 0);
|
|
|
|
|
record_command_buffer(command_buffers_[current_frame_], image_index);
|
|
|
|
|
|
|
|
|
|
update_uniform_buffer(current_frame_);
|
|
|
|
|
|
|
|
|
|
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
|
|
|
|
VkSubmitInfo submit_info{};
|
|
|
|
@@ -955,6 +1065,10 @@ window_(window)
|
|
|
|
|
create_swapchain(desired_present_mode);
|
|
|
|
|
create_image_views();
|
|
|
|
|
create_render_pass();
|
|
|
|
|
create_description_set_layout();
|
|
|
|
|
create_uniform_buffers();
|
|
|
|
|
create_descriptor_pool();
|
|
|
|
|
create_descriptor_sets();
|
|
|
|
|
create_graphics_pipeline();
|
|
|
|
|
create_framebuffers();
|
|
|
|
|
create_command_pool();
|
|
|
|
@@ -1004,6 +1118,21 @@ RenderEngine::~RenderEngine()
|
|
|
|
|
if (pipeline_layout_ != VK_NULL_HANDLE)
|
|
|
|
|
vkDestroyPipelineLayout(device_, pipeline_layout_, nullptr);
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < uniform_buffers_.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
vkUnmapMemory(device_, uniform_buffers_memory_[i]);
|
|
|
|
|
vkFreeMemory(device_, uniform_buffers_memory_[i], nullptr);
|
|
|
|
|
vkDestroyBuffer(device_, uniform_buffers_[i], nullptr);
|
|
|
|
|
}
|
|
|
|
|
uniform_buffers_.clear();
|
|
|
|
|
uniform_buffers_memory_.clear();
|
|
|
|
|
uniform_buffers_mapped_.clear();
|
|
|
|
|
|
|
|
|
|
vkDestroyDescriptorPool(device_, descriptor_pool_, nullptr);
|
|
|
|
|
|
|
|
|
|
if (ubo_layout_binding_ != VK_NULL_HANDLE)
|
|
|
|
|
vkDestroyDescriptorSetLayout(device_, ubo_layout_binding_, nullptr);
|
|
|
|
|
|
|
|
|
|
if (render_pass_ != VK_NULL_HANDLE)
|
|
|
|
|
vkDestroyRenderPass(device_, render_pass_, nullptr);
|
|
|
|
|
|
|
|
|
|