mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-26 00:33:51 +00:00
Merge #831
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:
commit
8a2ee26fff
@ -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,
|
||||||
|
@ -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>(
|
||||||
|
Loading…
Reference in New Issue
Block a user