Repository navigation
fix(gpu): cap GPU readback staging buffers to prevent memory exhaustion - #713
Open
mjohnson7cd wants to merge 1 commit into
Open
mjohnson7cd wants to merge 1 commit into
mjohnson7cd wants to merge 1 commit into
Conversation
mjohnson7cd
marked this pull request as ready for review
October 11, 2026 05:10
This branch has not been deployed
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
Fixes storytold/artcraft#2081 - Rendering stops at frame 970/1570, PC lags until app closed on high-end system (i7-12700KF, RTX 3090, 32GB RAM).
Problem
GPU readback staging buffers accumulated unbounded when layer bounds changed every frame (animated scale, blur radius, growing shapes). Each 1080p RGBA f32 buffer ≈ 33 MB in system RAM. At 970 frames × 33 MB ≈ 32 GB, the system exhausted available memory.
The buffers are kept for reuse (up to 2 per size), but there was no limit on total memory across all sizes.
Solution
Capped GPU readback staging buffers to 256 MB total. When adding a new buffer would exceed the cap, drop buffers of other sizes while keeping the current size for reuse. Renders with consistent frame sizes still benefit from buffer reuse.
Implementation
Changed:
crates/gpu/src/context.rs,crates/gpu/tests.rs(+34/-1)readback_staging_stays_bounded_across_sizesTest Results
Without fix: Test reads 120 different sizes (~480 MB), holds 620 MB, takes 28.5s (Apple M4/Metal)
With fix: Same test passes in 0.54s, stays within 256 MB budget
✓
cargo fmt✓
cargo clippy --workspace --all-targets -- -D warnings✓
cargo test -p effectcraft-gpu(204 tests passed)Notes
— sent on behalf of @mjohnson7cd by Claude Code