448: Fix framebuffers not always being cleaned up if invalid r=kvark a=LaylConway

This changes framebuffers to be cleaned up if only one view is cleaned up, instead of if all views are cleaned up. This is necessary because currently, at least for me, swapchain images will have a different view every frame. This means that if other views continue to exist between frames, the resulting framebuffers will never be cleaned up.

Fixes #447

Co-authored-by: Layl <2385329-layl@users.noreply.gitlab.com>
This commit is contained in:
bors[bot] 2020-01-15 14:24:19 +00:00 committed by GitHub
commit 3a41272cba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -418,20 +418,45 @@ impl<B: GfxBackend> LifetimeTracker<B> {
let remove_list = framebuffers
.keys()
.filter_map(|key| {
let mut last_submit: SubmissionIndex = 0;
let mut last_submit = None;
let mut needs_cleanup = false;
// A framebuffer needs to be scheduled for cleanup, if there's at least one
// attachment is no longer valid.
for &at in key.all() {
// If this attachment is still registered, it's still valid
if texture_view_guard.contains(at) {
return None;
continue;
}
// This attachment is no longer registered.
// Let's see if it's used by any of the active submissions.
// This attachment is no longer registered, this framebuffer needs cleanup
needs_cleanup = true;
// Check if there's any active submissions that are still referring to this
// attachment, if there are we need to get the greatest submission index, as
// that's the last time this attachment is still valid
let mut attachment_last_submit = None;
for a in &self.active {
if a.last_resources.image_views.iter().any(|&(id, _)| id == at) {
last_submit = last_submit.max(a.index);
let max = attachment_last_submit.unwrap_or(0).max(a.index);
attachment_last_submit = Some(max);
}
}
// Between all attachments, we need the smallest index, because that's the last
// time this framebuffer is still valid
if let Some(attachment_last_submit) = attachment_last_submit {
let min = last_submit.unwrap_or(std::usize::MAX).min(attachment_last_submit);
last_submit = Some(min);
}
}
if needs_cleanup {
Some((key.clone(), last_submit.unwrap_or(0)))
} else {
None
}
Some((key.clone(), last_submit))
})
.collect::<FastHashMap<_, _>>();