Search code examples
rusttextureswgpu-rs

WGPU: How to change max_bind_groups/device bind group limit?


I am trying to create multiple bind groups in wgpu (one for each texture I have to load) but it seems that my device can only support 4 bind groups: whenever I try to use more, I get the error "bind group layout count 5 exceeds device bind group limit 4".

From wgpu documentation it's not clear to me if this is an actual limit of the hardware device or if this is a soft limit and can be set in software. In https://docs.piston.rs/conrod/wgpu/struct.Limits.html, it mentions that the default of max_bind_groups is 4 which is the same as the max value in the error I get.

I think many applications use a lot more than 4 textures, and they all work on my device (even though likely not using wgpu?) so is it possible to change this limit and get rid of the error?

Thanks!


Solution

  • From wgpu documentation it's not clear to me if this is an actual limit of the hardware device or if this is a soft limit and can be set in software.

    wgpu is designed so that (when things are working properly) you don't get surprising errors when you run your program on new hardware. So, the Limits that you pass to request_device() are always enforced, regardless of what the hardware supports. But if you specify limits that are higher than the hardware supports, request_device() will fail.

    So, in general, you should specify Limits that are exactly as much as your application needs. If your application can be flexible, then consult Adapter::limits() to find out what is supported, then adjust that limit appropriately in your request.

    I think many applications use a lot more than 4 textures, and they all work on my device (even though likely not using wgpu?)

    There are lots of ways in which the max_bind_groups limit is not a limit on texturing:

    • Different draw calls can use different bind groups set with set_bind_group() — max_bind_groups is a limit on how many bind groups a pipeline uses at the same time, not on how many bind groups you can create.
    • Each bind group can have many bindings.
    • Each binding in a bind group can be an array of textures (if Features::TEXTURE_BINDING_ARRAY is supported).
    • A texture may used as an array texture (D2Array), which stores “layers” all of the same size but with different content.
    • A texture may be used as a texture atlas — this is not a graphics-API feature, but simply the idea of using different parts of a texture for different purposes.

    In a simple situation where you have mesh and texture assets, typically each mesh has an associated material (this is an abstraction you create in your code, not something in the graphics API) — the texture or textures it uses, and possibly other parameters controlling drawing. You create a bind group for each material, then when rendering, set_bind_group() for one material, draw all the objects that use that material, then set_bind_group() again, and so on. This uses only one bind group slot in the pipeline for the material, whichever material it is. You'd use at least another bind group for the camera — that's just 2 of the 4 slots you have available by default.

    Of course, other kinds of rendering may in fact need access to many textures at once. That's when you use the other techniques in the list above.