Skip dynamic cluster resizing when GPU clustering is active#23439
Conversation
There was a problem hiding this comment.
Pull request overview
This PR prevents clustered-light grid “dynamic resizing” from running when GPU clustering is enabled, avoiding unnecessary cluster-grid shrinking based on the uniform-buffer index limit and reducing flicker/thrashing in heavy clustered-light scenes.
Changes:
- Add a guard to skip dynamic resizing logic when
global_cluster_settings.gpu_clusteringis active.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // If the dynamic resizing feature is on, use the last frame's cluster | ||
| // index count to determine the new number of clusters. | ||
| // Skip when GPU clustering is active | ||
| if config.dynamic_resizing() |
There was a problem hiding this comment.
The dynamic resizing guard is currently tied to gpu_clustering.is_none(), but the index-list limit it’s trying to avoid (ViewClusterBindings::MAX_INDICES) is only enforced when supports_storage_buffers is false (see crates/bevy_pbr/src/cluster/mod.rs around the n_indices() >= MAX_INDICES && !supports_storage_buffers check). On devices where compute shaders are unavailable (so gpu_clustering is None) but storage buffers are supported, this will still shrink clusters unnecessarily. Consider gating dynamic resizing on !global_cluster_settings.supports_storage_buffers (or otherwise using an “effective max indices” value that reflects whether storage buffers are in use).
| if config.dynamic_resizing() | |
| if config.dynamic_resizing() | |
| && !global_cluster_settings.supports_storage_buffers |
The UBO index limit (16384) doesn't apply when using storage buffers.
4c446c3 to
c5574e1
Compare
|
changed to : |
|
Going through my review queue. Is this still relevant/should I review it? |
|
Yes, still relevant: |
pcwalton
left a comment
There was a problem hiding this comment.
I’m a little unsure about whether we shouldn’t have any limit, because clusters do have a cost, but I guess this at least makes it consistent.
|
|
||
| // If the dynamic resizing feature is on, use the last frame's cluster | ||
| // index count to determine the new number of clusters. | ||
| // Skip when storage buffers are available |
There was a problem hiding this comment.
| // Skip when storage buffers are available | |
| // We don’t need to do this if storage buffers are available, because we have plenty of space in that case. |
Objective
Fixes #23438
The dynamic resizing code in
assign_objects_to_clusterscompares last frame's cluster index count againstViewClusterBindings::MAX_INDICES(16384), which is the UBO limit. When GPU clustering (#23036) is active, storagebuffers are used and can hold far more indices. The resizing shrinks the grid unnecessarily, causing thrashing and
flickering.
#22874 added dynamic resizing before GPU clustering existed, so the UBO limit was correct. When #23036 landed, the
runtime index path was updated to skip the limit when storage buffers are available (line 500 in
cluster/mod.rs), butthe dynamic resizing path was not.
Solution
Skip the dynamic resizing when
global_cluster_settings.gpu_clusteringis active.Testing