From 8db6f99a3e488b0b673575d65b92c019587f48d9 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 1 Jul 2021 02:02:16 -0400 Subject: [PATCH] Suspect new resources for destruction only after the current submission is tracked --- wgpu-core/src/device/life.rs | 29 +++++++++++++++-------------- wgpu-core/src/device/mod.rs | 11 ++--------- wgpu-core/src/device/queue.rs | 27 +++++++++++++++++---------- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 6eb933c407..63270106af 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -230,6 +230,15 @@ impl LifetimeTracker { } } + self.active.alloc().init(ActiveSubmission { + index, + last_resources, + mapped: Vec::new(), + encoders, + }); + } + + pub fn post_submit(&mut self) { self.suspected_resources.buffers.extend( self.future_suspected_buffers .drain(..) @@ -240,13 +249,6 @@ impl LifetimeTracker { .drain(..) .map(|stored| stored.value), ); - - self.active.alloc().init(ActiveSubmission { - index, - last_resources, - mapped: Vec::new(), - encoders, - }); } pub(crate) fn map(&mut self, value: id::Valid, ref_count: RefCount) { @@ -310,13 +312,6 @@ impl LifetimeTracker { id: id::Valid, view: resource::TextureView, ) { - match view.source { - resource::TextureViewSource::Native(source_id) => { - self.suspected_resources.textures.push(source_id.value); - } - resource::TextureViewSource::SwapChain { .. } => {} - }; - let submit_index = view.life_guard.submission_index.load(Ordering::Acquire); self.active .iter_mut() @@ -392,6 +387,12 @@ impl LifetimeTracker { } if let Some(res) = hub.texture_views.unregister_locked(id.0, &mut *guard) { + match res.source { + resource::TextureViewSource::Native(ref source_id) => { + self.suspected_resources.textures.push(source_id.value); + } + resource::TextureViewSource::SwapChain { .. } => {} + }; self.schedule_texture_view_for_destruction(id, res); } } diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index b60808929f..26d224b5ce 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -333,19 +333,12 @@ impl Device { }) } - fn lock_life_internal<'this, 'token: 'this>( - tracker: &'this Mutex>, - _token: &mut Token<'token, Self>, - ) -> MutexGuard<'this, life::LifetimeTracker> { - tracker.lock() - } - fn lock_life<'this, 'token: 'this>( &'this self, //TODO: fix this - the token has to be borrowed for the lock - token: &mut Token<'token, Self>, + _token: &mut Token<'token, Self>, ) -> MutexGuard<'this, life::LifetimeTracker> { - Self::lock_life_internal(&self.life_tracker, token) + self.life_tracker.lock() } pub(crate) fn schedule_rogue_texture_view_for_destruction<'this, 'token: 'this>( diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 130070aecd..a68766a835 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -808,14 +808,6 @@ impl Global { } } - let callbacks = match device.maintain(&hub, false, &mut token) { - Ok(callbacks) => callbacks, - Err(WaitIdleError::Device(err)) => return Err(QueueSubmitError::Queue(err)), - Err(WaitIdleError::StuckGpu) => return Err(QueueSubmitError::StuckGpu), - }; - - device.temp_suspected.clear(); - profiling::scope!("cleanup"); if let Some(pending_execution) = device.pending_writes.post_submit( &device.command_allocator, @@ -824,12 +816,27 @@ impl Global { ) { active_executions.push(pending_execution); } - super::Device::lock_life_internal(&device.life_tracker, &mut token).track_submission( + + // this will register the new submission to the life time tracker + let mut pending_write_resources = mem::take(&mut device.pending_writes.temp_resources); + device.lock_life(&mut token).track_submission( submit_index, - device.pending_writes.temp_resources.drain(..), + pending_write_resources.drain(..), active_executions, ); + // This will schedule destruction of all resources that are no longer needed + // by the user but used in the command stream, among other things. + let callbacks = match device.maintain(&hub, false, &mut token) { + Ok(callbacks) => callbacks, + Err(WaitIdleError::Device(err)) => return Err(QueueSubmitError::Queue(err)), + Err(WaitIdleError::StuckGpu) => return Err(QueueSubmitError::StuckGpu), + }; + + device.pending_writes.temp_resources = pending_write_resources; + device.temp_suspected.clear(); + device.lock_life(&mut token).post_submit(); + callbacks };