From 80dff0fb0e9ff53e16813cb19f79cc184d026384 Mon Sep 17 00:00:00 2001 From: bflatastic Date: Wed, 7 Oct 2026 07:52:38 +0700 Subject: [PATCH] GPU: bounded readbacks block on the GPU instead of sleeping between polls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #139's bounded read_buffer polled the device without waiting and slept up to 10 ms between polls, adding up to 10 ms to every readback (the desktop viewer reads every GPU frame back): the gpu crate's tests took 227 s against 119 s before. It now waits with PollType::Wait and the remaining deadline as its timeout (a timeout still retires the context), then takes the result, giving another thread that polled the same device up to 1 ms to deliver its callback. The tests take 71–79 s. Co-Authored-By: Claude Opus 5.5 --- crates/gpu/src/context.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/gpu/src/context.rs b/crates/gpu/src/context.rs index 119648cf..7166302d 100644 --- a/crates/gpu/src/context.rs +++ b/crates/gpu/src/context.rs @@ -628,14 +628,17 @@ impl GpuContext { }); loop { self.readbacks.check()?; - self.poll_readbacks(wgpu::PollType::Poll)?; let remaining = deadline.saturating_duration_since(std::time::Instant::now()); if remaining.is_zero() { let error = "GPU readback receive timed out; context retired".to_string(); self.readbacks.retire(error.clone()); return Err(error); } - match rx.recv_timeout(remaining.min(std::time::Duration::from_millis(10))) { + // Block until the GPU is done (bounded by the deadline: a timeout retires the + // context) rather than polling and sleeping, which adds latency to every readback. + self.poll_readbacks(wgpu::PollType::Wait { submission_index: None, timeout: Some(remaining) })?; + // The callback may be running on another thread that polled the same device. + match rx.recv_timeout(remaining.min(std::time::Duration::from_millis(1))) { Ok(result) => return result, Err(std::sync::mpsc::RecvTimeoutError::Timeout) => {} Err(e) => return Err(format!("GPU readback completion channel: {e}")),