341: Track and destroy samplers r=kvark a=yanchith

This PR adds `ResourceId::Sampler`, `NativeResource::Sampler` and
`TrackerSet::samplers`. Samplers are (similarly to bind groups)
created with their own life guard and a device id to keep the device
ref count alive. Also added are `extern wgpu_sampler_destroy` and
`sampler_destroy`.

The rest of the implementation was guided by compiler errors, so there
is a good chance I didn't find something crucial that also needed
doing. Please check :)

I also imagine we might want to add the `Drop` impl for sampler in wgpu-rs.

Fixes: #231 

Co-authored-by: yanchith <yanchi.toth@gmail.com>
This commit is contained in:
bors[bot] 2019-09-24 17:11:49 +00:00 committed by GitHub
commit cbe197eb44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 77 additions and 5 deletions

View File

@ -899,6 +899,8 @@ void wgpu_render_pass_set_viewport(WGPURenderPassId pass_id,
WGPUAdapterId wgpu_request_adapter(const WGPURequestAdapterOptions *desc);
#endif
void wgpu_sampler_destroy(WGPUSamplerId sampler_id);
#if !defined(WGPU_REMOTE)
WGPUSwapChainOutput wgpu_swap_chain_get_next_texture(WGPUSwapChainId swap_chain_id);
#endif

View File

@ -160,6 +160,7 @@ impl<B: GfxBackend> CommandBuffer<B> {
});
base.views.merge_extend(&head.views).unwrap();
base.bind_groups.merge_extend(&head.bind_groups).unwrap();
base.samplers.merge_extend(&head.samplers).unwrap();
let stages = all_buffer_stages() | all_image_stages();
unsafe {

View File

@ -135,6 +135,7 @@ enum ResourceId {
Texture(TextureId),
TextureView(TextureViewId),
BindGroup(BindGroupId),
Sampler(SamplerId),
}
#[derive(Debug)]
@ -144,6 +145,7 @@ enum NativeResource<B: hal::Backend> {
ImageView(B::ImageView),
Framebuffer(B::Framebuffer),
DescriptorSet(DescriptorSet<B>),
Sampler(B::Sampler),
}
#[derive(Debug)]
@ -257,6 +259,9 @@ impl<B: GfxBackend> PendingResources<B> {
NativeResource::DescriptorSet(raw) => unsafe {
descriptor_allocator.free(iter::once(raw));
},
NativeResource::Sampler(raw) => unsafe {
device.destroy_sampler(raw);
},
}
}
@ -279,7 +284,8 @@ impl<B: GfxBackend> PendingResources<B> {
let (mut bind_group_guard, mut token) = hub.bind_groups.write(&mut token);
let (mut buffer_guard, mut token) = hub.buffers.write(&mut token);
let (mut texture_guard, mut token) = hub.textures.write(&mut token);
let (mut teview_view_guard, _) = hub.texture_views.write(&mut token);
let (mut teview_view_guard, mut token) = hub.texture_views.write(&mut token);
let (mut sampler_guard, _) = hub.samplers.write(&mut token);
for i in (0 .. self.referenced.len()).rev() {
let num_refs = self.referenced[i].1.load();
@ -329,6 +335,13 @@ impl<B: GfxBackend> PendingResources<B> {
NativeResource::DescriptorSet(bind_group.raw),
)
}
ResourceId::Sampler(id) => {
trackers.samplers.remove(id);
let sampler = sampler_guard.remove(id).unwrap();
#[cfg(not(feature = "remote"))]
hub.samplers.identity.lock().free(id);
(sampler.life_guard, NativeResource::Sampler(sampler.raw))
}
};
let submit_index = life_guard.submission_index.load(Ordering::Acquire);
@ -1041,6 +1054,11 @@ pub fn device_create_sampler<B: GfxBackend>(
let sampler = resource::Sampler {
raw: unsafe { device.raw.create_sampler(info).unwrap() },
device_id: Stored {
value: device_id,
ref_count: device.life_guard.ref_count.clone(),
},
life_guard: LifeGuard::new(),
};
hub.samplers.register_identity(id_in, sampler, &mut token)
}
@ -1054,6 +1072,26 @@ pub extern "C" fn wgpu_device_create_sampler(
gfx_select!(device_id => device_create_sampler(device_id, desc, PhantomData))
}
pub fn sampler_destroy<B: GfxBackend>(sampler_id: SamplerId) {
let hub = B::hub();
let mut token = Token::root();
let (device_guard, mut token) = hub.devices.read(&mut token);
let (sampler_guard, _) = hub.samplers.read(&mut token);
let sampler = &sampler_guard[sampler_id];
device_guard[sampler.device_id.value]
.pending
.lock()
.destroy(
ResourceId::Sampler(sampler_id),
sampler.life_guard.ref_count.clone(),
);
}
#[no_mangle]
pub extern "C" fn wgpu_sampler_destroy(sampler_id: SamplerId) {
gfx_select!(sampler_id => sampler_destroy(sampler_id))
}
pub fn device_create_bind_group_layout<B: GfxBackend>(
device_id: DeviceId,
desc: &binding_model::BindGroupLayoutDescriptor,
@ -1235,7 +1273,9 @@ pub fn device_create_bind_group<B: GfxBackend>(
}
binding_model::BindingResource::Sampler(id) => {
assert_eq!(decl.ty, binding_model::BindingType::Sampler);
let sampler = &sampler_guard[id];
let sampler = used.samplers
.use_extend(&*sampler_guard, id, (), ())
.unwrap();
hal::pso::Descriptor::Sampler(&sampler.raw)
}
binding_model::BindingResource::TextureView(id) => {
@ -1433,7 +1473,8 @@ pub fn queue_submit<B: GfxBackend>(queue_id: QueueId, command_buffer_ids: &[Comm
let (bind_group_guard, mut token) = hub.bind_groups.read(&mut token);
let (buffer_guard, mut token) = hub.buffers.read(&mut token);
let (texture_guard, mut token) = hub.textures.read(&mut token);
let (mut texture_view_guard, _) = hub.texture_views.write(&mut token);
let (mut texture_view_guard, mut token) = hub.texture_views.write(&mut token);
let (sampler_guard, _) = hub.samplers.read(&mut token);
//TODO: if multiple command buffers are submitted, we can re-use the last
// native command buffer of the previous chain instead of always creating
@ -1486,6 +1527,12 @@ pub fn queue_submit<B: GfxBackend>(queue_id: QueueId, command_buffer_ids: &[Comm
.submission_index
.store(submit_index, Ordering::Release);
}
for id in comb.trackers.samplers.used() {
sampler_guard[id]
.life_guard
.submission_index
.store(submit_index, Ordering::Release);
}
// execute resource transitions
let mut transit = device.com_allocator.extend(comb);

View File

@ -360,4 +360,12 @@ pub struct SamplerDescriptor {
#[derive(Debug)]
pub struct Sampler<B: hal::Backend> {
pub(crate) raw: B::Sampler,
pub(crate) device_id: Stored<DeviceId>,
pub(crate) life_guard: LifeGuard,
}
impl<B: hal::Backend> Borrow<RefCount> for Sampler<B> {
fn borrow(&self) -> &RefCount {
&self.life_guard.ref_count
}
}

View File

@ -2,7 +2,17 @@ mod buffer;
mod range;
mod texture;
use crate::{hub::Storage, Backend, BindGroupId, Epoch, Index, RefCount, TextureViewId, TypedId};
use crate::{
hub::Storage,
Backend,
BindGroupId,
Epoch,
Index,
RefCount,
SamplerId,
TextureViewId,
TypedId,
};
use hal::backend::FastHashMap;
@ -410,7 +420,7 @@ pub struct TrackerSet {
pub textures: ResourceTracker<TextureState>,
pub views: ResourceTracker<PhantomData<TextureViewId>>,
pub bind_groups: ResourceTracker<PhantomData<BindGroupId>>,
//TODO: samplers
pub samplers: ResourceTracker<PhantomData<SamplerId>>,
}
impl TrackerSet {
@ -421,6 +431,7 @@ impl TrackerSet {
textures: ResourceTracker::new(backend),
views: ResourceTracker::new(backend),
bind_groups: ResourceTracker::new(backend),
samplers: ResourceTracker::new(backend),
}
}
@ -430,6 +441,7 @@ impl TrackerSet {
self.textures.clear();
self.views.clear();
self.bind_groups.clear();
self.samplers.clear();
}
/// Try to optimize the tracking representation.
@ -438,6 +450,7 @@ impl TrackerSet {
self.textures.optimize();
self.views.optimize();
self.bind_groups.optimize();
self.samplers.optimize();
}
/// Merge all the trackers of another instance by extending
@ -447,6 +460,7 @@ impl TrackerSet {
self.textures.merge_extend(&other.textures).unwrap();
self.views.merge_extend(&other.views).unwrap();
self.bind_groups.merge_extend(&other.bind_groups).unwrap();
self.samplers.merge_extend(&other.samplers).unwrap();
}
pub fn backend(&self) -> Backend {