Tedd Hansen
Tedd Hansen

Reputation: 12316

Partial update of device local buffer in Vulkan

I'm generating vertex data to memory (from voxel data), setting up a staging buffer (host visible) (vkCreateBuffer), copying vertex data into staging buffer, setting up a device local buffer (vkCreateBuffer) and copy the buffer from host visible to device local (vkCmdCopyBuffer).

From what I understand there is a limit to how many buffers I can have, so I probably can't create one buffer per model.

For static models this is fine, just mash them together and upload. But I want to modify a few random vertexes "regularly". For this I'm thinking of doing differential update of device local buffers. So in a big buffer I only update the data that actually changed. Can this be done?

If I don't render anything from host visible buffer then it will not take up any resources on GPU? So I could keep the host visible buffers and don't have to recreate and fill them?

Upvotes: 0

Views: 1068

Answers (1)

stridecolossus
stridecolossus

Reputation: 1561

Yes you should be able to do what you want. Essentially you are sending your updated data without a staging buffer and copy command (similar to how we generally populate uniform buffers for example).

In psuedo-code:

  • update the data in your application
  • map the buffer
  • copy the changed data
  • unmap the buffer
  • synchronize

The last part if the tricky aspect - you could simply make the buffer VK_MEMORY_PROPERTY_HOST_COHERENT_BIT which means it will be updated before the next call to vkQueueSubmit. So basically you would want to do the above before the next frame is rendered, see spec. Note that the buffer will need to be VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT.

Whether you make this 'dynamic' data part of your uber-buffer or a completely separate buffer is up to you.

This approach is used for things like particle systems that are managed by the application. Obviously copying directly to a buffer that is visible to both the host and the GPU is (presumably) slower than the staging/copy approach.

If however you want to send some data via a staging buffer and copy command to a buffer that is only visible to the host and then periodically modify some or all of that data (e.g. for deformable terrain) then that might be trickier, it's not something I have looked into.

EDIT: just seen the following post that might be related? Best way to store animated vertex data

Upvotes: 1

Related Questions