forked from pupbrained/vulkan-test
Finished swap chain
This commit is contained in:
parent
9ae5a4675a
commit
ba46d3d834
90
src/main.cpp
90
src/main.cpp
|
@ -56,6 +56,11 @@ class VulkanApp {
|
|||
|
||||
vk::UniqueSurfaceKHR mSurface;
|
||||
|
||||
vk::UniqueSwapchainKHR mSwapChain;
|
||||
std::vector<vk::Image> mSwapChainImages;
|
||||
vk::Format mSwapChainImageFormat;
|
||||
vk::Extent2D mSwapChainExtent;
|
||||
|
||||
struct QueueFamilyIndices {
|
||||
std::optional<u32> graphics_family;
|
||||
std::optional<u32> present_family;
|
||||
|
@ -86,6 +91,7 @@ class VulkanApp {
|
|||
createSurface();
|
||||
pickPhysicalDevice();
|
||||
createLogicalDevice();
|
||||
createSwapChain();
|
||||
}
|
||||
|
||||
fn mainLoop() -> void {
|
||||
|
@ -115,7 +121,9 @@ class VulkanApp {
|
|||
#endif
|
||||
|
||||
vk::InstanceCreateInfo createInfo {
|
||||
.flags = vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR,
|
||||
#ifdef __APPLE__
|
||||
.flags = vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR,
|
||||
#endif
|
||||
.pApplicationInfo = &appInfo,
|
||||
.enabledLayerCount = enableValidationLayers ? static_cast<u32>(validationLayers.size()) : 0,
|
||||
.ppEnabledLayerNames = enableValidationLayers ? validationLayers.data() : nullptr,
|
||||
|
@ -258,6 +266,50 @@ class VulkanApp {
|
|||
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 {
|
||||
SwapChainSupportDetails details;
|
||||
|
||||
|
@ -268,6 +320,42 @@ class VulkanApp {
|
|||
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*> {
|
||||
std::span<const char*> extensionsSpan = vkfw::getRequiredInstanceExtensions();
|
||||
|
||||
|
|
Loading…
Reference in a new issue