Rewire the path of destruction for swapchain texture views

This commit is contained in:
Dzmitry Malyshau
2021-07-01 01:39:12 -04:00
parent 6dfcde4429
commit f9f19faed6
3 changed files with 33 additions and 24 deletions

View File

@@ -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<A: hal::Api> LifetimeTracker<A> {
}
impl<A: HalApi> LifetimeTracker<A> {
pub(super) fn schedule_texture_view_for_destruction(
&mut self,
id: id::Valid<id::TextureViewId>,
view: resource::TextureView<A>,
) {
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<G: GlobalIdentityHandlerFactory>(
&mut self,
hub: &Hub<A, G>,
@@ -362,7 +383,8 @@ impl<A: HalApi> LifetimeTracker<A> {
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<A: HalApi> LifetimeTracker<A> {
}
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() {

View File

@@ -348,15 +348,14 @@ impl<A: HalApi> Device<A> {
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<id::TextureViewId>,
view: resource::TextureView<A>,
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>(

View File

@@ -267,11 +267,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.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
};