move device_lost_closure from Device::life_tracker to Device

This commit is contained in:
teoxoy 2024-10-15 12:23:44 +02:00 committed by Teodor Tanasoaia
parent 61c84f956e
commit e934595bb2
4 changed files with 21 additions and 27 deletions

View File

@ -2090,14 +2090,14 @@ impl Global {
) { ) {
let device = self.hub.devices.get(device_id); let device = self.hub.devices.get(device_id);
let mut life_tracker = device.lock_life(); let old_device_lost_closure = device
if let Some(existing_closure) = life_tracker.device_lost_closure.take() { .device_lost_closure
// It's important to not hold the lock while calling the closure. .lock()
drop(life_tracker); .replace(device_lost_closure);
existing_closure.call(DeviceLostReason::ReplacedCallback, "".to_string());
life_tracker = device.lock_life(); if let Some(old_device_lost_closure) = old_device_lost_closure {
old_device_lost_closure.call(DeviceLostReason::ReplacedCallback, "".to_string());
} }
life_tracker.device_lost_closure = Some(device_lost_closure);
} }
pub fn device_destroy(&self, device_id: DeviceId) { pub fn device_destroy(&self, device_id: DeviceId) {

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
device::{ device::{
queue::{EncoderInFlight, SubmittedWorkDoneClosure, TempResource}, queue::{EncoderInFlight, SubmittedWorkDoneClosure, TempResource},
DeviceError, DeviceLostClosure, DeviceError,
}, },
resource::{self, Buffer, Texture, Trackable}, resource::{self, Buffer, Texture, Trackable},
snatch::SnatchGuard, snatch::SnatchGuard,
@ -196,11 +196,6 @@ pub(crate) struct LifetimeTracker {
/// must happen _after_ all mapped buffer callbacks are mapped, so we defer them /// must happen _after_ all mapped buffer callbacks are mapped, so we defer them
/// here until the next time the device is maintained. /// here until the next time the device is maintained.
work_done_closures: SmallVec<[SubmittedWorkDoneClosure; 1]>, work_done_closures: SmallVec<[SubmittedWorkDoneClosure; 1]>,
/// Closure to be called on "lose the device". This is invoked directly by
/// device.lose or by the UserCallbacks returned from maintain when the device
/// has been destroyed and its queues are empty.
pub device_lost_closure: Option<DeviceLostClosure>,
} }
impl LifetimeTracker { impl LifetimeTracker {
@ -209,7 +204,6 @@ impl LifetimeTracker {
active: Vec::new(), active: Vec::new(),
ready_to_map: Vec::new(), ready_to_map: Vec::new(),
work_done_closures: SmallVec::new(), work_done_closures: SmallVec::new(),
device_lost_closure: None,
} }
} }

View File

