mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-31 00:46:36 +00:00
wgpu streaming: background-thread chunk I/O kills render-thread stutters
The sync chunk-read on the render thread was causing 100-300 ms spikes during orbit whenever a new chunk needed to scatter-gather its mesh bytes from disk. p99 was 326 ms on the close-camera benchmark. New WgpuStreamingThread: one worker thread with a condvar-protected request/result queue. driveStreamingLoads becomes drain-then-enqueue: 1. Drain any results the worker pushed since last frame. For each, pool-allocate slices + queueWriteBuffer + build the chunk bind group (still main-thread because wgpu queue ops aren't thread-safe). 2. Walk visible non-resident chunks (sorted by distance), evict to make pool room, and enqueue the request. Chunk gains is_loading flag to prevent re-enqueueing while in flight. loadChunkBytesAndUploadGpu becomes the sync fallback path, used only when a screenshot is pending — the deferred-capture wait would otherwise let the window manager re-layout the window between frames and the test framework would capture at the wrong size. Normal streaming always goes through the worker. Bench warm-gate / requestUpdate gating updated to consider streaming_thread_.inFlightApprox() so we don't declare "converged" while a worker read is still in flight, and the render loop stays alive until the worker queue is empty. Refactored loadChunkBytesAndUploadGpu into two helpers: - makeChunkRequest: builds the worker request from chunk metadata - applyStreamedChunk: pool.alloc + queueWriteBuffer + bind group Both the sync and async paths share applyStreamedChunk. Benchmark (big federation, --streaming): close camera: avg 24 fps p99 47 ms (was 27/326) default camera: avg 24 fps p99 46 ms (was 31/186) stream time: ~2 ms (was 8-12) cull is now the bottleneck (20 ms median) — task #17 (GPU compute cull) is the next frontier. Pixel-identical to non-streaming on basic.ifc on both paths. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -122,6 +122,13 @@ struct WgpuModelGpuData {
|
||||
// and flips true once the chunk's vertex bytes are uploaded.
|
||||
// Render and pick skip chunks where !is_resident.
|
||||
bool is_resident = true;
|
||||
// Set true while a worker-thread read is in flight for this
|
||||
// chunk. Prevents driveStreamingLoads from re-enqueueing it
|
||||
// every frame until its result is drained. Cleared when the
|
||||
// result is applied (or dropped on failure / stale model).
|
||||
// Eviction is not gated on this (eviction only acts on resident
|
||||
// chunks; a loading chunk has no slice to free yet).
|
||||
bool is_loading = false;
|
||||
|
||||
// Aggregate vertex / index sizes across all meshes in this chunk
|
||||
// (sum of mesh.vertex_count * stride / mesh.index_count for each
|
||||
|
||||
Reference in New Issue
Block a user