Added swapchain
This commit is contained in:
@@ -13,6 +13,12 @@ namespace PB::Renderer
|
||||
VkQueue VulkanManager::s_GraphicsQueue = 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)
|
||||
{
|
||||
if (const std::optional<VkInstance> instance = VulkanManager::Init(); !instance)
|
||||
@@ -70,6 +76,18 @@ namespace PB::Renderer
|
||||
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)
|
||||
{
|
||||
if (s_Instance == std::nullopt)
|
||||
@@ -256,15 +274,134 @@ namespace PB::Renderer
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VulkanManager::Cleanup()
|
||||
bool VulkanManager::CreateSwapChain(GLFWwindow* window)
|
||||
{
|
||||
if (s_Surface != std::nullopt)
|
||||
vkDestroySurfaceKHR(s_Instance.value(), s_Surface.value(), nullptr);
|
||||
auto [capabilities, formats, presentModes] = QuerySwapChainSupport();
|
||||
auto [format, colorSpace] = ChooseSurfaceFormat(formats);
|
||||
|
||||
if (s_Instance != std::nullopt)
|
||||
vkDestroyInstance(s_Instance.value(), nullptr);
|
||||
const VkPresentModeKHR presentMode = ChoosePresentMode(presentModes);
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
@@ -25,12 +32,18 @@ namespace PB::Renderer
|
||||
static std::optional<VkSurfaceKHR> CreateSurface(GLFWwindow* window);
|
||||
static bool PickPhysicalDevice();
|
||||
static bool CreateLogicalDevice();
|
||||
static bool CreateSwapChain(GLFWwindow* window);
|
||||
|
||||
private:
|
||||
static bool IsDeviceSuitable(VkPhysicalDevice device, VkSurfaceKHR surface);
|
||||
static QueueFamilyIndices FindQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface);
|
||||
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<VkSurfaceKHR> s_Surface;
|
||||
|
||||
@@ -41,5 +54,11 @@ namespace PB::Renderer
|
||||
|
||||
static VkQueue s_GraphicsQueue;
|
||||
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