From 59388e329f5f81690979df2ae5c180dcefacf312 Mon Sep 17 00:00:00 2001 From: Rukai Date: Mon, 10 Jun 2019 16:02:46 +1000 Subject: [PATCH] Free descriptor sets --- wgpu-native/src/binding_model.rs | 3 ++ wgpu-native/src/device.rs | 54 +++++++++++++++++++++++++++++--- wgpu-native/src/track.rs | 6 ++++ 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/wgpu-native/src/binding_model.rs b/wgpu-native/src/binding_model.rs index 32dbdc3e77..2d2cecfcde 100644 --- a/wgpu-native/src/binding_model.rs +++ b/wgpu-native/src/binding_model.rs @@ -3,8 +3,10 @@ use crate::{ BindGroupLayoutId, BufferAddress, BufferId, + DeviceId, LifeGuard, SamplerId, + Stored, TextureViewId, }; @@ -97,6 +99,7 @@ pub struct BindGroupDescriptor { pub struct BindGroup { pub(crate) raw: DescriptorSet, + pub(crate) device_id: Stored, pub(crate) layout_id: BindGroupLayoutId, pub(crate) life_guard: LifeGuard, pub(crate) used: TrackerSet, diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index 7d83fad4f6..8254a0c1f8 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -49,7 +49,7 @@ use hal::{ }; use log::{info, trace}; use parking_lot::Mutex; -use rendy_descriptor::{DescriptorAllocator, DescriptorRanges}; +use rendy_descriptor::{DescriptorSet, DescriptorAllocator, DescriptorRanges}; use rendy_memory::{Block, Heaps, MemoryBlock}; #[cfg(feature = "local")] @@ -111,6 +111,7 @@ enum ResourceId { Buffer(BufferId), Texture(TextureId), TextureView(TextureViewId), + BindGroup(BindGroupId), } enum NativeResource { @@ -118,6 +119,7 @@ enum NativeResource { Image(B::Image, MemoryBlock), ImageView(B::ImageView), Framebuffer(B::Framebuffer), + DescriptorSet(DescriptorSet), } struct ActiveSubmission { @@ -175,6 +177,7 @@ impl PendingResources { &mut self, device: &B::Device, heaps_mutex: &Mutex>, + descriptor_allocator_mutex: &Mutex>, force_wait: bool, ) -> SubmissionIndex { if force_wait && !self.active.is_empty() { @@ -211,6 +214,7 @@ impl PendingResources { } let mut heaps = heaps_mutex.lock(); + let mut descriptor_allocator = descriptor_allocator_mutex.lock(); for resource in self.free.drain(..) { match resource { NativeResource::Buffer(raw, memory) => unsafe { @@ -227,6 +231,9 @@ impl PendingResources { NativeResource::Framebuffer(raw) => unsafe { device.destroy_framebuffer(raw); }, + NativeResource::DescriptorSet(raw) => unsafe { + descriptor_allocator.free(Some(raw).into_iter()); + }, } } @@ -274,6 +281,11 @@ impl PendingResources { let view = HUB.texture_views.unregister(id); (view.life_guard, NativeResource::ImageView(view.raw)) } + ResourceId::BindGroup(id) => { + trackers.bind_groups.remove(id); + let bind_group = HUB.bind_groups.unregister(id); + (bind_group.life_guard, NativeResource::DescriptorSet(bind_group.raw)) + } }; let submit_index = life_guard.submission_index.load(Ordering::Acquire); @@ -455,6 +467,7 @@ impl Device { unsafe { Heaps::new(types, mem_props.memory_heaps.iter().cloned()) } + }; Device { @@ -486,9 +499,15 @@ impl Device { pending.triage_referenced(&mut *trackers); pending.triage_framebuffers(&mut *self.framebuffers.lock()); - let last_done = pending.cleanup(&self.raw, &self.mem_allocator, force_wait); + let last_done = pending.cleanup(&self.raw, &self.mem_allocator, &self.desc_allocator, force_wait); let callbacks = pending.handle_mapping(&self.raw); + unsafe { + self.desc_allocator + .lock() + .cleanup(&self.raw); + } + if last_done != 0 { self.com_allocator.maintain(last_done); } @@ -1090,6 +1109,10 @@ pub fn device_create_bind_group( binding_model::BindGroup { raw: desc_set, + device_id: Stored { + value: device_id, + ref_count: device.life_guard.ref_count.clone(), + }, layout_id: desc.layout, life_guard: LifeGuard::new(), used, @@ -1097,6 +1120,19 @@ pub fn device_create_bind_group( } } +pub fn device_track_bind_group( + device_id: DeviceId, + buffer_id: BindGroupId, + ref_count: RefCount, +) { + let query = HUB.devices.read()[device_id] + .trackers + .lock() + .bind_groups + .query(buffer_id, &ref_count, DummyUsage); + assert!(query.initialized); +} + #[cfg(feature = "local")] #[no_mangle] pub extern "C" fn wgpu_device_create_bind_group( @@ -1104,12 +1140,22 @@ pub extern "C" fn wgpu_device_create_bind_group( desc: &binding_model::BindGroupDescriptor, ) -> BindGroupId { let bind_group = device_create_bind_group(device_id, desc); - HUB.bind_groups.register_local(bind_group) + let ref_count = bind_group.life_guard.ref_count.clone(); + let id = HUB.bind_groups.register_local(bind_group); + device_track_bind_group(device_id, id, ref_count); + + id } #[no_mangle] pub extern "C" fn wgpu_bind_group_destroy(bind_group_id: BindGroupId) { - HUB.bind_groups.unregister(bind_group_id); + let device_guard = HUB.devices.read(); + let bind_group_guard = HUB.bind_groups.read(); + let bind_group = &bind_group_guard[bind_group_id]; + device_guard[bind_group.device_id.value].pending.lock().destroy( + ResourceId::BindGroup(bind_group_id), + bind_group.life_guard.ref_count.clone(), + ); } pub fn device_create_shader_module( diff --git a/wgpu-native/src/track.rs b/wgpu-native/src/track.rs index 7b31d175da..84006e4aef 100644 --- a/wgpu-native/src/track.rs +++ b/wgpu-native/src/track.rs @@ -8,6 +8,7 @@ use crate::{ TextureId, TextureViewId, TypedId, + BindGroupId, }; use bitflags::bitflags; @@ -101,6 +102,7 @@ pub struct Tracker { pub type BufferTracker = Tracker; pub type TextureTracker = Tracker; pub type TextureViewTracker = Tracker; +pub type BindGroupTracker = Tracker; //TODO: make this a generic parameter. /// Mode of stitching to states together. @@ -156,6 +158,7 @@ pub struct TrackerSet { pub buffers: BufferTracker, pub textures: TextureTracker, pub views: TextureViewTracker, + pub bind_groups: BindGroupTracker, //TODO: samplers } @@ -165,6 +168,7 @@ impl TrackerSet { buffers: BufferTracker::new(), textures: TextureTracker::new(), views: TextureViewTracker::new(), + bind_groups: BindGroupTracker::new(), } } @@ -172,12 +176,14 @@ impl TrackerSet { self.buffers.clear(); self.textures.clear(); self.views.clear(); + self.bind_groups.clear(); } pub fn consume_by_extend(&mut self, other: &Self) { self.buffers.consume_by_extend(&other.buffers).unwrap(); self.textures.consume_by_extend(&other.textures).unwrap(); self.views.consume_by_extend(&other.views).unwrap(); + self.bind_groups.consume_by_extend(&other.bind_groups).unwrap(); } }