具有可变实例计数的 Vulkan vkCmdDraw

Vulkan vkCmdDraw with variable instance count

当我定义命令缓冲区时,我需要预先指定顶点数和实例数。是不是说如果我想动态更新实例数,就需要重新编译整个command buffer?只是改变这个单一的数字似乎是一个小而无害的调整。应该有更有效的方法来做到这一点。

vkCmdDrawIndirect 允许从 VkBuffer 获取参数的分派操作。这允许您更改该缓冲区对象中的存储,这将反映在 CB 使用的间接绘制调用中...

假设您进行了适当的同步,无论如何。

毕竟,当可能正在使用该存储的命令正在执行时,您不能修改与 VkBuffer 关联的存储中的值。因此,如果您想更改该内存中的数据,则需要在从缓冲区读取的最终间接绘制命令与写入数据的任何进程之间进行某种同步。如果它是 GPU 上的进程(例如,映射内存的副本),那么它就相当容易了。

但是,事件设置不是您可以在渲染过程中执行的操作,因此设置必须等到整个渲染过程结束。

处理此问题的最有效方法是对绘制间接缓冲区进行双重缓冲。在一帧上,您写入一块内存并执行从中读取的命令。在下一帧中,当 GPU 正在执行写入前一个内存的命令时,您将写入另一块内存。在第三帧,你回到第一块内存(使用你设置的同步来确保GPU完成)。

当然,如果您坚持使用静态命令缓冲区,这意味着命令缓冲区本身 也必须是双缓冲的。一个CB从一个缓冲区读取间接数据,另一个CB从另一个缓冲区读取。