diff --git a/wgpu-core/src/swap_chain.rs b/wgpu-core/src/swap_chain.rs index e2ece136f6..55453230b6 100644 --- a/wgpu-core/src/swap_chain.rs +++ b/wgpu-core/src/swap_chain.rs @@ -81,6 +81,8 @@ pub enum SwapChainError { Device(#[from] DeviceError), #[error("swap chain image is already acquired")] AlreadyAcquired, + #[error("acquired frame is still referenced")] + StillReferenced, } #[derive(Clone, Debug, Error)] @@ -250,12 +252,17 @@ impl Global { trace.lock().add(Action::PresentSwapChain(swap_chain_id)); } - let view_id = sc - .acquired_view_id - .take() - .ok_or(SwapChainError::AlreadyAcquired)?; - let (view_maybe, _) = hub.texture_views.unregister(view_id.value.0, &mut token); - let view = view_maybe.ok_or(SwapChainError::Invalid)?; + let view = { + let view_id = sc + .acquired_view_id + .take() + .ok_or(SwapChainError::AlreadyAcquired)?; + let (view_maybe, _) = hub.texture_views.unregister(view_id.value.0, &mut token); + view_maybe.ok_or(SwapChainError::Invalid)? + }; + if view.life_guard.ref_count.unwrap().load() != 1 { + return Err(SwapChainError::StillReferenced); + } let image = match view.inner { resource::TextureViewInner::Native { .. } => unreachable!(), resource::TextureViewInner::SwapChain { image, .. } => image, diff --git a/wgpu-core/src/track/mod.rs b/wgpu-core/src/track/mod.rs index 6d7e908ef6..2d2d76359f 100644 --- a/wgpu-core/src/track/mod.rs +++ b/wgpu-core/src/track/mod.rs @@ -370,7 +370,12 @@ impl ResourceTracker { e.insert(new.clone()); } Entry::Occupied(e) => { - assert_eq!(e.get().epoch, new.epoch); + assert_eq!( + e.get().epoch, + new.epoch, + "ID {:?} wasn't properly removed", + S::Id::zip(index, e.get().epoch, self.backend) + ); let id = Valid(S::Id::zip(index, new.epoch, self.backend)); e.into_mut().state.merge(id, &new.state, None)?; } @@ -388,7 +393,12 @@ impl ResourceTracker { e.insert(new.clone()); } Entry::Occupied(e) => { - assert_eq!(e.get().epoch, new.epoch); + assert_eq!( + e.get().epoch, + new.epoch, + "ID {:?} wasn't properly removed", + S::Id::zip(index, e.get().epoch, self.backend) + ); let id = Valid(S::Id::zip(index, new.epoch, self.backend)); e.into_mut() .state