Fix replaying issues with dropped texture views

This commit is contained in:
Dzmitry Malyshau 2021-01-19 22:03:48 -05:00
parent 7c9e239a24
commit 05bb482e49
3 changed files with 27 additions and 10 deletions

View File

@ -139,6 +139,7 @@ impl GlobalPlay for wgc::hub::Global<IdentityPassThroughFactory> {
) {
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<IdentityPassThroughFactory> {
}
}
A::DestroyTextureView(id) => {
self.texture_view_drop::<B>(id).unwrap();
self.texture_view_drop::<B>(id, true).unwrap();
}
A::CreateSampler(id, desc) => {
self.device_maintain_ids::<B>(device).unwrap();
@ -196,6 +197,7 @@ impl GlobalPlay for wgc::hub::Global<IdentityPassThroughFactory> {
}
A::GetSwapChainTexture { id, parent_id } => {
if let Some(id) = id {
self.device_maintain_ids::<B>(device).unwrap();
self.swap_chain_get_current_texture_view::<B>(parent_id, id)
.unwrap()
.view_id

View File

@ -326,10 +326,9 @@ impl<B: hal::Backend> LifetimeTracker<B> {
.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) {

View File

@ -2995,27 +2995,31 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub fn texture_view_drop<B: GfxBackend>(
&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<G: GlobalIdentityHandlerFactory> Global<G> {
};
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(())
}