Batch wgpu submit and present across immediate viewports#7961
Open
gcailly wants to merge 1 commit intoemilk:mainfrom
Open
Batch wgpu submit and present across immediate viewports#7961gcailly wants to merge 1 commit intoemilk:mainfrom
gcailly wants to merge 1 commit intoemilk:mainfrom
Conversation
Split `paint_and_update_textures` into three phases (`paint_prepare`, `paint_submit`, `paint_present`) so that immediate viewports can accumulate their prepared frames and submit them in a single `queue.submit()` call instead of one per viewport. This reduces frame time with many immediate viewports by eliminating redundant GPU synchronization between each viewport's submit+present cycle. Closes emilk#7885
|
Preview available at https://egui-pr-preview.github.io/pr/7961-fixviewport-perf View snapshot changes at kitdiff |
|
Thanks for this awesome optimization! The results are impressive — 3x FPS improvement with 10 viewports is a huge win. Hope this gets reviewed and merged soon. Keep up the great work! 🚀 |
Author
|
Thanks @liusuchao! I have to be honest : I was a bit too optimistic with the initial numbers. After more thorough benchmarking (see updated PR description), the real-world gain is closer to 30/40% rather than the 3x improvement I initially reported. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR addresses the FPS drop reported in #7885 when multiple immediate viewports are open.
The root cause is that each viewport does its own
queue.submit()+present()sequentially, causing redundant GPU synchronization. This PR splitspaint_and_update_texturesinto three phases:paint_prepare— upload textures/buffers, acquire surface texture, record render pass, encode commandspaint_submit— singlequeue.submit()for all viewports at oncepaint_present— present all viewports after GPU work is doneImmediate viewports now accumulate their
PreparedFrames, and the parent viewport batches everything into one submit+present cycle.paint_and_update_texturesis kept as a convenience wrapper calling the three phases sequentially, so the public API remains backward-compatible. Deferred viewports are unaffected (they still go through the wrapper).Before and after
Tested on Windows 11, release mode, with a minimal benchmark spawning 0 to 10 immediate viewports (vsync off, high-performance GPU).
Note: Initial testing on a different configuration showed a more dramatic improvement (~60 → ~180 FPS with 10 viewports). After more thorough benchmarking, the gain is closer to +30–48% with 4+ viewports.
Benchmark code
Disclosure
I'm not a Rust developer — I used Claude Code to help me write this. I hope I'm not making a mess, I just wanted to help! Please don't hesitate to point out anything wrong.
Test plan
cargo test -p egui-wgpu -p eframe— all tests passcargo clippy -p egui-wgpu -p eframe— no warningsmultiple_viewportsexample — works correctly