831: Carry RefCount in future suspects in order to prevent early removal r=cwfitzgerald a=kvark

**Connections**
Fixes  #830

**Description**
see https://github.com/gfx-rs/wgpu/issues/830#issuecomment-662825775

**Testing**
Tested on harmony + Sponza

Co-authored-by: Dzmitry Malyshau <kvarkus@gmail.com>
This commit is contained in:
bors[bot] 2020-07-23 16:09:02 +00:00 committed by GitHub
commit 8a2ee26fff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 21 deletions

View File

@ -132,17 +132,15 @@ impl<B: hal::Backend> NonReferencedResources<B> {
heaps_mutex: &Mutex<Heaps<B>>, heaps_mutex: &Mutex<Heaps<B>>,
descriptor_allocator_mutex: &Mutex<DescriptorAllocator<B>>, descriptor_allocator_mutex: &Mutex<DescriptorAllocator<B>>,
) { ) {
if !self.buffers.is_empty() { if !self.buffers.is_empty() || !self.images.is_empty() {
let mut heaps = heaps_mutex.lock(); let mut heaps = heaps_mutex.lock();
for (raw, memory) in self.buffers.drain(..) { for (raw, memory) in self.buffers.drain(..) {
log::trace!("Buffer {:?} is destroyed with memory {:?}", raw, memory); log::trace!("Buffer {:?} is destroyed with memory {:?}", raw, memory);
device.destroy_buffer(raw); device.destroy_buffer(raw);
heaps.free(device, memory); heaps.free(device, memory);
} }
}
if !self.images.is_empty() {
let mut heaps = heaps_mutex.lock();
for (raw, memory) in self.images.drain(..) { for (raw, memory) in self.images.drain(..) {
log::trace!("Image {:?} is destroyed with memory {:?}", raw, memory);
device.destroy_image(raw); device.destroy_image(raw);
heaps.free(device, memory); heaps.free(device, memory);
} }
@ -204,14 +202,14 @@ pub enum WaitIdleError {
/// 3. When `ActiveSubmission` is retired, the mapped buffers associated with it are moved to `ready_to_map` vector. /// 3. When `ActiveSubmission` is retired, the mapped buffers associated with it are moved to `ready_to_map` vector.
/// 4. Finally, `handle_mapping` issues all the callbacks. /// 4. Finally, `handle_mapping` issues all the callbacks.
#[derive(Debug)] #[derive(Debug)]
pub struct LifetimeTracker<B: hal::Backend> { pub(crate) struct LifetimeTracker<B: hal::Backend> {
/// Resources that the user has requested be mapped, but are still in use. /// Resources that the user has requested be mapped, but are still in use.
mapped: Vec<Stored<id::BufferId>>, mapped: Vec<Stored<id::BufferId>>,
/// Buffers can be used in a submission that is yet to be made, by the /// Buffers can be used in a submission that is yet to be made, by the
/// means of `write_buffer()`, so we have a special place for them. /// means of `write_buffer()`, so we have a special place for them.
pub future_suspected_buffers: Vec<id::BufferId>, pub future_suspected_buffers: Vec<Stored<id::BufferId>>,
/// Textures can be used in the upcoming submission by `write_texture`. /// Textures can be used in the upcoming submission by `write_texture`.
pub future_suspected_textures: Vec<id::TextureId>, pub future_suspected_textures: Vec<Stored<id::TextureId>>,
/// Resources that are suspected for destruction. /// Resources that are suspected for destruction.
pub suspected_resources: SuspectedResources, pub suspected_resources: SuspectedResources,
/// Resources that are not referenced any more but still used by GPU. /// Resources that are not referenced any more but still used by GPU.
@ -246,12 +244,16 @@ impl<B: hal::Backend> LifetimeTracker<B> {
) { ) {
let mut last_resources = NonReferencedResources::new(); let mut last_resources = NonReferencedResources::new();
last_resources.buffers.extend(temp_buffers); last_resources.buffers.extend(temp_buffers);
self.suspected_resources self.suspected_resources.buffers.extend(
.buffers self.future_suspected_buffers
.extend(self.future_suspected_buffers.drain(..)); .drain(..)
self.suspected_resources .map(|stored| stored.value),
.textures );
.extend(self.future_suspected_textures.drain(..)); self.suspected_resources.textures.extend(
self.future_suspected_textures
.drain(..)
.map(|stored| stored.value),
);
self.suspected_resources.extend(new_suspects); self.suspected_resources.extend(new_suspects);
self.active.alloc().init(ActiveSubmission { self.active.alloc().init(ActiveSubmission {
index, index,

View File

@ -879,18 +879,21 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let mut token = Token::root(); let mut token = Token::root();
log::info!("Buffer {:?} is dropped", buffer_id); log::info!("Buffer {:?} is dropped", buffer_id);
let device_id = { let (ref_count, device_id) = {
let (mut buffer_guard, _) = hub.buffers.write(&mut token); let (mut buffer_guard, _) = hub.buffers.write(&mut token);
let buffer = &mut buffer_guard[buffer_id]; let buffer = &mut buffer_guard[buffer_id];
buffer.life_guard.ref_count.take(); let ref_count = buffer.life_guard.ref_count.take().unwrap();
buffer.device_id.value (ref_count, buffer.device_id.value)
}; };
let (device_guard, mut token) = hub.devices.read(&mut token); let (device_guard, mut token) = hub.devices.read(&mut token);
device_guard[device_id] device_guard[device_id]
.lock_life(&mut token) .lock_life(&mut token)
.future_suspected_buffers .future_suspected_buffers
.push(buffer_id); .push(Stored {
value: buffer_id,
ref_count,
});
} }
pub fn device_create_texture<B: GfxBackend>( pub fn device_create_texture<B: GfxBackend>(
@ -934,18 +937,21 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let hub = B::hub(self); let hub = B::hub(self);
let mut token = Token::root(); let mut token = Token::root();
let device_id = { let (ref_count, device_id) = {
let (mut texture_guard, _) = hub.textures.write(&mut token); let (mut texture_guard, _) = hub.textures.write(&mut token);
let texture = &mut texture_guard[texture_id]; let texture = &mut texture_guard[texture_id];
texture.life_guard.ref_count.take(); let ref_count = texture.life_guard.ref_count.take().unwrap();
texture.device_id.value (ref_count, texture.device_id.value)
}; };
let (device_guard, mut token) = hub.devices.read(&mut token); let (device_guard, mut token) = hub.devices.read(&mut token);
device_guard[device_id] device_guard[device_id]
.lock_life(&mut token) .lock_life(&mut token)
.future_suspected_textures .future_suspected_textures
.push(texture_id); .push(Stored {
value: texture_id,
ref_count,
});
} }
pub fn texture_create_view<B: GfxBackend>( pub fn texture_create_view<B: GfxBackend>(