From f9f19faed6d9fece700f089247fb7da4d43a1ccd Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 1 Jul 2021 01:39:12 -0400 Subject: [PATCH] Rewire the path of destruction for swapchain texture views --- wgpu-core/src/device/life.rs | 42 ++++++++++++++++++++++-------------- wgpu-core/src/device/mod.rs | 7 +++--- wgpu-core/src/swap_chain.rs | 8 +++---- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 1abc6d8ade..6eb933c407 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -16,7 +16,7 @@ use hal::Device as _; use parking_lot::Mutex; use thiserror::Error; -use std::sync::atomic::Ordering; +use std::{mem, sync::atomic::Ordering}; /// A struct that keeps lists of resources that are no longer needed by the user. #[derive(Debug, Default)] @@ -305,6 +305,27 @@ impl LifetimeTracker { } impl LifetimeTracker { + pub(super) fn schedule_texture_view_for_destruction( + &mut self, + 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() + .find(|a| a.index == submit_index) + .map_or(&mut self.free_resources, |a| &mut a.last_resources) + .texture_views + .push((id, view.raw)); + } + pub(super) fn triage_suspected( &mut self, hub: &Hub, @@ -362,7 +383,8 @@ impl LifetimeTracker { let (mut guard, _) = hub.texture_views.write(token); let mut trackers = trackers.lock(); - for id in self.suspected_resources.texture_views.drain(..) { + let mut list = mem::take(&mut self.suspected_resources.texture_views); + for id in list.drain(..) { if trackers.views.remove_abandoned(id) { #[cfg(feature = "trace")] if let Some(t) = trace { @@ -370,23 +392,11 @@ impl LifetimeTracker { } if let Some(res) = hub.texture_views.unregister_locked(id.0, &mut *guard) { - match res.source { - resource::TextureViewSource::Native(source_id) => { - self.suspected_resources.textures.push(source_id.value); - } - resource::TextureViewSource::SwapChain { .. } => {} - }; - - let submit_index = res.life_guard.submission_index.load(Ordering::Acquire); - self.active - .iter_mut() - .find(|a| a.index == submit_index) - .map_or(&mut self.free_resources, |a| &mut a.last_resources) - .texture_views - .push((id, res.raw)); + self.schedule_texture_view_for_destruction(id, res); } } } + self.suspected_resources.texture_views = list; } if !self.suspected_resources.textures.is_empty() { diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 60b405328a..b60808929f 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -348,15 +348,14 @@ impl Device { Self::lock_life_internal(&self.life_tracker, token) } - pub(crate) fn suspect_texture_view_for_destruction<'this, 'token: 'this>( + pub(crate) fn schedule_rogue_texture_view_for_destruction<'this, 'token: 'this>( &'this self, view_id: id::Valid, + view: resource::TextureView, token: &mut Token<'token, Self>, ) { self.lock_life(token) - .suspected_resources - .texture_views - .push(view_id); + .schedule_texture_view_for_destruction(view_id, view); } fn maintain<'this, 'token: 'this, G: GlobalIdentityHandlerFactory>( diff --git a/wgpu-core/src/swap_chain.rs b/wgpu-core/src/swap_chain.rs index 3910dd01be..7919247d7f 100644 --- a/wgpu-core/src/swap_chain.rs +++ b/wgpu-core/src/swap_chain.rs @@ -267,11 +267,11 @@ impl Global { .ok_or(SwapChainError::AlreadyAcquired)?; drop(swap_chain_guard); - device.suspect_texture_view_for_destruction(view_id.value, &mut token); - let (mut view_guard, _) = hub.texture_views.write(&mut token); - let view = &mut view_guard[view_id.value]; - let _ = view.life_guard.ref_count.take(); + let (view, _) = hub.texture_views.unregister(view_id.value.0, &mut token); + if let Some(view) = view { + device.schedule_rogue_texture_view_for_destruction(view_id.value, view, &mut token); + } suf_texture };