查询呈现支持
尽管,具体的Vulkan实现可能对窗口系统进行了支持,但这并不意味着所有平台的Vulkan实现都支持同样的特性。所以,我们需要扩展isDeviceSuitable函数来确保设备可以在我们创建的表面上显示图像。
实际上,支持绘制指令的队列族和支持表现的队列族并不一定重叠。所以,我们需要修改QueueFamilyIndices结构体,添加成员变量存储表现队列族的索引:
struct QueueFamilyIndices {
int graphicsFamily = -1;
int presentFamily = -1;
bool isComplete() {
return graphicsFamily >= 0 && presentFamily >= 0;
}
};
接着,我们还需要修改findQueueFamilies函数,查找带有呈现图像到窗口表面能力的队列族。我们可以在检查队列族是否具有VK_QUEUE_GRAPHICS_BIT的同级循环调用vkGetPhysicalDeviceSurfaceSupportKHR函数来检查物理设备是否具有呈现能力:
VkBool32 presentSupport = false;
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
然后,根据队列族中的队列数量和是否支持表现确定使用的表现队列族的索引:
if (queueFamily.queueCount > 0 && presentSupport) {
indices.presentFamily = i;
}
读者可能已经注意到,按照上面的方法最后选择使用的绘制指令队列族和呈现队列族很有可能是同一个队列族。但为了统一操作,即使两者是同一个队列族,我们也按照它们是不同的队列族来对待。实际上,读者可以显式地指定绘制和呈现队列族是同一个的物理设备来提高性能表现。