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

Massively Degraded WebGPU performance #11220

Closed
cshenton-work opened this issue Jan 4, 2024 · 8 comments
Closed

Massively Degraded WebGPU performance #11220

cshenton-work opened this issue Jan 4, 2024 · 8 comments
Labels
C-Bug An unexpected or incorrect behavior C-Performance A change motivated by improving speed, memory usage or compile times O-WebGPU Specific to the WebGPU render API
Milestone

Comments

@cshenton-work
Copy link

Bevy version

main#cf70f532

Relevant system information

Windows 11, Chrome

What you did

Even a basically empty application has severely degraded performance on main on WebGPU. The following:

use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins((DefaultPlugins,))
        .add_systems(Startup, (setup,))
        .run();
}

fn setup(mut commands: Commands) {
    commands.spawn((Camera3dBundle { ..default() },));
}

Results in a profile that looks like this:

image image image

That prepare_windows system is one of the culprits but generally speaking just everything is taking ages.

If I instead build against the 0.12.1 release on crates.io, I get a clean profile:

image

Something has clearly gone awry.

@cshenton-work cshenton-work added C-Bug An unexpected or incorrect behavior S-Needs-Triage This issue needs to be labelled labels Jan 4, 2024
@alice-i-cecile alice-i-cecile added C-Performance A change motivated by improving speed, memory usage or compile times O-WebGPU Specific to the WebGPU render API and removed S-Needs-Triage This issue needs to be labelled labels Jan 4, 2024
@alice-i-cecile alice-i-cecile added this to the 0.13 milestone Jan 4, 2024
@alice-i-cecile
Copy link
Member

Are you able to bisect the commit history? I suspect there was a single PR responsible.

@cshenton-work
Copy link
Author

Yeah happy to, I shall report back if I find it.

@cshenton-work
Copy link
Author

cshenton-work commented Jan 4, 2024

Afaict the regression was introduced by #10702

3b59dbd has a clean profile
ced216f has the performance issues I see

@cshenton-work
Copy link
Author

3b59dbd
image

ced216f
image
Admittedly that is a particularly bad profile, it typically looked like the original post.

@alice-i-cecile
Copy link
Member

FYI @Vrixyz, who has been tracking follow-up tasks in #11052.

@Vrixyz
Copy link
Member

Vrixyz commented Jan 5, 2024

Thanks for providing such detailed report!

I'll still ask for more information, how are you running your app ?

There's a thin chance you're hitting #10702 (comment), Are you setting explicitly the width/height of your canvas ?

@daxpedda
Copy link
Contributor

daxpedda commented Jan 5, 2024

I'm going to assume that this is still the same as #11122.
I noted how this can be fixed in #11052 (comment): by using WindowEvent::RedrawRequested, otherwise drawing happens way too often.

@Vrixyz Vrixyz mentioned this issue Jan 5, 2024
23 tasks
@alice-i-cecile
Copy link
Member

Closing as a duplicate :) Traces and replication were super useful though.

@alice-i-cecile alice-i-cecile closed this as not planned Won't fix, can't repro, duplicate, stale Jan 5, 2024
github-merge-queue bot pushed a commit that referenced this issue Jan 6, 2024
# Objective

- Since #10702, the way bevy updates the window leads to major slowdowns
as seen in
    - #11122 
    - #11220
- Slow is bad, furthermore, _very_ slow is _very_ bad. We should fix
this issue.

## Solution

- Move the app update code into the `Event::WindowEvent { event:
WindowEvent::RedrawRequested }` branch of the event loop.
- Run `window.request_redraw()` When `runner_state.redraw_requested`
- Instead of swapping `ControlFlow` between `Poll` and `Wait`, we always
keep it at `Wait`, and use `window.request_redraw()` to schedule an
immediate call to the event loop.
- `runner_state.redraw_requested` is set to `true` when
`UpdateMode::Continuous` and when a `RequestRedraw` event is received.
- Extract the redraw code into a separate function, because otherwise
I'd go crazy with the indentation level.
- Fix #11122.

## Testing

I tested the WASM builds as follow:

```sh
cargo run -p build-wasm-example -- --api webgl2 bevymark
python -m http.server --directory examples/wasm/ 8080
# Open browser at http://localhost:8080
```

On main, even spawning a couple sprites is super choppy. Even if it says
"300 FPS". While on this branch, it is smooth as butter.

I also found that it fixes all choppiness on window resize (tested on
Linux/X11). This was another issue from #10702 IIRC.

So here is what I tested:

- On `wasm`: `many_foxes` and `bevymark`, with `argh::from_env()`
commented out, otherwise we get a cryptic error.
- Both with `PresentMode::AutoVsync` and `PresentMode::AutoNoVsync`
  - On main, it is consistently choppy.
- With this PR, the visible frame rate is consistent with the diagnostic
numbers
- On native (linux/x11) I ran similar tests, making sure that
`AutoVsync` limits to monitor framerate, and `AutoNoVsync` doesn't.

## Future work

Code could be improved, I wanted a quick solution easy to review, but we
really need to make the code more accessible.

- #9768
- ~~**`WinitSettings::desktop_app()` is completely borked.**~~ actually
broken on main as well

### Review guide

Consider enable the non-whitespace diff to see the _real_ change set.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-Bug An unexpected or incorrect behavior C-Performance A change motivated by improving speed, memory usage or compile times O-WebGPU Specific to the WebGPU render API
Projects
None yet
Development

No branches or pull requests

4 participants