Skip to content

Commit ad3817c

Browse files
authored
Reallocate materials when they change. (#17979)
PR #17898 regressed this, causing much of #17970. This commit fixes the issue by freeing and reallocating materials in the `MaterialBindGroupAllocator` on change. Note that more efficiency is possible, but I opted for the simple approach because (1) we should fix this bug ASAP; (2) I'd like #17965 to land first, because that unlocks the biggest potential optimization, which is not recreating the bind group if it isn't necessary to do so.
1 parent 465306b commit ad3817c

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

crates/bevy_pbr/src/material.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use bevy_ecs::{
2929
SystemParamItem,
3030
},
3131
};
32+
use bevy_platform_support::collections::hash_map::Entry;
3233
use bevy_platform_support::collections::{HashMap, HashSet};
3334
use bevy_platform_support::hash::FixedHasher;
3435
use bevy_reflect::std_traits::ReflectDefault;
@@ -1306,12 +1307,24 @@ impl<M: Material> RenderAsset for PreparedMaterial<M> {
13061307
false,
13071308
) {
13081309
Ok(unprepared) => {
1309-
let binding = *render_material_bindings
1310-
.entry(material_id.into())
1311-
.or_insert_with(|| {
1310+
// Allocate or update the material.
1311+
let binding = match render_material_bindings.entry(material_id.into()) {
1312+
Entry::Occupied(mut occupied_entry) => {
1313+
// TODO: Have a fast path that doesn't require
1314+
// recreating the bind group if only buffer contents
1315+
// change. For now, we just delete and recreate the bind
1316+
// group.
1317+
bind_group_allocator.free(*occupied_entry.get());
1318+
let new_binding = bind_group_allocator
1319+
.allocate_unprepared(unprepared, &pipeline.material_layout);
1320+
*occupied_entry.get_mut() = new_binding;
1321+
new_binding
1322+
}
1323+
Entry::Vacant(vacant_entry) => *vacant_entry.insert(
13121324
bind_group_allocator
1313-
.allocate_unprepared(unprepared, &pipeline.material_layout)
1314-
});
1325+
.allocate_unprepared(unprepared, &pipeline.material_layout),
1326+
),
1327+
};
13151328

13161329
Ok(PreparedMaterial {
13171330
binding,

0 commit comments

Comments
 (0)