From e48d175b76bebb6e3fe66eaa6f0a2269507c133e Mon Sep 17 00:00:00 2001 From: ouczbs Date: Sun, 3 Mar 2024 14:49:18 +0800 Subject: [PATCH] create device & swapchain --- engine/src/engine/vulkanapi/backend.cpp | 2 + engine/src/engine/vulkanapi/window.cpp | 5 +- .../src/engine/vulkanapi/wrapper/device.cpp | 39 +++-- engine/src/engine/vulkanapi/wrapper/device.h | 2 - .../vulkanapi/wrapper/device_creator.cpp | 142 ++++++++++++++- .../engine/vulkanapi/wrapper/device_creator.h | 15 +- .../engine/vulkanapi/wrapper/swapchain.cpp | 69 ++++---- .../src/engine/vulkanapi/wrapper/swapchain.h | 5 +- .../vulkanapi/wrapper/swapchain_creator.cpp | 43 +++++ .../vulkanapi/wrapper/swapchain_creator.h | 30 ++++ .../engine/vulkanapi/wrapper/swapchain_help.h | 162 ------------------ 11 files changed, 298 insertions(+), 216 deletions(-) create mode 100644 engine/src/engine/vulkanapi/wrapper/swapchain_creator.cpp create mode 100644 engine/src/engine/vulkanapi/wrapper/swapchain_creator.h delete mode 100644 engine/src/engine/vulkanapi/wrapper/swapchain_help.h diff --git a/engine/src/engine/vulkanapi/backend.cpp b/engine/src/engine/vulkanapi/backend.cpp index b0b4c01..838ef34 100644 --- a/engine/src/engine/vulkanapi/backend.cpp +++ b/engine/src/engine/vulkanapi/backend.cpp @@ -8,6 +8,7 @@ namespace vulkanapi { mInstance = new Instance(instanceCreator); auto deviceCreator = DeviceCreator(*mInstance); + deviceCreator.AddWindowExtension(); deviceCreator.desiredPhysicalDeviceFeatures.geometryShader = VK_TRUE; deviceCreator.AddQueue("TransferQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); deviceCreator.AddQueue("RenderQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); @@ -15,6 +16,7 @@ namespace vulkanapi { deviceCreator.AddQueue("PresentQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); mDevice = new Device(deviceCreator); + } Backend::~Backend() { diff --git a/engine/src/engine/vulkanapi/window.cpp b/engine/src/engine/vulkanapi/window.cpp index c3a0604..618ce48 100644 --- a/engine/src/engine/vulkanapi/window.cpp +++ b/engine/src/engine/vulkanapi/window.cpp @@ -3,6 +3,7 @@ #include "wrapper/instance.h" #include "wrapper/device.h" #include "wrapper/swapchain.h" +#include "wrapper/swapchain_creator.h" #include namespace vulkanapi { Window::Window(Backend& backend, int frames, uint32_t width, uint32_t height, const char* title) @@ -19,7 +20,7 @@ namespace vulkanapi { mPtr // HWND hwnd }; vkCreateWin32SurfaceKHR(instance, &surface_create_info, nullptr, &mSurfaceKHR); - - mSwapchain = new Swapchain(backend.GetDevice(), frames, width, height, mSurfaceKHR); + SwapchainCreator swapchainCreator(backend.GetDevice(), frames, width, height, mSurfaceKHR); + mSwapchain = new Swapchain(swapchainCreator); } } \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/device.cpp b/engine/src/engine/vulkanapi/wrapper/device.cpp index 786c5ef..06cef48 100644 --- a/engine/src/engine/vulkanapi/wrapper/device.cpp +++ b/engine/src/engine/vulkanapi/wrapper/device.cpp @@ -1,21 +1,38 @@ #include "device.h" #include "device_creator.h" +#include "zlog.h" namespace vulkanapi { Device::Device(DeviceCreator& Creator) { - - } - uint32_t Device::GetQueueFamilyIndex(VkQueueFlags flag) - { + Creator.FindDevice(mPhysical); std::vector queue_families; - // CheckAvailableQueueFamiliesAndTheirProperties(mPhysical, queue_families); - for (uint32_t i = 0, l = queue_families.size(); i < l; i++) { - if ((queue_families[i].queueFlags & flag) == flag) { - return i; - } + Creator.CheckAvailableQueueFamilies(mPhysical, queue_families); + std::vector queue_create_infos; + std::vector> queue_prioritie; + Creator.QueueCreateInfos(queue_create_infos, queue_prioritie, queue_families); + auto extensions = Creator.EnabledExtensionNames(); + VkDeviceCreateInfo device_create_info = { + VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType + nullptr, // const void * pNext + 0, // VkDeviceCreateFlags flags + static_cast(queue_create_infos.size()), // uint32_t queueCreateInfoCount + queue_create_infos.data(), // const VkDeviceQueueCreateInfo * pQueueCreateInfos + 0, // uint32_t enabledLayerCount + nullptr, // const char * const * ppEnabledLayerNames + static_cast(extensions.size()), // uint32_t enabledExtensionCount + extensions.data(), // const char * const * ppEnabledExtensionNames + &Creator.desiredPhysicalDeviceFeatures // const VkPhysicalDeviceFeatures * pEnabledFeatures + }; +#ifdef _USE_GRAPHIC_DEBUG + auto layers = Creator.EnabledLayerNames(); + device_create_info.enabledLayerCount = layers.size(); + device_create_info.ppEnabledLayerNames = layers.data(); +#endif // _USE_GRAPHIC_DEBUG + VkResult result = vkCreateDevice(mPhysical, &device_create_info, nullptr, &mPtr); + if ((result != VK_SUCCESS) || (mPtr == VK_NULL_HANDLE)) { + zlog::error("Could not create logical device."); } - return 0; - } + } VkCommandPool Device::CreateCommandPool(const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator) { VkCommandPool pCommandPool; diff --git a/engine/src/engine/vulkanapi/wrapper/device.h b/engine/src/engine/vulkanapi/wrapper/device.h index f8378c5..47a484a 100644 --- a/engine/src/engine/vulkanapi/wrapper/device.h +++ b/engine/src/engine/vulkanapi/wrapper/device.h @@ -18,8 +18,6 @@ namespace vulkanapi { } public: Device(DeviceCreator& Creator); - - uint32_t GetQueueFamilyIndex(VkQueueFlags flag); VkCommandPool CreateCommandPool(const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator); VkQueue GetQueue(uint32_t familyIndex, uint32_t queueIndex); VkDescriptorPool CreateDescriptorPool(const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator); diff --git a/engine/src/engine/vulkanapi/wrapper/device_creator.cpp b/engine/src/engine/vulkanapi/wrapper/device_creator.cpp index 5ddab33..404fd21 100644 --- a/engine/src/engine/vulkanapi/wrapper/device_creator.cpp +++ b/engine/src/engine/vulkanapi/wrapper/device_creator.cpp @@ -1,6 +1,7 @@ #pragma once #include "device.h" #include "device_creator.h" +#include "instance.h" #include "zlog.h" namespace vulkanapi { DeviceCreator::DeviceCreator(Instance& instance) @@ -23,10 +24,100 @@ namespace vulkanapi { AddLayer("VK_LAYER_RENDERDOC_Capture"); #endif } - void DeviceCreator::QueueCreateInfos(std::vector& queue_create_infos, std::vector& queue_families) + bool DeviceCreator::CheckProperty(const VkPhysicalDevice device) { - std::vector availableLayers(); - + VkPhysicalDeviceProperties deviceProperties; + vkGetPhysicalDeviceProperties(device, &deviceProperties); + return (deviceProperties.deviceType & desiredPhysicalDeviceType) == desiredPhysicalDeviceType; + } + bool DeviceCreator::CheckExtension(const VkPhysicalDevice device) + { + uint32_t extensionCount = 0; + vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr); + std::vector availableExtensions(extensionCount); + vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data()); + for (const auto& desiredExtension : desiredExtensions) + { + bool find = false; + for (const auto& availableExtension : availableExtensions) + { + if (strcmp(availableExtension.extensionName, desiredExtension.c_str()) == 0) + { + find = true; + break; + } + } + if (!find)return false; + } + return true; + } + bool DeviceCreator::FindDevice(VkPhysicalDevice& device) + { + std::vector available_devices; + instance.EnumerateAvailablePhysicalDevices(available_devices); + for (int i = 0, size = available_devices.size(); i < size;i++) + { + device = available_devices[i]; + if (!CheckProperty(device))continue; + if (!CheckExtension(device))continue; +#ifdef _USE_GRAPHIC_DEBUG + if (!CheckLayer(device))continue; +#endif // _USE_GRAPHIC_DEBUG + return true; + } + return false; + } + std::vector DeviceCreator::EnabledExtensionNames() + { + std::vector _extension; + for (int i = 0, l = desiredExtensions.size(); i < l; i++) { + _extension.push_back(desiredExtensions[i].c_str()); + } + return _extension; + } + void DeviceCreator::QueueCreateInfos(std::vector& queue_create_infos, std::vector>& queue_prioritie, + std::vector& queue_families) + { + uint32_t size = queue_families.size(); + for (uint32_t i = 0; i < size; i++) { + VkDeviceQueueCreateInfo queueCreateInfo{}; + queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queueCreateInfo.queueFamilyIndex = i; + queueCreateInfo.queueCount = 0; + queue_create_infos.push_back(queueCreateInfo); + queue_prioritie.emplace_back(std::vector{}); + } + uint32_t max_value = 1; + for (const auto& queue : desiredQueues) { + uint32_t index = -1; + bool bFind = false; + for (uint32_t i = 0; i < size; i++) { + auto family = queue_families[i]; + if ((family.queueFlags & queue.flag) == queue.flag) { + index = i; + if (queue_create_infos[i].queueCount < max_value * family.queueCount) { + bFind = true; + break; + } + } + } + if (index != -1 && queue_create_infos[index].queueCount < queue_families[index].queueCount) { + queue_create_infos[index].queueCount++; + queue_prioritie[index].push_back(queue.prioritie); + } + if (!bFind) + max_value++; + } + auto it = queue_create_infos.begin(); + for (uint32_t i = 0; i < size; i++) { + if (it->queueCount == 0) { + it = queue_create_infos.erase(it); + } + else { + it->pQueuePriorities = queue_prioritie[i].data(); + it++; + } + } } void DeviceCreator::AddExtension(std::string extensionName) { @@ -37,5 +128,50 @@ namespace vulkanapi { { desiredLayers.push_back(layerName); } + bool DeviceCreator::CheckLayer(const VkPhysicalDevice device) + { + uint32_t layerCount = 0; + vkEnumerateDeviceLayerProperties(device, &layerCount, nullptr); + std::vector availableLayers(layerCount); + vkEnumerateDeviceLayerProperties(device, &layerCount, availableLayers.data()); + for (const auto& desiredLayer : desiredLayers) + { + bool find = false; + for (const auto& availableLayer : availableLayers) + { + if (strcmp(availableLayer.layerName, desiredLayer.c_str()) == 0) + { + find = true; + break; + } + } + if (!find)return false; + } + return true; + } + std::vector DeviceCreator::EnabledLayerNames() + { + std::vector _extension; + for (int i = 0, l = desiredLayers.size(); i < l; i++) { + _extension.push_back(desiredLayers[i].c_str()); + } + return _extension; + } #endif + bool DeviceCreator::CheckAvailableQueueFamilies(VkPhysicalDevice physical_device, std::vector& queue_families) { + uint32_t queue_families_count = 0; + + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_families_count, nullptr); + if (queue_families_count == 0) { + zlog::error("Could not get the number of queue families."); + return false; + } + queue_families.resize(queue_families_count); + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_families_count, queue_families.data()); + if (queue_families_count == 0) { + zlog::error("Could not acquire properties of queue families."); + return false; + } + return true; + } }; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/device_creator.h b/engine/src/engine/vulkanapi/wrapper/device_creator.h index c1cf944..1555953 100644 --- a/engine/src/engine/vulkanapi/wrapper/device_creator.h +++ b/engine/src/engine/vulkanapi/wrapper/device_creator.h @@ -16,7 +16,7 @@ namespace vulkanapi { VkQueueFlags flag; float prioritie; DesiredQueue(std::string name, VkQueueFlags flag, float prioritie) - : name(name), flag(flag), prioritie(prioritie){} + : name(name), flag(flag), prioritie(prioritie) {} }; public: VkPhysicalDeviceFeatures desiredPhysicalDeviceFeatures; @@ -31,12 +31,21 @@ namespace vulkanapi { void AddQueue(std::string name, VkQueueFlags flag, float prioritie); void AddExtension(std::string extensionName); void AddWindowExtension(); - void QueueCreateInfos(std::vector& queue_create_infos, std::vector& queue_families); + bool CheckProperty(const VkPhysicalDevice device); + bool CheckExtension(const VkPhysicalDevice device); + bool FindDevice(VkPhysicalDevice& device); + std::vector EnabledExtensionNames(); + void QueueCreateInfos(std::vector& queue_create_infos, + std::vector>& queue_prioritie, + std::vector& queue_families); #ifdef _USE_GRAPHIC_DEBUG public: std::vector desiredLayers; void AddLayer(std::string layerName); + bool CheckLayer(const VkPhysicalDevice device); + std::vector EnabledLayerNames(); #endif private: - + static bool CheckAvailableQueueFamilies(VkPhysicalDevice physical_device, std::vector& queue_families); + }; }; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/swapchain.cpp b/engine/src/engine/vulkanapi/wrapper/swapchain.cpp index 189eac3..5c06d29 100644 --- a/engine/src/engine/vulkanapi/wrapper/swapchain.cpp +++ b/engine/src/engine/vulkanapi/wrapper/swapchain.cpp @@ -1,43 +1,50 @@ #include "swapchain.h" -#include "swapchain_help.h" +#include "swapchain_creator.h" #include "device.h" #include "image.h" +#include "zlog.h" namespace vulkanapi { - Swapchain::Swapchain(Device& device, int frames, int width, int height, VkSurfaceKHR presentation_surface) + Swapchain::Swapchain(SwapchainCreator& Creator) : mPtr(nullptr) { - uint32_t queue_family_index; - VkPhysicalDevice physical_device = device.GetPhysical(); - - //选择交换链图像的格式与颜色空间 - VkFormat image_format; - VkColorSpaceKHR image_color_space; - SelectFormatOfSwapchainImages(physical_device, presentation_surface, { VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR }, - image_format, image_color_space); - - VkSurfaceCapabilitiesKHR surface_capabilities; - GetCapabilitiesOfPresentationSurface(physical_device, presentation_surface, surface_capabilities); - - VkExtent2D image_size{ (uint32_t)width ,(uint32_t)height }; - ChooseSizeOfSwapchainImages(surface_capabilities, image_size); - - //调用设备接口,创建交换链 - VkSwapchainKHR old_swapchain = VK_NULL_HANDLE; - VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - CreateSwapchain(device.Ptr(), presentation_surface, frames, { image_format, image_color_space }, image_size - , imageUsage, VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,VK_PRESENT_MODE_FIFO_KHR, old_swapchain, mPtr); - + VkSurfaceCapabilitiesKHR capabilities{}; + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Creator.device.GetPhysical(), Creator.presentation_surface, &capabilities); + VkExtent2D image_extent = Creator.EnableImageExtent2D(capabilities); + VkSwapchainCreateInfoKHR swapchain_create_info = { + VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,// VkStructureType sType + nullptr, // const void * pNext + 0, // VkSwapchainCreateFlagsKHR flags + Creator.presentation_surface, // VkSurfaceKHR surface + (uint32_t)Creator.frames, // uint32_t minImageCount + Creator.imageFormat, // VkFormat imageFormat + Creator.imageColorSpace, // VkColorSpaceKHR imageColorSpace + image_extent, // VkExtent2D imageExtent + 1, // uint32_t imageArrayLayers + Creator.imageUsage, // VkImageUsageFlags imageUsage + VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode imageSharingMode + 0, // uint32_t queueFamilyIndexCount + nullptr, // const uint32_t * pQueueFamilyIndices + capabilities.currentTransform, // VkSurfaceTransformFlagBitsKHR preTransform + VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, // VkCompositeAlphaFlagBitsKHR compositeAlpha + Creator.presentMode, // VkPresentModeKHR presentMode + VK_TRUE, // VkBool32 clipped + VK_NULL_HANDLE // VkSwapchainKHR oldSwapchain + }; + VkResult result = vkCreateSwapchainKHR(Creator.device.Ptr(), &swapchain_create_info, nullptr, &mPtr); + if (result != VK_SUCCESS) { + zlog::error("Failed to create swap chain."); + } std::vector swapchain_images; - GetHandlesOfSwapchainImages(device.Ptr(), mPtr, swapchain_images); + Creator.CreateSwapchainImages(mPtr, swapchain_images); uint32_t image_count = swapchain_images.size(); for (auto img : swapchain_images) { - mImages.push_back(new Image(device, img, Image::Args{ + mImages.push_back(new Image(Creator.device, img, Image::Args{ 1, - "", - width, height, - 1, 1, 1, - image_format, imageUsage, - 1, 1, 1, 1})); + "", + (int)Creator.width, (int)Creator.height, + 1, 1, 1, + Creator.imageFormat, Creator.imageUsage, + 1, 1, 1, 1})); } - } + } } diff --git a/engine/src/engine/vulkanapi/wrapper/swapchain.h b/engine/src/engine/vulkanapi/wrapper/swapchain.h index 41248e8..9db1632 100644 --- a/engine/src/engine/vulkanapi/wrapper/swapchain.h +++ b/engine/src/engine/vulkanapi/wrapper/swapchain.h @@ -4,13 +4,14 @@ #include "../vulkan.h" namespace vulkanapi { - class Device; class Image; + class SwapchainCreator; class Swapchain { + friend class SwapchainCreator; protected: VkSwapchainKHR mPtr; std::vector mImages; public: - Swapchain(Device& device,int frames, int width, int height, VkSurfaceKHR presentation_surface); + Swapchain(SwapchainCreator& Creator); }; }; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/swapchain_creator.cpp b/engine/src/engine/vulkanapi/wrapper/swapchain_creator.cpp new file mode 100644 index 0000000..31b0db2 --- /dev/null +++ b/engine/src/engine/vulkanapi/wrapper/swapchain_creator.cpp @@ -0,0 +1,43 @@ +#include "swapchain_creator.h" +#include "device.h" +#include +namespace vulkanapi { + SwapchainCreator::SwapchainCreator(Device& device, int frames, uint32_t width, uint32_t height, + VkSurfaceKHR presentation_surface) + : device(device) + , presentation_surface(presentation_surface) + , frames(frames) + , width(width) + , height(height) + , imageFormat(VkFormat::VK_FORMAT_B8G8R8A8_SRGB) + , imageColorSpace(VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) + , presentMode(VkPresentModeKHR::VK_PRESENT_MODE_MAILBOX_KHR) + , imageUsage(VkImageUsageFlagBits::VK_IMAGE_USAGE_TRANSFER_DST_BIT) + , maxFrameInFlightCount(2) + { + + } + VkExtent2D SwapchainCreator::EnableImageExtent2D(VkSurfaceCapabilitiesKHR& capabilities) + { + VkExtent2D image_extent{ width , height }; + if (capabilities.currentExtent.width != 0xFFFFFFFF) + { + image_extent = capabilities.currentExtent; + } + else + { + image_extent.width = std::clamp(image_extent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width); + image_extent.height = std::clamp(image_extent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height); + } + return image_extent; + } + bool SwapchainCreator::CreateSwapchainImages(VkSwapchainKHR swapchain, std::vector& swapchain_images) + { + uint32_t imageCount = 0; + vkGetSwapchainImagesKHR(device.Ptr(), swapchain, &imageCount, nullptr); + std::vector scImages = std::vector(imageCount); + swapchain_images.resize(imageCount); + vkGetSwapchainImagesKHR(device.Ptr(), swapchain, &imageCount, swapchain_images.data()); + return true; + } +} \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/swapchain_creator.h b/engine/src/engine/vulkanapi/wrapper/swapchain_creator.h new file mode 100644 index 0000000..bb9b3e7 --- /dev/null +++ b/engine/src/engine/vulkanapi/wrapper/swapchain_creator.h @@ -0,0 +1,30 @@ +#pragma once +#include "../vulkan.h" +#include +#include + +namespace vulkanapi { + class Device; + class SwapchainCreator { + friend class Swapchain; + public: + int frames; + uint32_t width; + uint32_t height; + std::string title; + VkFormat imageFormat; + VkColorSpaceKHR imageColorSpace; + VkPresentModeKHR presentMode; + VkImageUsageFlags imageUsage; + uint32_t maxFrameInFlightCount; + + public: + VkSurfaceKHR presentation_surface; + Device& device; + public: + SwapchainCreator(Device& device,int frames,uint32_t width, uint32_t height, VkSurfaceKHR presentation_surface); + + VkExtent2D EnableImageExtent2D(VkSurfaceCapabilitiesKHR& capabilities); + bool CreateSwapchainImages(VkSwapchainKHR swapchain,std::vector& swapchain_images); + }; +}; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/swapchain_help.h b/engine/src/engine/vulkanapi/wrapper/swapchain_help.h deleted file mode 100644 index 33e79a9..0000000 --- a/engine/src/engine/vulkanapi/wrapper/swapchain_help.h +++ /dev/null @@ -1,162 +0,0 @@ -#pragma once -#include "instance.h" -#include -#include "zlog.h" -namespace vulkanapi { - bool GetCapabilitiesOfPresentationSurface(VkPhysicalDevice physical_device, - VkSurfaceKHR presentation_surface, - VkSurfaceCapabilitiesKHR& surface_capabilities) { - VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, presentation_surface, &surface_capabilities); - - if (VK_SUCCESS != result) { - zlog::error("Could not get the capabilities of a presentation surface."); - return false; - } - return true; - } - bool ChooseSizeOfSwapchainImages(VkSurfaceCapabilitiesKHR const& surface_capabilities, - VkExtent2D& size_of_images) { - if (0xFFFFFFFF == surface_capabilities.currentExtent.width) { - if (size_of_images.width < surface_capabilities.minImageExtent.width) { - size_of_images.width = surface_capabilities.minImageExtent.width; - } - else if (size_of_images.width > surface_capabilities.maxImageExtent.width) { - size_of_images.width = surface_capabilities.maxImageExtent.width; - } - - if (size_of_images.height < surface_capabilities.minImageExtent.height) { - size_of_images.height = surface_capabilities.minImageExtent.height; - } - else if (size_of_images.height > surface_capabilities.maxImageExtent.height) { - size_of_images.height = surface_capabilities.maxImageExtent.height; - } - } - else { - size_of_images = surface_capabilities.currentExtent; - } - return true; - } - bool SelectFormatOfSwapchainImages(VkPhysicalDevice physical_device, - VkSurfaceKHR presentation_surface, - VkSurfaceFormatKHR desired_surface_format, - VkFormat& image_format, - VkColorSpaceKHR& image_color_space) { - // Enumerate supported formats - uint32_t formats_count = 0; - VkResult result = VK_SUCCESS; - - result = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, presentation_surface, &formats_count, nullptr); - if ((VK_SUCCESS != result) || - (0 == formats_count)) { - zlog::error("Could not get the number of supported surface formats."); - return false; - } - - std::vector surface_formats(formats_count); - result = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, presentation_surface, &formats_count, surface_formats.data()); - if ((VK_SUCCESS != result) || - (0 == formats_count)) { - zlog::error("Could not enumerate supported surface formats."); - return false; - } - - // Select surface format - if ((1 == surface_formats.size()) && - (VK_FORMAT_UNDEFINED == surface_formats[0].format)) { - image_format = desired_surface_format.format; - image_color_space = desired_surface_format.colorSpace; - return true; - } - - for (auto& surface_format : surface_formats) { - if ((desired_surface_format.format == surface_format.format) && - (desired_surface_format.colorSpace == surface_format.colorSpace)) { - image_format = desired_surface_format.format; - image_color_space = desired_surface_format.colorSpace; - return true; - } - } - - for (auto& surface_format : surface_formats) { - if (desired_surface_format.format == surface_format.format) { - image_format = desired_surface_format.format; - image_color_space = surface_format.colorSpace; - zlog::error("Desired combination of format and colorspace is not supported. Selecting other colorspace."); - return true; - } - } - - image_format = surface_formats[0].format; - image_color_space = surface_formats[0].colorSpace; - zlog::error("Desired format is not supported. Selecting available format - colorspace combination."); - return true; - } - bool CreateSwapchain(VkDevice logical_device, - VkSurfaceKHR presentation_surface, - uint32_t image_count, - VkSurfaceFormatKHR surface_format, - VkExtent2D image_size, - VkImageUsageFlags image_usage, - VkSurfaceTransformFlagBitsKHR surface_transform, - VkPresentModeKHR present_mode, - VkSwapchainKHR& old_swapchain, - VkSwapchainKHR& swapchain) { - VkSwapchainCreateInfoKHR swapchain_create_info = { - VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, // VkStructureType sType - nullptr, // const void * pNext - 0, // VkSwapchainCreateFlagsKHR flags - presentation_surface, // VkSurfaceKHR surface - image_count, // uint32_t minImageCount - surface_format.format, // VkFormat imageFormat - surface_format.colorSpace, // VkColorSpaceKHR imageColorSpace - image_size, // VkExtent2D imageExtent - 1, // uint32_t imageArrayLayers - image_usage, // VkImageUsageFlags imageUsage - VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode imageSharingMode - 0, // uint32_t queueFamilyIndexCount - nullptr, // const uint32_t * pQueueFamilyIndices - surface_transform, // VkSurfaceTransformFlagBitsKHR preTransform - VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, // VkCompositeAlphaFlagBitsKHR compositeAlpha - present_mode, // VkPresentModeKHR presentMode - VK_TRUE, // VkBool32 clipped - old_swapchain // VkSwapchainKHR oldSwapchain - }; - - VkResult result = vkCreateSwapchainKHR(logical_device, &swapchain_create_info, nullptr, &swapchain); - if ((VK_SUCCESS != result) || - (VK_NULL_HANDLE == swapchain)) { - zlog::error("Could not create a swapchain."); - return false; - } - - if (VK_NULL_HANDLE != old_swapchain) { - vkDestroySwapchainKHR(logical_device, old_swapchain, nullptr); - old_swapchain = VK_NULL_HANDLE; - } - - return true; - } - bool GetHandlesOfSwapchainImages(VkDevice logical_device, - VkSwapchainKHR swapchain, - std::vector& swapchain_images) { - uint32_t images_count = 0; - VkResult result = VK_SUCCESS; - - result = vkGetSwapchainImagesKHR(logical_device, swapchain, &images_count, nullptr); - if ((VK_SUCCESS != result) || - (0 == images_count)) { - zlog::error("Could not get the number of swapchain images."); - return false; - } - - swapchain_images.resize(images_count); - result = vkGetSwapchainImagesKHR(logical_device, swapchain, &images_count, swapchain_images.data()); - if ((VK_SUCCESS != result) || - (0 == images_count)) { - zlog::error("Could not enumerate swapchain images."); - return false; - } - - return true; - } -} \ No newline at end of file