mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 16:24:24 +00:00
Eagerly release GPU resources when we lose the device. (#4851)
Co-authored-by: Connor Fitzgerald <connorwadefitzgerald@gmail.com>
This commit is contained in:
parent
85b91c0408
commit
9eea31a4ae
@ -65,6 +65,7 @@ Wgpu now exposes backend feature for the Direct3D 12 (`dx12`) and Metal (`metal`
|
||||
- Added `DownlevelFlags::VERTEX_AND_INSTANCE_INDEX_RESPECTS_RESPECTIVE_FIRST_VALUE_IN_INDIRECT_DRAW` to know if `@builtin(vertex_index)` and `@builtin(instance_index)` will respect the `first_vertex` / `first_instance` in indirect calls. If this is not present, both will always start counting from 0. Currently enabled on all backends except DX12. By @cwfitzgerald in [#4722](https://github.com/gfx-rs/wgpu/pull/4722)
|
||||
- No longer validate surfaces against their allowed extent range on configure. This caused warnings that were almost impossible to avoid. As before, the resulting behavior depends on the compositor. By @wumpf in [#4796](https://github.com/gfx-rs/wgpu/pull/4796)
|
||||
- Added support for the float32-filterable feature. By @almarklein in [#4759](https://github.com/gfx-rs/wgpu/pull/4759)
|
||||
- GPU buffer memory is released during "lose the device". By @bradwerth in [#4851](https://github.com/gfx-rs/wgpu/pull/4851)
|
||||
- wgpu and wgpu-core features are now documented on docs.rs. By @wumpf in [#4886](https://github.com/gfx-rs/wgpu/pull/4886)
|
||||
- DeviceLostClosure is guaranteed to be invoked exactly once. By @bradwerth in [#4862](https://github.com/gfx-rs/wgpu/pull/4862)
|
||||
|
||||
|
@ -241,7 +241,7 @@ pub(crate) struct LifetimeTracker<A: HalApi> {
|
||||
ready_to_map: Vec<Arc<Buffer<A>>>,
|
||||
|
||||
/// Queue "on_submitted_work_done" closures that were initiated for while there is no
|
||||
/// currently pending submissions. These cannot be immeidately invoked as they
|
||||
/// currently pending submissions. These cannot be immediately invoked as they
|
||||
/// must happen _after_ all mapped buffer callbacks are mapped, so we defer them
|
||||
/// here until the next time the device is maintained.
|
||||
work_done_closures: SmallVec<[SubmittedWorkDoneClosure; 1]>,
|
||||
@ -1017,4 +1017,47 @@ impl<A: HalApi> LifetimeTracker<A> {
|
||||
}
|
||||
pending_callbacks
|
||||
}
|
||||
|
||||
pub(crate) fn release_gpu_resources(&mut self) {
|
||||
// This is called when the device is lost, which makes every associated
|
||||
// resource invalid and unusable. This is an opportunity to release all of
|
||||
// the underlying gpu resources, even though the objects remain visible to
|
||||
// the user agent. We purge this memory naturally when resources have been
|
||||
// moved into the appropriate buckets, so this function just needs to
|
||||
// initiate movement into those buckets, and it can do that by calling
|
||||
// "destroy" on all the resources we know about which aren't already marked
|
||||
// for cleanup.
|
||||
|
||||
// During these iterations, we discard all errors. We don't care!
|
||||
|
||||
// Destroy all the mapped buffers.
|
||||
for buffer in &self.mapped {
|
||||
let _ = buffer.destroy();
|
||||
}
|
||||
|
||||
// Destroy all the unmapped buffers.
|
||||
for buffer in &self.ready_to_map {
|
||||
let _ = buffer.destroy();
|
||||
}
|
||||
|
||||
// Destroy all the future_suspected_buffers.
|
||||
for buffer in &self.future_suspected_buffers {
|
||||
let _ = buffer.destroy();
|
||||
}
|
||||
|
||||
// Destroy the buffers in all active submissions.
|
||||
for submission in &self.active {
|
||||
for buffer in &submission.mapped {
|
||||
let _ = buffer.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy all the future_suspected_textures.
|
||||
// TODO: texture.destroy is not implemented
|
||||
/*
|
||||
for texture in &self.future_suspected_textures {
|
||||
let _ = texture.destroy();
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -381,15 +381,19 @@ impl<A: HalApi> Device<A> {
|
||||
// our caller. This will complete the steps for both destroy and for
|
||||
// "lose the device".
|
||||
let mut device_lost_invocations = SmallVec::new();
|
||||
if !self.is_valid()
|
||||
&& life_tracker.queue_empty()
|
||||
&& life_tracker.device_lost_closure.is_some()
|
||||
{
|
||||
device_lost_invocations.push(DeviceLostInvocation {
|
||||
closure: life_tracker.device_lost_closure.take().unwrap(),
|
||||
reason: DeviceLostReason::Destroyed,
|
||||
message: String::new(),
|
||||
});
|
||||
if !self.is_valid() && life_tracker.queue_empty() {
|
||||
// We can release gpu resources associated with this device.
|
||||
life_tracker.release_gpu_resources();
|
||||
|
||||
// If we have a DeviceLostClosure, build an invocation with the
|
||||
// reason DeviceLostReason::Destroyed and no message.
|
||||
if life_tracker.device_lost_closure.is_some() {
|
||||
device_lost_invocations.push(DeviceLostInvocation {
|
||||
closure: life_tracker.device_lost_closure.take().unwrap(),
|
||||
reason: DeviceLostReason::Destroyed,
|
||||
message: String::new(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let closures = UserClosures {
|
||||
@ -3362,9 +3366,13 @@ impl<A: HalApi> Device<A> {
|
||||
self.valid.store(false, Ordering::Release);
|
||||
|
||||
// 1) Resolve the GPUDevice device.lost promise.
|
||||
let closure = self.lock_life().device_lost_closure.take();
|
||||
let mut life_lock = self.lock_life();
|
||||
let closure = life_lock.device_lost_closure.take();
|
||||
if let Some(device_lost_closure) = closure {
|
||||
// It's important to not hold the lock while calling the closure.
|
||||
drop(life_lock);
|
||||
device_lost_closure.call(DeviceLostReason::Unknown, message.to_string());
|
||||
life_lock = self.lock_life();
|
||||
}
|
||||
|
||||
// 2) Complete any outstanding mapAsync() steps.
|
||||
@ -3374,6 +3382,9 @@ impl<A: HalApi> Device<A> {
|
||||
// since that will prevent any new work from being added to the queues.
|
||||
// Future calls to poll_devices will continue to check the work queues
|
||||
// until they are cleared, and then drop the device.
|
||||
|
||||
// Eagerly release GPU resources.
|
||||
life_lock.release_gpu_resources();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user