如何在Vulkan中进行缓冲区的子分配

5
在Vulkan中,内存管理的推荐方法是对缓冲区进行子分配,例如下面的图片所示。
我正在尝试实现“好”的方法。我已经有了一个系统,可以告诉我在内存分配中哪里可用,因此我可以绑定单个大缓冲区的子区域。 然而,我找不到执行此操作的机制,或者只是误解了发生的情况,因为绑定函数以缓冲区和偏移量作为输入。我无法看到如何指定绑定的大小,除非通过现有缓冲区。
所以我有几个问题:
  • 下面图像中的点状矩形只是绑定,还是额外的缓冲区?
  • 如果它们是绑定,如何告诉Vulkan(最好使用VMA)使用缓冲区的该子段?
  • 如果它们是额外的缓冲区,如何创建它们?
  • 如果两者都不是,那它们是什么?
我已经阅读了一些自定义分配器,但它们似乎遵循“坏”的方法,返回大型分配的偏移量以进行绑定,因此仍然有许多缓冲区但较低的分配计数。 需要明确的是,除了通过VMA的自定义分配器回调之外,我没有使用任何自定义分配器;上面提到的“系统”位于VMA调用之上。
任何指针都非常感激!

here


1
不太熟悉Vulkan,但我认为点状矩形只是“数据所在的位置”。 - user253751
1个回答

7
下图中的虚线矩形代表实际数据,不是附加缓冲区。
如果它们是绑定,我如何告诉Vulkan(最好使用VMA)使用缓冲区的该子段?
这取决于您将VkBuffer用作资源的特定性质。一般来说,每个将VkBuffer用作资源的函数都需要一个字节偏移量,表示从何处开始读取。许多此类函数还接受一个大小,配合偏移量表示可以通过该特定资源读取的全部数据量。
例如,vkCmdBindVertexBuffers接受一个VkBuffer数组,对于每个VkBuffer,还需要一个字节偏移量,表示该顶点缓冲区的起始点。描述符使用的缓冲区由VkDescriptorBufferInfo结构体表示,它需要一个VkBuffer、一个字节偏移量和一个大小。
顶点缓冲区(和索引缓冲区)绑定没有大小,但它们不需要一个。它们的有效大小由使用它们的渲染命令(以及通过它读取的索引数据)定义。如果使用100个32位索引进行渲染,则期望的是索引缓冲区的大小(减去起始偏移量)至少为400个字节。如果不是,则会导致未定义行为。

好的,这很有道理。因此,vkBindBufferMemory将覆盖整个缓冲区,我将在vkCmdBindVertexBuffersvkCmdCopyBuffer等中使用我的偏移量。 - mike
2
需要注意的是,NVIDIA的建议是针对NVIDIA的硬件。虽然没有理由拥有大量缓冲区,但他们假设特定的硬件将提供允许顶点和统一存储的内存。因此,您必须根据您可能需要分离这些内容的知识来调整建议,因为硬件不允许它。或者因为您可能需要流式传输顶点数据,直接从CPU内存读取可能比执行传输操作更快。 - Nicol Bolas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接