如何调整设备本地 VkBuffer 的大小?

How to resize a device local VkBuffer?

假设主机可见并且设备本地 VkDeviceMemory 绑定到 VkBuffer,充当顶点缓冲区。内存的双向访问属性使“操纵”初始关联顶点集成为可能 post - 通过简单地对内存进行 memcpy 初始化 - 这很好。我喜欢。

但我真的很困惑实际调整顶点缓冲区大小的“流程”是什么?让我们将它应用于一大块体素地形 - 给出一个上下文:您破坏了一些地形,导致顶点比以前少。那么呢?

是否必须重新创建具有新大小的 VkBuffer?那会搞砸渲染过程中的绑定,不是吗?那么你必须重新记录整个命令缓冲区吗?你还能使用相同的 VkDeviceMemory 吗?你必须重新分配内存吗?这是... idk。我只需要更广泛概念的一些方向。

Do you have to recreate the VkBuffer with a new size?

Vulkan 将资源访问与底层内存分配分开。

就性能而言,重新分配内存的成本很高,但创建新的 buffer/buffer 视图实际上只是元数据,预计成本相对较低。对于动态资源,通常的方法是 over-allocate 内存为“大尺寸”,然后仅引用当前内容主动使用的内存范围。

如果您必须创建一个新版本的缓冲区 and/or 分配,您需要让旧版本保持“活动状态”,直到引用它的任何未决命令完成。

That would screw up the binding in the render pass, wouldn't it?

如果您要提交现有的 pre-recorded 命令缓冲区,那么是的,绑定是记录的命令缓冲区的一部分,需要重新生成。

如果您担心当前正在记录的命令缓冲区中的现有绑定,那么如果您提交命令,则需要确保已记录的保持有效。为新缓冲区分配一个新的 buffer/memory 范围,但不要 reuse/deallocate 先前排队的命令引用的缓冲区内存。等待它们先完成,然后释放现有缓冲区。

Do you have to re-record the whole command buffer then?

Pre-recorded 引用旧绑定的缓冲区需要 re-recoded.

您不需要re-record开始当前命令记录,只需确保“旧”缓冲区和内存保持活动状态,直到队列提交完成。