what a tedious API...
authorJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 23 Dec 2021 06:03:00 +0000 (08:03 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 23 Dec 2021 06:03:00 +0000 (08:03 +0200)
src/vk.c

index 101eaa8..cfe2668 100644 (file)
--- a/src/vk.c
+++ b/src/vk.c
@@ -27,7 +27,7 @@ static Window win;
 
 static VkInstance vk;
 static VkPhysicalDevice vkpdev;
-static int vkqfam_idx = -1;
+static int vkqfam_idx, vkqfam_maxq;
 static VkDevice vkdev;
 static VkQueue vkq;
 static VkSurfaceKHR vksurf;
@@ -95,6 +95,15 @@ static struct {
        {"VK_KHR_debug_report", 0}
 };
 
+static struct {
+       const char *name;
+       int required;
+} known_devext_list[] = {
+       {"VK_KHR_swapchain", 1},
+       {"VK_KHR_acceleration_structure", 0},
+       {"VK_KHR_ray_tracing_pipeline", 0}
+};
+
 static int create_instance(void)
 {
        int i, nlayers = 0, next = 0;
@@ -165,8 +174,6 @@ static int create_instance(void)
 
 static int create_surface(void)
 {
-       int res;
-
        /*
        VkXlibSurfaceCreateInfoKHR xinf = {0};
        xinf.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
@@ -183,8 +190,8 @@ static int create_surface(void)
        xinf.connection = XGetXCBConnection(dpy);
        xinf.window = (xcb_window_t)win;
 
-       if((res = vkCreateXcbSurfaceKHR(vk, &xinf, 0, &vksurf)) != 0) {
-               fprintf(stderr, "failed to create XCB window surface (%d)\n", res);
+       if(vkCreateXcbSurfaceKHR(vk, &xinf, 0, &vksurf) != 0) {
+               fprintf(stderr, "failed to create XCB window surface\n");
                return -1;
        }
        return 0;
@@ -192,9 +199,10 @@ static int create_surface(void)
 
 int choose_phys_dev(void)
 {
-       uint32_t i, num_pdev, score, best_score, best_dev;
+       uint32_t i, num_pdev, num_qfam, score, best_score, best_dev;
        VkPhysicalDevice *pdev;
        VkPhysicalDeviceProperties pdevprop;
+       VkQueueFamilyProperties *qfam;
 
        vkEnumeratePhysicalDevices(vk, &num_pdev, 0);
        if(!num_pdev) {
@@ -222,9 +230,23 @@ int choose_phys_dev(void)
                free(pdev);
                return -1;
        }
+       vkpdev = pdev[best_dev];
+
+       vkGetPhysicalDeviceQueueFamilyProperties(dev, &num_qfam, 0);
+       qfam = malloc_nf(num_qfam * sizeof *qfam);
+       vkGetPhysicalDeviceQueueFamilyProperties(dev, &num_qfam, qfam);
 
-       vkpdev = pdev[i];
+       vkqfam_idx = -1;
+       for(i=0; i<num_qfam; i++) {
+               vkGetPhysicalDeviceSurfaceSupportKHR(dev, 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;
+                       break;
+               }
+       }
 
+       free(qfam);
        free(pdev);
        choose_pixfmt();
        return 0;
@@ -232,9 +254,85 @@ int choose_phys_dev(void)
 
 static int create_device(void)
 {
+       float prio = 1.0f;
+       VkDeviceQueueCreateInfo qinf = {0};
+       VkPhysicalDeviceFeatures feat = {0};
+       VkDeviceCreateInfo devinf = {0};
+       const char *ext[ARRSZ(known_devext_list)];
+       int i, num_ext;
+
+       vkEnumerateDeviceExtensionProperties(vkpdev, 0, &dev_ext_count, 0);
+       dev_ext = malloc_nf(dev_ext_count * sizeof *dev_ext);
+       vkEnumerateDeviceExtensionProperties(vkpdev, 0, &dev_ext_count, dev_ext);
+
+       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;
+               } else if(known_devext_list[i].required) {
+                       fprintf(stderr, "Vulkan device lacks required extension: %s\n",
+                                       known_devext_list[i].name);
+                       return -1;
+               }
+       }
+
+       qinf.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+       qinf.queueFamilyIndex = vkqfam_idx;
+       qinf.queueCount = 1;
+       qinf.pQueuePriorities = &prio;
+
+       devinf.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
+       devinf.pQueueCreateInfos = &qinf;
+       devinf.queueCreateInfoCount = 1;
+       devinf.pEnabledFeatures = &feat;
+       devinf.enabledExtensionCount = num_ext;
+       devinf.ppEnabledExtensionNames = ext;
+
+       if(vkCreateDevice(vkpdev, &devinf, 0, &vkdev) != 0) {
+               fprintf(stderr, "failed to create vulkan device\n");
+               return -1;
+       }
+
+       vkGetDeviceQueue(vkdev, vkqfam_idx, 0, &vkq);
        return 0;
 }
 
+static int create_swapchain(void)
+{
+       uint32_t num;
+       VkSwapchainCreateInfoKHR scinf;
+
+       vksc_extent.width = win_width;
+       vksc_extent.height = win_height;
+
+       memset(&scinf, 0, sizeof scinf);
+       scinf.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+       scinf.surface = vksurf;
+       scinf.minImageCount = 2;
+       scinf.imageFormat = vksurf_fmt[vksurf_selfmt].format;
+       scinf.imageColorSpace = vksurf_fmt[vksurf_selfmt].colorSpace;
+       scinf.imageExtent = vksc_extent;
+       scinf.imageArrayLayers = 1;
+       scinf.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+       scinf.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+       scinf.preTransform = vksurf_caps.currentTransform;
+       scinf.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+       scinf.presentMode = VK_PRESENT_MODE_FIFO_KHR;
+       scinf.clipped = VK_TRUE;
+
+       if(vkCreateSwapchainKHR(vkdev, &scinf, 0, &vksc) != 0) {
+               fprintf(stderr, "failed to create swapchain\n");
+               return -1;
+       }
+
+       vkGetSwapchainImagesKHR(vkdev, vksc, &num, 0);
+       vksc_img = malloc_nf(num * sizeof *vksc_img);
+       vkGetSwapchainImagesKHR(vkdev, vksc, &num, vksc_img);
+       vksc_numimg = num;
+
+       return 0;
+}
+
+
 static int eval_pdev_score(VkPhysicalDevice dev)
 {
        uint32_t i, num_fmt, num_qfam, num_ext;
@@ -274,11 +372,9 @@ static int eval_pdev_score(VkPhysicalDevice dev)
        qfam = malloc_nf(num_qfam * sizeof *qfam);
        vkGetPhysicalDeviceQueueFamilyProperties(dev, &num_qfam, qfam);
 
-       vkqfam_idx = -1;
        for(i=0; i<num_qfam; i++) {
                vkGetPhysicalDeviceSurfaceSupportKHR(dev, i, vksurf, &can_pres);
                if(qfam[i].queueCount && (qfam[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) && can_pres) {
-                       vkqfam_idx = i;
                        free(ext);
                        free(sfmt);
                        free(qfam);