Suspect new resources for destruction only after the current submission is tracked

This commit is contained in:
Dzmitry Malyshau
2021-07-01 02:02:16 -04:00
parent f9f19faed6
commit 8db6f99a3e
3 changed files with 34 additions and 33 deletions

View File

@@ -230,6 +230,15 @@ impl<A: hal::Api> LifetimeTracker<A> {
}
}
self.active.alloc().init(ActiveSubmission {
index,
last_resources,
mapped: Vec::new(),
encoders,
});
}
pub fn post_submit(&mut self) {
self.suspected_resources.buffers.extend(
self.future_suspected_buffers
.drain(..)
@@ -240,13 +249,6 @@ impl<A: hal::Api> LifetimeTracker<A> {
.drain(..)
.map(|stored| stored.value),
);
self.active.alloc().init(ActiveSubmission {
index,
last_resources,
mapped: Vec::new(),
encoders,
});
}
pub(crate) fn map(&mut self, value: id::Valid<id::BufferId>, ref_count: RefCount) {
@@ -310,13 +312,6 @@ impl<A: HalApi> LifetimeTracker<A> {
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()
@@ -392,6 +387,12 @@ impl<A: HalApi> LifetimeTracker<A> {
}
if let Some(res) = hub.texture_views.unregister_locked(id.0, &mut *guard) {
match res.source {
resource::TextureViewSource::Native(ref source_id) => {
self.suspected_resources.textures.push(source_id.value);
}
resource::TextureViewSource::SwapChain { .. } => {}
};
self.schedule_texture_view_for_destruction(id, res);
}
}

View File

@@ -333,19 +333,12 @@ impl<A: HalApi> Device<A> {
})
}
fn lock_life_internal<'this, 'token: 'this>(
tracker: &'this Mutex<life::LifetimeTracker<A>>,
_token: &mut Token<'token, Self>,
) -> MutexGuard<'this, life::LifetimeTracker<A>> {
tracker.lock()
}
fn lock_life<'this, 'token: 'this>(
&'this self,
//TODO: fix this - the token has to be borrowed for the lock
token: &mut Token<'token, Self>,
_token: &mut Token<'token, Self>,
) -> MutexGuard<'this, life::LifetimeTracker<A>> {
Self::lock_life_internal(&self.life_tracker, token)
self.life_tracker.lock()
}
pub(crate) fn schedule_rogue_texture_view_for_destruction<'this, 'token: 'this>(

View File

@@ -808,14 +808,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
}
let callbacks = match device.maintain(&hub, false, &mut token) {
Ok(callbacks) => callbacks,
Err(WaitIdleError::Device(err)) => return Err(QueueSubmitError::Queue(err)),
Err(WaitIdleError::StuckGpu) => return Err(QueueSubmitError::StuckGpu),
};
device.temp_suspected.clear();
profiling::scope!("cleanup");
if let Some(pending_execution) = device.pending_writes.post_submit(
&device.command_allocator,
@@ -824,12 +816,27 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
) {
active_executions.push(pending_execution);
}
super::Device::lock_life_internal(&device.life_tracker, &mut token).track_submission(
// this will register the new submission to the life time tracker
let mut pending_write_resources = mem::take(&mut device.pending_writes.temp_resources);
device.lock_life(&mut token).track_submission(
submit_index,
device.pending_writes.temp_resources.drain(..),
pending_write_resources.drain(..),
active_executions,
);
// This will schedule destruction of all resources that are no longer needed
// by the user but used in the command stream, among other things.
let callbacks = match device.maintain(&hub, false, &mut token) {
Ok(callbacks) => callbacks,
Err(WaitIdleError::Device(err)) => return Err(QueueSubmitError::Queue(err)),
Err(WaitIdleError::StuckGpu) => return Err(QueueSubmitError::StuckGpu),
};
device.pending_writes.temp_resources = pending_write_resources;
device.temp_suspected.clear();
device.lock_life(&mut token).post_submit();
callbacks
};