Skip to content

Commit efb35d4

Browse files
authored
Snatch bind groups associated with destroyed textures and buffers (#5136)
* Make bind groups snatchable * Snatch bindgroups when destroying associated textures and buffers.
1 parent 7d0f656 commit efb35d4

File tree

6 files changed

+64
-5
lines changed

6 files changed

+64
-5
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ env:
7676
jobs:
7777
check:
7878
# runtime is normally 2-8 minutes
79-
timeout-minutes: 15
79+
#
80+
# currently high due to documentation time problems on mac.
81+
timeout-minutes: 30
8082

8183
strategy:
8284
fail-fast: false

wgpu-core/src/binding_model.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::{
1313
init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction},
1414
resource::{Resource, ResourceInfo, ResourceType},
1515
resource_log,
16-
snatch::SnatchGuard,
16+
snatch::{SnatchGuard, Snatchable},
1717
track::{BindGroupStates, UsageConflict},
1818
validation::{MissingBufferUsageError, MissingTextureUsageError},
1919
Label,
@@ -833,7 +833,7 @@ pub(crate) fn buffer_binding_type_alignment(
833833

834834
#[derive(Debug)]
835835
pub struct BindGroup<A: HalApi> {
836-
pub(crate) raw: Option<A::BindGroup>,
836+
pub(crate) raw: Snatchable<A::BindGroup>,
837837
pub(crate) device: Arc<Device<A>>,
838838
pub(crate) layout: Arc<BindGroupLayout<A>>,
839839
pub(crate) info: ResourceInfo<BindGroupId>,
@@ -874,7 +874,7 @@ impl<A: HalApi> BindGroup<A> {
874874
for texture in &self.used_texture_ranges {
875875
let _ = texture.texture.raw(guard)?;
876876
}
877-
self.raw.as_ref()
877+
self.raw.get(guard)
878878
}
879879
pub(crate) fn validate_dynamic_bindings(
880880
&self,

wgpu-core/src/device/global.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,6 +1130,15 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
11301130
};
11311131

11321132
let (id, resource) = fid.assign(bind_group);
1133+
1134+
let weak_ref = Arc::downgrade(&resource);
1135+
for range in &resource.used_texture_ranges {
1136+
range.texture.bind_groups.lock().push(weak_ref.clone());
1137+
}
1138+
for range in &resource.used_buffer_ranges {
1139+
range.buffer.bind_groups.lock().push(weak_ref.clone());
1140+
}
1141+
11331142
api_log!("Device::create_bind_group -> {id:?}");
11341143

11351144
device

wgpu-core/src/device/resource.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,7 @@ impl<A: HalApi> Device<A> {
566566
sync_mapped_writes: Mutex::new(None),
567567
map_state: Mutex::new(resource::BufferMapState::Idle),
568568
info: ResourceInfo::new(desc.label.borrow_or_default()),
569+
bind_groups: Mutex::new(Vec::new()),
569570
})
570571
}
571572

@@ -596,6 +597,7 @@ impl<A: HalApi> Device<A> {
596597
info: ResourceInfo::new(desc.label.borrow_or_default()),
597598
clear_mode: RwLock::new(clear_mode),
598599
views: Mutex::new(Vec::new()),
600+
bind_groups: Mutex::new(Vec::new()),
599601
}
600602
}
601603

@@ -615,6 +617,7 @@ impl<A: HalApi> Device<A> {
615617
sync_mapped_writes: Mutex::new(None),
616618
map_state: Mutex::new(resource::BufferMapState::Idle),
617619
info: ResourceInfo::new(desc.label.borrow_or_default()),
620+
bind_groups: Mutex::new(Vec::new()),
618621
}
619622
}
620623

@@ -2199,7 +2202,7 @@ impl<A: HalApi> Device<A> {
21992202
};
22002203

22012204
Ok(binding_model::BindGroup {
2202-
raw: Some(raw),
2205+
raw: Snatchable::new(raw),
22032206
device: self.clone(),
22042207
layout: layout.clone(),
22052208
info: ResourceInfo::new(desc.label.borrow_or_default()),

wgpu-core/src/present.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
232232
clear_view: Some(clear_view),
233233
}),
234234
views: Mutex::new(Vec::new()),
235+
bind_groups: Mutex::new(Vec::new()),
235236
};
236237

237238
let (id, resource) = fid.assign(texture);

