Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release GPU resources from device.trackers, not from lifetime_tracker. #5075

Merged
merged 1 commit into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ Bottom level categories:

### New features

#### General

- Many numeric built-ins have had a constant evaluation implementation added for them, which allows them to be used in a `const` context:
- [#4879](https://github.com/gfx-rs/wgpu/pull/4879) by @ErichDonGubler:
- `abs`
Expand All @@ -64,6 +66,8 @@ Bottom level categories:
- `step`
- `tan`
- `tanh`
- Eager release of GPU resources comes from device.trackers. By @bradwerth in [#5075](https://github.com/gfx-rs/wgpu/pull/5075)


### Bug Fixes

Expand Down
43 changes: 0 additions & 43 deletions wgpu-core/src/device/life.rs
Original file line number Diff line number Diff line change
Expand Up @@ -837,47 +837,4 @@ 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();
}
*/
}
}
24 changes: 21 additions & 3 deletions wgpu-core/src/device/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ impl<A: HalApi> Device<A> {
let mut device_lost_invocations = SmallVec::new();
if !self.is_valid() && life_tracker.queue_empty() {
// We can release gpu resources associated with this device.
life_tracker.release_gpu_resources();
self.release_gpu_resources();

// If we have a DeviceLostClosure, build an invocation with the
// reason DeviceLostReason::Destroyed and no message.
Expand Down Expand Up @@ -3331,7 +3331,6 @@ impl<A: HalApi> Device<A> {
// 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.
Expand All @@ -3343,7 +3342,26 @@ impl<A: HalApi> Device<A> {
// until they are cleared, and then drop the device.

// Eagerly release GPU resources.
life_lock.release_gpu_resources();
self.release_gpu_resources();
}

pub(crate) fn release_gpu_resources(&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.

// During these iterations, we discard all errors. We don't care!
let trackers = self.trackers.lock();
for buffer in trackers.buffers.used_resources() {
let _ = buffer.destroy();
}
for texture in trackers.textures.used_resources() {
let _ = texture.destroy();
}
}
}

Expand Down