From 66057efcd262b681ea2c08d5ce228ad1e34c533b Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Mon, 6 Mar 2023 00:07:40 +0100 Subject: [PATCH 1/3] Fix performance regression with shadow mapping --- crates/bevy_pbr/src/render/light.rs | 10 ++++++---- .../bevy_render/src/render_resource/pipeline_cache.rs | 4 ++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 6e6783caf676f..cdf1e7ab1548e 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -26,7 +26,6 @@ use bevy_render::{ Extract, }; use bevy_transform::{components::GlobalTransform, prelude::Transform}; -use bevy_utils::FloatOrd; use bevy_utils::{ tracing::{error, warn}, HashMap, @@ -1653,7 +1652,7 @@ pub struct Shadow { } impl PhaseItem for Shadow { - type SortKey = FloatOrd; + type SortKey = usize; #[inline] fn entity(&self) -> Entity { @@ -1662,7 +1661,7 @@ impl PhaseItem for Shadow { #[inline] fn sort_key(&self) -> Self::SortKey { - FloatOrd(self.distance) + self.pipeline.id() } #[inline] @@ -1672,7 +1671,10 @@ impl PhaseItem for Shadow { #[inline] fn sort(items: &mut [Self]) { - radsort::sort_by_key(items, |item| item.distance); + // The shadow phase is sorted by pipeline id for performance reasons. + // Grouping all draw commands using the same pipeline together performs + // better than rebinding everything at a high rate. + radsort::sort_by_key(items, |item| item.pipeline.id()); } } diff --git a/crates/bevy_render/src/render_resource/pipeline_cache.rs b/crates/bevy_render/src/render_resource/pipeline_cache.rs index 2dfe94913c1bb..3b34933296bb4 100644 --- a/crates/bevy_render/src/render_resource/pipeline_cache.rs +++ b/crates/bevy_render/src/render_resource/pipeline_cache.rs @@ -56,6 +56,10 @@ pub struct CachedRenderPipelineId(CachedPipelineId); impl CachedRenderPipelineId { /// An invalid cached render pipeline index, often used to initialize a variable. pub const INVALID: Self = CachedRenderPipelineId(usize::MAX); + + pub fn id(&self) -> usize { + self.0 + } } /// Index of a cached compute pipeline in a [`PipelineCache`]. From 8f07e32bc30e32e3e2f985af8e57b71a9f9c7af7 Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Mon, 6 Mar 2023 00:27:36 +0100 Subject: [PATCH 2/3] Add inline annotation to CachedRenderPipelineId id() --- crates/bevy_render/src/render_resource/pipeline_cache.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/bevy_render/src/render_resource/pipeline_cache.rs b/crates/bevy_render/src/render_resource/pipeline_cache.rs index 3b34933296bb4..3bb77feccf556 100644 --- a/crates/bevy_render/src/render_resource/pipeline_cache.rs +++ b/crates/bevy_render/src/render_resource/pipeline_cache.rs @@ -57,6 +57,7 @@ impl CachedRenderPipelineId { /// An invalid cached render pipeline index, often used to initialize a variable. pub const INVALID: Self = CachedRenderPipelineId(usize::MAX); + #[inline] pub fn id(&self) -> usize { self.0 } From ff40d9e937a62f5baee4479243a03f6f07311378 Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Mon, 6 Mar 2023 00:30:09 +0100 Subject: [PATCH 3/3] Add id() impl to CachedComputePipelineId for consistency --- crates/bevy_render/src/render_resource/pipeline_cache.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/bevy_render/src/render_resource/pipeline_cache.rs b/crates/bevy_render/src/render_resource/pipeline_cache.rs index 3bb77feccf556..783d35abb2c78 100644 --- a/crates/bevy_render/src/render_resource/pipeline_cache.rs +++ b/crates/bevy_render/src/render_resource/pipeline_cache.rs @@ -70,6 +70,11 @@ pub struct CachedComputePipelineId(CachedPipelineId); impl CachedComputePipelineId { /// An invalid cached compute pipeline index, often used to initialize a variable. pub const INVALID: Self = CachedComputePipelineId(usize::MAX); + + #[inline] + pub fn id(&self) -> usize { + self.0 + } } pub struct CachedPipeline {