diff --git a/crates/bevy_light/src/cluster/assign.rs b/crates/bevy_light/src/cluster/assign.rs index 7ddc9f32b218e..8be51681ac313 100644 --- a/crates/bevy_light/src/cluster/assign.rs +++ b/crates/bevy_light/src/cluster/assign.rs @@ -176,7 +176,7 @@ pub(crate) fn assign_objects_to_clusters( clusterable_objects.clear(); - // Collect clusterable objects if GPU clustering is enabled. + // Collect clusterable objects if GPU clustering is disabled. if global_cluster_settings.gpu_clustering.is_none() { // collect just the relevant query data into a persisted vec to avoid reallocating each frame clusterable_objects.extend(point_lights_query.iter().filter_map( diff --git a/crates/bevy_pbr/src/cluster/mod.rs b/crates/bevy_pbr/src/cluster/mod.rs index 959089758b07c..4294eca8cfcb8 100644 --- a/crates/bevy_pbr/src/cluster/mod.rs +++ b/crates/bevy_pbr/src/cluster/mod.rs @@ -13,7 +13,7 @@ use bevy_math::{uvec4, UVec3, UVec4, Vec4}; use bevy_render::{ render_resource::{ BindingResource, BufferBindingType, BufferUsages, DownlevelFlags, RawBufferVec, ShaderSize, - ShaderType, StorageBuffer, UniformBuffer, UninitBufferVec, + ShaderType, StorageBuffer, UniformBuffer, }, renderer::{RenderAdapter, RenderDevice, RenderQueue}, sync_world::{MainEntity, RenderEntity}, @@ -71,9 +71,12 @@ pub(crate) fn make_global_cluster_settings(world: &World) -> GlobalClusterSettin // We need to support compute shaders to use GPU clustering. To deal with // the `WGPU_SETTINGS_PRIO="webgl2"` environment setting, we check the // `RenderDevice` limits in addition to the `RenderAdapter`. + // // Some android devices report the capabilities and limits wrong, so we can't rely on them. // See for Android issues - let gpu_clustering_supported = !cfg!(target_os = "android") + // + // GPU clustering doesn't work properly on iOS simulator. See https://github.com/bevyengine/bevy/issues/23428 + let gpu_clustering_supported = !(cfg!(target_os = "android") || cfg!(target_abi = "sim")) && adapter .get_downlevel_capabilities() .flags @@ -237,7 +240,7 @@ enum ViewClusterBuffers { cluster_offsets_and_counts: UniformBuffer, }, Storage { - clusterable_object_index_lists: UninitBufferVec, + clusterable_object_index_lists: StorageBuffer, cluster_offsets_and_counts: StorageBuffer, }, } @@ -596,7 +599,7 @@ impl ViewClusterBindings { cluster_offsets_and_counts, .. } => { - clusterable_object_index_lists.clear(); + clusterable_object_index_lists.get_mut().data.clear(); cluster_offsets_and_counts.get_mut().data.clear(); } } @@ -657,11 +660,11 @@ impl ViewClusterBindings { clusterable_object_index_lists.get_mut().data[array_index][component] |= index << (8 * sub_index); } - ViewClusterBuffers::Storage { .. } => { - error!( - "Shouldn't be pushing a clusterable object index from CPU when GPU clustering \ - is in use" - ); + ViewClusterBuffers::Storage { + clusterable_object_index_lists, + .. + } => { + clusterable_object_index_lists.get_mut().data.push(index); } } @@ -714,7 +717,10 @@ impl ViewClusterBindings { clusterable_object_index_lists, .. } => { - clusterable_object_index_lists.add_multiple(elements); + clusterable_object_index_lists + .get_mut() + .data + .extend(iter::repeat_n(0, elements)); self.n_indices += elements; } } @@ -733,7 +739,7 @@ impl ViewClusterBindings { clusterable_object_index_lists, cluster_offsets_and_counts, } => { - clusterable_object_index_lists.write_buffer(render_device); + clusterable_object_index_lists.write_buffer(render_device, render_queue); cluster_offsets_and_counts.write_buffer(render_device, render_queue); } } @@ -801,9 +807,7 @@ impl ViewClusterBuffers { fn storage() -> Self { ViewClusterBuffers::Storage { - clusterable_object_index_lists: UninitBufferVec::new( - BufferUsages::STORAGE | BufferUsages::COPY_DST, - ), + clusterable_object_index_lists: StorageBuffer::default(), cluster_offsets_and_counts: StorageBuffer::default(), } } diff --git a/crates/bevy_pbr/src/lib.rs b/crates/bevy_pbr/src/lib.rs index 40ef01c3a2f93..498c47cb352e0 100644 --- a/crates/bevy_pbr/src/lib.rs +++ b/crates/bevy_pbr/src/lib.rs @@ -29,6 +29,7 @@ mod cluster; pub mod contact_shadows; #[cfg(feature = "bevy_gltf")] mod gltf; +use bevy_light::cluster::GlobalClusterSettings; use bevy_render::sync_component::SyncComponent; pub use contact_shadows::{ ContactShadows, ContactShadowsBuffer, ContactShadowsPlugin, ContactShadowsUniform, @@ -319,7 +320,13 @@ impl Plugin for PbrPlugin { prepare_lights .in_set(RenderSystems::CreateViews) .after(sort_cameras), - prepare_clusters_for_cpu_clustering.in_set(RenderSystems::PrepareResources), + prepare_clusters_for_cpu_clustering + .in_set(RenderSystems::PrepareResources) + .run_if( + |global_cluster_settings: Res| -> bool { + global_cluster_settings.gpu_clustering.is_none() + }, + ), ), ) .init_gpu_resource::() diff --git a/examples/mobile/src/lib.rs b/examples/mobile/src/lib.rs index 68d01587dc065..5efbc8a03ede9 100644 --- a/examples/mobile/src/lib.rs +++ b/examples/mobile/src/lib.rs @@ -97,7 +97,11 @@ fn setup_scene( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, + device: Res, ) { + bevy::log::info!("Configured wgpu adapter Limits: {:#?}", device.limits()); + bevy::log::info!("Configured wgpu adapter Features: {:#?}", device.features()); + // plane commands.spawn(( Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),