无法创建具有传输队列支持的 VkDevice

Unable to create VkDevice with transfer queue support

这是我的做法:

  1. 我使用 vkEnumeratePhysicalDevices 并得到一个 VkPhysicalDevice
  2. 我使用 vkGetPhysicalDeviceQueueFamilyProperties 查询设备的队列系列,以查看哪些队列支持图形 and/or 传输操作。
  3. 我使用 vkGetPhysicalDeviceSurfaceSupportKHR 来获得对队列的当前支持。
  4. 我循环遍历收集到的队列信息以找到第一个合适的图形队列、第一个当前队列和第一个专用传输队列(第一个具有 VK_QUEUE_TRANSFER_BIT 标志,但没有 VK_QUEUE_GRAPHICS_BIT 标志)
  5. 我使用 vkCreateDevice 创建一个 VkDevice,其中包含 3 个 VkDeviceQueueCreateInfo 对象的数组作为 VkDeviceCreateInfo 结构中的 pQueueCreateInfos 成员
  6. 我的第一个图形和第一个当前队列系列都在 0,而我的传输系列在索引 1,这是它们的样子:

    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);
    

问题是,vkCreateDevice returns VK_ERROR_INITIALIZATION_FAILED。如果我将 queueCreateInfoCount 设置为 2 并忽略传输队列,函数 returns 成功。但是,如果我不使用传输队列选项创建设备,我的 vkGetDeviceQueue 稍后会在我尝试使用传输系列时崩溃。

devideQueueInfos[1].queueFamilyIndex = device.FirstPresentQueueFamily(); //This is always 0

devideQueueInfos[0].queueFamilyIndex = device.FirstGraphicsQueueFamily(); //This is always 0

不允许将同一个队列索引多次传递给 vkCreateDevice

具有当前支持的队列将始终具有图形支持。同样,具有图形支持的 Queue 始终具有计算和传输支持。

您需要做的是确定是否存在 传输支持的队列,并仅在这种情况下将其指定为您的传输队列。否则,您还需要使用图形队列进行传输。你仍然可以有一个专用的传输队列,只是它也是一个图形队列,因为该设备没有公开任何专门的传输功能,或者出于某种原因不需要它与图形功能。

所以如果你想要一个传输队列和一个图形队列并且设备没有专用传输队列,你需要在创建结构中请求两个个图形队列,没有一个图形队列两次。通过演示,我不明白你为什么要分开它们。没有 'presentation' 队列类型。它始终是一个具有表示支持的图形队列,因此根本没有必要在创建结构中引用它。

编辑:正如 Nicol 指出的那样,不能保证会有 一个专用的传输队列,甚至除了一个图形队列之外的任何东西。因此,请始终确保您在设置代码中涵盖了所有可能的基础。