mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
webgpu: Implement device lost (#32354)
* device lost promise should be init at creation of device object * device lost impl * lock for device poll workaround for wgpu deadlocks * expect * Less lost reason reasoning in script
This commit is contained in:
parent
3381f2a704
commit
cbc9304c20
9 changed files with 224 additions and 5628 deletions
|
@ -7,7 +7,7 @@
|
|||
//! This is roughly based on <https://github.com/LucentFlux/wgpu-async/blob/1322c7e3fcdfc1865a472c7bbbf0e2e06dcf4da8/src/wgpu_future.rs>
|
||||
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::sync::{Arc, Mutex, MutexGuard};
|
||||
use std::thread::JoinHandle;
|
||||
|
||||
use log::warn;
|
||||
|
@ -40,14 +40,25 @@ pub(crate) struct Poller {
|
|||
is_done: Arc<AtomicBool>,
|
||||
/// Handle to the WGPU poller thread (to be used for unparking the thread)
|
||||
handle: Option<JoinHandle<()>>,
|
||||
/// Lock for device maintain calls (in poll_all_devices and queue_submit)
|
||||
///
|
||||
/// This is workaround for wgpu deadlocks: https://github.com/gfx-rs/wgpu/issues/5572
|
||||
lock: Arc<Mutex<()>>,
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn poll_all_devices(global: &Arc<Global>, more_work: &mut bool, force_wait: bool) {
|
||||
fn poll_all_devices(
|
||||
global: &Arc<Global>,
|
||||
more_work: &mut bool,
|
||||
force_wait: bool,
|
||||
lock: &Mutex<()>,
|
||||
) {
|
||||
let _guard = lock.lock().unwrap();
|
||||
match global.poll_all_devices(force_wait) {
|
||||
Ok(all_queue_empty) => *more_work = !all_queue_empty,
|
||||
Err(e) => warn!("Poller thread got `{e}` on poll_all_devices."),
|
||||
}
|
||||
// drop guard
|
||||
}
|
||||
|
||||
impl Poller {
|
||||
|
@ -56,9 +67,11 @@ impl Poller {
|
|||
let is_done = Arc::new(AtomicBool::new(false));
|
||||
let work = work_count.clone();
|
||||
let done = is_done.clone();
|
||||
let lock = Arc::new(Mutex::new(()));
|
||||
Self {
|
||||
work_count,
|
||||
is_done,
|
||||
lock: Arc::clone(&lock),
|
||||
handle: Some(
|
||||
std::thread::Builder::new()
|
||||
.name("WGPU poller".into())
|
||||
|
@ -69,9 +82,9 @@ impl Poller {
|
|||
// so every `ẁake` (even spurious) will do at least one poll.
|
||||
// this is mostly useful for stuff that is deferred
|
||||
// to maintain calls in wgpu (device resource destruction)
|
||||
poll_all_devices(&global, &mut more_work, false);
|
||||
poll_all_devices(&global, &mut more_work, false, &lock);
|
||||
while more_work || work.load(Ordering::Acquire) != 0 {
|
||||
poll_all_devices(&global, &mut more_work, true);
|
||||
poll_all_devices(&global, &mut more_work, true, &lock);
|
||||
}
|
||||
std::thread::park(); //TODO: should we use timeout here
|
||||
}
|
||||
|
@ -101,6 +114,11 @@ impl Poller {
|
|||
.thread()
|
||||
.unpark();
|
||||
}
|
||||
|
||||
/// Lock for device maintain calls (in poll_all_devices and queue_submit)
|
||||
pub(crate) fn lock(&self) -> MutexGuard<()> {
|
||||
self.lock.lock().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Poller {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue