create device & swapchain

This commit is contained in:
ouczbs 2024-03-03 14:49:18 +08:00
parent d8163fd614
commit e48d175b76
11 changed files with 298 additions and 216 deletions

View File

@ -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()
{

View File

@ -3,6 +3,7 @@
#include "wrapper/instance.h"
#include "wrapper/device.h"
#include "wrapper/swapchain.h"
#include "wrapper/swapchain_creator.h"
#include <vulkan/vulkan_win32.h>
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);
}
}

View File

@ -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<VkQueueFamilyProperties> 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<VkDeviceQueueCreateInfo> queue_create_infos;
std::vector<std::vector<float>> 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<uint32_t>(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<uint32_t>(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;

View File

@ -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);

View File

@ -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<VkDeviceQueueCreateInfo>& queue_create_infos, std::vector<VkQueueFamilyProperties>& queue_families)
bool DeviceCreator::CheckProperty(const VkPhysicalDevice device)
{
std::vector<VkLayerProperties> 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<VkExtensionProperties> 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<VkPhysicalDevice> 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<char const*> DeviceCreator::EnabledExtensionNames()
{
std::vector<char const*> _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<VkDeviceQueueCreateInfo>& queue_create_infos, std::vector<std::vector<float>>& queue_prioritie,
std::vector<VkQueueFamilyProperties>& 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<float>{});
}
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<VkLayerProperties> 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<char const*> DeviceCreator::EnabledLayerNames()
{
std::vector<char const*> _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<VkQueueFamilyProperties>& 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;
}
};

View File

@ -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<VkDeviceQueueCreateInfo>& queue_create_infos, std::vector<VkQueueFamilyProperties>& queue_families);
bool CheckProperty(const VkPhysicalDevice device);
bool CheckExtension(const VkPhysicalDevice device);
bool FindDevice(VkPhysicalDevice& device);
std::vector<char const*> EnabledExtensionNames();
void QueueCreateInfos(std::vector<VkDeviceQueueCreateInfo>& queue_create_infos,
std::vector<std::vector<float>>& queue_prioritie,
std::vector<VkQueueFamilyProperties>& queue_families);
#ifdef _USE_GRAPHIC_DEBUG
public:
std::vector<std::string> desiredLayers;
void AddLayer(std::string layerName);
bool CheckLayer(const VkPhysicalDevice device);
std::vector<char const*> EnabledLayerNames();
#endif
private:
static bool CheckAvailableQueueFamilies(VkPhysicalDevice physical_device, std::vector<VkQueueFamilyProperties>& queue_families);
};
};

View File

@ -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<VkImage> 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}));
}
}
}
}

View File

@ -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<Image*> mImages;
public:
Swapchain(Device& device,int frames, int width, int height, VkSurfaceKHR presentation_surface);
Swapchain(SwapchainCreator& Creator);
};
};

View File

@ -0,0 +1,43 @@
#include "swapchain_creator.h"
#include "device.h"
#include <algorithm>
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<VkImage>& swapchain_images)
{
uint32_t imageCount = 0;
vkGetSwapchainImagesKHR(device.Ptr(), swapchain, &imageCount, nullptr);
std::vector<VkImage> scImages = std::vector<VkImage>(imageCount);
swapchain_images.resize(imageCount);
vkGetSwapchainImagesKHR(device.Ptr(), swapchain, &imageCount, swapchain_images.data());
return true;
}
}

View File

@ -0,0 +1,30 @@
#pragma once
#include "../vulkan.h"
#include <string>
#include <vector>
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<VkImage>& swapchain_images);
};
};

View File

@ -1,162 +0,0 @@
#pragma once
#include "instance.h"
#include <iostream>
#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<VkSurfaceFormatKHR> 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<VkImage>& 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;
}
}