Вынес управление VkDevice в отдельный класс

This commit is contained in:
Jiga228
2026-06-23 20:51:12 +07:00
parent 3cbe642fca
commit b2dee85b26
8 changed files with 178 additions and 146 deletions
+78 -126
View File
@@ -72,57 +72,10 @@ VkShaderModule UwURenderEngine::create_shader_module(const std::string& code) co
shader_module_info.pCode = reinterpret_cast<const uint32_t*>(code.c_str()); shader_module_info.pCode = reinterpret_cast<const uint32_t*>(code.c_str());
VkShaderModule shader_module; VkShaderModule shader_module;
VK_CHECK(vkCreateShaderModule(device_, &shader_module_info, nullptr, &shader_module)) VK_CHECK(vkCreateShaderModule(device_.get_native(), &shader_module_info, nullptr, &shader_module))
return shader_module; return shader_module;
} }
void UwURenderEngine::create_logical_device()
{
VkObjects::PhysicalDevice::QueueFamilyIndices indices = physical_device_.get_queue_family_indices();
VkPhysicalDeviceFeatures device_features{};
std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
std::set<uint32_t> unique_queue_families = {indices.graphics_family,
indices.present_family,
indices.transfer_family};
float queue_priority = 1.0f;
VkDeviceQueueCreateInfo device_queue_create_info{};
device_queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
device_queue_create_info.pQueuePriorities = &queue_priority;
for (auto queue_family : unique_queue_families)
{
device_queue_create_info.queueFamilyIndex = queue_family;
device_queue_create_info.queueCount = 1;
queue_create_infos.push_back(device_queue_create_info);
}
VkDeviceCreateInfo device_create_info{};
device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
device_create_info.queueCreateInfoCount = static_cast<uint32_t>(unique_queue_families.size());
device_create_info.pQueueCreateInfos = queue_create_infos.data();
device_create_info.pEnabledFeatures = &device_features;
device_create_info.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
device_create_info.ppEnabledExtensionNames = deviceExtensions.data();
#ifdef _DEBUG
const std::vector<const char*> layers_validation = {
"VK_LAYER_KHRONOS_validation"
};
device_create_info.enabledLayerCount = static_cast<uint32_t>(layers_validation.size());
device_create_info.ppEnabledLayerNames = layers_validation.data();
#else
device_create_info.enabledLayerCount = 0;
device_create_info.ppEnabledLayerNames = nullptr;
#endif
VK_CHECK(vkCreateDevice(physical_device_.get_native(), &device_create_info, nullptr, &device_))
vkGetDeviceQueue(device_, indices.graphics_family, 0, &graphics_queue_);
vkGetDeviceQueue(device_, indices.present_family, 0, &present_queue_);
vkGetDeviceQueue(device_, indices.transfer_family, 0, &transfer_queue_);
}
void UwURenderEngine::create_swapchain() void UwURenderEngine::create_swapchain()
{ {
SwapchainSupportDetails swapchain_support = query_swapchain_details(); SwapchainSupportDetails swapchain_support = query_swapchain_details();
@@ -172,11 +125,11 @@ void UwURenderEngine::create_swapchain()
swapchain_create_info.pQueueFamilyIndices = nullptr; swapchain_create_info.pQueueFamilyIndices = nullptr;
} }
VK_CHECK(vkCreateSwapchainKHR(device_, &swapchain_create_info, nullptr, &swapchain_)) VK_CHECK(vkCreateSwapchainKHR(device_.get_native(), &swapchain_create_info, nullptr, &swapchain_))
vkGetSwapchainImagesKHR(device_, swapchain_, &image_count, nullptr); vkGetSwapchainImagesKHR(device_.get_native(), swapchain_, &image_count, nullptr);
swapchain_images_.resize(image_count); swapchain_images_.resize(image_count);
vkGetSwapchainImagesKHR(device_, swapchain_, &image_count, swapchain_images_.data()); vkGetSwapchainImagesKHR(device_.get_native(), swapchain_, &image_count, swapchain_images_.data());
swapchain_image_format_ = surface_format.format; swapchain_image_format_ = surface_format.format;
swapchain_extent_ = extent; swapchain_extent_ = extent;
@@ -202,7 +155,7 @@ void UwURenderEngine::create_image_views()
for (uint32_t i = 0; i < swapchain_images_.size(); ++i) for (uint32_t i = 0; i < swapchain_images_.size(); ++i)
{ {
image_view_info.image = swapchain_images_[i]; image_view_info.image = swapchain_images_[i];
VK_CHECK(vkCreateImageView(device_, &image_view_info, nullptr, &swapchain_image_views_[i])) VK_CHECK(vkCreateImageView(device_.get_native(), &image_view_info, nullptr, &swapchain_image_views_[i]))
} }
} }
@@ -244,7 +197,7 @@ void UwURenderEngine::create_render_pass()
render_pass_info.dependencyCount = 1; render_pass_info.dependencyCount = 1;
render_pass_info.pDependencies = &dependency; render_pass_info.pDependencies = &dependency;
VK_CHECK(vkCreateRenderPass(device_, &render_pass_info, nullptr, &render_pass_)) VK_CHECK(vkCreateRenderPass(device_.get_native(), &render_pass_info, nullptr, &render_pass_))
} }
void UwURenderEngine::create_description_set_layout() void UwURenderEngine::create_description_set_layout()
@@ -261,7 +214,7 @@ void UwURenderEngine::create_description_set_layout()
ubo_layout_info.bindingCount = 1; ubo_layout_info.bindingCount = 1;
ubo_layout_info.pBindings = &ubo_layout_binding; ubo_layout_info.pBindings = &ubo_layout_binding;
VK_CHECK(vkCreateDescriptorSetLayout(device_, &ubo_layout_info, nullptr, &ubo_layout_binding_)) VK_CHECK(vkCreateDescriptorSetLayout(device_.get_native(), &ubo_layout_info, nullptr, &ubo_layout_binding_))
} }
void UwURenderEngine::create_uniform_buffers() void UwURenderEngine::create_uniform_buffers()
@@ -274,11 +227,11 @@ void UwURenderEngine::create_uniform_buffers()
for (size_t i = 0; i < swapchain_images_.size(); ++i) for (size_t i = 0; i < swapchain_images_.size(); ++i)
{ {
const VkDeviceSize size = sizeof(UniformBufferObject); const VkDeviceSize size = sizeof(UniformBufferObject);
uniform_buffers_[i] = DeviceFunctions::create_buffer(device_, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, arr_indices); uniform_buffers_[i] = DeviceFunctions::create_buffer(device_.get_native(), size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, arr_indices);
uniform_buffers_memory_[i] = DeviceFunctions::allocate_device_memory(physical_device_.get_native(), device_, uniform_buffers_[i], VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); uniform_buffers_memory_[i] = DeviceFunctions::allocate_device_memory(physical_device_.get_native(), device_.get_native(), uniform_buffers_[i], VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
vkBindBufferMemory(device_, uniform_buffers_[i], uniform_buffers_memory_[i], 0); vkBindBufferMemory(device_.get_native(), uniform_buffers_[i], uniform_buffers_memory_[i], 0);
vkMapMemory(device_, uniform_buffers_memory_[i], 0, size, 0, &uniform_buffers_mapped_[i]); vkMapMemory(device_.get_native(), uniform_buffers_memory_[i], 0, size, 0, &uniform_buffers_mapped_[i]);
} }
} }
@@ -294,7 +247,7 @@ void UwURenderEngine::create_descriptor_pool()
descriptor_pool_info.pPoolSizes = &pool_size; descriptor_pool_info.pPoolSizes = &pool_size;
descriptor_pool_info.maxSets = static_cast<uint32_t>(swapchain_images_.size()); descriptor_pool_info.maxSets = static_cast<uint32_t>(swapchain_images_.size());
VK_CHECK(vkCreateDescriptorPool(device_, &descriptor_pool_info, nullptr, &descriptor_pool_)) VK_CHECK(vkCreateDescriptorPool(device_.get_native(), &descriptor_pool_info, nullptr, &descriptor_pool_))
} }
void UwURenderEngine::create_descriptor_sets() void UwURenderEngine::create_descriptor_sets()
@@ -307,7 +260,7 @@ void UwURenderEngine::create_descriptor_sets()
descriptor_set_allocate_info.pSetLayouts = layouts.data(); descriptor_set_allocate_info.pSetLayouts = layouts.data();
descriptor_sets_.resize(swapchain_images_.size()); descriptor_sets_.resize(swapchain_images_.size());
VK_CHECK(vkAllocateDescriptorSets(device_, &descriptor_set_allocate_info, descriptor_sets_.data())) VK_CHECK(vkAllocateDescriptorSets(device_.get_native(), &descriptor_set_allocate_info, descriptor_sets_.data()))
for (size_t i = 0; i < swapchain_images_.size(); ++i) for (size_t i = 0; i < swapchain_images_.size(); ++i)
{ {
@@ -327,7 +280,7 @@ void UwURenderEngine::create_descriptor_sets()
write_descriptor_set.pImageInfo = nullptr; write_descriptor_set.pImageInfo = nullptr;
write_descriptor_set.pTexelBufferView = nullptr; write_descriptor_set.pTexelBufferView = nullptr;
vkUpdateDescriptorSets(device_, 1, &write_descriptor_set, 0, nullptr); vkUpdateDescriptorSets(device_.get_native(), 1, &write_descriptor_set, 0, nullptr);
} }
} }
@@ -447,7 +400,7 @@ void UwURenderEngine::create_graphics_pipeline()
pipeline_layout_info.setLayoutCount = 1; pipeline_layout_info.setLayoutCount = 1;
pipeline_layout_info.pSetLayouts = &ubo_layout_binding_; pipeline_layout_info.pSetLayouts = &ubo_layout_binding_;
VK_CHECK(vkCreatePipelineLayout(device_, &pipeline_layout_info, nullptr, &pipeline_layout_)) VK_CHECK(vkCreatePipelineLayout(device_.get_native(), &pipeline_layout_info, nullptr, &pipeline_layout_))
VkGraphicsPipelineCreateInfo graphics_pipeline_info{}; VkGraphicsPipelineCreateInfo graphics_pipeline_info{};
graphics_pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; graphics_pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
@@ -467,10 +420,10 @@ void UwURenderEngine::create_graphics_pipeline()
graphics_pipeline_info.basePipelineHandle = nullptr; graphics_pipeline_info.basePipelineHandle = nullptr;
graphics_pipeline_info.basePipelineIndex = -1; graphics_pipeline_info.basePipelineIndex = -1;
VK_CHECK(vkCreateGraphicsPipelines(device_, nullptr, 1, &graphics_pipeline_info, nullptr, &graphics_pipeline_)) VK_CHECK(vkCreateGraphicsPipelines(device_.get_native(), nullptr, 1, &graphics_pipeline_info, nullptr, &graphics_pipeline_))
vkDestroyShaderModule(device_, vertex_shader, nullptr); vkDestroyShaderModule(device_.get_native(), vertex_shader, nullptr);
vkDestroyShaderModule(device_, fragment_shader, nullptr); vkDestroyShaderModule(device_.get_native(), fragment_shader, nullptr);
} }
void UwURenderEngine::create_framebuffers() void UwURenderEngine::create_framebuffers()
@@ -488,7 +441,7 @@ void UwURenderEngine::create_framebuffers()
for (size_t i = 0; i < framebuffers_.size(); ++i) for (size_t i = 0; i < framebuffers_.size(); ++i)
{ {
framebuffer_info.pAttachments = &swapchain_image_views_[i]; framebuffer_info.pAttachments = &swapchain_image_views_[i];
VK_CHECK(vkCreateFramebuffer(device_, &framebuffer_info, nullptr, &framebuffers_[i])) VK_CHECK(vkCreateFramebuffer(device_.get_native(), &framebuffer_info, nullptr, &framebuffers_[i]))
} }
} }
@@ -501,7 +454,7 @@ void UwURenderEngine::create_command_pool()
command_pool_info.queueFamilyIndex = queue_family_indices.graphics_family; command_pool_info.queueFamilyIndex = queue_family_indices.graphics_family;
command_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; command_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
VK_CHECK(vkCreateCommandPool(device_, &command_pool_info, nullptr, &command_pool_)) VK_CHECK(vkCreateCommandPool(device_.get_native(), &command_pool_info, nullptr, &command_pool_))
} }
void UwURenderEngine::allocate_vertex_buffer() void UwURenderEngine::allocate_vertex_buffer()
@@ -513,27 +466,27 @@ void UwURenderEngine::allocate_vertex_buffer()
std::vector<uint32_t> transfer_index = {indices.transfer_family}; std::vector<uint32_t> transfer_index = {indices.transfer_family};
VkDeviceSize size_buffer = sizeof(vertices_[0]) * vertices_.size(); VkDeviceSize size_buffer = sizeof(vertices_[0]) * vertices_.size();
VkBuffer staging_buffer = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VkBuffer staging_buffer = DeviceFunctions::create_buffer(device_.get_native(), size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
transfer_index); transfer_index);
VkDeviceMemory staging_buffer_memory = DeviceFunctions::allocate_device_memory( VkDeviceMemory staging_buffer_memory = DeviceFunctions::allocate_device_memory(
physical_device_.get_native(), device_, staging_buffer, physical_device_.get_native(), device_.get_native(), staging_buffer,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
vertex_buffer_ = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, arr_indices); vertex_buffer_ = DeviceFunctions::create_buffer(device_.get_native(), size_buffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, arr_indices);
vertex_buffer_memory_ = DeviceFunctions::allocate_device_memory(physical_device_.get_native(), device_, vertex_buffer_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); vertex_buffer_memory_ = DeviceFunctions::allocate_device_memory(physical_device_.get_native(), device_.get_native(), vertex_buffer_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
VK_CHECK(vkBindBufferMemory(device_, staging_buffer, staging_buffer_memory, 0)) VK_CHECK(vkBindBufferMemory(device_.get_native(), staging_buffer, staging_buffer_memory, 0))
VK_CHECK(vkBindBufferMemory(device_, vertex_buffer_, vertex_buffer_memory_, 0)) VK_CHECK(vkBindBufferMemory(device_.get_native(), vertex_buffer_, vertex_buffer_memory_, 0))
void* data; void* data;
VK_CHECK(vkMapMemory(device_, staging_buffer_memory, 0, size_buffer, 0, &data)) VK_CHECK(vkMapMemory(device_.get_native(), staging_buffer_memory, 0, size_buffer, 0, &data))
memcpy(data, vertices_.data(), size_buffer); memcpy(data, vertices_.data(), size_buffer);
vkUnmapMemory(device_, staging_buffer_memory); vkUnmapMemory(device_.get_native(), staging_buffer_memory);
DeviceFunctions::device_memcpy(device_, indices.transfer_family, staging_buffer, vertex_buffer_, size_buffer); DeviceFunctions::device_memcpy(device_.get_native(), indices.transfer_family, staging_buffer, vertex_buffer_, size_buffer);
vkFreeMemory(device_, staging_buffer_memory, nullptr); vkFreeMemory(device_.get_native(), staging_buffer_memory, nullptr);
vkDestroyBuffer(device_, staging_buffer, nullptr); vkDestroyBuffer(device_.get_native(), staging_buffer, nullptr);
} }
void UwURenderEngine::allocate_index_buffer() void UwURenderEngine::allocate_index_buffer()
@@ -543,26 +496,26 @@ void UwURenderEngine::allocate_index_buffer()
std::vector<uint32_t> transfer_index = {indices.transfer_family}; std::vector<uint32_t> transfer_index = {indices.transfer_family};
VkDeviceSize size_buffer = sizeof(indices_[0]) * indices_.size(); VkDeviceSize size_buffer = sizeof(indices_[0]) * indices_.size();
VkBuffer staging_buffer = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VkBuffer staging_buffer = DeviceFunctions::create_buffer(device_.get_native(), size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
transfer_index); transfer_index);
VkDeviceMemory staging_buffer_memory = DeviceFunctions::allocate_device_memory( VkDeviceMemory staging_buffer_memory = DeviceFunctions::allocate_device_memory(
physical_device_.get_native(), device_, staging_buffer, physical_device_.get_native(), device_.get_native(), staging_buffer,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
vkBindBufferMemory(device_, staging_buffer, staging_buffer_memory, 0); vkBindBufferMemory(device_.get_native(), staging_buffer, staging_buffer_memory, 0);
void* data; void* data;
vkMapMemory(device_, staging_buffer_memory, 0, size_buffer, 0, &data); vkMapMemory(device_.get_native(), staging_buffer_memory, 0, size_buffer, 0, &data);
memcpy(data, indices_.data(), size_buffer); memcpy(data, indices_.data(), size_buffer);
vkUnmapMemory(device_, staging_buffer_memory); vkUnmapMemory(device_.get_native(), staging_buffer_memory);
index_buffer_ = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, arr_indices); index_buffer_ = DeviceFunctions::create_buffer(device_.get_native(), size_buffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, arr_indices);
index_buffer_memory_ = DeviceFunctions::allocate_device_memory(physical_device_.get_native(), device_, index_buffer_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); index_buffer_memory_ = DeviceFunctions::allocate_device_memory(physical_device_.get_native(), device_.get_native(), index_buffer_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
vkBindBufferMemory(device_, index_buffer_, index_buffer_memory_, 0); vkBindBufferMemory(device_.get_native(), index_buffer_, index_buffer_memory_, 0);
DeviceFunctions::device_memcpy(device_, indices.transfer_family,staging_buffer, index_buffer_, size_buffer); DeviceFunctions::device_memcpy(device_.get_native(), indices.transfer_family,staging_buffer, index_buffer_, size_buffer);
vkDestroyBuffer(device_, staging_buffer, nullptr); vkDestroyBuffer(device_.get_native(), staging_buffer, nullptr);
vkFreeMemory(device_, staging_buffer_memory, nullptr); vkFreeMemory(device_.get_native(), staging_buffer_memory, nullptr);
} }
void UwURenderEngine::allocate_command_buffers() void UwURenderEngine::allocate_command_buffers()
@@ -575,7 +528,7 @@ void UwURenderEngine::allocate_command_buffers()
command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
command_buffer_allocate_info.commandBufferCount = static_cast<uint32_t>(command_buffers_.size()); command_buffer_allocate_info.commandBufferCount = static_cast<uint32_t>(command_buffers_.size());
VK_CHECK(vkAllocateCommandBuffers(device_, &command_buffer_allocate_info, command_buffers_.data())) VK_CHECK(vkAllocateCommandBuffers(device_.get_native(), &command_buffer_allocate_info, command_buffers_.data()))
} }
void UwURenderEngine::create_sync_objects() void UwURenderEngine::create_sync_objects()
@@ -593,9 +546,9 @@ void UwURenderEngine::create_sync_objects()
for (size_t i = 0; i < swapchain_images_.size(); ++i) for (size_t i = 0; i < swapchain_images_.size(); ++i)
{ {
VK_CHECK(vkCreateSemaphore(device_, &semaphore_info, nullptr, &image_available_semaphores_[i])) VK_CHECK(vkCreateSemaphore(device_.get_native(), &semaphore_info, nullptr, &image_available_semaphores_[i]))
VK_CHECK(vkCreateSemaphore(device_, &semaphore_info, nullptr, &render_finished_semaphores_[i])) VK_CHECK(vkCreateSemaphore(device_.get_native(), &semaphore_info, nullptr, &render_finished_semaphores_[i]))
VK_CHECK(vkCreateFence(device_, &fence_info, nullptr, &in_flight_fences_[i])) VK_CHECK(vkCreateFence(device_.get_native(), &fence_info, nullptr, &in_flight_fences_[i]))
} }
} }
@@ -677,14 +630,14 @@ void UwURenderEngine::update_uniform_buffer(uint32_t current_frame) const
void UwURenderEngine::draw_frame() void UwURenderEngine::draw_frame()
{ {
vkWaitForFences(device_, 1, &in_flight_fences_[current_frame_], VK_TRUE, UINT64_MAX); vkWaitForFences(device_.get_native(), 1, &in_flight_fences_[current_frame_], VK_TRUE, UINT64_MAX);
vkResetFences(device_, 1, &in_flight_fences_[current_frame_]); vkResetFences(device_.get_native(), 1, &in_flight_fences_[current_frame_]);
// Free video memory // Free video memory
garbage_collector_->FreeHeap(); garbage_collector_->FreeHeap();
uint32_t image_index; uint32_t image_index;
vkAcquireNextImageKHR(device_, swapchain_, UINT64_MAX, image_available_semaphores_[current_frame_], VK_NULL_HANDLE, &image_index); vkAcquireNextImageKHR(device_.get_native(), swapchain_, UINT64_MAX, image_available_semaphores_[current_frame_], VK_NULL_HANDLE, &image_index);
vkResetCommandBuffer(command_buffers_[current_frame_], 0); vkResetCommandBuffer(command_buffers_[current_frame_], 0);
@@ -702,7 +655,7 @@ void UwURenderEngine::draw_frame()
submit_info.signalSemaphoreCount = 1; submit_info.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores = &render_finished_semaphores_[current_frame_]; submit_info.pSignalSemaphores = &render_finished_semaphores_[current_frame_];
VK_CHECK(vkQueueSubmit(graphics_queue_, 1, &submit_info, in_flight_fences_[current_frame_])) VK_CHECK(vkQueueSubmit(device_.get_graphics_queue(), 1, &submit_info, in_flight_fences_[current_frame_]))
VkPresentInfoKHR present_info{}; VkPresentInfoKHR present_info{};
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
@@ -713,18 +666,19 @@ void UwURenderEngine::draw_frame()
present_info.pImageIndices = &image_index; present_info.pImageIndices = &image_index;
present_info.pResults = nullptr; present_info.pResults = nullptr;
vkQueuePresentKHR(present_queue_, &present_info); vkQueuePresentKHR(device_.get_present_queue(), &present_info);
current_frame_ = (current_frame_ + 1) % static_cast<unsigned int>(swapchain_images_.size()); current_frame_ = (current_frame_ + 1) % static_cast<unsigned int>(swapchain_images_.size());
} }
UwURenderEngine::UwURenderEngine(CoreInstance& core):RenderEngineBase(core), UwURenderEngine::UwURenderEngine(CoreInstance& core):
RenderEngineBase(core),
core_(core),
instance_(core), instance_(core),
surface_(instance_, get_window()), surface_(instance_, get_window()),
physical_device_(instance_, surface_, deviceExtensions), physical_device_(instance_, surface_, deviceExtensions),
core_(core) device_(physical_device_, deviceExtensions)
{ {
create_logical_device();
create_swapchain(); create_swapchain();
create_image_views(); create_image_views();
create_render_pass(); create_render_pass();
@@ -740,77 +694,75 @@ core_(core)
allocate_index_buffer(); allocate_index_buffer();
create_sync_objects(); create_sync_objects();
garbage_collector_.reset(new GPU_GarbageCollector(device_)); garbage_collector_.reset(new GPU_GarbageCollector(device_.get_native()));
model_manager_.reset(new ModelManager(physical_device_.get_native(), device_)); model_manager_.reset(new ModelManager(physical_device_.get_native(), device_.get_native()));
} }
UwURenderEngine::~UwURenderEngine() UwURenderEngine::~UwURenderEngine()
{ {
vkDeviceWaitIdle(device_); vkDeviceWaitIdle(device_.get_native());
if (index_buffer_memory_ != VK_NULL_HANDLE) if (index_buffer_memory_ != VK_NULL_HANDLE)
vkFreeMemory(device_, index_buffer_memory_, nullptr); vkFreeMemory(device_.get_native(), index_buffer_memory_, nullptr);
if (index_buffer_ != VK_NULL_HANDLE) if (index_buffer_ != VK_NULL_HANDLE)
vkDestroyBuffer(device_, index_buffer_, nullptr); vkDestroyBuffer(device_.get_native(), index_buffer_, nullptr);
if (vertex_buffer_memory_ != VK_NULL_HANDLE) if (vertex_buffer_memory_ != VK_NULL_HANDLE)
vkFreeMemory(device_, vertex_buffer_memory_, nullptr); vkFreeMemory(device_.get_native(), vertex_buffer_memory_, nullptr);
if (vertex_buffer_ != VK_NULL_HANDLE) if (vertex_buffer_ != VK_NULL_HANDLE)
vkDestroyBuffer(device_, vertex_buffer_, nullptr); vkDestroyBuffer(device_.get_native(), vertex_buffer_, nullptr);
for (auto& i : image_available_semaphores_) for (auto& i : image_available_semaphores_)
vkDestroySemaphore(device_, i, nullptr); vkDestroySemaphore(device_.get_native(), i, nullptr);
for (auto& i : render_finished_semaphores_) for (auto& i : render_finished_semaphores_)
vkDestroySemaphore(device_, i, nullptr); vkDestroySemaphore(device_.get_native(), i, nullptr);
for (auto& i : in_flight_fences_) for (auto& i : in_flight_fences_)
vkDestroyFence(device_, i, nullptr); vkDestroyFence(device_.get_native(), i, nullptr);
if (command_buffers_.empty() == false) if (command_buffers_.empty() == false)
vkFreeCommandBuffers(device_, command_pool_, static_cast<uint32_t>(command_buffers_.size()), command_buffers_.data()); vkFreeCommandBuffers(device_.get_native(), command_pool_, static_cast<uint32_t>(command_buffers_.size()), command_buffers_.data());
if (command_pool_ != VK_NULL_HANDLE) if (command_pool_ != VK_NULL_HANDLE)
vkDestroyCommandPool(device_, command_pool_, nullptr); vkDestroyCommandPool(device_.get_native(), command_pool_, nullptr);
for (auto& i : framebuffers_) for (auto& i : framebuffers_)
vkDestroyFramebuffer(device_, i, nullptr); vkDestroyFramebuffer(device_.get_native(), i, nullptr);
if (graphics_pipeline_ != VK_NULL_HANDLE) if (graphics_pipeline_ != VK_NULL_HANDLE)
vkDestroyPipeline(device_, graphics_pipeline_, nullptr); vkDestroyPipeline(device_.get_native(), graphics_pipeline_, nullptr);
if (pipeline_layout_ != VK_NULL_HANDLE) if (pipeline_layout_ != VK_NULL_HANDLE)
vkDestroyPipelineLayout(device_, pipeline_layout_, nullptr); vkDestroyPipelineLayout(device_.get_native(), pipeline_layout_, nullptr);
for (size_t i = 0; i < uniform_buffers_.size(); ++i) for (size_t i = 0; i < uniform_buffers_.size(); ++i)
{ {
vkUnmapMemory(device_, uniform_buffers_memory_[i]); vkUnmapMemory(device_.get_native(), uniform_buffers_memory_[i]);
vkFreeMemory(device_, uniform_buffers_memory_[i], nullptr); vkFreeMemory(device_.get_native(), uniform_buffers_memory_[i], nullptr);
vkDestroyBuffer(device_, uniform_buffers_[i], nullptr); vkDestroyBuffer(device_.get_native(), uniform_buffers_[i], nullptr);
} }
uniform_buffers_.clear(); uniform_buffers_.clear();
uniform_buffers_memory_.clear(); uniform_buffers_memory_.clear();
uniform_buffers_mapped_.clear(); uniform_buffers_mapped_.clear();
vkDestroyDescriptorPool(device_, descriptor_pool_, nullptr); vkDestroyDescriptorPool(device_.get_native(), descriptor_pool_, nullptr);
if (ubo_layout_binding_ != VK_NULL_HANDLE) if (ubo_layout_binding_ != VK_NULL_HANDLE)
vkDestroyDescriptorSetLayout(device_, ubo_layout_binding_, nullptr); vkDestroyDescriptorSetLayout(device_.get_native(), ubo_layout_binding_, nullptr);
if (render_pass_ != VK_NULL_HANDLE) if (render_pass_ != VK_NULL_HANDLE)
vkDestroyRenderPass(device_, render_pass_, nullptr); vkDestroyRenderPass(device_.get_native(), render_pass_, nullptr);
for (auto image_view : swapchain_image_views_) for (auto image_view : swapchain_image_views_)
vkDestroyImageView(device_, image_view, nullptr); vkDestroyImageView(device_.get_native(), image_view, nullptr);
swapchain_image_views_.clear(); swapchain_image_views_.clear();
if (swapchain_ != VK_NULL_HANDLE) if (swapchain_ != VK_NULL_HANDLE)
vkDestroySwapchainKHR(device_, swapchain_, nullptr); vkDestroySwapchainKHR(device_.get_native(), swapchain_, nullptr);
if (device_ != VK_NULL_HANDLE)
vkDestroyDevice(device_, nullptr);
} }
void UwURenderEngine::start() void UwURenderEngine::start()
@@ -11,6 +11,7 @@
#include <mutex> #include <mutex>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "VkObjects/Device.hpp"
#include "VkObjects/Instance.hpp" #include "VkObjects/Instance.hpp"
#include "VkObjects/PhysicalDevice.hpp" #include "VkObjects/PhysicalDevice.hpp"
#include "VkObjects/Surface.hpp" #include "VkObjects/Surface.hpp"
@@ -67,11 +68,7 @@ class UwURenderEngine : public RenderEngineBase
VkObjects::Instance instance_; VkObjects::Instance instance_;
VkObjects::Surface surface_; VkObjects::Surface surface_;
VkObjects::PhysicalDevice physical_device_; VkObjects::PhysicalDevice physical_device_;
//VkPhysicalDevice physical_device_ = VK_NULL_HANDLE; VkObjects::Device device_;
VkDevice device_ = VK_NULL_HANDLE;
VkQueue graphics_queue_ = VK_NULL_HANDLE;
VkQueue present_queue_ = VK_NULL_HANDLE;
VkQueue transfer_queue_ = VK_NULL_HANDLE;
VkSwapchainKHR swapchain_ = VK_NULL_HANDLE; VkSwapchainKHR swapchain_ = VK_NULL_HANDLE;
std::vector<VkImage> swapchain_images_; std::vector<VkImage> swapchain_images_;
VkFormat swapchain_image_format_; VkFormat swapchain_image_format_;
@@ -104,7 +101,6 @@ class UwURenderEngine : public RenderEngineBase
static VkPresentModeKHR choose_present_mode(const std::vector<VkPresentModeKHR>& present_modes, VkPresentModeKHR desired_present_mode); static VkPresentModeKHR choose_present_mode(const std::vector<VkPresentModeKHR>& present_modes, VkPresentModeKHR desired_present_mode);
VkShaderModule create_shader_module(const std::string& code) const; VkShaderModule create_shader_module(const std::string& code) const;
void create_logical_device();
void create_swapchain(); void create_swapchain();
void create_image_views(); void create_image_views();
void create_render_pass(); void create_render_pass();
@@ -0,0 +1,60 @@
#include "Device.hpp"
#include "PhysicalDevice.hpp"
#include <set>
#include "DeviceFunctions/DeviceFunctions.hpp"
VkObjects::Device::Device(const PhysicalDevice& physical_device, const std::vector<const char*>& device_extensions)
{
PhysicalDevice::QueueFamilyIndices indices = physical_device.get_queue_family_indices();
VkPhysicalDeviceFeatures device_features{};
std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
std::set<uint32_t> unique_queue_families = {indices.graphics_family,
indices.present_family,
indices.transfer_family};
float queue_priority = 1.0f;
VkDeviceQueueCreateInfo device_queue_create_info{};
device_queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
device_queue_create_info.pQueuePriorities = &queue_priority;
for (auto queue_family : unique_queue_families)
{
device_queue_create_info.queueFamilyIndex = queue_family;
device_queue_create_info.queueCount = 1;
queue_create_infos.push_back(device_queue_create_info);
}
VkDeviceCreateInfo device_create_info{};
device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
device_create_info.queueCreateInfoCount = static_cast<uint32_t>(unique_queue_families.size());
device_create_info.pQueueCreateInfos = queue_create_infos.data();
device_create_info.pEnabledFeatures = &device_features;
device_create_info.enabledExtensionCount = static_cast<uint32_t>(device_extensions.size());
device_create_info.ppEnabledExtensionNames = device_extensions.data();
#ifdef _DEBUG
const std::vector<const char*> layers_validation = {
"VK_LAYER_KHRONOS_validation"
};
device_create_info.enabledLayerCount = static_cast<uint32_t>(layers_validation.size());
device_create_info.ppEnabledLayerNames = layers_validation.data();
#else
device_create_info.enabledLayerCount = 0;
device_create_info.ppEnabledLayerNames = nullptr;
#endif
VK_CHECK(vkCreateDevice(physical_device.get_native(), &device_create_info, nullptr, &device_))
vkGetDeviceQueue(device_, indices.graphics_family, 0, &graphics_queue_);
vkGetDeviceQueue(device_, indices.present_family, 0, &present_queue_);
vkGetDeviceQueue(device_, indices.transfer_family, 0, &transfer_queue_);
}
VkObjects::Device::~Device()
{
if (device_ != nullptr)
vkDestroyDevice(device_, nullptr);
}
@@ -0,0 +1,25 @@
#pragma once
#include <vector>
#include <vulkan/vulkan.h>
namespace VkObjects
{
class PhysicalDevice;
class Device
{
VkDevice device_ = nullptr;
VkQueue graphics_queue_ = nullptr;
VkQueue present_queue_ = nullptr;
VkQueue transfer_queue_ = nullptr;
public:
explicit Device(const PhysicalDevice& physical_device, const std::vector<const char*>& device_extensions);
~Device();
inline VkDevice get_native() const { return device_; }
inline VkQueue get_graphics_queue() const { return graphics_queue_; }
inline VkQueue get_present_queue() const { return present_queue_; }
inline VkQueue get_transfer_queue() const { return transfer_queue_; }
};
}
@@ -25,7 +25,7 @@ namespace VkObjects
std::vector<const char*> Instance::get_required_extensions(); std::vector<const char*> Instance::get_required_extensions();
public: public:
Instance(CoreInstance& core); explicit Instance(CoreInstance& core);
~Instance(); ~Instance();
inline VkInstance get_native() const { return instance_; } inline VkInstance get_native() const { return instance_; }
@@ -58,27 +58,29 @@ VkObjects::PhysicalDevice::QueueFamilyIndices VkObjects::PhysicalDevice::find_qu
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queueFamilyCount, family_properties.data()); vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queueFamilyCount, family_properties.data());
// Find graphics // Find graphics
bool is_find_graphics_family = false;
for(uint32_t i = 0; i < family_properties.size(); ++i) for(uint32_t i = 0; i < family_properties.size(); ++i)
{ {
if (family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) if (family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
{ {
queue_family_indices.graphics_family = i; queue_family_indices.graphics_family = i;
queue_family_indices.is_find_graphics_family = true; is_find_graphics_family = true;
break; break;
} }
} }
if (queue_family_indices.is_find_graphics_family == false) if (is_find_graphics_family == false)
throw std::runtime_error("Failed to find a graphics queue family"); throw std::runtime_error("Failed to find a graphics queue family");
// Find present // Find present
VkBool32 present_support = false; VkBool32 present_support = false;
VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue_family_indices.graphics_family, surface, &present_support)) VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue_family_indices.graphics_family, surface, &present_support))
// Если графическая очередь поддерживет презентацию кадров, то используем её // Если графическая очередь поддерживет презентацию кадров, то используем её
bool is_find_present_family = false;
if (present_support == VK_TRUE) if (present_support == VK_TRUE)
{ {
queue_family_indices.present_family = queue_family_indices.graphics_family; queue_family_indices.present_family = queue_family_indices.graphics_family;
queue_family_indices.is_find_present_family = true; is_find_present_family = true;
} }
// иначе ищем другую подходящую очередь // иначе ищем другую подходящую очередь
else else
@@ -90,17 +92,18 @@ VkObjects::PhysicalDevice::QueueFamilyIndices VkObjects::PhysicalDevice::find_qu
if (present_support == VK_TRUE) if (present_support == VK_TRUE)
{ {
queue_family_indices.present_family = i; queue_family_indices.present_family = i;
queue_family_indices.is_find_present_family = true; is_find_present_family = true;
break; break;
} }
} }
} }
if (queue_family_indices.is_find_present_family == false) if (is_find_present_family == false)
throw std::runtime_error("Failed to find a present queue family"); throw std::runtime_error("Failed to find a present queue family");
// С начала пытаемся найти очередь специалезированную // С начала пытаемся найти очередь специалезированную
// для копирования отличную от графической // для копирования отличную от графической
bool is_find_transfer_family = false;
for(uint32_t i = 0; i < family_properties.size(); ++i) for(uint32_t i = 0; i < family_properties.size(); ++i)
{ {
if (i == queue_family_indices.graphics_family) if (i == queue_family_indices.graphics_family)
@@ -108,14 +111,13 @@ VkObjects::PhysicalDevice::QueueFamilyIndices VkObjects::PhysicalDevice::find_qu
if (family_properties[i].queueFlags & VK_QUEUE_TRANSFER_BIT) if (family_properties[i].queueFlags & VK_QUEUE_TRANSFER_BIT)
{ {
queue_family_indices.transfer_family = i; queue_family_indices.transfer_family = i;
queue_family_indices.is_find_transfer_family = true; is_find_transfer_family = true;
} }
} }
// Если не находим, то используем графическую // Если не находим, то используем графическую
if (queue_family_indices.is_find_transfer_family == false) if (is_find_transfer_family == false)
{ {
queue_family_indices.transfer_family = queue_family_indices.graphics_family; queue_family_indices.transfer_family = queue_family_indices.graphics_family;
queue_family_indices.is_find_transfer_family = true;
} }
return queue_family_indices; return queue_family_indices;
} }
@@ -17,9 +17,6 @@ namespace VkObjects
uint32_t graphics_family = 0; uint32_t graphics_family = 0;
uint32_t present_family = 0; uint32_t present_family = 0;
uint32_t transfer_family = 0; uint32_t transfer_family = 0;
bool is_find_graphics_family = false;
bool is_find_present_family = false;
bool is_find_transfer_family = false;
}; };
QueueFamilyIndices queue_family_indices_{}; QueueFamilyIndices queue_family_indices_{};
@@ -32,7 +29,7 @@ namespace VkObjects
static QueueFamilyIndices find_queue_family_indices(VkPhysicalDevice physical_device, static QueueFamilyIndices find_queue_family_indices(VkPhysicalDevice physical_device,
VkSurfaceKHR surface); VkSurfaceKHR surface);
public: public:
PhysicalDevice(const Instance& instance, const Surface& surface, const std::vector<const char*>& device_extensions); explicit PhysicalDevice(const Instance& instance, const Surface& surface, const std::vector<const char*>& device_extensions);
inline VkPhysicalDevice get_native() const { return physical_device_; } inline VkPhysicalDevice get_native() const { return physical_device_; }
inline QueueFamilyIndices get_queue_family_indices() const { return queue_family_indices_; } inline QueueFamilyIndices get_queue_family_indices() const { return queue_family_indices_; }
@@ -13,7 +13,7 @@ namespace VkObjects
VkSurfaceKHR surface_ = nullptr; VkSurfaceKHR surface_ = nullptr;
const Instance& instance_; const Instance& instance_;
public: public:
Surface(const Instance& instance, GLFWwindow* window); explicit Surface(const Instance& instance, GLFWwindow* window);
~Surface(); ~Surface();
inline VkSurfaceKHR get_native() const { return surface_; } inline VkSurfaceKHR get_native() const { return surface_; }