Skip to content

Commit 2d27279

Browse files
committed
add a retry mechanism for waiting on the last submission in Queue::drop
1 parent dcedb6a commit 2d27279

File tree

1 file changed

+66
-28
lines changed

1 file changed

+66
-28
lines changed

wgpu-core/src/device/queue.rs

Lines changed: 66 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -147,37 +147,75 @@ impl Drop for Queue {
147147
.load(Ordering::Acquire);
148148

149149
let fence = self.device.fence.read();
150-
let wait_res = unsafe {
151-
self.device.raw().wait(
152-
fence.as_ref(),
153-
last_successful_submission_index,
154-
#[cfg(not(target_arch = "wasm32"))]
155-
crate::device::CLEANUP_WAIT_MS,
156-
#[cfg(target_arch = "wasm32")]
157-
0, // WebKit and Chromium don't support a non-0 timeout
158-
)
159-
};
160-
drop(fence);
161150

162-
match wait_res {
163-
Ok(true) => {}
164-
// Note: If we don't panic here we are in UB land (destroying resources while they are still in use by the GPU).
165-
Ok(false) => {
166-
// It's fine that we timed out on WebGL; GL objects can be deleted early as they
167-
// will be kept around by the driver if GPU work hasn't finished.
168-
// Moreover, the way we emulate read mappings on WebGL allows us to execute map_buffer earlier than on other
169-
// backends since getBufferSubData is synchronous with respect to the other previously enqueued GL commands.
170-
// TODO: Relying on this behavior breaks the clean abstraction wgpu-hal tries to maintain and
171-
// we should find ways to improve this.
172-
#[cfg(not(target_arch = "wasm32"))]
173-
panic!("We timed out while waiting on the last successful submission to complete!");
174-
}
175-
Err(e) => {
176-
panic!(
177-
"We ran into an error while waiting on the last successful submission to complete! - {e}"
178-
);
151+
// Try waiting on the last submission using the following sequence of timeouts
152+
let timeouts_in_ms = [100, 200, 400, 800, 1600, 3200];
153+
154+
for (i, timeout_ms) in timeouts_in_ms.into_iter().enumerate() {
155+
let is_last_iter = i == timeouts_in_ms.len() - 1;
156+
157+
api_log!(
158+
"Waiting on last submission. try: {}/{}. timeout: {}ms",
159+
i + 1,
160+
timeouts_in_ms.len(),
161+
timeout_ms
162+
);
163+
164+
let wait_res = unsafe {
165+
self.device.raw().wait(
166+
fence.as_ref(),
167+
last_successful_submission_index,
168+
#[cfg(not(target_arch = "wasm32"))]
169+
timeout_ms,
170+
#[cfg(target_arch = "wasm32")]
171+
0, // WebKit and Chromium don't support a non-0 timeout
172+
)
173+
};
174+
// Note: If we don't panic below we are in UB land (destroying resources while they are still in use by the GPU).
175+
match wait_res {
176+
Ok(true) => break,
177+
Ok(false) => {
178+
// It's fine that we timed out on WebGL; GL objects can be deleted early as they
179+
// will be kept around by the driver if GPU work hasn't finished.
180+
// Moreover, the way we emulate read mappings on WebGL allows us to execute map_buffer earlier than on other
181+
// backends since getBufferSubData is synchronous with respect to the other previously enqueued GL commands.
182+
// TODO: Relying on this behavior breaks the clean abstraction wgpu-hal tries to maintain and
183+
// we should find ways to improve this.
184+
#[cfg(target_arch = "wasm32")]
185+
{
186+
break;
187+
}
188+
#[cfg(not(target_arch = "wasm32"))]
189+
{
190+
if is_last_iter {
191+
panic!(
192+
"We timed out while waiting on the last successful submission to complete!"
193+
);
194+
}
195+
}
196+
}
197+
Err(e) => match e {
198+
hal::DeviceError::OutOfMemory => {
199+
if is_last_iter {
200+
panic!(
201+
"We ran into an OOM error while waiting on the last successful submission to complete!"
202+
);
203+
}
204+
}
205+
hal::DeviceError::Lost => {
206+
self.device.handle_hal_error(e); // will lose the device
207+
break;
208+
}
209+
hal::DeviceError::ResourceCreationFailed => unreachable!(),
210+
hal::DeviceError::Unexpected => {
211+
panic!(
212+
"We ran into an unexpected error while waiting on the last successful submission to complete!"
213+
);
214+
}
215+
},
179216
}
180217
}
218+
drop(fence);
181219

182220
let snatch_guard = self.device.snatchable_lock.read();
183221
let (submission_closures, mapping_closures, queue_empty) =

0 commit comments

Comments
 (0)