Disable clustered decals on Metal. (#17554)
Unfortunately, Apple platforms don't have enough texture bindings to properly support clustered decals. This should be fixed once `wgpu` has first-class bindless texture support. In the meantime, we disable them. Closes #17553. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
parent
dda97880c4
commit
7aeb1c51a6
@ -21,7 +21,8 @@ use bevy_utils::prelude::default;
|
|||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
binding_arrays_are_usable, decal::clustered::ClusteredDecal, prelude::EnvironmentMapLight,
|
decal::{self, clustered::ClusteredDecal},
|
||||||
|
prelude::EnvironmentMapLight,
|
||||||
ClusterConfig, ClusterFarZMode, Clusters, ExtractedPointLight, GlobalVisibleClusterableObjects,
|
ClusterConfig, ClusterFarZMode, Clusters, ExtractedPointLight, GlobalVisibleClusterableObjects,
|
||||||
LightProbe, PointLight, SpotLight, ViewClusterBindings, VisibleClusterableObjects,
|
LightProbe, PointLight, SpotLight, ViewClusterBindings, VisibleClusterableObjects,
|
||||||
VolumetricLight, CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT,
|
VolumetricLight, CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT,
|
||||||
@ -257,7 +258,8 @@ pub(crate) fn assign_objects_to_clusters(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if binding_arrays_are_usable(&render_device, &render_adapter) {
|
// Add decals if the current platform supports them.
|
||||||
|
if decal::clustered::clustered_decals_are_usable(&render_device, &render_adapter) {
|
||||||
clusterable_objects.extend(decals_query.iter().map(|(entity, transform)| {
|
clusterable_objects.extend(decals_query.iter().map(|(entity, transform)| {
|
||||||
ClusterableObjectAssignmentData {
|
ClusterableObjectAssignmentData {
|
||||||
entity,
|
entity,
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
//!
|
//!
|
||||||
//! Clustered decals are the highest-quality types of decals that Bevy supports,
|
//! Clustered decals are the highest-quality types of decals that Bevy supports,
|
||||||
//! but they require bindless textures. This means that they presently can't be
|
//! but they require bindless textures. This means that they presently can't be
|
||||||
//! used on WebGL 2 or WebGPU. Bevy's clustered decals can be used with forward
|
//! used on WebGL 2, WebGPU, macOS, or iOS. Bevy's clustered decals can be used
|
||||||
//! or deferred rendering and don't require a prepass.
|
//! with forward or deferred rendering and don't require a prepass.
|
||||||
//!
|
//!
|
||||||
//! On their own, clustered decals only project the base color of a texture. You
|
//! On their own, clustered decals only project the base color of a texture. You
|
||||||
//! can, however, use the built-in *tag* field to customize the appearance of a
|
//! can, however, use the built-in *tag* field to customize the appearance of a
|
||||||
@ -77,8 +77,8 @@ pub struct ClusteredDecalPlugin;
|
|||||||
///
|
///
|
||||||
/// Clustered decals are the highest-quality types of decals that Bevy supports,
|
/// Clustered decals are the highest-quality types of decals that Bevy supports,
|
||||||
/// but they require bindless textures. This means that they presently can't be
|
/// but they require bindless textures. This means that they presently can't be
|
||||||
/// used on WebGL 2 or WebGPU. Bevy's clustered decals can be used with forward
|
/// used on WebGL 2, WebGPU, macOS, or iOS. Bevy's clustered decals can be used
|
||||||
/// or deferred rendering and don't require a prepass.
|
/// with forward or deferred rendering and don't require a prepass.
|
||||||
#[derive(Component, Debug, Clone, Reflect, ExtractComponent)]
|
#[derive(Component, Debug, Clone, Reflect, ExtractComponent)]
|
||||||
#[reflect(Component, Debug)]
|
#[reflect(Component, Debug)]
|
||||||
#[require(Transform, Visibility, VisibilityClass)]
|
#[require(Transform, Visibility, VisibilityClass)]
|
||||||
@ -263,7 +263,7 @@ pub(crate) fn get_bind_group_layout_entries(
|
|||||||
) -> Option<[BindGroupLayoutEntryBuilder; 3]> {
|
) -> Option<[BindGroupLayoutEntryBuilder; 3]> {
|
||||||
// If binding arrays aren't supported on the current platform, we have no
|
// If binding arrays aren't supported on the current platform, we have no
|
||||||
// bind group layout entries.
|
// bind group layout entries.
|
||||||
if !binding_arrays_are_usable(render_device, render_adapter) {
|
if !clustered_decals_are_usable(render_device, render_adapter) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,7 +290,7 @@ impl<'a> RenderViewClusteredDecalBindGroupEntries<'a> {
|
|||||||
render_adapter: &RenderAdapter,
|
render_adapter: &RenderAdapter,
|
||||||
) -> Option<RenderViewClusteredDecalBindGroupEntries<'a>> {
|
) -> Option<RenderViewClusteredDecalBindGroupEntries<'a>> {
|
||||||
// Skip the entries if decals are unsupported on the current platform.
|
// Skip the entries if decals are unsupported on the current platform.
|
||||||
if !binding_arrays_are_usable(render_device, render_adapter) {
|
if !clustered_decals_are_usable(render_device, render_adapter) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,3 +367,19 @@ fn upload_decals(
|
|||||||
|
|
||||||
decals_buffer.write_buffer(&render_device, &render_queue);
|
decals_buffer.write_buffer(&render_device, &render_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if clustered decals are usable on the current platform or false
|
||||||
|
/// otherwise.
|
||||||
|
///
|
||||||
|
/// Clustered decals are currently disabled on macOS and iOS due to insufficient
|
||||||
|
/// texture bindings and limited bindless support in `wgpu`.
|
||||||
|
pub fn clustered_decals_are_usable(
|
||||||
|
render_device: &RenderDevice,
|
||||||
|
render_adapter: &RenderAdapter,
|
||||||
|
) -> bool {
|
||||||
|
// Disable binding arrays on Metal. There aren't enough texture bindings available.
|
||||||
|
// See issue #17553.
|
||||||
|
// Re-enable this when `wgpu` has first-class bindless.
|
||||||
|
binding_arrays_are_usable(render_device, render_adapter)
|
||||||
|
&& cfg!(not(any(target_os = "macos", target_os = "ios")))
|
||||||
|
}
|
||||||
|
@ -1528,6 +1528,9 @@ pub struct MeshPipeline {
|
|||||||
/// This affects whether reflection probes can be used.
|
/// This affects whether reflection probes can be used.
|
||||||
pub binding_arrays_are_usable: bool,
|
pub binding_arrays_are_usable: bool,
|
||||||
|
|
||||||
|
/// Whether clustered decals are usable on the current render device.
|
||||||
|
pub clustered_decals_are_usable: bool,
|
||||||
|
|
||||||
/// Whether skins will use uniform buffers on account of storage buffers
|
/// Whether skins will use uniform buffers on account of storage buffers
|
||||||
/// being unavailable on this platform.
|
/// being unavailable on this platform.
|
||||||
pub skins_use_uniform_buffers: bool,
|
pub skins_use_uniform_buffers: bool,
|
||||||
@ -1589,6 +1592,10 @@ impl FromWorld for MeshPipeline {
|
|||||||
mesh_layouts: MeshLayouts::new(&render_device, &render_adapter),
|
mesh_layouts: MeshLayouts::new(&render_device, &render_adapter),
|
||||||
per_object_buffer_batch_size: GpuArrayBuffer::<MeshUniform>::batch_size(&render_device),
|
per_object_buffer_batch_size: GpuArrayBuffer::<MeshUniform>::batch_size(&render_device),
|
||||||
binding_arrays_are_usable: binding_arrays_are_usable(&render_device, &render_adapter),
|
binding_arrays_are_usable: binding_arrays_are_usable(&render_device, &render_adapter),
|
||||||
|
clustered_decals_are_usable: decal::clustered::clustered_decals_are_usable(
|
||||||
|
&render_device,
|
||||||
|
&render_adapter,
|
||||||
|
),
|
||||||
skins_use_uniform_buffers: skin::skins_use_uniform_buffers(&render_device),
|
skins_use_uniform_buffers: skin::skins_use_uniform_buffers(&render_device),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2295,7 +2302,7 @@ impl SpecializedMeshPipeline for MeshPipeline {
|
|||||||
shader_defs.push("IRRADIANCE_VOLUMES_ARE_USABLE".into());
|
shader_defs.push("IRRADIANCE_VOLUMES_ARE_USABLE".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.binding_arrays_are_usable {
|
if self.clustered_decals_are_usable {
|
||||||
shader_defs.push("CLUSTERED_DECALS_ARE_USABLE".into());
|
shader_defs.push("CLUSTERED_DECALS_ARE_USABLE".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,16 +2,22 @@
|
|||||||
|
|
||||||
use std::f32::consts::{FRAC_PI_3, PI};
|
use std::f32::consts::{FRAC_PI_3, PI};
|
||||||
use std::fmt::{self, Formatter};
|
use std::fmt::{self, Formatter};
|
||||||
|
use std::process;
|
||||||
|
|
||||||
use bevy::pbr::{ExtendedMaterial, MaterialExtension};
|
|
||||||
use bevy::window::SystemCursorIcon;
|
|
||||||
use bevy::winit::cursor::CursorIcon;
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
color::palettes::css::{LIME, ORANGE_RED, SILVER},
|
color::palettes::css::{LIME, ORANGE_RED, SILVER},
|
||||||
input::mouse::AccumulatedMouseMotion,
|
input::mouse::AccumulatedMouseMotion,
|
||||||
pbr::decal::clustered::ClusteredDecal,
|
pbr::{
|
||||||
|
decal::{self, clustered::ClusteredDecal},
|
||||||
|
ExtendedMaterial, MaterialExtension,
|
||||||
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
render::render_resource::{AsBindGroup, ShaderRef},
|
render::{
|
||||||
|
render_resource::{AsBindGroup, ShaderRef},
|
||||||
|
renderer::{RenderAdapter, RenderDevice},
|
||||||
|
},
|
||||||
|
window::SystemCursorIcon,
|
||||||
|
winit::cursor::CursorIcon,
|
||||||
};
|
};
|
||||||
use ops::{acos, cos, sin};
|
use ops::{acos, cos, sin};
|
||||||
use widgets::{
|
use widgets::{
|
||||||
@ -152,9 +158,17 @@ fn setup(
|
|||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
asset_server: Res<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
app_status: Res<AppStatus>,
|
app_status: Res<AppStatus>,
|
||||||
|
render_device: Res<RenderDevice>,
|
||||||
|
render_adapter: Res<RenderAdapter>,
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
mut materials: ResMut<Assets<ExtendedMaterial<StandardMaterial, CustomDecalExtension>>>,
|
mut materials: ResMut<Assets<ExtendedMaterial<StandardMaterial, CustomDecalExtension>>>,
|
||||||
) {
|
) {
|
||||||
|
// Error out if clustered decals aren't supported on the current platform.
|
||||||
|
if !decal::clustered::clustered_decals_are_usable(&render_device, &render_adapter) {
|
||||||
|
eprintln!("Clustered decals aren't usable on this platform.");
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
spawn_cube(&mut commands, &mut meshes, &mut materials);
|
spawn_cube(&mut commands, &mut meshes, &mut materials);
|
||||||
spawn_camera(&mut commands);
|
spawn_camera(&mut commands);
|
||||||
spawn_light(&mut commands);
|
spawn_light(&mut commands);
|
||||||
|
Loading…
Reference in New Issue
Block a user