create device & swapchain
This commit is contained in:
parent
d8163fd614
commit
e48d175b76
@ -8,6 +8,7 @@ namespace vulkanapi {
|
|||||||
mInstance = new Instance(instanceCreator);
|
mInstance = new Instance(instanceCreator);
|
||||||
|
|
||||||
auto deviceCreator = DeviceCreator(*mInstance);
|
auto deviceCreator = DeviceCreator(*mInstance);
|
||||||
|
deviceCreator.AddWindowExtension();
|
||||||
deviceCreator.desiredPhysicalDeviceFeatures.geometryShader = VK_TRUE;
|
deviceCreator.desiredPhysicalDeviceFeatures.geometryShader = VK_TRUE;
|
||||||
deviceCreator.AddQueue("TransferQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
deviceCreator.AddQueue("TransferQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
||||||
deviceCreator.AddQueue("RenderQueue", 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);
|
deviceCreator.AddQueue("PresentQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
||||||
mDevice = new Device(deviceCreator);
|
mDevice = new Device(deviceCreator);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Backend::~Backend()
|
Backend::~Backend()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#include "wrapper/instance.h"
|
#include "wrapper/instance.h"
|
||||||
#include "wrapper/device.h"
|
#include "wrapper/device.h"
|
||||||
#include "wrapper/swapchain.h"
|
#include "wrapper/swapchain.h"
|
||||||
|
#include "wrapper/swapchain_creator.h"
|
||||||
#include <vulkan/vulkan_win32.h>
|
#include <vulkan/vulkan_win32.h>
|
||||||
namespace vulkanapi {
|
namespace vulkanapi {
|
||||||
Window::Window(Backend& backend, int frames, uint32_t width, uint32_t height, const char* title)
|
Window::Window(Backend& backend, int frames, uint32_t width, uint32_t height, const char* title)
|
||||||
@ -19,7 +20,7 @@ namespace vulkanapi {
|
|||||||
mPtr // HWND hwnd
|
mPtr // HWND hwnd
|
||||||
};
|
};
|
||||||
vkCreateWin32SurfaceKHR(instance, &surface_create_info, nullptr, &mSurfaceKHR);
|
vkCreateWin32SurfaceKHR(instance, &surface_create_info, nullptr, &mSurfaceKHR);
|
||||||
|
SwapchainCreator swapchainCreator(backend.GetDevice(), frames, width, height, mSurfaceKHR);
|
||||||
mSwapchain = new Swapchain(backend.GetDevice(), frames, width, height, mSurfaceKHR);
|
mSwapchain = new Swapchain(swapchainCreator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,21 +1,38 @@
|
|||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "device_creator.h"
|
#include "device_creator.h"
|
||||||
|
#include "zlog.h"
|
||||||
namespace vulkanapi {
|
namespace vulkanapi {
|
||||||
Device::Device(DeviceCreator& Creator)
|
Device::Device(DeviceCreator& Creator)
|
||||||
{
|
{
|
||||||
|
Creator.FindDevice(mPhysical);
|
||||||
}
|
|
||||||
uint32_t Device::GetQueueFamilyIndex(VkQueueFlags flag)
|
|
||||||
{
|
|
||||||
std::vector<VkQueueFamilyProperties> queue_families;
|
std::vector<VkQueueFamilyProperties> queue_families;
|
||||||
// CheckAvailableQueueFamiliesAndTheirProperties(mPhysical, queue_families);
|
Creator.CheckAvailableQueueFamilies(mPhysical, queue_families);
|
||||||
for (uint32_t i = 0, l = queue_families.size(); i < l; i++) {
|
std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
|
||||||
if ((queue_families[i].queueFlags & flag) == flag) {
|
std::vector<std::vector<float>> queue_prioritie;
|
||||||
return i;
|
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 Device::CreateCommandPool(const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
|
||||||
{
|
{
|
||||||
VkCommandPool pCommandPool;
|
VkCommandPool pCommandPool;
|
||||||
|
|||||||
@ -18,8 +18,6 @@ namespace vulkanapi {
|
|||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
Device(DeviceCreator& Creator);
|
Device(DeviceCreator& Creator);
|
||||||
|
|
||||||
uint32_t GetQueueFamilyIndex(VkQueueFlags flag);
|
|
||||||
VkCommandPool CreateCommandPool(const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator);
|
VkCommandPool CreateCommandPool(const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator);
|
||||||
VkQueue GetQueue(uint32_t familyIndex, uint32_t queueIndex);
|
VkQueue GetQueue(uint32_t familyIndex, uint32_t queueIndex);
|
||||||
VkDescriptorPool CreateDescriptorPool(const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator);
|
VkDescriptorPool CreateDescriptorPool(const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator);
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "device_creator.h"
|
#include "device_creator.h"
|
||||||
|
#include "instance.h"
|
||||||
#include "zlog.h"
|
#include "zlog.h"
|
||||||
namespace vulkanapi {
|
namespace vulkanapi {
|
||||||
DeviceCreator::DeviceCreator(Instance& instance)
|
DeviceCreator::DeviceCreator(Instance& instance)
|
||||||
@ -23,10 +24,100 @@ namespace vulkanapi {
|
|||||||
AddLayer("VK_LAYER_RENDERDOC_Capture");
|
AddLayer("VK_LAYER_RENDERDOC_Capture");
|
||||||
#endif
|
#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)
|
void DeviceCreator::AddExtension(std::string extensionName)
|
||||||
{
|
{
|
||||||
@ -37,5 +128,50 @@ namespace vulkanapi {
|
|||||||
{
|
{
|
||||||
desiredLayers.push_back(layerName);
|
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
|
#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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
@ -16,7 +16,7 @@ namespace vulkanapi {
|
|||||||
VkQueueFlags flag;
|
VkQueueFlags flag;
|
||||||
float prioritie;
|
float prioritie;
|
||||||
DesiredQueue(std::string name, 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:
|
public:
|
||||||
VkPhysicalDeviceFeatures desiredPhysicalDeviceFeatures;
|
VkPhysicalDeviceFeatures desiredPhysicalDeviceFeatures;
|
||||||
@ -31,12 +31,21 @@ namespace vulkanapi {
|
|||||||
void AddQueue(std::string name, VkQueueFlags flag, float prioritie);
|
void AddQueue(std::string name, VkQueueFlags flag, float prioritie);
|
||||||
void AddExtension(std::string extensionName);
|
void AddExtension(std::string extensionName);
|
||||||
void AddWindowExtension();
|
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
|
#ifdef _USE_GRAPHIC_DEBUG
|
||||||
public:
|
public:
|
||||||
std::vector<std::string> desiredLayers;
|
std::vector<std::string> desiredLayers;
|
||||||
void AddLayer(std::string layerName);
|
void AddLayer(std::string layerName);
|
||||||
|
bool CheckLayer(const VkPhysicalDevice device);
|
||||||
|
std::vector<char const*> EnabledLayerNames();
|
||||||
#endif
|
#endif
|
||||||
private:
|
private:
|
||||||
|
static bool CheckAvailableQueueFamilies(VkPhysicalDevice physical_device, std::vector<VkQueueFamilyProperties>& queue_families);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
@ -1,43 +1,50 @@
|
|||||||
#include "swapchain.h"
|
#include "swapchain.h"
|
||||||
#include "swapchain_help.h"
|
#include "swapchain_creator.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
#include "zlog.h"
|
||||||
namespace vulkanapi {
|
namespace vulkanapi {
|
||||||
Swapchain::Swapchain(Device& device, int frames, int width, int height, VkSurfaceKHR presentation_surface)
|
Swapchain::Swapchain(SwapchainCreator& Creator)
|
||||||
: mPtr(nullptr)
|
: mPtr(nullptr)
|
||||||
{
|
{
|
||||||
uint32_t queue_family_index;
|
VkSurfaceCapabilitiesKHR capabilities{};
|
||||||
VkPhysicalDevice physical_device = device.GetPhysical();
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Creator.device.GetPhysical(), Creator.presentation_surface, &capabilities);
|
||||||
|
VkExtent2D image_extent = Creator.EnableImageExtent2D(capabilities);
|
||||||
//选择交换链图像的格式与颜色空间
|
VkSwapchainCreateInfoKHR swapchain_create_info = {
|
||||||
VkFormat image_format;
|
VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,// VkStructureType sType
|
||||||
VkColorSpaceKHR image_color_space;
|
nullptr, // const void * pNext
|
||||||
SelectFormatOfSwapchainImages(physical_device, presentation_surface, { VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR },
|
0, // VkSwapchainCreateFlagsKHR flags
|
||||||
image_format, image_color_space);
|
Creator.presentation_surface, // VkSurfaceKHR surface
|
||||||
|
(uint32_t)Creator.frames, // uint32_t minImageCount
|
||||||
VkSurfaceCapabilitiesKHR surface_capabilities;
|
Creator.imageFormat, // VkFormat imageFormat
|
||||||
GetCapabilitiesOfPresentationSurface(physical_device, presentation_surface, surface_capabilities);
|
Creator.imageColorSpace, // VkColorSpaceKHR imageColorSpace
|
||||||
|
image_extent, // VkExtent2D imageExtent
|
||||||
VkExtent2D image_size{ (uint32_t)width ,(uint32_t)height };
|
1, // uint32_t imageArrayLayers
|
||||||
ChooseSizeOfSwapchainImages(surface_capabilities, image_size);
|
Creator.imageUsage, // VkImageUsageFlags imageUsage
|
||||||
|
VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode imageSharingMode
|
||||||
//调用设备接口,创建交换链
|
0, // uint32_t queueFamilyIndexCount
|
||||||
VkSwapchainKHR old_swapchain = VK_NULL_HANDLE;
|
nullptr, // const uint32_t * pQueueFamilyIndices
|
||||||
VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
capabilities.currentTransform, // VkSurfaceTransformFlagBitsKHR preTransform
|
||||||
CreateSwapchain(device.Ptr(), presentation_surface, frames, { image_format, image_color_space }, image_size
|
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, // VkCompositeAlphaFlagBitsKHR compositeAlpha
|
||||||
, imageUsage, VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,VK_PRESENT_MODE_FIFO_KHR, old_swapchain, mPtr);
|
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;
|
std::vector<VkImage> swapchain_images;
|
||||||
GetHandlesOfSwapchainImages(device.Ptr(), mPtr, swapchain_images);
|
Creator.CreateSwapchainImages(mPtr, swapchain_images);
|
||||||
uint32_t image_count = swapchain_images.size();
|
uint32_t image_count = swapchain_images.size();
|
||||||
for (auto img : swapchain_images) {
|
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,
|
1,
|
||||||
"",
|
"",
|
||||||
width, height,
|
(int)Creator.width, (int)Creator.height,
|
||||||
1, 1, 1,
|
1, 1, 1,
|
||||||
image_format, imageUsage,
|
Creator.imageFormat, Creator.imageUsage,
|
||||||
1, 1, 1, 1}));
|
1, 1, 1, 1}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,13 +4,14 @@
|
|||||||
#include "../vulkan.h"
|
#include "../vulkan.h"
|
||||||
|
|
||||||
namespace vulkanapi {
|
namespace vulkanapi {
|
||||||
class Device;
|
|
||||||
class Image;
|
class Image;
|
||||||
|
class SwapchainCreator;
|
||||||
class Swapchain {
|
class Swapchain {
|
||||||
|
friend class SwapchainCreator;
|
||||||
protected:
|
protected:
|
||||||
VkSwapchainKHR mPtr;
|
VkSwapchainKHR mPtr;
|
||||||
std::vector<Image*> mImages;
|
std::vector<Image*> mImages;
|
||||||
public:
|
public:
|
||||||
Swapchain(Device& device,int frames, int width, int height, VkSurfaceKHR presentation_surface);
|
Swapchain(SwapchainCreator& Creator);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
43
engine/src/engine/vulkanapi/wrapper/swapchain_creator.cpp
Normal file
43
engine/src/engine/vulkanapi/wrapper/swapchain_creator.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
30
engine/src/engine/vulkanapi/wrapper/swapchain_creator.h
Normal file
30
engine/src/engine/vulkanapi/wrapper/swapchain_creator.h
Normal 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);
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user