Skip to content

Commit

Permalink
Reallocate materials when they change. (bevyengine#17979)
Browse files Browse the repository at this point in the history
PR bevyengine#17898 regressed this, causing much of bevyengine#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 bevyengine#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.
  • Loading branch information
pcwalton authored Feb 22, 2025
1 parent 465306b commit ad3817c
Showing 1 changed file with 18 additions and 5 deletions.
23 changes: 18 additions & 5 deletions crates/bevy_pbr/src/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use bevy_ecs::{
SystemParamItem,
},
};
use bevy_platform_support::collections::hash_map::Entry;
use bevy_platform_support::collections::{HashMap, HashSet};
use bevy_platform_support::hash::FixedHasher;
use bevy_reflect::std_traits::ReflectDefault;
Expand Down Expand Up @@ -1306,12 +1307,24 @@ impl<M: Material> RenderAsset for PreparedMaterial<M> {
false,
) {
Ok(unprepared) => {
let binding = *render_material_bindings
.entry(material_id.into())
.or_insert_with(|| {
// Allocate or update the material.
let binding = match render_material_bindings.entry(material_id.into()) {
Entry::Occupied(mut occupied_entry) => {
// TODO: Have a fast path that doesn't require
// recreating the bind group if only buffer contents
// change. For now, we just delete and recreate the bind
// group.
bind_group_allocator.free(*occupied_entry.get());
let new_binding = bind_group_allocator
.allocate_unprepared(unprepared, &pipeline.material_layout);
*occupied_entry.get_mut() = new_binding;
new_binding
}
Entry::Vacant(vacant_entry) => *vacant_entry.insert(
bind_group_allocator
.allocate_unprepared(unprepared, &pipeline.material_layout)
});
.allocate_unprepared(unprepared, &pipeline.material_layout),
),
};

Ok(PreparedMaterial {
binding,
Expand Down

0 comments on commit ad3817c

Please sign in to comment.