@ -51,8 +51,8 @@ use std::{
}; };
use super::{ use super::{
queue::Queue, DeviceDescriptor, DeviceError, UserClosures, ENTRYPOINT_FAILURE_ERROR, queue::Queue, DeviceDescriptor, DeviceError, DeviceLostClosure, UserClosures,
ZERO_BUFFER_SIZE, ENTRYPOINT_FAILURE_ERROR, ZERO_BUFFER_SIZE,
}; };
/// Structure describing a logical device. Some members are internally mutable, /// Structure describing a logical device. Some members are internally mutable,
@ -106,6 +106,11 @@ pub struct Device {
/// using ref-counted references for internal access. /// using ref-counted references for internal access.
pub(crate) valid: AtomicBool, pub(crate) valid: AtomicBool,
/// Closure to be called on "lose the device". This is invoked directly by
/// device.lose or by the UserCallbacks returned from maintain when the device
/// has been destroyed and its queues are empty.
pub(crate) device_lost_closure: Mutex<Option<DeviceLostClosure>>,
/// Stores the state of buffers and textures. /// Stores the state of buffers and textures.
pub(crate) trackers: Mutex<DeviceTracker>, pub(crate) trackers: Mutex<DeviceTracker>,
pub(crate) tracker_indices: TrackerIndexAllocators, pub(crate) tracker_indices: TrackerIndexAllocators,
@ -147,8 +152,7 @@ impl Drop for Device {
fn drop(&mut self) { fn drop(&mut self) {
resource_log!("Drop {}", self.error_ident()); resource_log!("Drop {}", self.error_ident());
let device_lost_closure = self.lock_life().device_lost_closure.take(); if let Some(closure) = self.device_lost_closure.lock().take() {
if let Some(closure) = device_lost_closure {
closure.call(DeviceLostReason::Dropped, String::from("Device dropped.")); closure.call(DeviceLostReason::Dropped, String::from("Device dropped."));
} }
@ -259,6 +263,7 @@ impl Device {
fence: RwLock::new(rank::DEVICE_FENCE, ManuallyDrop::new(fence)), fence: RwLock::new(rank::DEVICE_FENCE, ManuallyDrop::new(fence)),
snatchable_lock: unsafe { SnatchLock::new(rank::DEVICE_SNATCHABLE_LOCK) }, snatchable_lock: unsafe { SnatchLock::new(rank::DEVICE_SNATCHABLE_LOCK) },
valid: AtomicBool::new(true), valid: AtomicBool::new(true),
device_lost_closure: Mutex::new(rank::DEVICE_LOST_CLOSURE, None),
trackers: Mutex::new(rank::DEVICE_TRACKERS, DeviceTracker::new()), trackers: Mutex::new(rank::DEVICE_TRACKERS, DeviceTracker::new()),
tracker_indices: TrackerIndexAllocators::new(), tracker_indices: TrackerIndexAllocators::new(),
life_tracker: Mutex::new(rank::DEVICE_LIFE_TRACKER, LifetimeTracker::new()), life_tracker: Mutex::new(rank::DEVICE_LIFE_TRACKER, LifetimeTracker::new()),
@ -466,9 +471,9 @@ impl Device {
// If we have a DeviceLostClosure, build an invocation with the // If we have a DeviceLostClosure, build an invocation with the
// reason DeviceLostReason::Destroyed and no message. // reason DeviceLostReason::Destroyed and no message.
if life_tracker.device_lost_closure.is_some() { if let Some(device_lost_closure) = self.device_lost_closure.lock().take() {
device_lost_invocations.push(DeviceLostInvocation { device_lost_invocations.push(DeviceLostInvocation {
closure: life_tracker.device_lost_closure.take().unwrap(), closure: device_lost_closure,
reason: DeviceLostReason::Destroyed, reason: DeviceLostReason::Destroyed,
message: String::new(), message: String::new(),
}); });
@ -3623,13 +3628,7 @@ impl Device {
self.valid.store(false, Ordering::Release); self.valid.store(false, Ordering::Release);
// 1) Resolve the GPUDevice device.lost promise. // 1) Resolve the GPUDevice device.lost promise.
let mut life_lock = self.lock_life(); if let Some(device_lost_closure) = self.device_lost_closure.lock().take() {
let closure = life_lock.device_lost_closure.take();
// It's important to not hold the lock while calling the closure and while calling
// release_gpu_resources which may take the lock again.
drop(life_lock);
if let Some(device_lost_closure) = closure {
device_lost_closure.call(DeviceLostReason::Unknown, message.to_string()); device_lost_closure.call(DeviceLostReason::Unknown, message.to_string());
} }

View File

@ -135,6 +135,7 @@ define_lock_ranks! {
#[allow(dead_code)] #[allow(dead_code)]
rank DEVICE_TRACE "Device::trace" followed by { } rank DEVICE_TRACE "Device::trace" followed by { }
rank DEVICE_TRACKERS "Device::trackers" followed by { } rank DEVICE_TRACKERS "Device::trackers" followed by { }
rank DEVICE_LOST_CLOSURE "Device::device_lost_closure" followed by { }
rank DEVICE_USAGE_SCOPES "Device::usage_scopes" followed by { } rank DEVICE_USAGE_SCOPES "Device::usage_scopes" followed by { }
rank IDENTITY_MANAGER_VALUES "IdentityManager::values" followed by { } rank IDENTITY_MANAGER_VALUES "IdentityManager::values" followed by { }
rank REGISTRY_STORAGE "Registry::storage" followed by { } rank REGISTRY_STORAGE "Registry::storage" followed by { }