some device scoring heuristics
[vkray] / src / vk.c
index f3cb508..2a1db64 100644 (file)
--- a/src/vk.c
+++ b/src/vk.c
@@ -26,6 +26,7 @@ static int have_ext(VkExtensionProperties *ext, int next, const char *name);
 
 static Display *dpy;
 static Window win;
+static int initflags;
 
 static VkInstance vk;
 static VkPhysicalDevice vkpdev;
@@ -57,12 +58,22 @@ void vk_init_xwin(Display *d, Window w)
        win = w;
 }
 
-int vk_init(void)
+int vk_init(unsigned int flags, unsigned int *usedflags)
 {
+       initflags = flags;
        if(create_instance() == -1)     return -1;
        if(create_surface() == -1) return -1;
        if(choose_phys_dev() == -1) return -1;
        if(create_device() == -1) return -1;
+
+       if(initflags != flags) {
+               if(usedflags) {
+                       *usedflags = initflags;
+               } else {
+                       vk_cleanup();
+                       return -1;
+               }
+       }
        return 0;
 }
 
@@ -124,7 +135,10 @@ int vk_reshape(int xsz, int ysz)
        vksc_extent.width = xsz;
        vksc_extent.height = ysz;
 
-       return create_swapchain();
+       if(create_swapchain() == -1) return -1;
+
+       /* TODO create depth/stencil buffers as needed (initflags) */
+       return 0;
 }
 
 #define ARRSZ(arr)     (sizeof arr / sizeof *arr)
@@ -316,7 +330,7 @@ static int create_device(void)
        VkDeviceQueueCreateInfo qinf = {0};
        VkPhysicalDeviceFeatures feat = {0};
        VkDeviceCreateInfo devinf = {0};
-       const char *ext[ARRSZ(known_devext_list)];
+       const char *ext[ARRSZ(known_devext_list) + 16];
        int i, num_ext;
 
        vkEnumerateDeviceExtensionProperties(vkpdev, 0, &dev_ext_count, 0);
@@ -334,6 +348,16 @@ static int create_device(void)
                }
        }
 
+       if(initflags & VKINIT_RAY) {
+               if(have_ext(dev_ext, dev_ext_count, "VK_KHR_acceleration_structure") &&
+                               have_ext(dev_ext, dev_ext_count, "VK_KHR_ray_tracing_pipeline")) {
+                       ext[num_ext++] = "VK_KHR_acceleration_structure";
+                       ext[num_ext++] = "VK_KHR_ray_tracing_pipeline";
+               } else {
+                       initflags &= ~VKINIT_RAY;
+               }
+       }
+
        qinf.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
        qinf.queueFamilyIndex = vkqfam_idx;
        qinf.queueCount = 1;
@@ -422,6 +446,7 @@ static int create_swapchain(void)
 
 static int eval_pdev_score(VkPhysicalDevice dev)
 {
+       int score = 0;
        uint32_t i, num_fmt, num_qfam, num_ext;
        VkQueueFamilyProperties *qfam;
        VkExtensionProperties *ext;
@@ -462,17 +487,35 @@ static int eval_pdev_score(VkPhysicalDevice dev)
        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) {
-                       free(ext);
-                       free(sfmt);
-                       free(qfam);
-                       return 1;
+                       score = 1;
+               }
+       }
+
+       switch(prop.deviceType) {
+       case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
+               score++;
+               break;
+       case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
+               score += 2;
+               break;
+       case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
+               score += 4;
+               break;
+       default:
+               break;
+       }
+
+       if(initflags & VKINIT_RAY) {
+               if(have_ext(ext, num_ext, "VK_KHR_acceleration_structure") &&
+                               have_ext(ext, num_ext, "VK_KHR_ray_tracing_pipeline")) {
+                       score += 100;
                }
        }
 
        free(ext);
        free(sfmt);
        free(qfam);
-       return 0;
+       return score;
 }
 
 static int choose_pixfmt(void)