1
Fork 0
mirror of https://github.com/redstrate/Novus.git synced 2025-04-27 06:07:45 +00:00
novus/renderer/src/swapchain.cpp
Joshua Goins e34daadbcd Split up Renderer's source files and a lot of refactoring
This now splits up the rendering system into sensible parts, and makes
it easier to switch between the simple renderer and the new experimental
one. Lots of refactors I needed to do for a while are now done, too.
2024-04-21 17:35:51 -04:00

131 lines
5.3 KiB
C++

// SPDX-FileCopyrightText: 2024 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later
#include "swapchain.h"
#include "device.h"
SwapChain::SwapChain(Device &device, VkSurfaceKHR surface, int width, int height)
: m_device(device)
{
resize(surface, width, height);
}
void SwapChain::resize(VkSurfaceKHR surface, int width, int height)
{
vkQueueWaitIdle(m_device.presentQueue);
if (width == 0 || height == 0)
return;
// TODO: fix this pls
VkBool32 supported;
vkGetPhysicalDeviceSurfaceSupportKHR(m_device.physicalDevice, 0, surface, &supported);
// query swapchain support
VkSurfaceCapabilitiesKHR capabilities;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(m_device.physicalDevice, surface, &capabilities);
std::vector<VkSurfaceFormatKHR> formats;
uint32_t formatCount;
vkGetPhysicalDeviceSurfaceFormatsKHR(m_device.physicalDevice, surface, &formatCount, nullptr);
formats.resize(formatCount);
vkGetPhysicalDeviceSurfaceFormatsKHR(m_device.physicalDevice, surface, &formatCount, formats.data());
std::vector<VkPresentModeKHR> presentModes;
uint32_t presentModeCount;
vkGetPhysicalDeviceSurfacePresentModesKHR(m_device.physicalDevice, surface, &presentModeCount, nullptr);
presentModes.resize(presentModeCount);
vkGetPhysicalDeviceSurfacePresentModesKHR(m_device.physicalDevice, surface, &presentModeCount, presentModes.data());
// choosing swapchain features
VkSurfaceFormatKHR swapchainSurfaceFormat = formats[0];
for (const auto &availableFormat : formats) {
if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
swapchainSurfaceFormat = availableFormat;
}
}
VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
for (const auto &availablePresentMode : presentModes) {
if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
swapchainPresentMode = availablePresentMode;
}
}
uint32_t imageCount = capabilities.minImageCount + 1;
if (capabilities.maxImageCount > 0 && imageCount > capabilities.maxImageCount) {
imageCount = capabilities.maxImageCount;
}
// create swapchain
VkSwapchainCreateInfoKHR createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
createInfo.surface = surface;
createInfo.minImageCount = imageCount;
createInfo.imageFormat = swapchainSurfaceFormat.format;
createInfo.imageColorSpace = swapchainSurfaceFormat.colorSpace;
createInfo.imageExtent.width = width;
createInfo.imageExtent.height = height;
createInfo.imageArrayLayers = 1;
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
createInfo.preTransform = capabilities.currentTransform;
createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
createInfo.presentMode = swapchainPresentMode;
createInfo.clipped = VK_TRUE;
surfaceFormat = swapchainSurfaceFormat.format;
VkSwapchainKHR oldSwapchain = swapchain;
createInfo.oldSwapchain = oldSwapchain;
vkCreateSwapchainKHR(m_device.device, &createInfo, nullptr, &swapchain);
if (oldSwapchain != VK_NULL_HANDLE)
vkDestroySwapchainKHR(m_device.device, oldSwapchain, nullptr);
extent.width = width;
extent.height = height;
vkGetSwapchainImagesKHR(m_device.device, swapchain, &imageCount, nullptr);
swapchainImages.resize(imageCount);
vkGetSwapchainImagesKHR(m_device.device, swapchain, &imageCount, swapchainImages.data());
swapchainViews.resize(swapchainImages.size());
for (size_t i = 0; i < swapchainImages.size(); i++) {
VkImageViewCreateInfo view_create_info = {};
view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
view_create_info.image = swapchainImages[i];
view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_create_info.format = swapchainSurfaceFormat.format;
view_create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
view_create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
view_create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
view_create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
view_create_info.subresourceRange.baseMipLevel = 0;
view_create_info.subresourceRange.levelCount = 1;
view_create_info.subresourceRange.baseArrayLayer = 0;
view_create_info.subresourceRange.layerCount = 1;
vkCreateImageView(m_device.device, &view_create_info, nullptr, &swapchainViews[i]);
}
VkSemaphoreCreateInfo semaphoreInfo = {};
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
VkFenceCreateInfo fenceCreateInfo = {};
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
for (size_t i = 0; i < 3; i++) {
vkCreateSemaphore(m_device.device, &semaphoreInfo, nullptr, &imageAvailableSemaphores[i]);
vkCreateSemaphore(m_device.device, &semaphoreInfo, nullptr, &renderFinishedSemaphores[i]);
vkCreateFence(m_device.device, &fenceCreateInfo, nullptr, &inFlightFences[i]);
}
}