Use RenderStartup in MaterialPlugin (#19885)

# Objective

- The MaterialPlugin has some ugly code to initialize some data in the
render world
- #19887

## Solution

- Use the new RenderStartup schedule to use a system instead of using
the plugin `finish()`

## Testing

- Tested that the 3d_scene and shader_material example still work as
expected
This commit is contained in:
IceSentry 2025-06-30 19:54:13 -04:00 committed by GitHub
parent 735eb88db9
commit f98727c1b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -37,6 +37,7 @@ use bevy_render::erased_render_asset::{
use bevy_render::mesh::mark_3d_meshes_as_changed_if_their_assets_changed;
use bevy_render::render_asset::{prepare_assets, RenderAssets};
use bevy_render::renderer::RenderQueue;
use bevy_render::RenderStartup;
use bevy_render::{
batching::gpu_preprocessing::GpuPreprocessingSupport,
extract_resource::ExtractResource,
@ -371,44 +372,40 @@ where
}
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
render_app.add_systems(
ExtractSchedule,
(
extract_mesh_materials::<M>.in_set(MaterialExtractionSystems),
early_sweep_material_instances::<M>
.after(MaterialExtractionSystems)
.before(late_sweep_material_instances),
extract_entities_needs_specialization::<M>.after(extract_cameras),
),
);
}
}
fn finish(&self, app: &mut App) {
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
return;
};
render_app.world_mut().resource_scope(
|world, mut bind_group_allocators: Mut<MaterialBindGroupAllocators>| {
let render_device = world.resource::<RenderDevice>();
bind_group_allocators.insert(
TypeId::of::<M>(),
MaterialBindGroupAllocator::new(
render_device,
M::label(),
material_uses_bindless_resources::<M>(render_device)
.then(|| M::bindless_descriptor())
.flatten(),
M::bind_group_layout(render_device),
M::bindless_slot_count(),
render_app
.add_systems(RenderStartup, setup_render_app::<M>)
.add_systems(
ExtractSchedule,
(
extract_mesh_materials::<M>.in_set(MaterialExtractionSystems),
early_sweep_material_instances::<M>
.after(MaterialExtractionSystems)
.before(late_sweep_material_instances),
extract_entities_needs_specialization::<M>.after(extract_cameras),
),
);
},
);
}
}
}
fn setup_render_app<M: Material>(
render_device: Res<RenderDevice>,
mut bind_group_allocators: ResMut<MaterialBindGroupAllocators>,
) {
bind_group_allocators.insert(
TypeId::of::<M>(),
MaterialBindGroupAllocator::new(
&render_device,
M::label(),
material_uses_bindless_resources::<M>(&render_device)
.then(|| M::bindless_descriptor())
.flatten(),
M::bind_group_layout(&render_device),
M::bindless_slot_count(),
),
);
}
/// A dummy [`AssetId`] that we use as a placeholder whenever a mesh doesn't
/// have a material.
///