typedefstructVkQueueFamilyProperties{VkQueueFlags queueFlags;uint32_t queueCount;uint32_t timestampValidBits;VkExtent3D minImageTransferGranularity;}VkQueueFamilyProperties;
该结构体里的第一个字段是queueFlags,描述了队列的所有功能。这个字段由VkQueueFlagBits类型的标志位的组合组成,其含义如下。
VK_QUEUE_GRAPHICS_BIT 如果设置了,该族里的队列支持图形操作,例如绘制点、线和三角形。VK_QUEUE_COMPUTE_BIT如果设置了,该族里的队列支持计算操作,例如发送计算着色器。VK_QUEUE_TRANSFER_BIT 如果设置了,该族里的队列支持传送操作,例如复制缓冲区和图像内容。VK_QUEUE_SPARSE_BINDING_BIT 如果设置了,该族里的队列支持内存绑定操作,用于更新稀疏资源。
字段queueCount表示族里的队列数量,该值可能是1。如果设备支持具有相同基础功能的多个队列,该值也可能更高。
字段timestampValidBits表示当从队列里取时间戳时,多少位有效。如果这个值设置为0,那么队列不支持时间戳。如果不是0,那么会保证最少支持36位。如果设备的结构体VkPhysicalDeviceLimits里的字段timestampComputeAndGraphics是VK_TRUE,那么所有支持VK_QUEUE_GRAPHICS_BIT或者VK_QUEUE_COMPUTE_BIT的队列都能保证支持36位的时间戳。这种情况下,无须检查每一个队列。
最后,字段minImageTimestampGranularity指定了队列传输图像时支持多少单位(如果有的话)。
注意,有可能出现这种情形,设备报告多个明显拥有相同属性的队列族。一个族里的所有队列实质上都等同。不同族里的队列可能拥有不同的内部功能,而这些不能在Vulkan API里轻易表达。由于这个原因,具体实现可能选择将类似的队列作为不同族的成员。这对资源如何在队列间共享施加了更多限制,这可能允许具体实现接纳这些不同。
代码清单1.2展示了如何查询物理设备的内存属性和队列族属性。需要在创建逻辑设备(在下一节会讲到)之前获取队列族的属性。
代码清单1.2 查询物理设备的属性
uint32_t queueFamilyPropertyCount;std::vectorqueueFamilyProperties;VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties;//获取物理设备的内存属性vkGetPhysicalDeviceMemoryProperties( m_physicalDevices[deviceIndex],&physicalDeviceMemoryProperties);//首先查询物理设备支持的队列族的数量vkGetPhysicalDeviceQueueFamilyProperties( m_physicalDevices[0],&queueFamilyPropertyCount,nullptr);//为队列属性结构体分配足够的空间queueFamilyProperties.resize(queueFamilyPropertyCount);//现在查询所有队列族的实际属性vkGetPhysicalDeviceQueueFamilyProperties( m_physicalDevices[0],&queueFamilyPropertyCount,queueFamilyProperties.data());
1.2.5 创建逻辑设备
在枚举完系统里的所有物理设备之后,应用程序应该选择一个设备,并且针对该设备创建逻辑设备。逻辑设备代表处于初始化状态的设备。在创建逻辑设备时,可以选择可选特性,开启需要的扩展,等等。创建逻辑设备需要调用vkCreateDevice(),其原型如下。
VkResult vkCreateDevice (VkPhysicalDevice physicalDevice,constVkDeviceCreateInfo* pCreateInfo,constVkAllocationCallbacks* pAllocator,VkDevice* pDevice);
把与逻辑设备相对应的物理设备传给physicalDevice,把关于新的逻辑对象的信息传给结构体VkDeviceCreateInfo的实例pCreateInfo。VkDeviceCreateInfo的定义如下。
typedefstructVkDeviceCreateInfo{VkStructureType sType;constvoid* pNext;VkDeviceCreateFlags flags;uint32_t queueCreateInfoCount;constVkDeviceQueueCreateInfo* pQueueCreateInfos;uint32_t enabledLayerCount;constchar*const* ppEnabledLayerNames;uint32_t enabledExtensionCount;constchar*const* ppEnabledExtensionNames;constVkPhysicalDeviceFeatures* pEnabledFeatures;}VkDeviceCreateInfo;
字段sType应该设置为VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO。通常,除非你希望使用扩展,否则pNext应该设置为nullptr。Vulkan当前版本没有为字段flags定义标志位,所以将这个字段设置为0。
接下来是队列创建信息。