首页 > 解决方案 > Vulkan 中设备本地缓冲区的部分更新

问题描述

我正在将顶点数据生成到内存(从体素数据),设置暂存缓冲区(主机可见)(vkCreateBuffer),将顶点数据复制到暂存缓冲区,设置设备本地缓冲区(vkCreateBuffer)并将缓冲区从主机可见复制到设备本地 ( vkCmdCopyBuffer)。

据我了解,我可以拥有的缓冲区数量是有限的,因此我可能无法为每个模型创建一个缓冲区。

对于静态模型,这很好,只需将它们混合在一起并上传即可。但我想“定期”修改一些随机顶点。为此,我正在考虑对设备本地缓冲区进行差异更新。因此,在一个大缓冲区中,我只更新实际更改的数据。这可以做到吗?

如果我不从主机可见缓冲区渲染任何东西,那么它不会占用 GPU 上的任何资源?所以我可以保持主机可见的缓冲区,而不必重新创建和填充它们?

标签: vulkan

解决方案


是的,你应该能够做你想做的事。本质上,您发送的更新数据没有暂存缓冲区和复制命令(例如,类似于我们通常填充统一缓冲区的方式)。

在伪代码中:

  • 更新应用程序中的数据
  • 映射缓冲区
  • 复制更改的数据
  • 取消映射缓冲区
  • 同步

最后一部分如果是棘手的方面 - 您可以简单地制作缓冲区VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,这意味着它将在下次调用vkQueueSubmit. 所以基本上你会想要在渲染下一帧之前执行上述操作,请参阅规范。请注意,缓冲区需要是VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT.

是否将此“动态”数据作为超级缓冲区的一部分或完全独立的缓冲区取决于您。

这种方法用于由应用程序管理的粒子系统等事物。显然,直接复制到主机和 GPU 都可见的缓冲区(大概)比暂存/复制方法慢。

但是,如果您想通过暂存缓冲区发送一些数据并将命令复制到仅对主机可见的缓冲区,然后定期修改部分或全部数据(例如对于可变形地形),那么这可能会更棘手,这不是什么我已经调查过了。

编辑:刚刚看到以下可能相关的帖子? 存储动画顶点数据的最佳方式


推荐阅读