Vulkan中如何确定是否需要设置缓冲区TRANSFER_SOURCE使用标志?
Vulkan缓冲区创建时TRANSFER_DST_BIT标志的正确处理方案
首先对比你提出的两个方案的可行性:
- 方案1:根据集成/独立显卡类型判断是否添加标志的方式可靠性极低。当前硬件场景非常复杂,比如开启可调整大小BAR的独立显卡也会存在大段支持host访问的device-local内存,部分移动端集成显卡的device-local内存反而不支持host访问,靠设备类型硬编码判断很容易出现兼容性问题,不推荐使用。
- 方案2:所有场景默认添加
VK_BUFFER_USAGE_TRANSFER_DST_BIT是最简单也最通用的方案,几乎没有副作用。该标志仅声明缓冲区可以作为传输操作的目标,不会带来额外的运行时性能开销,也不会影响你后续直接映射host-visible内存写入数据的逻辑,90%以上的通用开发场景都可以直接采用该方案。
如果你的项目对缓冲区usage标志有严格要求,不想添加冗余标志,可以采用运行时预查询的方案,步骤如下:
- 先创建仅携带业务所需usage位的临时缓冲区(比如示例中的
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,不带传输相关标志) - 调用
vkGetBufferMemoryRequirements获取该缓冲区的内存要求 - 遍历设备支持的所有内存类型,检查是否存在同时满足以下条件的内存类型:
- 落在内存要求返回的
memoryTypeBits掩码范围内 - 同时携带
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT和VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT属性
- 落在内存要求返回的
- 如果存在符合要求的内存类型,直接分配内存绑定到该缓冲区即可,不需要走staging buffer传输流程
- 如果不存在符合要求的内存类型,销毁临时缓冲区,重新创建携带
VK_BUFFER_USAGE_TRANSFER_DST_BIT的正式缓冲区,再走staging buffer传输流程
补充说明:
- 预查询方案的额外开销极低,临时缓冲区的创建销毁不会占用实际显存,仅会消耗少量驱动侧的状态资源,对初始化性能几乎没有影响
- 如果你的项目仅针对特定硬件部署,也可以提前离线确认目标硬件的内存属性,硬编码是否需要添加传输标志,不需要做运行时判断
内容的提问来源于stack exchange,提问作者Zebrafish
相关产品推荐
相关产品推荐

