Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retain RenderMeshInstance and MeshInputUniform data from frame to frame. #16385

Merged

Conversation

pcwalton
Copy link
Contributor

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

Screenshot 2024-11-13 143850

This patch is only lightly tested and shouldn't land before 0.15 is released anyway, so I'm releasing it as a draft.

frame.

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.
@pcwalton pcwalton added A-Rendering Drawing game state to the screen C-Performance A change motivated by improving speed, memory usage or compile times S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Nov 14, 2024
@alice-i-cecile alice-i-cecile added this to the 0.16 milestone Nov 14, 2024
@pcwalton pcwalton marked this pull request as ready for review December 2, 2024 04:59
@pcwalton pcwalton added S-Needs-Review Needs reviewer attention (from anyone!) to move forward and removed S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Dec 2, 2024
Copy link
Contributor

@JMS55 JMS55 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally approve.

Some followups I think we should do in the future (nothing to do this with this PR):

  • Hookup MeshletMesh to this API too (it already uses MeshUniform, but it doesn't use the existing queuing system)
  • Switch to writing indices into the mesh uniforms per view, instead of copying the uniforms
  • Experiment with using entities again instead of resources for storing data
  • Rename MeshUniform to MeshInstanceData or something better

GpuCulling {
/// Stores GPU data for each entity that became visible or changed in
/// such a way that necessitates updating the [`MeshInputUniform`] (e.g.
/// changed transform).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fields of each variant are identical, right? Can we pull this out to a new type?

Copy link
Contributor

@tim-blackbird tim-blackbird Dec 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost, the gpu culling side additionally needs MeshCullingData.
The removed vec could be shared but that would cause a decent bit of churn. Doesn't seem worthwhile

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah damn I thought I must have missed something. Agreed, lets leave it.

crates/bevy_pbr/src/render/mesh.rs Outdated Show resolved Hide resolved
@pcwalton pcwalton added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Dec 5, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Dec 5, 2024
Merged via the queue into bevyengine:main with commit 8c2c07b Dec 5, 2024
28 checks passed
ecoskey pushed a commit to ecoskey/bevy that referenced this pull request Jan 6, 2025
… frame. (bevyengine#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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Performance A change motivated by improving speed, memory usage or compile times S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants