static VkInstance vk;
static VkPhysicalDevice vkpdev;
-static int vkqfam_idx, vkqfam_maxq;
+static VkQueueFamilyProperties *qfam;
+static uint32_t num_qfam;
static VkDevice vkdev;
-static VkQueue vkq;
static VkSurfaceKHR vksurf;
static VkSurfaceCapabilitiesKHR vksurf_caps;
static int vksurf_numfmt, vksurf_selfmt;
return 0;
}
+int vk_find_qfamily(unsigned int flags)
+{
+ int i, famidx = -1;
+ VkBool32 can_pres;
+
+ if(!qfam) return -1; /* not initialized I guess... */
+
+ for(i=0; i<num_qfam; i++) {
+ vkGetPhysicalDeviceSurfaceSupportKHR(vkpdev, i, vksurf, &can_pres);
+
+ if((flags & VKQ_PRESENT) && !can_pres) {
+ continue;
+ }
+ if((flags & VKQ_GFX) && !(qfam[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)) {
+ continue;
+ }
+ if((flags & VKQ_COMPUTE) && !(qfam[i].queueFlags & VK_QUEUE_COMPUTE_BIT)) {
+ continue;
+ }
+
+ return i; /* found a suitabe queue family */
+ }
+
+ return -1;
+}
+
+VkQueue vk_getq_fam(int fam, int n)
+{
+ VkQueue q;
+
+ if(fam < 0) return 0;
+ if(n < 0 || n >= qfam[fam].queueCount) {
+ fprintf(stderr, "vk_getq_fam: invalid index %d, family %d has %d queues\n",
+ n, fam, qfam[fam].queueCount);
+ return 0;
+ }
+
+ vkGetDeviceQueue(vkdev, fam, n, &q);
+ return q;
+}
+
+VkQueue vk_getq(unsigned int flags)
+{
+ return vk_getq_fam(vk_find_qfamily(flags), 0);
+}
int vk_create_rpass(void)
{
int choose_phys_dev(void)
{
- uint32_t i, num_pdev, num_qfam, score, best_score, best_dev;
+ uint32_t i, num_pdev, score, best_score, best_dev;
VkPhysicalDevice *pdev;
VkPhysicalDeviceProperties pdevprop;
- VkQueueFamilyProperties *qfam;
VkBool32 can_pres;
vkEnumeratePhysicalDevices(vk, &num_pdev, 0);
}
vkpdev = pdev[best_dev];
+ if(qfam) free(qfam);
+
vkGetPhysicalDeviceQueueFamilyProperties(vkpdev, &num_qfam, 0);
qfam = malloc_nf(num_qfam * sizeof *qfam);
vkGetPhysicalDeviceQueueFamilyProperties(vkpdev, &num_qfam, qfam);
- vkqfam_idx = -1;
- for(i=0; i<num_qfam; i++) {
- 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;
- break;
- }
- }
-
- free(qfam);
free(pdev);
choose_pixfmt();
return 0;
}
qinf.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- qinf.queueFamilyIndex = vkqfam_idx;
+ qinf.queueFamilyIndex = vk_find_qfamily(VKQ_GFX | VKQ_PRESENT);
qinf.queueCount = 1;
qinf.pQueuePriorities = &prio;
fprintf(stderr, "failed to create vulkan device\n");
return -1;
}
-
- vkGetDeviceQueue(vkdev, vkqfam_idx, 0, &vkq);
return 0;
}
VKINIT_RAY = 0x100
};
+/* queue capability flags for vk_find_qfamily */
+enum {
+ VKQ_GFX = 1,
+ VKQ_COMPUTE = 2,
+ VKQ_PRESENT = 4
+};
+
void vk_init_xwin(Display *dpy, Window win);
int vk_init(unsigned int flags, unsigned int *usedflags);
int vk_reshape(int xsz, int ysz);
+int vk_find_qfamily(unsigned int flags);
+VkQueue vk_getq_fam(int fam, int n);
+VkQueue vk_getq(unsigned int flags);
+
int vk_create_rpass(void);
void vk_free_rpass(int rp);
void vk_rpass_colorbuf(int rp, int fmt, int n);