First attempt at creating a swapchain

This commit is contained in:
Warwick New 2024-12-30 15:51:43 +00:00
parent a95e3a79b1
commit 4eb4e00f58

View file

@ -1,4 +1,6 @@
#include "dyn_arr.h" #include "dyn_arr.h"
#include <limits.h>
#include <math.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
@ -45,6 +47,7 @@ typedef struct Application {
VkDevice device; VkDevice device;
VkQueue graphicsQueue; VkQueue graphicsQueue;
VkQueue presentQueue; VkQueue presentQueue;
VkSwapchainKHR swapChain;
} Application; } Application;
typedef struct SwapChainSupportDetails { typedef struct SwapChainSupportDetails {
@ -355,6 +358,29 @@ VkPresentModeKHR chooseSwapPresentMode(VkPresentModeKHR *availablePresentModes,
return VK_PRESENT_MODE_FIFO_KHR; 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) { bool isDeviceSuitable(VkPhysicalDevice device, VkSurfaceKHR *surface) {
QueueFamilyIndices indices = findQueueFamilies(device, surface); QueueFamilyIndices indices = findQueueFamilies(device, surface);
bool completeIndeces = bool completeIndeces =
@ -484,6 +510,59 @@ void createSurface(Application *app) {
exit(EXIT_FAILURE); 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) { void initVulkan(Application *app) {
createInstance(app); createInstance(app);
@ -491,6 +570,7 @@ void initVulkan(Application *app) {
createSurface(app); createSurface(app);
pickPhysicalDevice(app); pickPhysicalDevice(app);
createLogicalDevice(app); createLogicalDevice(app);
createSwapChain(app);
} }
void mainLoop(Application *app) { void mainLoop(Application *app) {
@ -500,6 +580,7 @@ void mainLoop(Application *app) {
} }
void cleanup(Application *app) { void cleanup(Application *app) {
vkDestroySwapchainKHR(app->device, app->swapChain, NULL);
vkDestroyDevice(app->device, NULL); vkDestroyDevice(app->device, NULL);
if (enableValidationLayers) { if (enableValidationLayers) {
DestroyDebugUtilsMessengerEXT(app->instance, app->debugMessenger, NULL); DestroyDebugUtilsMessengerEXT(app->instance, app->debugMessenger, NULL);