Here is what I do:
- I use vkEnumeratePhysicalDevices and get one VkPhysicalDevice
- I use vkGetPhysicalDeviceQueueFamilyProperties to query the queue families of the device to see which queues support graphic and/or transfer operations.
- I use vkGetPhysicalDeviceSurfaceSupportKHR to get present support as well for the queues.
- I loop trough the queue info I gathered to find the first suitable graphics queue, the first present queue and the first dedicated transfer queue(the first one that has the VK_QUEUE_TRANSFER_BIT flag, but not the VK_QUEUE_GRAPHICS_BIT flag)
- I use vkCreateDevice to create a VkDevice with an array of 3 VkDeviceQueueCreateInfo objects as the pQueueCreateInfos member in the VkDeviceCreateInfo structure
My first graphics and first present queue families are both at 0, while my transfer family is at index 1, here is how they look:
float queuePriorities[] = { 1.0f }; VkDeviceQueueCreateInfo devideQueueInfos[3]; devideQueueInfos[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; devideQueueInfos[0].pNext = null; devideQueueInfos[0].flags = 0; devideQueueInfos[0].queueFamilyIndex = device.FirstGraphicsQueueFamily(); //This is always 0 devideQueueInfos[0].queueCount = 1; devideQueueInfos[0].pQueuePriorities = queuePriorities; devideQueueInfos[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; devideQueueInfos[1].pNext = null; devideQueueInfos[1].flags = 0; devideQueueInfos[1].queueFamilyIndex = device.FirstPresentQueueFamily(); //This is always 0 devideQueueInfos[1].queueCount = 1; devideQueueInfos[1].pQueuePriorities = queuePriorities; devideQueueInfos[2].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; devideQueueInfos[2].pNext = null; devideQueueInfos[2].flags = 0; devideQueueInfos[2].queueFamilyIndex = device.FirstTransferQueueFamily(); //This is always 1 devideQueueInfos[2].queueCount = 1; devideQueueInfos[2].pQueuePriorities = queuePriorities; deviceInfo.queueCreateInfoCount = 3; deviceInfo.pQueueCreateInfos = devideQueueInfos; VkResult result = vkCreateDevice(deviceHandle, &deviceInfo, null, logicalDeviceHandle);
The problem is, vkCreateDevice returns VK_ERROR_INITIALIZATION_FAILED. If I set queueCreateInfoCount to 2 and ignore the transfer queue, the function returns success. But if I don't create the device with the transfer queue options, my vkGetDeviceQueue crashes later on when I try to use the transfer family.