Skip to content

Commit

Permalink
Retain RenderMeshInstance and MeshInputUniform data from frame to…
Browse files Browse the repository at this point in the history
… frame. (#16385)

This commit moves the front end of the rendering pipeline to a retained
model when GPU preprocessing is in use (i.e. by default, except in
constrained environments). `RenderMeshInstance` and `MeshUniformData`
are stored from frame to frame and are updated only for the entities
that changed state. This was rather tricky and requires some careful
surgery to keep the data valid in the case of removals.

This patch is built on top of Bevy's change detection. Generally, this
worked, except that `ViewVisibility` isn't currently properly tracked.
Therefore, this commit adds proper change tracking for `ViewVisibility`.
Doing this required adding a new system that runs after all
`check_visibility` invocations, as no single `check_visibility`
invocation has enough global information to detect changes.

On the Bistro exterior scene, with all textures forced to opaque, this
patch improves steady-state `extract_meshes_for_gpu_building` from
93.8us to 34.5us and steady-state `collect_meshes_for_gpu_building` from
195.7us to 4.28us. Altogether this constitutes an improvement from 290us
to 38us, which is a 7.46x speedup.

![Screenshot 2024-11-13
143841](https://github.com/user-attachments/assets/40b1aacc-373d-4016-b7fd-b0284bc33de4)

![Screenshot 2024-11-13
143850](https://github.com/user-attachments/assets/53b401c3-7461-43b3-918b-cff89ea780d6)

This patch is only lightly tested and shouldn't land before 0.15 is
released anyway, so I'm releasing it as a draft.
  • Loading branch information
pcwalton authored Dec 5, 2024
1 parent bf765e6 commit 8c2c07b
Show file tree
Hide file tree
Showing 6 changed files with 450 additions and 95 deletions.
9 changes: 6 additions & 3 deletions crates/bevy_pbr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,8 @@ impl Plugin for PbrPlugin {
.in_set(SimulationLightSystems::AssignLightsToClusters)
.after(TransformSystem::TransformPropagate)
.after(VisibilitySystems::CheckVisibility)
.after(CameraUpdateSystem),
.after(CameraUpdateSystem)
.ambiguous_with(VisibilitySystems::VisibilityChangeDetect),
clear_directional_light_cascades
.in_set(SimulationLightSystems::UpdateDirectionalLightCascades)
.after(TransformSystem::TransformPropagate)
Expand All @@ -398,7 +399,8 @@ impl Plugin for PbrPlugin {
// We assume that no entity will be both a directional light and a spot light,
// so these systems will run independently of one another.
// FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
.ambiguous_with(update_spot_light_frusta),
.ambiguous_with(update_spot_light_frusta)
.ambiguous_with(VisibilitySystems::VisibilityChangeDetect),
update_point_light_frusta
.in_set(SimulationLightSystems::UpdateLightFrusta)
.after(TransformSystem::TransformPropagate)
Expand All @@ -419,7 +421,8 @@ impl Plugin for PbrPlugin {
// NOTE: This MUST be scheduled AFTER the core renderer visibility check
// because that resets entity `ViewVisibility` for the first view
// which would override any results from this otherwise
.after(VisibilitySystems::CheckVisibility),
.after(VisibilitySystems::CheckVisibility)
.ambiguous_with(VisibilitySystems::VisibilityChangeDetect),
),
);

Expand Down
5 changes: 2 additions & 3 deletions crates/bevy_pbr/src/render/gpu_preprocess.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,8 @@ pub fn prepare_preprocess_bind_groups(
} = batched_instance_buffers.into_inner();

let (Some(current_input_buffer), Some(previous_input_buffer), Some(data_buffer)) = (
current_input_buffer_vec.buffer(),
previous_input_buffer_vec.buffer(),
current_input_buffer_vec.buffer.buffer(),
previous_input_buffer_vec.buffer.buffer(),
data_buffer_vec.buffer(),
) else {
return;
Expand Down Expand Up @@ -483,5 +483,4 @@ pub fn write_mesh_culling_data_buffer(
mut mesh_culling_data_buffer: ResMut<MeshCullingDataBuffer>,
) {
mesh_culling_data_buffer.write_buffer(&render_device, &render_queue);
mesh_culling_data_buffer.clear();
}
Loading

0 comments on commit 8c2c07b

Please sign in to comment.