mechanism to request queues before creating the device (vk_init_queue)
authorJohn Tsiombikas <nuclear@member.fsf.org>
Fri, 19 Aug 2022 08:43:39 +0000 (11:43 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Fri, 19 Aug 2022 08:43:39 +0000 (11:43 +0300)
src/vk.c
src/vk.h

index 82b1ccf..6887460 100644 (file)
--- a/src/vk.c
+++ b/src/vk.c
@@ -62,6 +62,12 @@ static int have_ext(VkExtensionProperties *ext, int next, const char *name);
 static Display *dpy;
 static Window win;
 static int initflags;
+#define MAX_INIT_QUEUE 32
+static struct {
+       unsigned int flags;
+       int count;
+} initq[MAX_INIT_QUEUE];
+static int num_initq;
 
 static VkInstance vk;
 static VkPhysicalDevice vkpdev;
@@ -93,8 +99,23 @@ void vk_init_xwin(Display *d, Window w)
        win = w;
 }
 
+void vk_init_queue(unsigned int qflags, int count)
+{
+       if(num_initq >= MAX_INIT_QUEUE) {
+               fprintf(stderr, "vk_init_queue: too many queues\n");
+               return;
+       }
+       initq[num_initq].flags = qflags;
+       initq[num_initq].count = count;
+       num_initq++;
+}
+
 int vk_init(unsigned int flags, unsigned int *usedflags)
 {
+       if(!num_initq) {
+               vk_init_queue(VKQ_GFX | VKQ_PRESENT, 1);
+       }
+
        initflags = flags;
        if(create_instance() == -1)     return -1;
        if(create_surface() == -1) return -1;
@@ -648,12 +669,12 @@ int choose_phys_dev(void)
 
 static int create_device(void)
 {
-       float prio = 1.0f;
-       VkDeviceQueueCreateInfo qinf = {0};
+       float *prio;
+       VkDeviceQueueCreateInfo qinf[MAX_INIT_QUEUE] = {0};
        VkPhysicalDeviceFeatures feat = {0};
        VkDeviceCreateInfo devinf = {0};
        const char *ext[ARRSZ(known_devext_list) + 16];
-       int i, num_ext;
+       int i, j, num_ext, qfam, totalq;
 
        vkEnumerateDeviceExtensionProperties(vkpdev, 0, &dev_ext_count, 0);
        dev_ext = malloc_nf(dev_ext_count * sizeof *dev_ext);
@@ -680,14 +701,34 @@ static int create_device(void)
                }
        }
 
-       qinf.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
-       qinf.queueFamilyIndex = vk_find_qfamily(VKQ_GFX | VKQ_PRESENT);
-       qinf.queueCount = 1;
-       qinf.pQueuePriorities = &prio;
+       totalq = 0;
+       for(i=0; i<num_initq; i++) {
+               totalq += initq[i].count;
+       }
+       if(totalq > 1024) {
+               fprintf(stderr, "create_device: arbitrary limit of total queues exceeded (%d)\n", totalq);
+               return -1;
+       }
+       prio = alloca(totalq * sizeof *prio);
+
+       for(i=0; i<num_initq; i++) {
+               if((qfam = vk_find_qfamily(initq[i].flags)) == -1) {
+                       fprintf(stderr, "create_device: failed to find queue family (flags: 0x%2x)\n",
+                                       initq[i].flags);
+                       return -1;
+               }
+               qinf[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+               qinf[i].queueFamilyIndex = qfam;
+               qinf[i].queueCount = initq[i].count;
+               qinf[i].pQueuePriorities = prio;
+               for(j=0; j<initq[i].count; i++) {
+                       *prio++ = 1.0f; /* all queue priorities 1 */
+               }
+       }
 
        devinf.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
-       devinf.pQueueCreateInfos = &qinf;
-       devinf.queueCreateInfoCount = 1;
+       devinf.pQueueCreateInfos = qinf;
+       devinf.queueCreateInfoCount = num_initq;
        devinf.pEnabledFeatures = &feat;
        devinf.enabledExtensionCount = num_ext;
        devinf.ppEnabledExtensionNames = ext;
index 319fa99..3f765ac 100644 (file)
--- a/src/vk.h
+++ b/src/vk.h
@@ -10,14 +10,16 @@ enum {
        VKINIT_RAY              = 0x100
 };
 
-/* queue capability flags for vk_find_qfamily */
+/* queue capability flags for vk_find_qfamily and vk_init_queue */
 enum {
        VKQ_GFX                 = 1,
        VKQ_COMPUTE             = 2,
-       VKQ_PRESENT             = 4
+       VKQ_PRESENT             = 4,
+       VKQ_XFER                = 8
 };
 
 void vk_init_xwin(Display *dpy, Window win);
+void vk_init_queue(unsigned int qflags, int count);
 
 int vk_init(unsigned int flags, unsigned int *usedflags);
 void vk_cleanup(void);