表面格式

我们添加了一个叫做chooseSwapSurfaceFormat的函数来选择合适的表面格式:

VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR> &availableFormats) {

}

每一个VkSurfaceFormatKHR条目包含了一个format和colorSpace成员变量。format成员变量用于指定颜色通道和存储类型。比如,如果fomat成员变量的值为VK_FORMAT_B8G8R8A8_UNORM表示我们以B,G,R和A的顺序,每个颜色通道用8位无符号整型数表示,总共每像素使用32位表示。colorSpace成员变量用来表示SRGB颜色空间是否被支持,是否使用VK_COLOR_SPACE_SRGB_NONLINEAR_KHR标志。需要注意VK_COLOR_SPACE_SRGB_NONLINEAR_KHR在之前的Vulkan规范中叫做VK_COLORSPACE_SRGB_NONLINEAR_KHR。

对于颜色空间,如果SRGB被支持,我们就使用SRGB,使用它可以得到更加准确的颜色表示。直接使用SRGB颜色有很大挑战,所以我们使用RGB作为颜色格式,这一格式可以通过VK_FORMAT_B8G8R8A8_UNORM宏指定。

Vulkan通过返回一个format成员变量值为VK_FORMAT_UNDEFINED的VkSurfaceFormatKHR表明表面没有自己的首选格式,这时,我们直接返回我们设定的格式:

if (availableFormats.size() == 1 && availableFormats[0].format == VK_FORMAT_UNDEFINED) {
    return {VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR};
}

如果Vulkan返回了一个格式列表,那么我们检查这个列表,看下我们想要设定的格式是否存在于这个列表中:

for (const auto& availableFormat : availableFormats) {
    if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
        return availableFormat;
    }
}

如果不能在列表中找到我们想要的格式,我们可以对列表中存在的格式进行打分,选择分数最高的那个作为我们使用的格式,当然,大多数情况下,直接使用列表中的第一个格式也是非常不错的选择:

VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR> &availableFormats) {
    if (availableFormats.size() == 1 && availableFormats[0].format == VK_FORMAT_UNDEFINED) {
        return {VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR};
    }

    for (const auto& availableFormat : availableFormats) {
        if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR){
            return availableFormat;
        }
    }

    return availableFormats[0];
}