你可以在Vulkan中重复使用暂存缓冲区以供多个顶点缓冲使用吗?

huangapple go评论47阅读模式
英文:

Can i reuse staging buffer for multiple vertex buffer in Vulkan?

问题

你可以使用相同的临时缓冲区来更新所有顶点缓冲区,无需为每个顶点缓冲区创建单独的临时缓冲区。这与创建可主机访问的顶点缓冲区并使用内存映射进行更新相比,没有区别。

英文:

My application has multiple vertex buffers that contain dynamic data which is updated every frame. I'm not sure whether I can use the same staging buffer to update all the vertex buffers, or if I must create a staging buffer for each vertex buffer. If I do need to create a staging buffer for each vertex buffer, what is the difference compared to just creating host-visible vertex buffer and update them with memory mapping?

答案1

得分: 1

这取决于你对“创建临时缓冲区”的理解。如果你是指是否可以使用相同的VkBuffer对象来传输到多个内存目标区域,是的。只要你遵循内存传输的对齐要求,你可以使用单个缓冲区对象来传输到任意多个目标缓冲区(或图像)。

然而,如果你是指要在同一帧内多次重用相同的内存区域进行临时操作,那么如果你试图在同一帧内执行这样的操作,这是不明智的。请记住:临时的整个目的是通过使CPU不必等待GPU操作来传输数据来避免CPU停滞。如果你写入某个内存区域,然后从中传输到设备本地内存,然后再次写入它,CPU必须等待传输完成。

从同一缓冲区对象的不同区域进行操作是可以的。但在同一帧内从同一缓冲区对象的同一区域进行操作是不可以的。下一帧是可以的,因为传输可能在那时完成,所以你不会等待太长时间。

与只创建可主机访问的顶点缓冲区并使用内存映射更新它们相比,有什么区别?

你的实现不必允许用户使用附加到可主机访问内存的顶点缓冲区。大多数情况下会允许,但这是你需要检查的事情。对于流式传输顶点数据(特别是大批量传输),如果可主机访问内存也是设备本地内存,那么这比临时操作更可取。

或者换句话说,对于缓冲区数据的临时操作应该被视为如果你不能使用可主机访问/设备本地映射内存,或者如果你对该内存的访问模式不适合CPU写入(顺序访问是好的,其他访问方式效果较差)。

另外,FYI:只有在你打算释放内存时才会取消映射一块内存。没有理由不将可映射内存永久映射。

英文:

That depends on what you mean by "creating a staging buffer". If you're talking about whether you can use the same VkBuffer object for staging to multiple destination regions of memory, yes. So long as you follow the alignment requirements of the memory transfer, you can use a single buffer object to transfer to however many destination buffers (or images) you like.

However, if you're talking about reusing the same region of memory for multiple staging operations, that's a bad idea if you're trying to do it in the same frame. Remember: the whole point of staging is to not stall the CPU by making it wait on a GPU operation when transferring data. If you write to some region of memory, transfer from it to device-local memory, and then want to write to it again, the CPU must wait until the transfer is complete.

Using different regions from the same buffer object is fine. Using the same region from the same buffer object in the same frame is not fine. Next frame is OK because the transfer will probably be complete by then, so you won't wait for any real length of time.

> what is the difference compared to just creating host-visible vertex buffer and update them with memory mapping?

Your implementation does not have to allow its users to use vertex buffers attached to host-visible memory. Most often will, but it's something you have to check for. And for streaming vertex data (particularly in bulk), this would be preferable to staging if the host-visible memory is also device-local.

Or to put it another way, staging for buffer data should be thought of as what you have to do if you can't use host-visible/device-local mapped memory. Or if your access patterns for that memory are not good ones for CPU writing (sequential accesses are good, everything else is less good).

And FYI: only unmap a piece of memory if you're about to deallocate it. There is no reason not to keep mapable memory permanently mapped.

huangapple
  • 本文由 发表于 2023年6月6日 16:16:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76412671.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定