From 05bb482e498c56b9bc2397dbd7468648052e681c Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Tue, 19 Jan 2021 22:03:48 -0500 Subject: [PATCH] Fix replaying issues with dropped texture views --- player/src/lib.rs | 4 +++- wgpu-core/src/device/life.rs | 7 +++---- wgpu-core/src/device/mod.rs | 26 +++++++++++++++++++++----- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/player/src/lib.rs b/player/src/lib.rs index 91bfe15ce4..9d416993c7 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -139,6 +139,7 @@ impl GlobalPlay for wgc::hub::Global { ) { use wgc::device::trace::Action as A; log::info!("action {:?}", action); + //TODO: find a way to force ID perishing without excessive `maintain()` calls. match action { A::Init { .. } => panic!("Unexpected Action::Init: has to be the first action only"), A::CreateSwapChain { .. } | A::PresentSwapChain(_) => { @@ -182,7 +183,7 @@ impl GlobalPlay for wgc::hub::Global { } } A::DestroyTextureView(id) => { - self.texture_view_drop::(id).unwrap(); + self.texture_view_drop::(id, true).unwrap(); } A::CreateSampler(id, desc) => { self.device_maintain_ids::(device).unwrap(); @@ -196,6 +197,7 @@ impl GlobalPlay for wgc::hub::Global { } A::GetSwapChainTexture { id, parent_id } => { if let Some(id) = id { + self.device_maintain_ids::(device).unwrap(); self.swap_chain_get_current_texture_view::(parent_id, id) .unwrap() .view_id diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 3541043a3d..f30fe89b6f 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -326,10 +326,9 @@ impl LifetimeTracker { .iter() .position(|a| unsafe { !device.get_fence_status(&a.fence).unwrap_or(false) }) .unwrap_or_else(|| self.active.len()); - let last_done = if done_count != 0 { - self.active[done_count - 1].index - } else { - return Ok(0); + let last_done = match done_count.checked_sub(1) { + Some(i) => self.active[i].index, + None => return Ok(0), }; for a in self.active.drain(..done_count) { diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index ed82b7a580..83bede8b50 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -2995,27 +2995,31 @@ impl Global { pub fn texture_view_drop( &self, texture_view_id: id::TextureViewId, + wait: bool, ) -> Result<(), resource::TextureViewDestroyError> { span!(_guard, INFO, "TextureView::drop"); let hub = B::hub(self); let mut token = Token::root(); - let device_id = { + let (last_submit_index, device_id) = { let (texture_guard, mut token) = hub.textures.read(&mut token); let (mut texture_view_guard, _) = hub.texture_views.write(&mut token); match texture_view_guard.get_mut(texture_view_id) { Ok(view) => { - view.life_guard.ref_count.take(); - match view.inner { + let _ref_count = view.life_guard.ref_count.take(); + let last_submit_index = + view.life_guard.submission_index.load(Ordering::Acquire); + let device_id = match view.inner { resource::TextureViewInner::Native { ref source_id, .. } => { texture_guard[source_id.value].device_id.value } resource::TextureViewInner::SwapChain { .. } => { return Err(resource::TextureViewDestroyError::SwapChainImage) } - } + }; + (last_submit_index, device_id) } Err(InvalidId) => { hub.texture_views @@ -3026,11 +3030,23 @@ impl Global { }; let (device_guard, mut token) = hub.devices.read(&mut token); - device_guard[device_id] + let device = &device_guard[device_id]; + device .lock_life(&mut token) .suspected_resources .texture_views .push(id::Valid(texture_view_id)); + + if wait { + match device.wait_for_submit(last_submit_index, &mut token) { + Ok(()) => (), + Err(e) => tracing::error!( + "Failed to wait for texture view {:?}: {:?}", + texture_view_id, + e + ), + } + } Ok(()) }