create swapchain, images and image views for the swapchain
authorJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 23 Dec 2021 07:46:32 +0000 (09:46 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 23 Dec 2021 07:46:32 +0000 (09:46 +0200)
src/app.c
src/vk.c
src/vk.h

index 4d845c5..1d97906 100644 (file)
--- a/src/app.c
+++ b/src/app.c
@@ -1,3 +1,4 @@
+#include <stdlib.h>
 #include "app.h"
 #include "vk.h"
 
@@ -21,6 +22,9 @@ void app_display(void)
 
 void app_reshape(int x, int y)
 {
+       if(vk_reshape(x, y) == -1) {
+               abort();
+       }
 }
 
 void app_keyboard(int key, int press)
index cfe2668..f3cb508 100644 (file)
--- a/src/vk.c
+++ b/src/vk.c
@@ -17,6 +17,8 @@ static int create_instance(void);
 static int create_surface(void);
 static int choose_phys_dev(void);
 static int create_device(void);
+static int create_swapchain(void);
+
 static int choose_pixfmt(void);
 static int eval_pdev_score(VkPhysicalDevice dev);
 static int have_inst_layer(const char *name);
@@ -36,6 +38,9 @@ static int vksurf_numfmt, vksurf_selfmt;
 static VkSurfaceFormatKHR *vksurf_fmt;
 static VkSwapchainKHR vksc;
 static int vksc_numimg;
+static VkImage *vksc_img;
+static VkExtent2D vksc_extent;
+static VkImageView *vksc_view;
 
 static VkLayerProperties *inst_layers;
 static VkExtensionProperties *inst_ext, *dev_ext;
@@ -63,12 +68,64 @@ int vk_init(void)
 
 void vk_cleanup(void)
 {
-       vkDestroyInstance(vk, 0);
+       int i;
+
+       free(vksc_img);
+       vksc_img = 0;
+       free(vksc_view);
+       vksc_view = 0;
+       if(vksc_view) {
+               for(i=0; i<vksc_numimg; i++) {
+                       vkDestroyImageView(vkdev, vksc_view[i], 0);
+               }
+               vksc_view = 0;
+       }
+       if(vksc) {
+               vkDestroySwapchainKHR(vkdev, vksc, 0);
+               vksc = 0;
+       }
+       if(vkdev) {
+               vkDestroyDevice(vkdev, 0);
+               vkdev = 0;
+       }
+       if(vksurf) {
+               vkDestroySurfaceKHR(vk, vksurf, 0);
+               vksurf = 0;
+       }
+       if(vk) {
+               vkDestroyInstance(vk, 0);
+               vk = 0;
+       }
        free(inst_layers);
+       inst_layers = 0;
        free(inst_ext);
+       inst_ext = 0;
+       free(dev_ext);
+       dev_ext = 0;
        free(pdev_list);
+       pdev_list = 0;
 }
 
+int vk_reshape(int xsz, int ysz)
+{
+       int i;
+
+       if(vksc && vksc_extent.width == xsz && vksc_extent.height == ysz) {
+               return 0;
+       }
+
+       if(vksc_view) {
+               for(i=0; i<vksc_numimg; i++) {
+                       vkDestroyImageView(vkdev, vksc_view[i], 0);
+               }
+       }
+       if(vksc) vkDestroySwapchainKHR(vkdev, vksc, 0);
+
+       vksc_extent.width = xsz;
+       vksc_extent.height = ysz;
+
+       return create_swapchain();
+}
 
 #define ARRSZ(arr)     (sizeof arr / sizeof *arr)
 static const char *known_layer_list[] = {
@@ -203,6 +260,7 @@ int choose_phys_dev(void)
        VkPhysicalDevice *pdev;
        VkPhysicalDeviceProperties pdevprop;
        VkQueueFamilyProperties *qfam;
+       VkBool32 can_pres;
 
        vkEnumeratePhysicalDevices(vk, &num_pdev, 0);
        if(!num_pdev) {
@@ -232,13 +290,13 @@ int choose_phys_dev(void)
        }
        vkpdev = pdev[best_dev];
 
-       vkGetPhysicalDeviceQueueFamilyProperties(dev, &num_qfam, 0);
+       vkGetPhysicalDeviceQueueFamilyProperties(vkpdev, &num_qfam, 0);
        qfam = malloc_nf(num_qfam * sizeof *qfam);
-       vkGetPhysicalDeviceQueueFamilyProperties(dev, &num_qfam, qfam);
+       vkGetPhysicalDeviceQueueFamilyProperties(vkpdev, &num_qfam, qfam);
 
        vkqfam_idx = -1;
        for(i=0; i<num_qfam; i++) {
-               vkGetPhysicalDeviceSurfaceSupportKHR(dev, i, vksurf, &can_pres);
+               vkGetPhysicalDeviceSurfaceSupportKHR(vkpdev, i, vksurf, &can_pres);
                if(qfam[i].queueCount && (qfam[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) && can_pres) {
                        vkqfam_maxq = qfam[i].queueCount;
                        vkqfam_idx = i;
@@ -265,6 +323,7 @@ static int create_device(void)
        dev_ext = malloc_nf(dev_ext_count * sizeof *dev_ext);
        vkEnumerateDeviceExtensionProperties(vkpdev, 0, &dev_ext_count, dev_ext);
 
+       num_ext = 0;
        for(i=0; i<ARRSZ(known_devext_list); i++) {
                if(have_ext(dev_ext, dev_ext_count, known_devext_list[i].name)) {
                        ext[num_ext++] = known_devext_list[i].name;
@@ -298,13 +357,15 @@ static int create_device(void)
 
 static int create_swapchain(void)
 {
+       int i;
        uint32_t num;
-       VkSwapchainCreateInfoKHR scinf;
+       VkSwapchainCreateInfoKHR scinf = {0};
+       VkImageViewCreateInfo ivinf;
 
-       vksc_extent.width = win_width;
-       vksc_extent.height = win_height;
+       if(vksc_extent.width <= 0 || vksc_extent.height <= 0) {
+               return -1;
+       }
 
-       memset(&scinf, 0, sizeof scinf);
        scinf.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
        scinf.surface = vksurf;
        scinf.minImageCount = 2;
@@ -324,11 +385,37 @@ static int create_swapchain(void)
                return -1;
        }
 
-       vkGetSwapchainImagesKHR(vkdev, vksc, &num, 0);
-       vksc_img = malloc_nf(num * sizeof *vksc_img);
-       vkGetSwapchainImagesKHR(vkdev, vksc, &num, vksc_img);
+       if(!vksc_img || vksc_numimg != num) {
+               free(vksc_img);
+               vkGetSwapchainImagesKHR(vkdev, vksc, &num, 0);
+               vksc_img = malloc_nf(num * sizeof *vksc_img);
+               vkGetSwapchainImagesKHR(vkdev, vksc, &num, vksc_img);
+       }
+       if(!vksc_view || vksc_numimg != num) {
+               free(vksc_view);
+               vksc_view = malloc_nf(num * sizeof *vksc_view);
+       }
        vksc_numimg = num;
 
+       for(i=0; i<num; i++) {
+               memset(&ivinf, 0, sizeof ivinf);
+               ivinf.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+               ivinf.image = vksc_img[i];
+               ivinf.format = vksurf_fmt[vksurf_selfmt].format;
+               ivinf.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
+               ivinf.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
+               ivinf.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
+               ivinf.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
+               ivinf.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+               ivinf.subresourceRange.levelCount = 1;
+               ivinf.subresourceRange.layerCount = 1;
+               ivinf.viewType = VK_IMAGE_VIEW_TYPE_2D;
+
+               if(vkCreateImageView(vkdev, &ivinf, 0, vksc_view + i) != 0) {
+                       fprintf(stderr, "failed to create image view (%d)\n", i);
+                       return -1;
+               }
+       }
        return 0;
 }
 
@@ -398,27 +485,27 @@ static int choose_pixfmt(void)
        };
        int i, j;
        uint32_t num_fmt;
-       VkSurfaceFormatKHR *sfmt;
 
        vkGetPhysicalDeviceSurfaceFormatsKHR(vkpdev, vksurf, &num_fmt, 0);
        if(!num_fmt) return -1;
-       sfmt = malloc_nf(num_fmt * sizeof *sfmt);
-       vkGetPhysicalDeviceSurfaceFormatsKHR(vkpdev, vksurf, &num_fmt, sfmt);
+       vksurf_fmt = malloc_nf(num_fmt * sizeof *vksurf_fmt);
+       vkGetPhysicalDeviceSurfaceFormatsKHR(vkpdev, vksurf, &num_fmt, vksurf_fmt);
 
        vksurf_selfmt = 0;
        for(i=0; i<num_fmt; i++) {
-               if(sfmt[i].colorSpace != VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
+               if(vksurf_fmt[i].colorSpace != VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
                        continue;
                }
                for(j=0; j<sizeof pref / sizeof *pref; j++) {
-                       if(sfmt[i].format == pref[j]) {
+                       if(vksurf_fmt[i].format == pref[j]) {
                                vksurf_selfmt = i;
-                               free(sfmt);
+                               vksurf_numfmt = num_fmt;
                                return i;
                        }
                }
        }
-       free(sfmt);
+       free(vksurf_fmt);
+       vksurf_fmt = 0;
        return -1;
 }
 
index 5fcf16e..746b0e0 100644 (file)
--- a/src/vk.h
+++ b/src/vk.h
@@ -8,4 +8,6 @@ void vk_init_xwin(Display *dpy, Window win);
 int vk_init(void);
 void vk_cleanup(void);
 
+int vk_reshape(int xsz, int ysz);
+
 #endif /* VK_H_ */