From 4eb4e00f58d1485667fee1b00ea8de42f64a9fdb Mon Sep 17 00:00:00 2001 From: Warwick New Date: Mon, 30 Dec 2024 15:51:43 +0000 Subject: [PATCH] First attempt at creating a swapchain --- src/main.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/src/main.c b/src/main.c index 444f1a2..4430366 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,6 @@ #include "dyn_arr.h" +#include +#include #include #include #include @@ -45,6 +47,7 @@ typedef struct Application { VkDevice device; VkQueue graphicsQueue; VkQueue presentQueue; + VkSwapchainKHR swapChain; } Application; typedef struct SwapChainSupportDetails { @@ -355,6 +358,29 @@ VkPresentModeKHR chooseSwapPresentMode(VkPresentModeKHR *availablePresentModes, return VK_PRESENT_MODE_FIFO_KHR; } +VkExtent2D chooseSwapExtent(GLFWwindow *window, + const VkSurfaceCapabilitiesKHR *capabilities) { + if (capabilities->currentExtent.width != UINT_MAX) { + return capabilities->currentExtent; + } + + int width, height; + glfwGetFramebufferSize(window, &width, &height); + VkExtent2D actualExtent = {(uint32_t)width, (uint32_t)height}; + + // check width and height are within bounds + actualExtent.width = + fmin(capabilities->maxImageExtent.width, actualExtent.width); + actualExtent.width = + fmax(capabilities->minImageExtent.width, actualExtent.width); + actualExtent.height = + fmin(capabilities->maxImageExtent.height, actualExtent.height); + actualExtent.height = + fmax(capabilities->minImageExtent.height, actualExtent.height); + + return actualExtent; +} + bool isDeviceSuitable(VkPhysicalDevice device, VkSurfaceKHR *surface) { QueueFamilyIndices indices = findQueueFamilies(device, surface); bool completeIndeces = @@ -484,6 +510,59 @@ void createSurface(Application *app) { exit(EXIT_FAILURE); } } +void createSwapChain(Application *app) { + SwapChainSupportDetails swapChainSupport = + querySwapchainSupport(app->physicalDevice, &app->surface); + VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat( + swapChainSupport.formats, swapChainSupport.numFormats); + VkPresentModeKHR presentMode = chooseSwapPresentMode( + swapChainSupport.presentModes, swapChainSupport.numPresentModes); + VkExtent2D extent = + chooseSwapExtent(app->window, &swapChainSupport.capabilities); + + uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1; + if (swapChainSupport.capabilities.maxImageCount > 0 && + imageCount > swapChainSupport.capabilities.maxImageCount) { + imageCount = swapChainSupport.capabilities.maxImageCount; + } + + VkSwapchainCreateInfoKHR createInfo = {0}; + createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + createInfo.surface = app->surface; + createInfo.minImageCount = imageCount; + createInfo.imageFormat = surfaceFormat.format; + createInfo.imageColorSpace = surfaceFormat.colorSpace; + createInfo.imageExtent = extent; + createInfo.imageArrayLayers = 1; + createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + + QueueFamilyIndices indices = + findQueueFamilies(app->physicalDevice, &app->surface); + uint32_t queueFamilyIndices[] = {indices.graphicsFamily, + indices.presentFamily}; + + if (indices.graphicsFamily != indices.presentFamily) { + createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT; + createInfo.queueFamilyIndexCount = 2; + createInfo.pQueueFamilyIndices = queueFamilyIndices; + } else { + createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + createInfo.queueFamilyIndexCount = 0; + createInfo.pQueueFamilyIndices = NULL; + } + + createInfo.preTransform = swapChainSupport.capabilities.currentTransform; + createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + createInfo.presentMode = presentMode; + createInfo.clipped = VK_TRUE; + createInfo.oldSwapchain = VK_NULL_HANDLE; + + if (vkCreateSwapchainKHR(app->device, &createInfo, NULL, &app->swapChain) != + VK_SUCCESS) { + fprintf(stderr, "Failed to create swapchain!"); + exit(EXIT_FAILURE); + } +} void initVulkan(Application *app) { createInstance(app); @@ -491,6 +570,7 @@ void initVulkan(Application *app) { createSurface(app); pickPhysicalDevice(app); createLogicalDevice(app); + createSwapChain(app); } void mainLoop(Application *app) { @@ -500,6 +580,7 @@ void mainLoop(Application *app) { } void cleanup(Application *app) { + vkDestroySwapchainKHR(app->device, app->swapChain, NULL); vkDestroyDevice(app->device, NULL); if (enableValidationLayers) { DestroyDebugUtilsMessengerEXT(app->instance, app->debugMessenger, NULL);