mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 16:24:24 +00:00
Save bind group layout inside pipeline layouts
This commit is contained in:
parent
14d44c2d84
commit
367e09a022
@ -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)]
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user