Перенёс управление VkSwapchainKHR и ImageViews в отдельный класс
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
#include "UwURenderEngine.hpp"
|
#include "UwURenderEngine.hpp"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <set>
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
@@ -11,59 +10,14 @@
|
|||||||
#include "GPU_GarbageCollector.h"
|
#include "GPU_GarbageCollector.h"
|
||||||
#include "../Game/Actors/Camera.hpp"
|
#include "../Game/Actors/Camera.hpp"
|
||||||
#include "Core/CoreInstance.hpp"
|
#include "Core/CoreInstance.hpp"
|
||||||
#include "Log/Log.hpp"
|
|
||||||
|
|
||||||
#include "Game/GameInstance.hpp"
|
#include "Game/GameInstance.hpp"
|
||||||
#include "Game/World/World.hpp"
|
#include "Game/World/World.hpp"
|
||||||
#include "../Game/Actors/Mesh/Mesh.hpp"
|
#include "../Game/Actors/Mesh/Mesh.hpp"
|
||||||
#include "DeviceFunctions/DeviceFunctions.hpp"
|
#include "DeviceFunctions/DeviceFunctions.hpp"
|
||||||
|
|
||||||
const std::vector<const char*> UwURenderEngine::deviceExtensions = {
|
|
||||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
|
||||||
};
|
|
||||||
|
|
||||||
RENDER_ENGINE_FACTORY_GENERATE(UwURenderEngine)
|
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<VkSurfaceFormatKHR>& 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<VkPresentModeKHR>& 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
|
VkShaderModule UwURenderEngine::create_shader_module(const std::string& code) const
|
||||||
{
|
{
|
||||||
VkShaderModuleCreateInfo shader_module_info{};
|
VkShaderModuleCreateInfo shader_module_info{};
|
||||||
@@ -76,93 +30,11 @@ VkShaderModule UwURenderEngine::create_shader_module(const std::string& code) co
|
|||||||
return shader_module;
|
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<uint32_t> queue_family_indices = { family_indices.graphics_family,
|
|
||||||
family_indices.present_family,
|
|
||||||
family_indices.transfer_family };
|
|
||||||
std::vector<uint32_t> 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<uint32_t>(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()
|
void UwURenderEngine::create_render_pass()
|
||||||
{
|
{
|
||||||
VkAttachmentDescription attachment_description{};
|
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.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
@@ -219,14 +91,14 @@ void UwURenderEngine::create_description_set_layout()
|
|||||||
|
|
||||||
void UwURenderEngine::create_uniform_buffers()
|
void UwURenderEngine::create_uniform_buffers()
|
||||||
{
|
{
|
||||||
uniform_buffers_.resize(swapchain_images_.size());
|
uniform_buffers_.resize(swapchain_.get_images().size());
|
||||||
uniform_buffers_memory_.resize(swapchain_images_.size());
|
uniform_buffers_memory_.resize(swapchain_.get_images().size());
|
||||||
uniform_buffers_mapped_.resize(swapchain_images_.size());
|
uniform_buffers_mapped_.resize(swapchain_.get_images().size());
|
||||||
|
|
||||||
std::vector<uint32_t> arr_indices = physical_device_.get_unique_family_indices();
|
std::vector<uint32_t> 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_[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);
|
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);
|
vkBindBufferMemory(device_.get_native(), uniform_buffers_[i], uniform_buffers_memory_[i], 0);
|
||||||
@@ -239,30 +111,30 @@ void UwURenderEngine::create_descriptor_pool()
|
|||||||
{
|
{
|
||||||
VkDescriptorPoolSize pool_size;
|
VkDescriptorPoolSize pool_size;
|
||||||
pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||||
pool_size.descriptorCount = static_cast<uint32_t>(swapchain_images_.size());
|
pool_size.descriptorCount = static_cast<uint32_t>(swapchain_.get_images().size());
|
||||||
|
|
||||||
VkDescriptorPoolCreateInfo descriptor_pool_info{};
|
VkDescriptorPoolCreateInfo descriptor_pool_info{};
|
||||||
descriptor_pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
descriptor_pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||||
descriptor_pool_info.poolSizeCount = 1;
|
descriptor_pool_info.poolSizeCount = 1;
|
||||||
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_.get_images().size());
|
||||||
|
|
||||||
VK_CHECK(vkCreateDescriptorPool(device_.get_native(), &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()
|
||||||
{
|
{
|
||||||
std::vector<VkDescriptorSetLayout> layouts(swapchain_images_.size(), ubo_layout_binding_);
|
std::vector<VkDescriptorSetLayout> layouts(swapchain_.get_images().size(), ubo_layout_binding_);
|
||||||
VkDescriptorSetAllocateInfo descriptor_set_allocate_info{};
|
VkDescriptorSetAllocateInfo descriptor_set_allocate_info{};
|
||||||
descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_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.descriptorPool = descriptor_pool_;
|
||||||
descriptor_set_allocate_info.descriptorSetCount = static_cast<uint32_t>(swapchain_images_.size());
|
descriptor_set_allocate_info.descriptorSetCount = static_cast<uint32_t>(swapchain_.get_images().size());
|
||||||
descriptor_set_allocate_info.pSetLayouts = layouts.data();
|
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()))
|
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{};
|
VkDescriptorBufferInfo buffer_info{};
|
||||||
buffer_info.buffer = uniform_buffers_[i];
|
buffer_info.buffer = uniform_buffers_[i];
|
||||||
@@ -344,14 +216,14 @@ void UwURenderEngine::create_graphics_pipeline()
|
|||||||
VkViewport viewport{};
|
VkViewport viewport{};
|
||||||
viewport.x = 0.0f;
|
viewport.x = 0.0f;
|
||||||
viewport.y = 0.0f;
|
viewport.y = 0.0f;
|
||||||
viewport.width = static_cast<float>(swapchain_extent_.width);
|
viewport.width = static_cast<float>(swapchain_.get_extent().width);
|
||||||
viewport.height = static_cast<float>(swapchain_extent_.height);
|
viewport.height = static_cast<float>(swapchain_.get_extent().height);
|
||||||
viewport.minDepth = 0.0f;
|
viewport.minDepth = 0.0f;
|
||||||
viewport.maxDepth = 1.0f;
|
viewport.maxDepth = 1.0f;
|
||||||
|
|
||||||
VkRect2D scissor{};
|
VkRect2D scissor{};
|
||||||
scissor.offset = {0, 0};
|
scissor.offset = {0, 0};
|
||||||
scissor.extent = swapchain_extent_;
|
scissor.extent = swapchain_.get_extent();
|
||||||
|
|
||||||
VkPipelineViewportStateCreateInfo viewport_info{};
|
VkPipelineViewportStateCreateInfo viewport_info{};
|
||||||
viewport_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_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()
|
void UwURenderEngine::create_framebuffers()
|
||||||
{
|
{
|
||||||
framebuffers_.resize(swapchain_images_.size());
|
framebuffers_.resize(swapchain_.get_images().size());
|
||||||
|
|
||||||
VkFramebufferCreateInfo framebuffer_info{};
|
VkFramebufferCreateInfo framebuffer_info{};
|
||||||
framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||||
framebuffer_info.renderPass = render_pass_;
|
framebuffer_info.renderPass = render_pass_;
|
||||||
framebuffer_info.attachmentCount = 1;
|
framebuffer_info.attachmentCount = 1;
|
||||||
framebuffer_info.width = swapchain_extent_.width;
|
framebuffer_info.width = swapchain_.get_extent().width;
|
||||||
framebuffer_info.height = swapchain_extent_.height;
|
framebuffer_info.height = swapchain_.get_extent().height;
|
||||||
framebuffer_info.layers = 1;
|
framebuffer_info.layers = 1;
|
||||||
|
|
||||||
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_.get_image_views()[i];
|
||||||
VK_CHECK(vkCreateFramebuffer(device_.get_native(), &framebuffer_info, nullptr, &framebuffers_[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()
|
void UwURenderEngine::allocate_command_buffers()
|
||||||
{
|
{
|
||||||
command_buffers_.resize(swapchain_images_.size());
|
command_buffers_.resize(swapchain_.get_images().size());
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo command_buffer_allocate_info{};
|
VkCommandBufferAllocateInfo command_buffer_allocate_info{};
|
||||||
command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_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()
|
void UwURenderEngine::create_sync_objects()
|
||||||
{
|
{
|
||||||
image_available_semaphores_.resize(swapchain_images_.size());
|
image_available_semaphores_.resize(swapchain_.get_images().size());
|
||||||
render_finished_semaphores_.resize(swapchain_images_.size());
|
render_finished_semaphores_.resize(swapchain_.get_images().size());
|
||||||
in_flight_fences_.resize(swapchain_images_.size());
|
in_flight_fences_.resize(swapchain_.get_images().size());
|
||||||
|
|
||||||
VkSemaphoreCreateInfo semaphore_info{};
|
VkSemaphoreCreateInfo semaphore_info{};
|
||||||
semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_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.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||||
fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
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, &image_available_semaphores_[i]))
|
||||||
VK_CHECK(vkCreateSemaphore(device_.get_native(), &semaphore_info, nullptr, &render_finished_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.renderPass = render_pass_;
|
||||||
render_pass_begin_info.framebuffer = framebuffers_[image_index];
|
render_pass_begin_info.framebuffer = framebuffers_[image_index];
|
||||||
render_pass_begin_info.renderArea.offset = {0, 0};
|
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.clearValueCount = 1;
|
||||||
render_pass_begin_info.pClearValues = &clear_color;
|
render_pass_begin_info.pClearValues = &clear_color;
|
||||||
vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE);
|
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;
|
VkViewport viewport;
|
||||||
viewport.x = 0.0f;
|
viewport.x = 0.0f;
|
||||||
viewport.y = 0.0f;
|
viewport.y = 0.0f;
|
||||||
viewport.width = static_cast<float>(swapchain_extent_.width);
|
viewport.width = static_cast<float>(swapchain_.get_extent().width);
|
||||||
viewport.height = static_cast<float>(swapchain_extent_.height);
|
viewport.height = static_cast<float>(swapchain_.get_extent().height);
|
||||||
viewport.minDepth = 0.0f;
|
viewport.minDepth = 0.0f;
|
||||||
viewport.maxDepth = 1.0f;
|
viewport.maxDepth = 1.0f;
|
||||||
vkCmdSetViewport(command_buffer, 0, 1, &viewport);
|
vkCmdSetViewport(command_buffer, 0, 1, &viewport);
|
||||||
|
|
||||||
VkRect2D scissor;
|
VkRect2D scissor;
|
||||||
scissor.offset = {0, 0};
|
scissor.offset = {0, 0};
|
||||||
scissor.extent = swapchain_extent_;
|
scissor.extent = swapchain_.get_extent();
|
||||||
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
||||||
|
|
||||||
vkCmdDrawIndexed(command_buffer, static_cast<uint32_t>(indices_.size()), 1, 0, 0, 0);
|
vkCmdDrawIndexed(command_buffer, static_cast<uint32_t>(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)};
|
up = {0, glm::sin(rot.z), glm::cos(rot.z)};
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto start_time = std::chrono::high_resolution_clock::now();
|
// static auto start_time = std::chrono::high_resolution_clock::now();
|
||||||
auto current_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();
|
// float time = std::chrono::duration_cast<std::chrono::duration<float>>(current_time - start_time).count();
|
||||||
UniformBufferObject ubo;
|
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.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.view = glm::lookAt(eye, center, up);
|
||||||
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 = glm::perspective(glm::radians(45.0f), static_cast<float>(swapchain_.get_extent().width) / static_cast<float>(swapchain_.get_extent().height), 0.1f, 256.0f);
|
||||||
ubo.proj[1][1] *= -1;
|
ubo.proj[1][1] *= -1;
|
||||||
memcpy(uniform_buffers_mapped_[current_frame], &ubo, sizeof(ubo));
|
memcpy(uniform_buffers_mapped_[current_frame], &ubo, sizeof(ubo));
|
||||||
}
|
}
|
||||||
@@ -637,7 +509,7 @@ void UwURenderEngine::draw_frame()
|
|||||||
garbage_collector_->FreeHeap();
|
garbage_collector_->FreeHeap();
|
||||||
|
|
||||||
uint32_t image_index;
|
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);
|
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_]))
|
VK_CHECK(vkQueueSubmit(device_.get_graphics_queue(), 1, &submit_info, in_flight_fences_[current_frame_]))
|
||||||
|
|
||||||
|
VkSwapchainKHR swapchain = swapchain_.get_native();
|
||||||
VkPresentInfoKHR present_info{};
|
VkPresentInfoKHR present_info{};
|
||||||
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
present_info.waitSemaphoreCount = 1;
|
present_info.waitSemaphoreCount = 1;
|
||||||
present_info.pWaitSemaphores = &render_finished_semaphores_[current_frame_];
|
present_info.pWaitSemaphores = &render_finished_semaphores_[current_frame_];
|
||||||
present_info.swapchainCount = 1;
|
present_info.swapchainCount = 1;
|
||||||
present_info.pSwapchains = &swapchain_;
|
present_info.pSwapchains = &swapchain;
|
||||||
present_info.pImageIndices = &image_index;
|
present_info.pImageIndices = &image_index;
|
||||||
present_info.pResults = nullptr;
|
present_info.pResults = nullptr;
|
||||||
|
|
||||||
vkQueuePresentKHR(device_.get_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_.get_images().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
UwURenderEngine::UwURenderEngine(CoreInstance& core):
|
UwURenderEngine::UwURenderEngine(CoreInstance& core):
|
||||||
@@ -677,10 +550,9 @@ core_(core),
|
|||||||
instance_(core),
|
instance_(core),
|
||||||
surface_(instance_, get_window()),
|
surface_(instance_, get_window()),
|
||||||
physical_device_(instance_, surface_, deviceExtensions),
|
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_render_pass();
|
||||||
create_description_set_layout();
|
create_description_set_layout();
|
||||||
create_uniform_buffers();
|
create_uniform_buffers();
|
||||||
@@ -755,14 +627,6 @@ UwURenderEngine::~UwURenderEngine()
|
|||||||
|
|
||||||
if (render_pass_ != VK_NULL_HANDLE)
|
if (render_pass_ != VK_NULL_HANDLE)
|
||||||
vkDestroyRenderPass(device_.get_native(), render_pass_, nullptr);
|
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()
|
void UwURenderEngine::start()
|
||||||
@@ -788,7 +652,7 @@ void UwURenderEngine::stop_render() const
|
|||||||
glfwSetWindowShouldClose(get_window(), true);
|
glfwSetWindowShouldClose(get_window(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UwURenderEngine::SetActiveCamera(std::weak_ptr<Camera> camera)
|
void UwURenderEngine::SetActiveCamera(const std::weak_ptr<Camera>& camera)
|
||||||
{
|
{
|
||||||
std::scoped_lock lock(m_active_camera_);
|
std::scoped_lock lock(m_active_camera_);
|
||||||
active_camera_ = camera;
|
active_camera_ = camera;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "VkObjects/Instance.hpp"
|
#include "VkObjects/Instance.hpp"
|
||||||
#include "VkObjects/PhysicalDevice.hpp"
|
#include "VkObjects/PhysicalDevice.hpp"
|
||||||
#include "VkObjects/Surface.hpp"
|
#include "VkObjects/Surface.hpp"
|
||||||
|
#include "VkObjects/Swapchain.hpp"
|
||||||
|
|
||||||
class Camera;
|
class Camera;
|
||||||
class GPU_GarbageCollector;
|
class GPU_GarbageCollector;
|
||||||
@@ -23,12 +24,6 @@ class GPU_GarbageCollector;
|
|||||||
|
|
||||||
class UwURenderEngine : public RenderEngineBase
|
class UwURenderEngine : public RenderEngineBase
|
||||||
{
|
{
|
||||||
struct SwapchainSupportDetails
|
|
||||||
{
|
|
||||||
std::vector<VkSurfaceFormatKHR> formats;
|
|
||||||
std::vector<VkPresentModeKHR> present_modes;
|
|
||||||
VkSurfaceCapabilitiesKHR capabilities;
|
|
||||||
};
|
|
||||||
struct UniformBufferObject {
|
struct UniformBufferObject {
|
||||||
glm::mat4 model;
|
glm::mat4 model;
|
||||||
glm::mat4 view;
|
glm::mat4 view;
|
||||||
@@ -54,7 +49,9 @@ class UwURenderEngine : public RenderEngineBase
|
|||||||
4, 5, 1, 1, 0, 4
|
4, 5, 1, 1, 0, 4
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::vector<const char*> deviceExtensions;
|
const std::vector<const char*> UwURenderEngine::deviceExtensions = {
|
||||||
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||||
|
};
|
||||||
|
|
||||||
// Counting frame from the beginning
|
// Counting frame from the beginning
|
||||||
unsigned int current_frame_ = 0;
|
unsigned int current_frame_ = 0;
|
||||||
@@ -69,11 +66,7 @@ class UwURenderEngine : public RenderEngineBase
|
|||||||
VkObjects::Surface surface_;
|
VkObjects::Surface surface_;
|
||||||
VkObjects::PhysicalDevice physical_device_;
|
VkObjects::PhysicalDevice physical_device_;
|
||||||
VkObjects::Device device_;
|
VkObjects::Device device_;
|
||||||
VkSwapchainKHR swapchain_ = VK_NULL_HANDLE;
|
VkObjects::Swapchain swapchain_;
|
||||||
std::vector<VkImage> swapchain_images_;
|
|
||||||
VkFormat swapchain_image_format_;
|
|
||||||
VkExtent2D swapchain_extent_;
|
|
||||||
std::vector<VkImageView> swapchain_image_views_;
|
|
||||||
VkRenderPass render_pass_ = VK_NULL_HANDLE;
|
VkRenderPass render_pass_ = VK_NULL_HANDLE;
|
||||||
VkDescriptorSetLayout ubo_layout_binding_ = VK_NULL_HANDLE;
|
VkDescriptorSetLayout ubo_layout_binding_ = VK_NULL_HANDLE;
|
||||||
VkDescriptorPool descriptor_pool_ = VK_NULL_HANDLE;
|
VkDescriptorPool descriptor_pool_ = VK_NULL_HANDLE;
|
||||||
@@ -95,14 +88,9 @@ class UwURenderEngine : public RenderEngineBase
|
|||||||
std::vector<VkSemaphore> image_available_semaphores_, render_finished_semaphores_;
|
std::vector<VkSemaphore> image_available_semaphores_, render_finished_semaphores_;
|
||||||
std::vector<VkFence> in_flight_fences_;
|
std::vector<VkFence> in_flight_fences_;
|
||||||
|
|
||||||
SwapchainSupportDetails query_swapchain_details() const;
|
|
||||||
|
|
||||||
static VkSurfaceFormatKHR choose_surface_format(const std::vector<VkSurfaceFormatKHR>& surface_formats);
|
|
||||||
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_swapchain();
|
|
||||||
void create_image_views();
|
|
||||||
void create_render_pass();
|
void create_render_pass();
|
||||||
void create_description_set_layout();
|
void create_description_set_layout();
|
||||||
void create_uniform_buffers();
|
void create_uniform_buffers();
|
||||||
@@ -129,5 +117,5 @@ public:
|
|||||||
|
|
||||||
std::shared_ptr<ModelManager> GetModelManager() const { return model_manager_; }
|
std::shared_ptr<ModelManager> GetModelManager() const { return model_manager_; }
|
||||||
|
|
||||||
void SetActiveCamera(std::weak_ptr<Camera> camera);
|
void SetActiveCamera(const std::weak_ptr<Camera>& camera);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
#include "Swapchain.hpp"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#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<VkSurfaceFormatKHR>& 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<VkPresentModeKHR>& 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<uint32_t> queue_family_indices = { family_indices.graphics_family,
|
||||||
|
family_indices.present_family,
|
||||||
|
family_indices.transfer_family };
|
||||||
|
std::vector<uint32_t> 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<uint32_t>(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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
|
#include "GLFW/glfw3.h"
|
||||||
|
|
||||||
|
namespace VkObjects
|
||||||
|
{
|
||||||
|
class Device;
|
||||||
|
class PhysicalDevice;
|
||||||
|
class Surface;
|
||||||
|
|
||||||
|
class Swapchain
|
||||||
|
{
|
||||||
|
struct SwapchainSupportDetails
|
||||||
|
{
|
||||||
|
std::vector<VkSurfaceFormatKHR> formats;
|
||||||
|
std::vector<VkPresentModeKHR> present_modes;
|
||||||
|
VkSurfaceCapabilitiesKHR capabilities;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Device& device_;
|
||||||
|
VkSwapchainKHR swapchain_ = nullptr;
|
||||||
|
std::vector<VkImage> swapchain_images_;
|
||||||
|
std::vector<VkImageView> 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<VkSurfaceFormatKHR>& surface_formats);
|
||||||
|
static VkPresentModeKHR choose_present_mode(const std::vector<VkPresentModeKHR>& 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<VkImage>& get_images() const { return swapchain_images_; }
|
||||||
|
inline const std::vector<VkImageView>& 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_; }
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user