Skip to content

Commit 4ee408f

Browse files
committed
dedupe pipelines
1 parent cf08e7a commit 4ee408f

File tree

1 file changed

+32
-7
lines changed

1 file changed

+32
-7
lines changed

crates/bevy_render/src/render_resource/pipeline_specializer.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
use crate::{
22
mesh::{InnerMeshVertexBufferLayout, MeshVertexBufferLayout},
3-
render_resource::{CachedPipelineId, RenderPipelineCache, RenderPipelineDescriptor},
3+
render_resource::{
4+
CachedPipelineId, RenderPipelineCache, RenderPipelineDescriptor, VertexBufferLayout,
5+
},
6+
};
7+
use bevy_utils::{
8+
hashbrown::hash_map::RawEntryMut, Entry, HashMap, Hashed, PreHashMap, PreHashMapExt,
49
};
5-
use bevy_utils::{HashMap, PreHashMap, PreHashMapExt};
610
use std::hash::Hash;
711

812
pub struct SpecializedPipelines<S: SpecializedPipeline> {
@@ -37,13 +41,15 @@ pub trait SpecializedPipeline {
3741
}
3842

3943
pub struct SpecializedMeshPipelines<S: SpecializedMeshPipeline> {
40-
cache: PreHashMap<InnerMeshVertexBufferLayout, HashMap<S::Key, CachedPipelineId>>,
44+
mesh_layout_cache: PreHashMap<InnerMeshVertexBufferLayout, HashMap<S::Key, CachedPipelineId>>,
45+
vertex_layout_cache: HashMap<VertexBufferLayout, HashMap<S::Key, CachedPipelineId>>,
4146
}
4247

4348
impl<S: SpecializedMeshPipeline> Default for SpecializedMeshPipelines<S> {
4449
fn default() -> Self {
4550
Self {
46-
cache: Default::default(),
51+
mesh_layout_cache: Default::default(),
52+
vertex_layout_cache: Default::default(),
4753
}
4854
}
4955
}
@@ -57,10 +63,29 @@ impl<S: SpecializedMeshPipeline> SpecializedMeshPipelines<S> {
5763
key: S::Key,
5864
layout: &MeshVertexBufferLayout,
5965
) -> CachedPipelineId {
60-
let map = self.cache.get_or_insert_with(layout, Default::default);
66+
let map = self
67+
.mesh_layout_cache
68+
.get_or_insert_with(layout, Default::default);
6169
*map.entry(key.clone()).or_insert_with(|| {
62-
let descriptor = specialize_pipeline.specialize(key, layout);
63-
cache.queue(descriptor)
70+
let descriptor = specialize_pipeline.specialize(key.clone(), layout);
71+
// Different MeshVertexBufferLayouts can produce the same final VertexBufferLayout
72+
// We want compatible vertex buffer layouts to use the same pipelines, so we must "deduplicate" them
73+
let layout_map = match self
74+
.vertex_layout_cache
75+
.raw_entry_mut()
76+
.from_key(&descriptor.vertex.buffers[0])
77+
{
78+
RawEntryMut::Occupied(entry) => entry.into_mut(),
79+
RawEntryMut::Vacant(entry) => {
80+
entry
81+
.insert(descriptor.vertex.buffers[0].clone(), Default::default())
82+
.1
83+
}
84+
};
85+
match layout_map.entry(key) {
86+
Entry::Occupied(entry) => *entry.into_mut(),
87+
Entry::Vacant(entry) => *entry.insert(cache.queue(descriptor)),
88+
}
6489
})
6590
}
6691
}

0 commit comments

Comments
 (0)