GPU: bounded readbacks block on the GPU instead of sleeping between polls
#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 <noreply@anthropic.com>
This commit is contained in:
parent
bfabc72be1
commit
80dff0fb0e
|
|
@ -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}")),
|
||||
|
|
|
|||
Loading…
Reference in New Issue