Save bind group layout inside pipeline layouts

This commit is contained in:
Dzmitry Malyshau
2020-05-04 23:46:06 -04:00
parent e2d59201fd
commit fbc533bfee
5 changed files with 64 additions and 21 deletions

View File

@@ -60,6 +60,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,
@@ -77,7 +78,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

@@ -186,13 +186,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

@@ -952,14 +952,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

@@ -31,6 +31,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>>,
}
@@ -43,6 +44,7 @@ impl SuspectedResources {
self.bind_groups.clear();
self.compute_pipelines.clear();
self.render_pipelines.clear();
self.bind_group_layouts.clear();
self.pipeline_layouts.clear();
}
@@ -56,6 +58,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);
}
@@ -74,6 +78,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>,
}
@@ -88,6 +93,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(),
}
}
@@ -101,6 +107,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(
@@ -147,6 +155,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);
}
@@ -472,6 +483,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

@@ -1081,6 +1081,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(),
@@ -1107,22 +1108,24 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
) {
let hub = B::hub(self);
let mut token = Token::root();
let (device_guard, mut token) = hub.devices.read(&mut token);
let (bgl, _) = hub
.bind_group_layouts
.unregister(bind_group_layout_id, &mut token);
let device = &device_guard[bgl.device_id.value];
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace
.lock()
.add(trace::Action::DestroyBindGroupLayout(bind_group_layout_id)),
None => (),
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(),
)
};
unsafe {
device.raw.destroy_descriptor_set_layout(bgl.raw);
}
let (device_guard, mut token) = hub.devices.read(&mut token);
device_guard[device_id]
.lock_life(&mut token)
.suspected_resources
.bind_group_layouts
.push(Stored {
value: bind_group_layout_id,
ref_count,
});
}
pub fn device_create_pipeline_layout<B: GfxBackend>(
@@ -1168,7 +1171,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()
},
};
let id = hub