dont hard code clustering limits on cpu side so they can be informed by Limits later (#19985)

# Objective

- prepare bevy_light for split
- make limits more dynamically configurable

## Solution

- use settings struct

## Testing

- 3d_scene, lighting
This commit is contained in:
atlv 2025-07-06 15:36:58 -04:00 committed by GitHub
parent baa88b98a3
commit 5b38989ac4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 20 additions and 10 deletions

View File

@ -20,8 +20,7 @@ use tracing::warn;
use super::{ use super::{
ClusterConfig, ClusterFarZMode, ClusteredDecal, Clusters, GlobalClusterSettings, ClusterConfig, ClusterFarZMode, ClusteredDecal, Clusters, GlobalClusterSettings,
GlobalVisibleClusterableObjects, ViewClusterBindings, VisibleClusterableObjects, GlobalVisibleClusterableObjects, VisibleClusterableObjects,
MAX_UNIFORM_BUFFER_CLUSTERABLE_OBJECTS,
}; };
use crate::{ use crate::{
prelude::EnvironmentMapLight, ExtractedPointLight, LightProbe, PointLight, SpotLight, prelude::EnvironmentMapLight, ExtractedPointLight, LightProbe, PointLight, SpotLight,
@ -263,7 +262,7 @@ pub(crate) fn assign_objects_to_clusters(
})); }));
} }
if clusterable_objects.len() > MAX_UNIFORM_BUFFER_CLUSTERABLE_OBJECTS if clusterable_objects.len() > global_cluster_settings.max_uniform_buffer_clusterable_objects
&& !global_cluster_settings.supports_storage_buffers && !global_cluster_settings.supports_storage_buffers
{ {
clusterable_objects.sort_by_cached_key(|clusterable_object| { clusterable_objects.sort_by_cached_key(|clusterable_object| {
@ -282,7 +281,9 @@ pub(crate) fn assign_objects_to_clusters(
let mut clusterable_objects_in_view_count = 0; let mut clusterable_objects_in_view_count = 0;
clusterable_objects.retain(|clusterable_object| { clusterable_objects.retain(|clusterable_object| {
// take one extra clusterable object to check if we should emit the warning // take one extra clusterable object to check if we should emit the warning
if clusterable_objects_in_view_count == MAX_UNIFORM_BUFFER_CLUSTERABLE_OBJECTS + 1 { if clusterable_objects_in_view_count
== global_cluster_settings.max_uniform_buffer_clusterable_objects + 1
{
false false
} else { } else {
let clusterable_object_sphere = clusterable_object.sphere(); let clusterable_object_sphere = clusterable_object.sphere();
@ -298,17 +299,19 @@ pub(crate) fn assign_objects_to_clusters(
} }
}); });
if clusterable_objects.len() > MAX_UNIFORM_BUFFER_CLUSTERABLE_OBJECTS if clusterable_objects.len()
> global_cluster_settings.max_uniform_buffer_clusterable_objects
&& !*max_clusterable_objects_warning_emitted && !*max_clusterable_objects_warning_emitted
{ {
warn!( warn!(
"MAX_UNIFORM_BUFFER_CLUSTERABLE_OBJECTS ({}) exceeded", "max_uniform_buffer_clusterable_objects ({}) exceeded",
MAX_UNIFORM_BUFFER_CLUSTERABLE_OBJECTS global_cluster_settings.max_uniform_buffer_clusterable_objects
); );
*max_clusterable_objects_warning_emitted = true; *max_clusterable_objects_warning_emitted = true;
} }
clusterable_objects.truncate(MAX_UNIFORM_BUFFER_CLUSTERABLE_OBJECTS); clusterable_objects
.truncate(global_cluster_settings.max_uniform_buffer_clusterable_objects);
} }
for ( for (
@ -448,14 +451,17 @@ pub(crate) fn assign_objects_to_clusters(
(xy_count.x + x_overlap) * (xy_count.y + y_overlap) * z_count as f32; (xy_count.x + x_overlap) * (xy_count.y + y_overlap) * z_count as f32;
} }
if cluster_index_estimate > ViewClusterBindings::MAX_INDICES as f32 { if cluster_index_estimate
> global_cluster_settings.view_cluster_bindings_max_indices as f32
{
// scale x and y cluster count to be able to fit all our indices // scale x and y cluster count to be able to fit all our indices
// we take the ratio of the actual indices over the index estimate. // we take the ratio of the actual indices over the index estimate.
// this is not guaranteed to be small enough due to overlapped tiles, but // this is not guaranteed to be small enough due to overlapped tiles, but
// the conservative estimate is more than sufficient to cover the // the conservative estimate is more than sufficient to cover the
// difference // difference
let index_ratio = ViewClusterBindings::MAX_INDICES as f32 / cluster_index_estimate; let index_ratio = global_cluster_settings.view_cluster_bindings_max_indices as f32
/ cluster_index_estimate;
let xy_ratio = index_ratio.sqrt(); let xy_ratio = index_ratio.sqrt();
requested_cluster_dimensions.x = requested_cluster_dimensions.x =

View File

@ -47,6 +47,8 @@ pub(crate) fn make_global_cluster_settings(world: &World) -> GlobalClusterSettin
GlobalClusterSettings { GlobalClusterSettings {
supports_storage_buffers, supports_storage_buffers,
clustered_decals_are_usable, clustered_decals_are_usable,
max_uniform_buffer_clusterable_objects: MAX_UNIFORM_BUFFER_CLUSTERABLE_OBJECTS,
view_cluster_bindings_max_indices: ViewClusterBindings::MAX_INDICES,
} }
} }

View File

@ -43,6 +43,8 @@ mod test;
pub struct GlobalClusterSettings { pub struct GlobalClusterSettings {
pub supports_storage_buffers: bool, pub supports_storage_buffers: bool,
pub clustered_decals_are_usable: bool, pub clustered_decals_are_usable: bool,
pub max_uniform_buffer_clusterable_objects: usize,
pub view_cluster_bindings_max_indices: usize,
} }
/// Configure the far z-plane mode used for the furthest depth slice for clustered forward /// Configure the far z-plane mode used for the furthest depth slice for clustered forward