Finished swap chain

This commit is contained in:
Mars 2024-10-01 16:57:40 -04:00
parent 9ae5a4675a
commit ba46d3d834
Signed by untrusted user: pupbrained
GPG key ID: 0FF5B8826803F895

View file

@ -56,6 +56,11 @@ class VulkanApp {
vk::UniqueSurfaceKHR mSurface; vk::UniqueSurfaceKHR mSurface;
vk::UniqueSwapchainKHR mSwapChain;
std::vector<vk::Image> mSwapChainImages;
vk::Format mSwapChainImageFormat;
vk::Extent2D mSwapChainExtent;
struct QueueFamilyIndices { struct QueueFamilyIndices {
std::optional<u32> graphics_family; std::optional<u32> graphics_family;
std::optional<u32> present_family; std::optional<u32> present_family;
@ -86,6 +91,7 @@ class VulkanApp {
createSurface(); createSurface();
pickPhysicalDevice(); pickPhysicalDevice();
createLogicalDevice(); createLogicalDevice();
createSwapChain();
} }
fn mainLoop() -> void { fn mainLoop() -> void {
@ -115,7 +121,9 @@ class VulkanApp {
#endif #endif
vk::InstanceCreateInfo createInfo { vk::InstanceCreateInfo createInfo {
.flags = vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR, #ifdef __APPLE__
.flags = vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR,
#endif
.pApplicationInfo = &appInfo, .pApplicationInfo = &appInfo,
.enabledLayerCount = enableValidationLayers ? static_cast<u32>(validationLayers.size()) : 0, .enabledLayerCount = enableValidationLayers ? static_cast<u32>(validationLayers.size()) : 0,
.ppEnabledLayerNames = enableValidationLayers ? validationLayers.data() : nullptr, .ppEnabledLayerNames = enableValidationLayers ? validationLayers.data() : nullptr,
@ -258,6 +266,50 @@ class VulkanApp {
return indices; return indices;
} }
fn createSwapChain() -> void {
SwapChainSupportDetails swapChainSupport = querySwapChainSupport(mPhysicalDevice);
vk::SurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats);
vk::PresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.present_modes);
vk::Extent2D extent = chooseSwapExtent(swapChainSupport.capabilities);
u32 imageCount = swapChainSupport.capabilities.minImageCount + 1;
if (swapChainSupport.capabilities.maxImageCount > 0 &&
imageCount > swapChainSupport.capabilities.maxImageCount)
imageCount = swapChainSupport.capabilities.maxImageCount;
QueueFamilyIndices indices = findQueueFamilies(mPhysicalDevice);
std::array<u32, 2> queueFamilyIndices = { indices.graphics_family.value(),
indices.present_family.value() };
vk::SwapchainCreateInfoKHR createInfo {
.surface = mSurface.get(),
.minImageCount = imageCount,
.imageFormat = surfaceFormat.format,
.imageColorSpace = surfaceFormat.colorSpace,
.imageExtent = extent,
.imageArrayLayers = 1,
.imageUsage = vk::ImageUsageFlagBits::eColorAttachment,
.imageSharingMode = indices.graphics_family != indices.present_family ? vk::SharingMode::eConcurrent
: vk::SharingMode::eExclusive,
.queueFamilyIndexCount = static_cast<u32>(indices.graphics_family != indices.present_family ? 2 : 0),
.pQueueFamilyIndices =
indices.graphics_family != indices.present_family ? queueFamilyIndices.data() : nullptr,
.preTransform = swapChainSupport.capabilities.currentTransform,
.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque,
.presentMode = presentMode,
.clipped = VK_TRUE,
.oldSwapchain = nullptr,
};
mSwapChain = mDevice->createSwapchainKHRUnique(createInfo);
mSwapChainImages = mDevice->getSwapchainImagesKHR(mSwapChain.get());
mSwapChainImageFormat = surfaceFormat.format;
mSwapChainExtent = extent;
}
fn querySwapChainSupport(vk::PhysicalDevice device) -> SwapChainSupportDetails { fn querySwapChainSupport(vk::PhysicalDevice device) -> SwapChainSupportDetails {
SwapChainSupportDetails details; SwapChainSupportDetails details;
@ -268,6 +320,42 @@ class VulkanApp {
return details; return details;
} }
static fn chooseSwapSurfaceFormat(const std::vector<vk::SurfaceFormatKHR>& availableFormats
) -> vk::SurfaceFormatKHR {
for (const auto& availableFormat : availableFormats)
if (availableFormat.format == vk::Format::eB8G8R8A8Srgb &&
availableFormat.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear)
return availableFormat;
return availableFormats[0];
}
static fn chooseSwapPresentMode(const std::vector<vk::PresentModeKHR>& availablePresentModes
) -> vk::PresentModeKHR {
for (const auto& availablePresentMode : availablePresentModes)
if (availablePresentMode == vk::PresentModeKHR::eMailbox)
return availablePresentMode;
return vk::PresentModeKHR::eFifo;
}
fn chooseSwapExtent(const vk::SurfaceCapabilitiesKHR capabilities) -> vk::Extent2D {
if (capabilities.currentExtent.width != UINT32_MAX)
return capabilities.currentExtent;
u32 width = 0, height = 0;
std::tie(width, height) = mWindow->getFramebufferSize();
vk::Extent2D actualExtent = { width, height };
actualExtent.width =
std::clamp(actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
actualExtent.height =
std::clamp(actualExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
return actualExtent;
}
static fn getRequiredExtensions() -> std::vector<const char*> { static fn getRequiredExtensions() -> std::vector<const char*> {
std::span<const char*> extensionsSpan = vkfw::getRequiredInstanceExtensions(); std::span<const char*> extensionsSpan = vkfw::getRequiredInstanceExtensions();