From 93eb08fe9f8f1c344d2337f18dd5ef046b46c368 Mon Sep 17 00:00:00 2001 From: Jiga228 Date: Tue, 23 Jun 2026 21:59:34 +0700 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D1=91=D1=81=20?= =?UTF-8?q?=D1=83=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?VkSwapchainKHR=20=D0=B8=20ImageViews=20=D0=B2=20=D0=BE=D1=82?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20=D0=BA=D0=BB=D0=B0?= =?UTF-8?q?=D1=81=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RenderEngine/UwURenderEngine.cpp | 214 ++++-------------- .../RenderEngine/UwURenderEngine.hpp | 24 +- .../RenderEngine/VkObjects/Swapchain.cpp | 148 ++++++++++++ .../RenderEngine/VkObjects/Swapchain.hpp | 46 ++++ 4 files changed, 239 insertions(+), 193 deletions(-) create mode 100644 UwURenderEngine/RenderEngine/VkObjects/Swapchain.cpp create mode 100644 UwURenderEngine/RenderEngine/VkObjects/Swapchain.hpp diff --git a/UwURenderEngine/RenderEngine/UwURenderEngine.cpp b/UwURenderEngine/RenderEngine/UwURenderEngine.cpp index 038e510..4b1583b 100644 --- a/UwURenderEngine/RenderEngine/UwURenderEngine.cpp +++ b/UwURenderEngine/RenderEngine/UwURenderEngine.cpp @@ -1,7 +1,6 @@ #include "UwURenderEngine.hpp" #include -#include #include #include #include @@ -11,59 +10,14 @@ #include "GPU_GarbageCollector.h" #include "../Game/Actors/Camera.hpp" #include "Core/CoreInstance.hpp" -#include "Log/Log.hpp" #include "Game/GameInstance.hpp" #include "Game/World/World.hpp" #include "../Game/Actors/Mesh/Mesh.hpp" #include "DeviceFunctions/DeviceFunctions.hpp" -const std::vector UwURenderEngine::deviceExtensions = { - VK_KHR_SWAPCHAIN_EXTENSION_NAME -}; - RENDER_ENGINE_FACTORY_GENERATE(UwURenderEngine) - -UwURenderEngine::SwapchainSupportDetails UwURenderEngine::query_swapchain_details() const -{ - SwapchainSupportDetails details; - - vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device_.get_native(), surface_.get_native(), &details.capabilities); - - uint32_t surface_format_cnt = 0; - VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device_.get_native(), surface_.get_native(), &surface_format_cnt, nullptr)) - details.formats.resize(surface_format_cnt); - VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device_.get_native(), surface_.get_native(), &surface_format_cnt, details.formats.data())) - - uint32_t present_modes_cnt = 0; - VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device_.get_native(), surface_.get_native(), &present_modes_cnt, nullptr)) - details.present_modes.resize(surface_format_cnt); - VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device_.get_native(), surface_.get_native(), &present_modes_cnt, details.present_modes.data())) - - return details; -} - -VkSurfaceFormatKHR UwURenderEngine::choose_surface_format(const std::vector& surface_formats) -{ - for (const auto& i : surface_formats) - { - if (i.format == VK_FORMAT_B8G8R8A8_SRGB && i.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) - return i; - } - return surface_formats[0]; -} - -VkPresentModeKHR UwURenderEngine::choose_present_mode(const std::vector& present_modes, VkPresentModeKHR desired_present_mode) -{ - for (const auto& i : present_modes) - { - if (i == desired_present_mode) - return i; - } - return VK_PRESENT_MODE_FIFO_KHR; -} - VkShaderModule UwURenderEngine::create_shader_module(const std::string& code) const { VkShaderModuleCreateInfo shader_module_info{}; @@ -76,93 +30,11 @@ VkShaderModule UwURenderEngine::create_shader_module(const std::string& code) co return shader_module; } -void UwURenderEngine::create_swapchain() -{ - SwapchainSupportDetails swapchain_support = query_swapchain_details(); - VkSurfaceFormatKHR surface_format = choose_surface_format(swapchain_support.formats); - VkPresentModeKHR present_mode = choose_present_mode(swapchain_support.present_modes, VK_PRESENT_MODE_MAILBOX_KHR); - VkExtent2D extent = DeviceFunctions::choose_extent(swapchain_support.capabilities, get_window()); - - uint32_t image_count = swapchain_support.capabilities.minImageCount + 1; - if (swapchain_support.capabilities.maxImageCount > 0 && image_count > swapchain_support.capabilities.maxImageCount) - image_count = swapchain_support.capabilities.maxImageCount; - - VkSwapchainCreateInfoKHR swapchain_create_info{}; - swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - swapchain_create_info.surface = surface_.get_native(); - swapchain_create_info.minImageCount = image_count; - swapchain_create_info.imageFormat = surface_format.format; - swapchain_create_info.imageColorSpace = surface_format.colorSpace; - swapchain_create_info.imageExtent = extent; - swapchain_create_info.imageArrayLayers = 1; - swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - swapchain_create_info.preTransform = swapchain_support.capabilities.currentTransform; - swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - swapchain_create_info.presentMode = present_mode; - swapchain_create_info.clipped = VK_TRUE; - swapchain_create_info.oldSwapchain = VK_NULL_HANDLE; - - VkObjects::PhysicalDevice::QueueFamilyIndices family_indices = physical_device_.get_queue_family_indices(); - const std::set queue_family_indices = { family_indices.graphics_family, - family_indices.present_family, - family_indices.transfer_family }; - std::vector arr_families; - if (queue_family_indices.size() > 1) - { - arr_families.reserve(queue_family_indices.size()); - for(auto& i : queue_family_indices) - arr_families.push_back(i); - - - swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT; - swapchain_create_info.queueFamilyIndexCount = static_cast(arr_families.size()); - swapchain_create_info.pQueueFamilyIndices = arr_families.data(); - } - else - { - swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - swapchain_create_info.queueFamilyIndexCount = 0; - swapchain_create_info.pQueueFamilyIndices = nullptr; - } - - VK_CHECK(vkCreateSwapchainKHR(device_.get_native(), &swapchain_create_info, nullptr, &swapchain_)) - - vkGetSwapchainImagesKHR(device_.get_native(), swapchain_, &image_count, nullptr); - swapchain_images_.resize(image_count); - vkGetSwapchainImagesKHR(device_.get_native(), swapchain_, &image_count, swapchain_images_.data()); - - swapchain_image_format_ = surface_format.format; - swapchain_extent_ = extent; -} - -void UwURenderEngine::create_image_views() -{ - VkImageViewCreateInfo image_view_info{}; - image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - image_view_info.viewType = VK_IMAGE_VIEW_TYPE_2D; - image_view_info.format = swapchain_image_format_; - image_view_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; - image_view_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; - image_view_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; - image_view_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; - image_view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - image_view_info.subresourceRange.baseMipLevel = 0; - image_view_info.subresourceRange.levelCount = 1; - image_view_info.subresourceRange.baseArrayLayer = 0; - image_view_info.subresourceRange.layerCount = 1; - - swapchain_image_views_.resize(swapchain_images_.size()); - for (uint32_t i = 0; i < swapchain_images_.size(); ++i) - { - image_view_info.image = swapchain_images_[i]; - VK_CHECK(vkCreateImageView(device_.get_native(), &image_view_info, nullptr, &swapchain_image_views_[i])) - } -} void UwURenderEngine::create_render_pass() { VkAttachmentDescription attachment_description{}; - attachment_description.format = swapchain_image_format_; + attachment_description.format = swapchain_.get_image_format(); attachment_description.samples = VK_SAMPLE_COUNT_1_BIT; attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_STORE; @@ -219,14 +91,14 @@ void UwURenderEngine::create_description_set_layout() void UwURenderEngine::create_uniform_buffers() { - uniform_buffers_.resize(swapchain_images_.size()); - uniform_buffers_memory_.resize(swapchain_images_.size()); - uniform_buffers_mapped_.resize(swapchain_images_.size()); + uniform_buffers_.resize(swapchain_.get_images().size()); + uniform_buffers_memory_.resize(swapchain_.get_images().size()); + uniform_buffers_mapped_.resize(swapchain_.get_images().size()); std::vector arr_indices = physical_device_.get_unique_family_indices(); - for (size_t i = 0; i < swapchain_images_.size(); ++i) + for (size_t i = 0; i < swapchain_.get_images().size(); ++i) { - const VkDeviceSize size = sizeof(UniformBufferObject); + constexpr VkDeviceSize size = sizeof(UniformBufferObject); 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_.get_native(), uniform_buffers_[i], VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); vkBindBufferMemory(device_.get_native(), uniform_buffers_[i], uniform_buffers_memory_[i], 0); @@ -239,30 +111,30 @@ void UwURenderEngine::create_descriptor_pool() { VkDescriptorPoolSize pool_size; pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - pool_size.descriptorCount = static_cast(swapchain_images_.size()); + pool_size.descriptorCount = static_cast(swapchain_.get_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(swapchain_images_.size()); + descriptor_pool_info.maxSets = static_cast(swapchain_.get_images().size()); VK_CHECK(vkCreateDescriptorPool(device_.get_native(), &descriptor_pool_info, nullptr, &descriptor_pool_)) } void UwURenderEngine::create_descriptor_sets() { - std::vector layouts(swapchain_images_.size(), ubo_layout_binding_); + std::vector layouts(swapchain_.get_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(swapchain_images_.size()); + descriptor_set_allocate_info.descriptorSetCount = static_cast(swapchain_.get_images().size()); descriptor_set_allocate_info.pSetLayouts = layouts.data(); - descriptor_sets_.resize(swapchain_images_.size()); + descriptor_sets_.resize(swapchain_.get_images().size()); 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_.get_images().size(); ++i) { VkDescriptorBufferInfo buffer_info{}; buffer_info.buffer = uniform_buffers_[i]; @@ -344,14 +216,14 @@ void UwURenderEngine::create_graphics_pipeline() VkViewport viewport{}; viewport.x = 0.0f; viewport.y = 0.0f; - viewport.width = static_cast(swapchain_extent_.width); - viewport.height = static_cast(swapchain_extent_.height); + viewport.width = static_cast(swapchain_.get_extent().width); + viewport.height = static_cast(swapchain_.get_extent().height); viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f; VkRect2D scissor{}; scissor.offset = {0, 0}; - scissor.extent = swapchain_extent_; + scissor.extent = swapchain_.get_extent(); VkPipelineViewportStateCreateInfo viewport_info{}; viewport_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; @@ -428,19 +300,19 @@ void UwURenderEngine::create_graphics_pipeline() void UwURenderEngine::create_framebuffers() { - framebuffers_.resize(swapchain_images_.size()); + framebuffers_.resize(swapchain_.get_images().size()); VkFramebufferCreateInfo framebuffer_info{}; framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebuffer_info.renderPass = render_pass_; framebuffer_info.attachmentCount = 1; - framebuffer_info.width = swapchain_extent_.width; - framebuffer_info.height = swapchain_extent_.height; + framebuffer_info.width = swapchain_.get_extent().width; + framebuffer_info.height = swapchain_.get_extent().height; framebuffer_info.layers = 1; for (size_t i = 0; i < framebuffers_.size(); ++i) { - framebuffer_info.pAttachments = &swapchain_image_views_[i]; + framebuffer_info.pAttachments = &swapchain_.get_image_views()[i]; VK_CHECK(vkCreateFramebuffer(device_.get_native(), &framebuffer_info, nullptr, &framebuffers_[i])) } } @@ -520,7 +392,7 @@ void UwURenderEngine::allocate_index_buffer() void UwURenderEngine::allocate_command_buffers() { - command_buffers_.resize(swapchain_images_.size()); + command_buffers_.resize(swapchain_.get_images().size()); VkCommandBufferAllocateInfo command_buffer_allocate_info{}; command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; @@ -533,9 +405,9 @@ void UwURenderEngine::allocate_command_buffers() void UwURenderEngine::create_sync_objects() { - image_available_semaphores_.resize(swapchain_images_.size()); - render_finished_semaphores_.resize(swapchain_images_.size()); - in_flight_fences_.resize(swapchain_images_.size()); + image_available_semaphores_.resize(swapchain_.get_images().size()); + render_finished_semaphores_.resize(swapchain_.get_images().size()); + in_flight_fences_.resize(swapchain_.get_images().size()); VkSemaphoreCreateInfo semaphore_info{}; semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; @@ -544,7 +416,7 @@ void UwURenderEngine::create_sync_objects() fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT; - for (size_t i = 0; i < swapchain_images_.size(); ++i) + for (size_t i = 0; i < swapchain_.get_images().size(); ++i) { VK_CHECK(vkCreateSemaphore(device_.get_native(), &semaphore_info, nullptr, &image_available_semaphores_[i])) VK_CHECK(vkCreateSemaphore(device_.get_native(), &semaphore_info, nullptr, &render_finished_semaphores_[i])) @@ -564,7 +436,7 @@ void UwURenderEngine::record_command_buffer(VkCommandBuffer command_buffer, uint render_pass_begin_info.renderPass = render_pass_; render_pass_begin_info.framebuffer = framebuffers_[image_index]; render_pass_begin_info.renderArea.offset = {0, 0}; - render_pass_begin_info.renderArea.extent = swapchain_extent_; + render_pass_begin_info.renderArea.extent = swapchain_.get_extent(); render_pass_begin_info.clearValueCount = 1; render_pass_begin_info.pClearValues = &clear_color; vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE); @@ -582,15 +454,15 @@ void UwURenderEngine::record_command_buffer(VkCommandBuffer command_buffer, uint VkViewport viewport; viewport.x = 0.0f; viewport.y = 0.0f; - viewport.width = static_cast(swapchain_extent_.width); - viewport.height = static_cast(swapchain_extent_.height); + viewport.width = static_cast(swapchain_.get_extent().width); + viewport.height = static_cast(swapchain_.get_extent().height); viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f; vkCmdSetViewport(command_buffer, 0, 1, &viewport); VkRect2D scissor; scissor.offset = {0, 0}; - scissor.extent = swapchain_extent_; + scissor.extent = swapchain_.get_extent(); vkCmdSetScissor(command_buffer, 0, 1, &scissor); vkCmdDrawIndexed(command_buffer, static_cast(indices_.size()), 1, 0, 0, 0); @@ -617,13 +489,13 @@ void UwURenderEngine::update_uniform_buffer(uint32_t current_frame) const up = {0, glm::sin(rot.z), glm::cos(rot.z)}; } - 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>(current_time - start_time).count(); + // 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>(current_time - start_time).count(); UniformBufferObject ubo; ubo.model = glm::rotate(glm::mat4(1.0f), /*time * glm::radians(45.0f)*/0.f, glm::vec3(0.0f, 0.0f, 1.0f)); ubo.view = glm::lookAt(eye, center, up); - ubo.proj = glm::perspective(glm::radians(45.0f), static_cast(swapchain_extent_.width) / static_cast(swapchain_extent_.height), 0.1f, 256.0f); + ubo.proj = glm::perspective(glm::radians(45.0f), static_cast(swapchain_.get_extent().width) / static_cast(swapchain_.get_extent().height), 0.1f, 256.0f); ubo.proj[1][1] *= -1; memcpy(uniform_buffers_mapped_[current_frame], &ubo, sizeof(ubo)); } @@ -637,7 +509,7 @@ void UwURenderEngine::draw_frame() garbage_collector_->FreeHeap(); uint32_t image_index; - vkAcquireNextImageKHR(device_.get_native(), swapchain_, UINT64_MAX, image_available_semaphores_[current_frame_], VK_NULL_HANDLE, &image_index); + vkAcquireNextImageKHR(device_.get_native(), swapchain_.get_native(), UINT64_MAX, image_available_semaphores_[current_frame_], VK_NULL_HANDLE, &image_index); vkResetCommandBuffer(command_buffers_[current_frame_], 0); @@ -657,18 +529,19 @@ void UwURenderEngine::draw_frame() VK_CHECK(vkQueueSubmit(device_.get_graphics_queue(), 1, &submit_info, in_flight_fences_[current_frame_])) + VkSwapchainKHR swapchain = swapchain_.get_native(); VkPresentInfoKHR present_info{}; present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; present_info.waitSemaphoreCount = 1; present_info.pWaitSemaphores = &render_finished_semaphores_[current_frame_]; present_info.swapchainCount = 1; - present_info.pSwapchains = &swapchain_; + present_info.pSwapchains = &swapchain; present_info.pImageIndices = &image_index; present_info.pResults = nullptr; vkQueuePresentKHR(device_.get_present_queue(), &present_info); - current_frame_ = (current_frame_ + 1) % static_cast(swapchain_images_.size()); + current_frame_ = (current_frame_ + 1) % static_cast(swapchain_.get_images().size()); } UwURenderEngine::UwURenderEngine(CoreInstance& core): @@ -677,10 +550,9 @@ core_(core), instance_(core), surface_(instance_, get_window()), physical_device_(instance_, surface_, deviceExtensions), -device_(physical_device_, deviceExtensions) +device_(physical_device_, deviceExtensions), +swapchain_(surface_, physical_device_, device_, get_window()) { - create_swapchain(); - create_image_views(); create_render_pass(); create_description_set_layout(); create_uniform_buffers(); @@ -755,14 +627,6 @@ UwURenderEngine::~UwURenderEngine() if (render_pass_ != VK_NULL_HANDLE) vkDestroyRenderPass(device_.get_native(), render_pass_, nullptr); - - for (auto image_view : swapchain_image_views_) - vkDestroyImageView(device_.get_native(), image_view, nullptr); - swapchain_image_views_.clear(); - - if (swapchain_ != VK_NULL_HANDLE) - vkDestroySwapchainKHR(device_.get_native(), swapchain_, nullptr); - } void UwURenderEngine::start() @@ -788,7 +652,7 @@ void UwURenderEngine::stop_render() const glfwSetWindowShouldClose(get_window(), true); } -void UwURenderEngine::SetActiveCamera(std::weak_ptr camera) +void UwURenderEngine::SetActiveCamera(const std::weak_ptr& camera) { std::scoped_lock lock(m_active_camera_); active_camera_ = camera; diff --git a/UwURenderEngine/RenderEngine/UwURenderEngine.hpp b/UwURenderEngine/RenderEngine/UwURenderEngine.hpp index e45d600..ef598e8 100644 --- a/UwURenderEngine/RenderEngine/UwURenderEngine.hpp +++ b/UwURenderEngine/RenderEngine/UwURenderEngine.hpp @@ -15,6 +15,7 @@ #include "VkObjects/Instance.hpp" #include "VkObjects/PhysicalDevice.hpp" #include "VkObjects/Surface.hpp" +#include "VkObjects/Swapchain.hpp" class Camera; class GPU_GarbageCollector; @@ -23,12 +24,6 @@ class GPU_GarbageCollector; class UwURenderEngine : public RenderEngineBase { - struct SwapchainSupportDetails - { - std::vector formats; - std::vector present_modes; - VkSurfaceCapabilitiesKHR capabilities; - }; struct UniformBufferObject { glm::mat4 model; glm::mat4 view; @@ -54,7 +49,9 @@ class UwURenderEngine : public RenderEngineBase 4, 5, 1, 1, 0, 4 }; - static const std::vector deviceExtensions; + const std::vector UwURenderEngine::deviceExtensions = { + VK_KHR_SWAPCHAIN_EXTENSION_NAME + }; // Counting frame from the beginning unsigned int current_frame_ = 0; @@ -69,11 +66,7 @@ class UwURenderEngine : public RenderEngineBase VkObjects::Surface surface_; VkObjects::PhysicalDevice physical_device_; VkObjects::Device device_; - VkSwapchainKHR swapchain_ = VK_NULL_HANDLE; - std::vector swapchain_images_; - VkFormat swapchain_image_format_; - VkExtent2D swapchain_extent_; - std::vector swapchain_image_views_; + VkObjects::Swapchain swapchain_; VkRenderPass render_pass_ = VK_NULL_HANDLE; VkDescriptorSetLayout ubo_layout_binding_ = VK_NULL_HANDLE; VkDescriptorPool descriptor_pool_ = VK_NULL_HANDLE; @@ -95,14 +88,9 @@ class UwURenderEngine : public RenderEngineBase std::vector image_available_semaphores_, render_finished_semaphores_; std::vector in_flight_fences_; - SwapchainSupportDetails query_swapchain_details() const; - static VkSurfaceFormatKHR choose_surface_format(const std::vector& surface_formats); - static VkPresentModeKHR choose_present_mode(const std::vector& present_modes, VkPresentModeKHR desired_present_mode); VkShaderModule create_shader_module(const std::string& code) const; - void create_swapchain(); - void create_image_views(); void create_render_pass(); void create_description_set_layout(); void create_uniform_buffers(); @@ -129,5 +117,5 @@ public: std::shared_ptr GetModelManager() const { return model_manager_; } - void SetActiveCamera(std::weak_ptr camera); + void SetActiveCamera(const std::weak_ptr& camera); }; diff --git a/UwURenderEngine/RenderEngine/VkObjects/Swapchain.cpp b/UwURenderEngine/RenderEngine/VkObjects/Swapchain.cpp new file mode 100644 index 0000000..4f0ff33 --- /dev/null +++ b/UwURenderEngine/RenderEngine/VkObjects/Swapchain.cpp @@ -0,0 +1,148 @@ +#include "Swapchain.hpp" + +#include + +#include "Device.hpp" +#include "PhysicalDevice.hpp" +#include "Surface.hpp" +#include "DeviceFunctions/DeviceFunctions.hpp" + +VkObjects::Swapchain::SwapchainSupportDetails VkObjects::Swapchain::query_swapchain_details(const Surface& surface, const PhysicalDevice& physical_device) +{ + SwapchainSupportDetails details; + + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device.get_native(), surface.get_native(), &details.capabilities); + + uint32_t surface_format_cnt = 0; + VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device.get_native(), surface.get_native(), &surface_format_cnt, nullptr)) + details.formats.resize(surface_format_cnt); + VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device.get_native(), surface.get_native(), &surface_format_cnt, details.formats.data())) + + uint32_t present_modes_cnt = 0; + VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device.get_native(), surface.get_native(), &present_modes_cnt, nullptr)) + details.present_modes.resize(surface_format_cnt); + VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device.get_native(), surface.get_native(), &present_modes_cnt, details.present_modes.data())) + + return details; +} + +VkSurfaceFormatKHR VkObjects::Swapchain::choose_surface_format(const std::vector& surface_formats) +{ + for (const auto& i : surface_formats) + { + if (i.format == VK_FORMAT_B8G8R8A8_SRGB && i.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) + return i; + } + return surface_formats[0]; +} + +VkPresentModeKHR VkObjects::Swapchain::choose_present_mode(const std::vector& present_modes, + VkPresentModeKHR desired_present_mode) +{ + for (const auto& i : present_modes) + { + if (i == desired_present_mode) + return i; + } + return VK_PRESENT_MODE_FIFO_KHR; +} + +void VkObjects::Swapchain::create_swapchain(const Surface& surface, const PhysicalDevice& physical_device, GLFWwindow* window) +{ + SwapchainSupportDetails swapchain_support = query_swapchain_details(surface, physical_device); + VkSurfaceFormatKHR surface_format = choose_surface_format(swapchain_support.formats); + VkPresentModeKHR present_mode = choose_present_mode(swapchain_support.present_modes, VK_PRESENT_MODE_MAILBOX_KHR); + VkExtent2D extent = DeviceFunctions::choose_extent(swapchain_support.capabilities, window); + + uint32_t image_count = swapchain_support.capabilities.minImageCount + 1; + if (swapchain_support.capabilities.maxImageCount > 0 && image_count > swapchain_support.capabilities.maxImageCount) + image_count = swapchain_support.capabilities.maxImageCount; + + VkSwapchainCreateInfoKHR swapchain_create_info{}; + swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + swapchain_create_info.surface = surface.get_native(); + swapchain_create_info.minImageCount = image_count; + swapchain_create_info.imageFormat = surface_format.format; + swapchain_create_info.imageColorSpace = surface_format.colorSpace; + swapchain_create_info.imageExtent = extent; + swapchain_create_info.imageArrayLayers = 1; + swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + swapchain_create_info.preTransform = swapchain_support.capabilities.currentTransform; + swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + swapchain_create_info.presentMode = present_mode; + swapchain_create_info.clipped = VK_TRUE; + swapchain_create_info.oldSwapchain = VK_NULL_HANDLE; + + VkObjects::PhysicalDevice::QueueFamilyIndices family_indices = physical_device.get_queue_family_indices(); + const std::set queue_family_indices = { family_indices.graphics_family, + family_indices.present_family, + family_indices.transfer_family }; + std::vector arr_families; + if (queue_family_indices.size() > 1) + { + arr_families.reserve(queue_family_indices.size()); + for(auto& i : queue_family_indices) + arr_families.push_back(i); + + + swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT; + swapchain_create_info.queueFamilyIndexCount = static_cast(arr_families.size()); + swapchain_create_info.pQueueFamilyIndices = arr_families.data(); + } + else + { + swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + swapchain_create_info.queueFamilyIndexCount = 0; + swapchain_create_info.pQueueFamilyIndices = nullptr; + } + + VK_CHECK(vkCreateSwapchainKHR(device_.get_native(), &swapchain_create_info, nullptr, &swapchain_)) + + vkGetSwapchainImagesKHR(device_.get_native(), swapchain_, &image_count, nullptr); + swapchain_images_.resize(image_count); + vkGetSwapchainImagesKHR(device_.get_native(), swapchain_, &image_count, swapchain_images_.data()); + + swapchain_image_format_ = surface_format.format; + swapchain_extent_ = extent; +} + +void VkObjects::Swapchain::create_image_views() +{ + VkImageViewCreateInfo image_view_info{}; + image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + image_view_info.viewType = VK_IMAGE_VIEW_TYPE_2D; + image_view_info.format = swapchain_image_format_; + image_view_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + image_view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + image_view_info.subresourceRange.baseMipLevel = 0; + image_view_info.subresourceRange.levelCount = 1; + image_view_info.subresourceRange.baseArrayLayer = 0; + image_view_info.subresourceRange.layerCount = 1; + + swapchain_image_views_.resize(swapchain_images_.size()); + for (uint32_t i = 0; i < swapchain_images_.size(); ++i) + { + image_view_info.image = swapchain_images_[i]; + VK_CHECK(vkCreateImageView(device_.get_native(), &image_view_info, nullptr, &swapchain_image_views_[i])) + } +} + +VkObjects::Swapchain::Swapchain(const Surface& surface, const PhysicalDevice& physical_device, const Device& device, GLFWwindow* window): +device_(device) +{ + create_swapchain(surface, physical_device, window); + create_image_views(); +} + +VkObjects::Swapchain::~Swapchain() +{ + for (auto image_view : swapchain_image_views_) + vkDestroyImageView(device_.get_native(), image_view, nullptr); + swapchain_image_views_.clear(); + + if (swapchain_ != nullptr) + vkDestroySwapchainKHR(device_.get_native(), swapchain_, nullptr); +} diff --git a/UwURenderEngine/RenderEngine/VkObjects/Swapchain.hpp b/UwURenderEngine/RenderEngine/VkObjects/Swapchain.hpp new file mode 100644 index 0000000..7ab2dfa --- /dev/null +++ b/UwURenderEngine/RenderEngine/VkObjects/Swapchain.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include +#include + +#include "GLFW/glfw3.h" + +namespace VkObjects +{ + class Device; + class PhysicalDevice; + class Surface; + + class Swapchain + { + struct SwapchainSupportDetails + { + std::vector formats; + std::vector present_modes; + VkSurfaceCapabilitiesKHR capabilities; + }; + + const Device& device_; + VkSwapchainKHR swapchain_ = nullptr; + std::vector swapchain_images_; + std::vector swapchain_image_views_; + VkFormat swapchain_image_format_; + VkExtent2D swapchain_extent_; + + static SwapchainSupportDetails query_swapchain_details(const Surface& surface, const PhysicalDevice& physical_device); + static VkSurfaceFormatKHR choose_surface_format(const std::vector& surface_formats); + static VkPresentModeKHR choose_present_mode(const std::vector& present_modes, VkPresentModeKHR desired_present_mode); + + void create_swapchain(const Surface& surface, const PhysicalDevice& physical_device, GLFWwindow* window); + void create_image_views(); + public: + Swapchain(const Surface& surface, const PhysicalDevice& physical_device, const Device& device, GLFWwindow* window); + ~Swapchain(); + + inline VkSwapchainKHR get_native() const { return swapchain_; } + inline const std::vector& get_images() const { return swapchain_images_; } + inline const std::vector& get_image_views() const { return swapchain_image_views_; } + inline VkExtent2D get_extent() const { return swapchain_extent_; } + inline VkFormat get_image_format() const { return swapchain_image_format_; } + }; +}