wgpu-core/src/resource.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#[cfg(feature = "trace")]
22
use crate::device::trace;
33
use crate::{
4+
binding_model::BindGroup,
45
device::{
56
queue, BufferMapPendingClosure, Device, DeviceError, HostMap, MissingDownlevelFlags,
67
MissingFeatures,
@@ -378,6 +379,7 @@ pub struct Buffer<A: HalApi> {
378379
pub(crate) sync_mapped_writes: Mutex<Option<hal::MemoryRange>>,
379380
pub(crate) info: ResourceInfo<BufferId>,
380381
pub(crate) map_state: Mutex<BufferMapState<A>>,
382+
pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup<A>>>>,
381383
}
382384

383385
impl<A: HalApi> Drop for Buffer<A> {
@@ -541,12 +543,18 @@ impl<A: HalApi> Buffer<A> {
541543
}
542544
};
543545

546+
let bind_groups = {
547+
let mut guard = self.bind_groups.lock();
548+
std::mem::take(&mut *guard)
549+
};
550+
544551
queue::TempResource::DestroyedBuffer(Arc::new(DestroyedBuffer {
545552
raw: Some(raw),
546553
device: Arc::clone(&self.device),
547554
submission_index: self.info.submission_index(),
548555
id: self.info.id.unwrap(),
549556
label: self.info.label.clone(),
557+
bind_groups,
550558
}))
551559
};
552560

@@ -596,6 +604,29 @@ impl<A: HalApi> Resource<BufferId> for Buffer<A> {
596604
}
597605
}
598606

607+
fn snatch_and_destroy_bind_groups<A: HalApi>(
608+
device: &Device<A>,
609+
bind_groups: &[Weak<BindGroup<A>>],
610+
) {
611+
for bind_group in bind_groups {
612+
if let Some(bind_group) = bind_group.upgrade() {
613+
if let Some(raw_bind_group) = bind_group.raw.snatch(device.snatchable_lock.write()) {
614+
resource_log!("Destroy raw BindGroup (destroyed) {:?}", bind_group.label());
615+
616+
#[cfg(feature = "trace")]
617+
if let Some(t) = device.trace.lock().as_mut() {
618+
t.add(trace::Action::DestroyBindGroup(bind_group.info.id()));
619+
}
620+
621+
unsafe {
622+
use hal::Device;
623+
device.raw().destroy_bind_group(raw_bind_group);
624+
}
625+
}
626+
}
627+
}
628+
}
629+
599630
/// A buffer that has been marked as destroyed and is staged for actual deletion soon.
600631
#[derive(Debug)]
601632
pub struct DestroyedBuffer<A: HalApi> {
@@ -604,6 +635,7 @@ pub struct DestroyedBuffer<A: HalApi> {
604635
label: String,
605636
pub(crate) id: BufferId,
606637
pub(crate) submission_index: u64,
638+
bind_groups: Vec<Weak<BindGroup<A>>>,
607639
}
608640

609641
impl<A: HalApi> DestroyedBuffer<A> {
@@ -618,6 +650,8 @@ impl<A: HalApi> DestroyedBuffer<A> {
618650

619651
impl<A: HalApi> Drop for DestroyedBuffer<A> {
620652
fn drop(&mut self) {
653+
snatch_and_destroy_bind_groups(&self.device, &self.bind_groups);
654+
621655
if let Some(raw) = self.raw.take() {
622656
resource_log!("Destroy raw Buffer (destroyed) {:?}", self.label());
623657

@@ -742,6 +776,7 @@ pub struct Texture<A: HalApi> {
742776
pub(crate) info: ResourceInfo<TextureId>,
743777
pub(crate) clear_mode: RwLock<TextureClearMode<A>>,
744778
pub(crate) views: Mutex<Vec<Weak<TextureView<A>>>>,
779+
pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup<A>>>>,
745780
}
746781

747782
impl<A: HalApi> Drop for Texture<A> {
@@ -858,9 +893,15 @@ impl<A: HalApi> Texture<A> {
858893
std::mem::take(&mut *guard)
859894
};
860895

896+
let bind_groups = {
897+
let mut guard = self.bind_groups.lock();
898+
std::mem::take(&mut *guard)
899+
};
900+
861901
queue::TempResource::DestroyedTexture(Arc::new(DestroyedTexture {
862902
raw: Some(raw),
863903
views,
904+
bind_groups,
864905
device: Arc::clone(&self.device),
865906
submission_index: self.info.submission_index(),
866907
id: self.info.id.unwrap(),
@@ -978,6 +1019,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
9781019
pub struct DestroyedTexture<A: HalApi> {
9791020
raw: Option<A::Texture>,
9801021
views: Vec<Weak<TextureView<A>>>,
1022+
bind_groups: Vec<Weak<BindGroup<A>>>,
9811023
device: Arc<Device<A>>,
9821024
label: String,
9831025
pub(crate) id: TextureId,
@@ -997,6 +1039,8 @@ impl<A: HalApi> DestroyedTexture<A> {
9971039
impl<A: HalApi> Drop for DestroyedTexture<A> {
9981040
fn drop(&mut self) {
9991041
let device = &self.device;
1042+
snatch_and_destroy_bind_groups(device, &self.bind_groups);
1043+
10001044
for view in self.views.drain(..) {
10011045
if let Some(view) = view.upgrade() {
10021046
if let Some(raw_view) = view.raw.snatch(device.snatchable_lock.write()) {

0 commit comments

Comments
 (0)