Skip to content

Commit 8878083

Browse files
authored
Use RenderStartup for meshlets. (#20210)
# Objective - Progress towards #19887. ## Solution - Convert FromWorld impls to systems in `RenderStartup`. - Use a closure system for initializing `ResourceManager` to capture the `cluster_buffer_slots`. ## Testing - Ran the `meshlet` example and it behaves the same as main.
1 parent 0924881 commit 8878083

File tree

4 files changed

+470
-457
lines changed

4 files changed

+470
-457
lines changed

crates/bevy_pbr/src/meshlet/meshlet_mesh_manager.rs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ use alloc::sync::Arc;
55
use bevy_asset::{AssetId, Assets};
66
use bevy_ecs::{
77
resource::Resource,
8-
system::{Res, ResMut},
9-
world::{FromWorld, World},
8+
system::{Commands, Res, ResMut},
109
};
1110
use bevy_math::Vec2;
1211
use bevy_platform::collections::HashMap;
@@ -30,20 +29,17 @@ pub struct MeshletMeshManager {
3029
HashMap<AssetId<MeshletMesh>, ([Range<BufferAddress>; 7], MeshletAabb, u32)>,
3130
}
3231

33-
impl FromWorld for MeshletMeshManager {
34-
fn from_world(world: &mut World) -> Self {
35-
let render_device = world.resource::<RenderDevice>();
36-
Self {
37-
vertex_positions: PersistentGpuBuffer::new("meshlet_vertex_positions", render_device),
38-
vertex_normals: PersistentGpuBuffer::new("meshlet_vertex_normals", render_device),
39-
vertex_uvs: PersistentGpuBuffer::new("meshlet_vertex_uvs", render_device),
40-
indices: PersistentGpuBuffer::new("meshlet_indices", render_device),
41-
bvh_nodes: PersistentGpuBuffer::new("meshlet_bvh_nodes", render_device),
42-
meshlets: PersistentGpuBuffer::new("meshlets", render_device),
43-
meshlet_cull_data: PersistentGpuBuffer::new("meshlet_cull_data", render_device),
44-
meshlet_mesh_slices: HashMap::default(),
45-
}
46-
}
32+
pub fn init_meshlet_mesh_manager(mut commands: Commands, render_device: Res<RenderDevice>) {
33+
commands.insert_resource(MeshletMeshManager {
34+
vertex_positions: PersistentGpuBuffer::new("meshlet_vertex_positions", &render_device),
35+
vertex_normals: PersistentGpuBuffer::new("meshlet_vertex_normals", &render_device),
36+
vertex_uvs: PersistentGpuBuffer::new("meshlet_vertex_uvs", &render_device),
37+
indices: PersistentGpuBuffer::new("meshlet_indices", &render_device),
38+
bvh_nodes: PersistentGpuBuffer::new("meshlet_bvh_nodes", &render_device),
39+
meshlets: PersistentGpuBuffer::new("meshlets", &render_device),
40+
meshlet_cull_data: PersistentGpuBuffer::new("meshlet_cull_data", &render_device),
41+
meshlet_mesh_slices: HashMap::default(),
42+
});
4743
}
4844

4945
impl MeshletMeshManager {

crates/bevy_pbr/src/meshlet/mod.rs

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,17 @@ use self::{
4949
material_shade_nodes::{
5050
MeshletDeferredGBufferPrepassNode, MeshletMainOpaquePass3dNode, MeshletPrepassNode,
5151
},
52-
meshlet_mesh_manager::{perform_pending_meshlet_mesh_writes, MeshletMeshManager},
52+
meshlet_mesh_manager::perform_pending_meshlet_mesh_writes,
5353
pipelines::*,
5454
resource_manager::{
5555
prepare_meshlet_per_frame_resources, prepare_meshlet_view_bind_groups, ResourceManager,
5656
},
5757
visibility_buffer_raster_node::MeshletVisibilityBufferRasterPassNode,
5858
};
59-
use crate::{graph::NodePbr, PreviousGlobalTransform};
59+
use crate::{
60+
graph::NodePbr, meshlet::meshlet_mesh_manager::init_meshlet_mesh_manager,
61+
PreviousGlobalTransform,
62+
};
6063
use bevy_app::{App, Plugin};
6164
use bevy_asset::{embedded_asset, AssetApp, AssetId, Handle};
6265
use bevy_core_pipeline::{
@@ -70,7 +73,7 @@ use bevy_ecs::{
7073
query::Has,
7174
reflect::ReflectComponent,
7275
schedule::IntoScheduleConfigs,
73-
system::{Commands, Query},
76+
system::{Commands, Query, Res},
7477
};
7578
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
7679
use bevy_render::{
@@ -79,7 +82,7 @@ use bevy_render::{
7982
renderer::RenderDevice,
8083
settings::WgpuFeatures,
8184
view::{self, prepare_view_targets, Msaa, Visibility, VisibilityClass},
82-
ExtractSchedule, Render, RenderApp, RenderSystems,
85+
ExtractSchedule, Render, RenderApp, RenderStartup, RenderSystems,
8386
};
8487
use bevy_transform::components::Transform;
8588
use derive_more::From;
@@ -163,22 +166,18 @@ impl Plugin for MeshletPlugin {
163166

164167
app.init_asset::<MeshletMesh>()
165168
.register_asset_loader(MeshletMeshLoader);
166-
}
167169

168-
fn finish(&self, app: &mut App) {
169170
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
170171
return;
171172
};
172173

173-
let render_device = render_app.world().resource::<RenderDevice>().clone();
174-
let features = render_device.features();
175-
if !features.contains(Self::required_wgpu_features()) {
176-
error!(
177-
"MeshletPlugin can't be used. GPU lacks support for required features: {:?}.",
178-
Self::required_wgpu_features().difference(features)
179-
);
180-
std::process::exit(1);
181-
}
174+
// Create a variable here so we can move-capture it.
175+
let cluster_buffer_slots = self.cluster_buffer_slots;
176+
let init_resource_manager_system =
177+
move |mut commands: Commands, render_device: Res<RenderDevice>| {
178+
commands
179+
.insert_resource(ResourceManager::new(cluster_buffer_slots, &render_device));
180+
};
182181

183182
render_app
184183
.add_render_graph_node::<MeshletVisibilityBufferRasterPassNode>(
@@ -214,13 +213,18 @@ impl Plugin for MeshletPlugin {
214213
Node3d::EndMainPass,
215214
),
216215
)
217-
.init_resource::<MeshletMeshManager>()
218216
.insert_resource(InstanceManager::new())
219-
.insert_resource(ResourceManager::new(
220-
self.cluster_buffer_slots,
221-
&render_device,
222-
))
223-
.init_resource::<MeshletPipelines>()
217+
.add_systems(
218+
RenderStartup,
219+
(
220+
check_meshlet_features,
221+
(
222+
(init_resource_manager_system, init_meshlet_pipelines).chain(),
223+
init_meshlet_mesh_manager,
224+
),
225+
)
226+
.chain(),
227+
)
224228
.add_systems(ExtractSchedule, extract_meshlet_mesh_entities)
225229
.add_systems(
226230
Render,
@@ -240,6 +244,17 @@ impl Plugin for MeshletPlugin {
240244
}
241245
}
242246

247+
fn check_meshlet_features(render_device: Res<RenderDevice>) {
248+
let features = render_device.features();
249+
if !features.contains(MeshletPlugin::required_wgpu_features()) {
250+
error!(
251+
"MeshletPlugin can't be used. GPU lacks support for required features: {:?}.",
252+
MeshletPlugin::required_wgpu_features().difference(features)
253+
);
254+
std::process::exit(1);
255+
}
256+
}
257+
243258
/// The meshlet mesh equivalent of [`bevy_render::mesh::Mesh3d`].
244259
#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq, From)]
245260
#[reflect(Component, Default, Clone, PartialEq)]

0 commit comments

Comments
 (0)