Save bind group layout inside pipeline layouts

This commit is contained in:
Dzmitry Malyshau 2020-05-04 23:46:06 -04:00
parent 14d44c2d84
commit 367e09a022
5 changed files with 63 additions and 13 deletions

View File

@ -64,6 +64,7 @@ pub struct BindGroupLayoutDescriptor {
pub struct BindGroupLayout<B: hal::Backend> {
pub(crate) raw: B::DescriptorSetLayout,
pub(crate) device_id: Stored<DeviceId>,
pub(crate) life_guard: LifeGuard,
pub(crate) entries: FastHashMap<u32, BindGroupLayoutEntry>,
pub(crate) desc_counts: DescriptorCounts,
pub(crate) dynamic_count: usize,
@ -81,7 +82,7 @@ pub struct PipelineLayout<B: hal::Backend> {
pub(crate) raw: B::PipelineLayout,
pub(crate) device_id: Stored<DeviceId>,
pub(crate) life_guard: LifeGuard,
pub(crate) bind_group_layout_ids: ArrayVec<[BindGroupLayoutId; wgt::MAX_BIND_GROUPS]>,
pub(crate) bind_group_layout_ids: ArrayVec<[Stored<BindGroupLayoutId>; wgt::MAX_BIND_GROUPS]>,
}
#[repr(C)]

View File

@ -182,13 +182,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
binder.reset_expectations(pipeline_layout.bind_group_layout_ids.len());
let mut is_compatible = true;
for (index, (entry, &bgl_id)) in binder
for (index, (entry, bgl_id)) in binder
.entries
.iter_mut()
.zip(&pipeline_layout.bind_group_layout_ids)
.enumerate()
{
match entry.expect_layout(bgl_id) {
match entry.expect_layout(bgl_id.value) {
LayoutChange::Match(bg_id, offsets) if is_compatible => {
let desc_set = bind_group_guard[bg_id].raw.raw();
unsafe {

View File

@ -944,14 +944,14 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.reset_expectations(pipeline_layout.bind_group_layout_ids.len());
let mut is_compatible = true;
for (index, (entry, &bgl_id)) in state
for (index, (entry, bgl_id)) in state
.binder
.entries
.iter_mut()
.zip(&pipeline_layout.bind_group_layout_ids)
.enumerate()
{
match entry.expect_layout(bgl_id) {
match entry.expect_layout(bgl_id.value) {
LayoutChange::Match(bg_id, offsets) if is_compatible => {
let desc_set = bind_group_guard[bg_id].raw.raw();
unsafe {

View File

@ -29,6 +29,7 @@ pub struct SuspectedResources {
pub(crate) bind_groups: Vec<id::BindGroupId>,
pub(crate) compute_pipelines: Vec<id::ComputePipelineId>,
pub(crate) render_pipelines: Vec<id::RenderPipelineId>,
pub(crate) bind_group_layouts: Vec<Stored<id::BindGroupLayoutId>>,
pub(crate) pipeline_layouts: Vec<Stored<id::PipelineLayoutId>>,
}
@ -41,6 +42,7 @@ impl SuspectedResources {
self.bind_groups.clear();
self.compute_pipelines.clear();
self.render_pipelines.clear();
self.bind_group_layouts.clear();
self.pipeline_layouts.clear();
}
@ -54,6 +56,8 @@ impl SuspectedResources {
.extend_from_slice(&other.compute_pipelines);
self.render_pipelines
.extend_from_slice(&other.render_pipelines);
self.bind_group_layouts
.extend_from_slice(&other.bind_group_layouts);
self.pipeline_layouts
.extend_from_slice(&other.pipeline_layouts);
}
@ -72,6 +76,7 @@ struct NonReferencedResources<B: hal::Backend> {
desc_sets: Vec<DescriptorSet<B>>,
compute_pipes: Vec<B::ComputePipeline>,
graphics_pipes: Vec<B::GraphicsPipeline>,
descriptor_set_layouts: Vec<B::DescriptorSetLayout>,
pipeline_layouts: Vec<B::PipelineLayout>,
}
@ -86,6 +91,7 @@ impl<B: hal::Backend> NonReferencedResources<B> {
desc_sets: Vec::new(),
compute_pipes: Vec::new(),
graphics_pipes: Vec::new(),
descriptor_set_layouts: Vec::new(),
pipeline_layouts: Vec::new(),
}
}
@ -99,6 +105,8 @@ impl<B: hal::Backend> NonReferencedResources<B> {
self.desc_sets.extend(other.desc_sets);
self.compute_pipes.extend(other.compute_pipes);
self.graphics_pipes.extend(other.graphics_pipes);
assert!(other.descriptor_set_layouts.is_empty());
assert!(other.pipeline_layouts.is_empty());
}
unsafe fn clean(
@ -145,6 +153,9 @@ impl<B: hal::Backend> NonReferencedResources<B> {
for raw in self.graphics_pipes.drain(..) {
device.destroy_graphics_pipeline(raw);
}
for raw in self.descriptor_set_layouts.drain(..) {
device.destroy_descriptor_set_layout(raw);
}
for raw in self.pipeline_layouts.drain(..) {
device.destroy_pipeline_layout(raw);
}
@ -455,6 +466,25 @@ impl<B: GfxBackend> LifetimeTracker<B> {
}
}
if !self.suspected_resources.bind_group_layouts.is_empty() {
let (mut guard, _) = hub.bind_group_layouts.write(token);
for Stored {
value: id,
ref_count,
} in self.suspected_resources.bind_group_layouts.drain(..)
{
//Note: this has to happen after all the suspected pipelines are destroyed
if ref_count.load() == 1 {
#[cfg(feature = "trace")]
trace.map(|t| t.lock().add(trace::Action::DestroyBindGroupLayout(id)));
hub.bind_group_layouts.free_id(id);
let layout = guard.remove(id).unwrap();
self.free_resources.descriptor_set_layouts.push(layout.raw);
}
}
}
if !self.suspected_resources.pipeline_layouts.is_empty() {
let (mut guard, _) = hub.pipeline_layouts.write(token);

View File

@ -943,6 +943,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
value: device_id,
ref_count: device.life_guard.add_ref(),
},
life_guard: LifeGuard::new(),
entries: entry_map,
desc_counts: raw_bindings.iter().cloned().collect(),
dynamic_count: entries.iter().filter(|b| b.has_dynamic_offset).count(),
@ -958,15 +959,24 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
) {
let hub = B::hub(self);
let mut token = Token::root();
let (device_id, ref_count) = {
let (mut bind_group_layout_guard, _) = hub.bind_group_layouts.write(&mut token);
let layout = &mut bind_group_layout_guard[bind_group_layout_id];
(
layout.device_id.value,
layout.life_guard.ref_count.take().unwrap(),
)
};
let (device_guard, mut token) = hub.devices.read(&mut token);
let (bgl, _) = hub
device_guard[device_id]
.lock_life(&mut token)
.suspected_resources
.bind_group_layouts
.unregister(bind_group_layout_id, &mut token);
unsafe {
device_guard[bgl.device_id.value]
.raw
.destroy_descriptor_set_layout(bgl.raw);
}
.push(Stored {
value: bind_group_layout_id,
ref_count,
});
}
pub fn device_create_pipeline_layout<B: GfxBackend>(
@ -1008,7 +1018,16 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
ref_count: device.life_guard.add_ref(),
},
life_guard: LifeGuard::new(),
bind_group_layout_ids: bind_group_layout_ids.iter().cloned().collect(),
bind_group_layout_ids: {
let (bind_group_layout_guard, _) = hub.bind_group_layouts.read(&mut token);
bind_group_layout_ids
.iter()
.map(|&id| Stored {
value: id,
ref_count: bind_group_layout_guard[id].life_guard.add_ref(),
})
.collect()
},
};
hub.pipeline_layouts
.register_identity(id_in, layout, &mut token)