Description
While upgrading Myth Engine from wgpu 29.0.4 to wgpu 30.0.0, our release performance tests showed a repeatable frame-time regression.
Phase measurements localized most of the difference around presentation, so I extracted the relevant path into a small standalone Rust reproducer containing no Myth Engine code.
The attached reproducer performs only:
Surface::get_current_texture
- one render pass that clears the acquired texture
Queue::submit
- presentation
The wgpu 29 build uses SurfaceTexture::present(), while the wgpu 30 build uses Queue::present(surface_texture). Every acquired texture is rendered to and submitted before presentation.
Reproduction
The attachment contains two projects sharing the same benchmark source, with wgpu fixed to 29.0.4 and 30.0.0 respectively.
wgpu-present-repro.zip
Build both versions:
cargo build --release --workspace --locked
Then run them as separate processes in A29/B30/B30/A29 order:
cargo run --release --locked -p wgpu-present-bench29
cargo run --release --locked -p wgpu-present-bench30
cargo run --release --locked -p wgpu-present-bench30
cargo run --release --locked -p wgpu-present-bench29
Each run uses 10,000 warm-up frames followed by 100,000 measured frames.
Results
Two-run means from the A29/B30/B30/A29 block:
| Wall-time segment |
wgpu 29.0.4 |
wgpu 30.0.0 |
Difference |
| Acquire |
13.79 µs |
14.05 µs |
+0.26 µs |
| Encode + submit |
51.15 µs |
53.63 µs |
+2.48 µs |
| Present |
83.29 µs |
108.44 µs |
+25.15 µs (+30.2%) |
| Total loop |
148.23 µs |
176.12 µs |
+27.88 µs (+18.8%) |
The final wgpu 29 run returned to the original range, so the result does not appear to be explained by one-way warm-up drift.
These measurements are host-observed wall-clock intervals around the API calls. In particular, the present interval may include driver, WSI, compositor, or frame-pacing waits; it should not be interpreted as pure CPU execution time.
Expected behavior / question
I expected the common acquire-render-submit-present path to remain close to wgpu 29 while retaining the correctness behavior added for unrendered or otherwise unprepared surface textures.
I am not suggesting that #9361 should be reverted. Could maintainers confirm whether this cost is expected, and whether the normal successfully-rendered path could safely avoid part of the presentation preparation work?
I have not completed a commit-level bisect or profiler trace. The benchmark compares the released 29.0.4 and 30.0.0 crates.
Platform
OS: Windows 11, build 10.0.26200.8875 (25H2)
CPU: Intel Core i9-9900K
GPU: NVIDIA GeForce GTX 1080 Ti
Driver: 581.57
Backend: Vulkan
Present mode: AutoNoVsync
desired_maximum_frame_latency: 2
winit: 0.30.13
Rust: 1.95.0, x86_64-pc-windows-msvc
The complete reproducer and lockfile are attached. I have not yet tested DX12, another GPU/vendor, another present mode, or the current development branch.
Description
While upgrading Myth Engine from
wgpu 29.0.4towgpu 30.0.0, our release performance tests showed a repeatable frame-time regression.Phase measurements localized most of the difference around presentation, so I extracted the relevant path into a small standalone Rust reproducer containing no Myth Engine code.
The attached reproducer performs only:
Surface::get_current_textureQueue::submitThe wgpu 29 build uses
SurfaceTexture::present(), while the wgpu 30 build usesQueue::present(surface_texture). Every acquired texture is rendered to and submitted before presentation.Reproduction
The attachment contains two projects sharing the same benchmark source, with wgpu fixed to
29.0.4and30.0.0respectively.wgpu-present-repro.zip
Build both versions:
cargo build --release --workspace --lockedThen run them as separate processes in A29/B30/B30/A29 order:
Each run uses 10,000 warm-up frames followed by 100,000 measured frames.
Results
Two-run means from the A29/B30/B30/A29 block:
The final wgpu 29 run returned to the original range, so the result does not appear to be explained by one-way warm-up drift.
These measurements are host-observed wall-clock intervals around the API calls. In particular, the present interval may include driver, WSI, compositor, or frame-pacing waits; it should not be interpreted as pure CPU execution time.
Expected behavior / question
I expected the common acquire-render-submit-present path to remain close to wgpu 29 while retaining the correctness behavior added for unrendered or otherwise unprepared surface textures.
I am not suggesting that #9361 should be reverted. Could maintainers confirm whether this cost is expected, and whether the normal successfully-rendered path could safely avoid part of the presentation preparation work?
I have not completed a commit-level bisect or profiler trace. The benchmark compares the released 29.0.4 and 30.0.0 crates.
Platform
OS: Windows 11, build 10.0.26200.8875 (25H2)
CPU: Intel Core i9-9900K
GPU: NVIDIA GeForce GTX 1080 Ti
Driver: 581.57
Backend: Vulkan
Present mode: AutoNoVsync
desired_maximum_frame_latency: 2
winit: 0.30.13
Rust: 1.95.0, x86_64-pc-windows-msvc
The complete reproducer and lockfile are attached. I have not yet tested DX12, another GPU/vendor, another present mode, or the current development branch.