示例代码
VkFormat get_suitable_depth_format(VkPhysicalDevice physical_device, bool depth_only, const std::vector<VkFormat> &depth_format_priority_list)
{
VkFormat depth_format{VK_FORMAT_UNDEFINED};
for (auto &format : depth_format_priority_list)
{
if (depth_only && !is_depth_only_format(format))
{
continue;
}
VkFormatProperties properties;
vkGetPhysicalDeviceFormatProperties(physical_device, format, &properties);
// Format must support depth stencil attachment for optimal tiling
if (properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
{
depth_format = format;
break;
}
}
if (depth_format != VK_FORMAT_UNDEFINED)
{
LOGI("Depth format selected: {}", to_string(depth_format));
return depth_format;
}
throw std::runtime_error("No suitable depth format could be determined");
} 详细解释
这个函数用于选择合适的深度缓冲区格式,其中核心判断条件 Format must support depth stencil attachment for optimal tiling 涉及到 Vulkan 中的内存布局优化。让我详细解释:
Optimal Tiling
- 它是 Vulkan 中的一种内存布局方式
- 与 linear tiling 相对
- 由 GPU 厂商优化的内存布局,具体布局对应用程序不可见
- 通常性能更好,因为是为特定 GPU 架构优化的
Depth Stencil Attachment
- 深度模板附件,用于深度测试和模板测试
- 是渲染管线中重要的组成部分
- 用于确定像素的可见性和特殊效果
代码分析
if (properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)这行代码在检查:
- 该格式是否支持作为深度模板附件
- 是否支持以 optimal tiling 方式使用
- 两个条件必须同时满足
为什么需要这个检查
- 不是所有格式都支持 optimal tiling
- 不是所有格式都能用作深度模板附件
- 使用最优的内存布局可以获得更好的性能
这个检查确保选择的深度格式能够:
- 高效地存储在显存中(optimal tiling)
- 正确用作深度缓冲区(depth stencil attachment)
- 得到硬件的良好支持
如果没有找到满足条件的格式,函数会抛出异常,因为深度缓冲区对于 3D 渲染来说通常是必需的。