feat(renderer): on-disk cache for per-mesh SDFs (#22)#50
Open
proggeramlug wants to merge 1 commit intomainfrom
Open
feat(renderer): on-disk cache for per-mesh SDFs (#22)#50proggeramlug wants to merge 1 commit intomainfrom
proggeramlug wants to merge 1 commit intomainfrom
Conversation
Cold launches re-baked every per-mesh 32³ R32Float SDF from scratch even though the same content always produces the same voxel data. Sponza's first 9 frames spent ~8 bakes/frame on this path; second launch spent another 9. This change content-hashes (positions + indices) at GPU upload time, checks a platform-appropriate cache directory, and `queue.write_texture`s the cached voxel bytes directly when the file exists — bypassing the GPU dispatch entirely. Misses fall through to the existing bake; the renderer encodes a copy_texture_to_buffer alongside each dispatch and persists the readback to disk after the frame's main submit. The next launch hits and skips the bake. The cache is best-effort throughout: a corrupt entry, missing dir, or write failure silently re-bakes. wasm32 has no filesystem path so load returns None and store is gated out — web builds bake every launch as before. Cache layout: - macOS / iOS / tvOS / watchOS: ~/Library/Caches/bloom/sdf - Linux / Android: $XDG_CACHE_HOME/bloom/sdf - Windows: %LOCALAPPDATA%\bloom\cache\sdf - 16 B header (magic + version + voxel_res) + 128 KB R32Float payload Sponza disk footprint: 68 × 128 KB = 8.7 MB (matches the issue's budget). Disk reads happen synchronously at upload — a 128 KB read from local cache is sub-millisecond. The synchronous device.poll(Wait) on flush blocks for the bake submission to finish before persisting; this is a cold-launch-only stall (~9 frames) and the bake itself is the bottleneck on those frames anyway. Async pipelining is a follow-up if the cold-launch stall ever shows up in profiles. 8 new unit tests cover hash stability, change-detection on positions and indices, count-vs-value distinguishability, store/load round-trip, miss handling, size validation, and bad-magic rejection. cargo test 74/0 (was 66/0) on macOS, wasm32 cargo check clean.
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
Cold launches re-baked every per-mesh 32³ R32Float SDF from scratch — Sponza's first 9 frames spent ~8 bakes/frame on this path, then the next launch spent another 9 on the same content. This PR content-hashes (positions + indices) at upload, checks a platform cache dir, and `queue.write_texture`s the cached voxels directly when the file exists. Misses fall through to the existing bake; the renderer encodes a `copy_texture_to_buffer` alongside each dispatch and persists the readback to disk after the frame's main submit. Next launch hits and skips the bake.
Closes #22.
Cache layout
Behavior on the hot/cold paths
Test plan