use std::sync::Mutex;
use crate::device_health::DeviceHealth;
struct Pending {
health: DeviceHealth,
device: wgpu::Device,
submissions: Vec<wgpu::SubmissionIndex>,
}
fn finished(device: &wgpu::Device, submission: &wgpu::SubmissionIndex) -> bool {
let polled = device.poll(wgpu::PollType::Wait {
submission_index: Some(submission.clone()),
timeout: Some(std::time::Duration::ZERO),
});
!matches!(polled, Err(wgpu::PollError::Timeout))
}
static PENDING: Mutex<Vec<Pending>> = Mutex::new(Vec::new());
pub fn flag_device(
health: &DeviceHealth,
device: &wgpu::Device,
submission: wgpu::SubmissionIndex,
) {
let mut pending = PENDING.lock().unwrap_or_else(|e| e.into_inner());
match pending.iter_mut().find(|p| p.health.same_device(health)) {
Some(p) => {
let device = &p.device;
p.submissions.retain(|s| !finished(device, s));
p.submissions.push(submission);
}
None => pending.push(Pending {
health: health.clone(),
device: device.clone(),
submissions: vec![submission],
}),
}
}
pub fn poll_gpu_reclaim() -> bool {
let mut pending = PENDING.lock().unwrap_or_else(|e| e.into_inner());
pending.retain_mut(|p| {
if p.health.is_lost() {
return false;
}
let device = &p.device;
p.submissions.retain(|s| !finished(device, s));
!p.submissions.is_empty()
});
!pending.is_empty()
}
#[doc(hidden)]
pub fn pending_reclaims() -> usize {
PENDING.lock().unwrap_or_else(|e| e.into_inner()).len()
}