Added swapchain
This commit is contained in:
@@ -13,6 +13,12 @@ namespace PB::Renderer
|
|||||||
VkQueue VulkanManager::s_GraphicsQueue = VK_NULL_HANDLE;
|
VkQueue VulkanManager::s_GraphicsQueue = VK_NULL_HANDLE;
|
||||||
VkQueue VulkanManager::s_PresentQueue = VK_NULL_HANDLE;
|
VkQueue VulkanManager::s_PresentQueue = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
VkSwapchainKHR VulkanManager::s_SwapChain = VK_NULL_HANDLE;
|
||||||
|
std::vector<VkImage> VulkanManager::s_SwapChainImages = {};
|
||||||
|
std::vector<VkImageView> VulkanManager::s_SwapChainImageViews = {};
|
||||||
|
VkFormat VulkanManager::s_SwapChainImageFormat = {};
|
||||||
|
VkExtent2D VulkanManager::s_SwapChainExtent = {};
|
||||||
|
|
||||||
bool VulkanManager::InitAll(GLFWwindow* window)
|
bool VulkanManager::InitAll(GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (const std::optional<VkInstance> instance = VulkanManager::Init(); !instance)
|
if (const std::optional<VkInstance> instance = VulkanManager::Init(); !instance)
|
||||||
@@ -70,6 +76,18 @@ namespace PB::Renderer
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VulkanManager::Cleanup()
|
||||||
|
{
|
||||||
|
if (s_Surface != std::nullopt)
|
||||||
|
vkDestroySurfaceKHR(s_Instance.value(), s_Surface.value(), nullptr);
|
||||||
|
|
||||||
|
if (s_Instance != std::nullopt)
|
||||||
|
vkDestroyInstance(s_Instance.value(), nullptr);
|
||||||
|
|
||||||
|
s_Instance = std::nullopt;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<VkSurfaceKHR> VulkanManager::CreateSurface(GLFWwindow* window)
|
std::optional<VkSurfaceKHR> VulkanManager::CreateSurface(GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (s_Instance == std::nullopt)
|
if (s_Instance == std::nullopt)
|
||||||
@@ -256,15 +274,134 @@ namespace PB::Renderer
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanManager::Cleanup()
|
bool VulkanManager::CreateSwapChain(GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (s_Surface != std::nullopt)
|
auto [capabilities, formats, presentModes] = QuerySwapChainSupport();
|
||||||
vkDestroySurfaceKHR(s_Instance.value(), s_Surface.value(), nullptr);
|
auto [format, colorSpace] = ChooseSurfaceFormat(formats);
|
||||||
|
|
||||||
if (s_Instance != std::nullopt)
|
const VkPresentModeKHR presentMode = ChoosePresentMode(presentModes);
|
||||||
vkDestroyInstance(s_Instance.value(), nullptr);
|
s_SwapChainExtent = ChooseSwapExtent(capabilities, window);
|
||||||
|
|
||||||
|
uint32_t imageCount = capabilities.minImageCount + 1;
|
||||||
|
if (capabilities.maxImageCount > 0 && imageCount > capabilities.maxImageCount)
|
||||||
|
imageCount = capabilities.maxImageCount;
|
||||||
|
|
||||||
|
VkSwapchainCreateInfoKHR createInfo{};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||||
|
createInfo.surface = s_Surface.value();
|
||||||
|
|
||||||
|
createInfo.minImageCount = imageCount;
|
||||||
|
createInfo.imageFormat = format;
|
||||||
|
createInfo.imageColorSpace = colorSpace;
|
||||||
|
createInfo.imageExtent = s_SwapChainExtent;
|
||||||
|
createInfo.imageArrayLayers = 1;
|
||||||
|
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
|
|
||||||
|
const uint32_t queueFamilyIndices[] =
|
||||||
|
{
|
||||||
|
s_QueueIndices.graphicsFamily.value(),
|
||||||
|
s_QueueIndices.presentFamily.value()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (queueFamilyIndices[0] != queueFamilyIndices[1])
|
||||||
|
{
|
||||||
|
createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||||
|
createInfo.queueFamilyIndexCount = 2;
|
||||||
|
createInfo.pQueueFamilyIndices = queueFamilyIndices;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
createInfo.queueFamilyIndexCount = 0;
|
||||||
|
createInfo.pQueueFamilyIndices = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
createInfo.preTransform = capabilities.currentTransform;
|
||||||
|
createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||||
|
createInfo.presentMode = presentMode;
|
||||||
|
createInfo.clipped = VK_TRUE;
|
||||||
|
createInfo.oldSwapchain = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
if (!vkCreateSwapchainKHR(s_Device, &createInfo, nullptr, &s_SwapChain))
|
||||||
|
{
|
||||||
|
std::cout << "PB::Renderer::VulkanManager::CreateSwapChain(): Failed to create swap chain" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vkGetSwapchainImagesKHR(s_Device, s_SwapChain, &imageCount, nullptr);
|
||||||
|
s_SwapChainImages.resize(imageCount);
|
||||||
|
|
||||||
|
vkGetSwapchainImagesKHR(s_Device, s_SwapChain, &imageCount, s_SwapChainImages.data());
|
||||||
|
s_SwapChainImageFormat = format;
|
||||||
|
|
||||||
s_Instance = std::nullopt;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SwapChainSupportDetails VulkanManager::QuerySwapChainSupport()
|
||||||
|
{
|
||||||
|
SwapChainSupportDetails details;
|
||||||
|
const VkSurfaceKHR surface = s_Surface.value();
|
||||||
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(s_PhysicalDevice, surface, &details.capabilities);
|
||||||
|
|
||||||
|
uint32_t formatCount;
|
||||||
|
vkGetPhysicalDeviceSurfaceFormatsKHR(s_PhysicalDevice, surface, &formatCount, nullptr);
|
||||||
|
details.formats.resize(formatCount);
|
||||||
|
vkGetPhysicalDeviceSurfaceFormatsKHR(s_PhysicalDevice, surface, &formatCount, details.formats.data());
|
||||||
|
|
||||||
|
uint32_t presentModeCount;
|
||||||
|
vkGetPhysicalDeviceSurfacePresentModesKHR(s_PhysicalDevice, surface, &presentModeCount, nullptr);
|
||||||
|
details.presentModes.resize(presentModeCount);
|
||||||
|
vkGetPhysicalDeviceSurfacePresentModesKHR(s_PhysicalDevice, surface, &presentModeCount, details.presentModes.data());
|
||||||
|
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkSurfaceFormatKHR VulkanManager::ChooseSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats)
|
||||||
|
{
|
||||||
|
for (const auto& format : availableFormats)
|
||||||
|
{
|
||||||
|
if (format.format == VK_FORMAT_B8G8R8A8_SRGB && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
|
||||||
|
{
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return availableFormats[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
VkPresentModeKHR VulkanManager::ChoosePresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes)
|
||||||
|
{
|
||||||
|
for (const auto& mode : availablePresentModes)
|
||||||
|
{
|
||||||
|
if (mode == VK_PRESENT_MODE_MAILBOX_KHR)
|
||||||
|
{
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return VK_PRESENT_MODE_FIFO_KHR;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkExtent2D VulkanManager::ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (capabilities.currentExtent.width != UINT32_MAX)
|
||||||
|
{
|
||||||
|
return capabilities.currentExtent;
|
||||||
|
}
|
||||||
|
|
||||||
|
int width, height;
|
||||||
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
|
|
||||||
|
VkExtent2D actualExtent =
|
||||||
|
{
|
||||||
|
static_cast<uint32_t>(width),
|
||||||
|
static_cast<uint32_t>(height)
|
||||||
|
};
|
||||||
|
|
||||||
|
actualExtent.width = std::max(capabilities.minImageExtent.width, std::min(capabilities.maxImageExtent.width, actualExtent.width));
|
||||||
|
actualExtent.height = std::max(capabilities.minImageExtent.height, std::min(capabilities.maxImageExtent.height, actualExtent.height));
|
||||||
|
|
||||||
|
return actualExtent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,13 @@ namespace PB::Renderer
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SwapChainSupportDetails
|
||||||
|
{
|
||||||
|
VkSurfaceCapabilitiesKHR capabilities;
|
||||||
|
std::vector<VkSurfaceFormatKHR> formats;
|
||||||
|
std::vector<VkPresentModeKHR> presentModes;
|
||||||
|
};
|
||||||
|
|
||||||
class VulkanManager
|
class VulkanManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -25,12 +32,18 @@ namespace PB::Renderer
|
|||||||
static std::optional<VkSurfaceKHR> CreateSurface(GLFWwindow* window);
|
static std::optional<VkSurfaceKHR> CreateSurface(GLFWwindow* window);
|
||||||
static bool PickPhysicalDevice();
|
static bool PickPhysicalDevice();
|
||||||
static bool CreateLogicalDevice();
|
static bool CreateLogicalDevice();
|
||||||
|
static bool CreateSwapChain(GLFWwindow* window);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool IsDeviceSuitable(VkPhysicalDevice device, VkSurfaceKHR surface);
|
static bool IsDeviceSuitable(VkPhysicalDevice device, VkSurfaceKHR surface);
|
||||||
static QueueFamilyIndices FindQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface);
|
static QueueFamilyIndices FindQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface);
|
||||||
static bool CheckDeviceExtensionSupport(VkPhysicalDevice device);
|
static bool CheckDeviceExtensionSupport(VkPhysicalDevice device);
|
||||||
|
|
||||||
|
static SwapChainSupportDetails QuerySwapChainSupport();
|
||||||
|
static VkSurfaceFormatKHR ChooseSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
|
||||||
|
static VkPresentModeKHR ChoosePresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes);
|
||||||
|
static VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, GLFWwindow* window);
|
||||||
|
|
||||||
static std::optional<VkInstance> s_Instance;
|
static std::optional<VkInstance> s_Instance;
|
||||||
static std::optional<VkSurfaceKHR> s_Surface;
|
static std::optional<VkSurfaceKHR> s_Surface;
|
||||||
|
|
||||||
@@ -41,5 +54,11 @@ namespace PB::Renderer
|
|||||||
|
|
||||||
static VkQueue s_GraphicsQueue;
|
static VkQueue s_GraphicsQueue;
|
||||||
static VkQueue s_PresentQueue;
|
static VkQueue s_PresentQueue;
|
||||||
|
|
||||||
|
static VkSwapchainKHR s_SwapChain;
|
||||||
|
static std::vector<VkImage> s_SwapChainImages;
|
||||||
|
static std::vector<VkImageView> s_SwapChainImageViews;
|
||||||
|
static VkFormat s_SwapChainImageFormat;
|
||||||
|
static VkExtent2D s_SwapChainExtent;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user