Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGPU: BindGroups aren't being reused #6315

Closed
erikdubbelboer opened this issue Apr 29, 2024 · 3 comments · Fixed by #6349
Closed

WebGPU: BindGroups aren't being reused #6315

erikdubbelboer opened this issue Apr 29, 2024 · 3 comments · Fixed by #6349
Assignees
Labels
area: graphics Graphics related issue performance Relating to load times or frame rate

Comments

@erikdubbelboer
Copy link
Contributor

When using https://github.com/brendan-duncan/webgpu_inspector to look at what is happening, it's very obvious that BindGroups are constantly being created, up to a 20000 sometimes, and then being garbage collected. This then causes a lag spike.

Screenshot 2024-04-29 at 22 27 44

It would be more optimal to reuse BindGroups.

@willeastcott willeastcott added performance Relating to load times or frame rate area: graphics Graphics related issue labels Apr 29, 2024
@mvaligursky
Copy link
Contributor

BindGroup is actually re-used as much as possible. Only when it's content changes a new one is created. The reason a bind group is re-created:

  • when a different texture needs to be attached - this cannot be avoided, but is low frequency.
  • when a different buffer storing the uniforms is assigned to it. Most UniformBuffers are allocated from a large pools (1MB blocks currently), and a dynamic offset to those is used. Space in the buffers is allocated in order of rendering, so if the camera moves around, and the amount of meshes causes more than one 1MB buffers is used, some meshes switch between those buffers and a new BindGroup must be reallocated.

Plan to improve this:

  • Material Uniform buffers: Implement material level uniform buffer (WebGPU initially) #6157 - without this, a lot of uniforms are each frame being added to dynamic buffers, making it more likely to have to recreate the BindGroup. When material uniforms will be moved to per material persistent UBs, this allocation size will be a lot smaller.
  • I also tried to play with the size of these pools (1MB). If I make them larger, it's more likely an allocation would be in the same buffer. But with WebGPU rendering few frames ahead, and buffer needs to be uploaded to GPU each time we submit CBs (which is often only 1-2 times a frame), the total amount of used memory gets pretty high.

I wish I had better options at the moment, but as they say here gpuweb/gpuweb#915, It's pretty clear that bindgroup creation will be one of the biggest hotspots of the API.

Thanks for the issue. I'll close it for now, as I do not see a way to improve this, but will always keen an eye on it.

@mvaligursky
Copy link
Contributor

Actually, let me re-open this. I see a solution, I'll try it soon:

  • as mentioned, the problem is those bind groups that use uniform buffers allocated from those large dynamic buffers. When they switch to a different buffer, bind groups need to be re-created.
  • those are used for bing groups / uniform buffers of meshes. Scene / materials use persistent UBs / bind groups.
  • what I will do is to split the mesh bind group into two. One that contains textures, and one that contains only a single UB with uniforms for the mesh.
  • and then the bind group with textures will be static.
  • and for the bind group for the uniforms I will need to allocate a single bind group for each dynamic buffer. So a small number, all persistent. I'll then assign them with the offset, as currently.
  • so this should create zero additional bind groups, unless textures are swapped or similar.

@mvaligursky
Copy link
Contributor

So it seems the solution works. Slightly more complicated due to bind group keeping the size of the UB, but that's still pretty good. Initial implementation is here, applied to the clear-renderer only: #6341, but next I'll work on applying this to the mesh bind groups, which is bit more involved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: graphics Graphics related issue performance Relating to load times or frame rate
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants