mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 14:55:05 +00:00
Track pipeline layout lifetime
This commit is contained in:
parent
49dbe08f37
commit
3cc4fa51bc
@ -80,6 +80,7 @@ pub struct PipelineLayoutDescriptor {
|
||||
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]>,
|
||||
}
|
||||
|
||||
|
@ -176,9 +176,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
}
|
||||
|
||||
// Rebind resources
|
||||
if binder.pipeline_layout_id != Some(pipeline.layout_id) {
|
||||
let pipeline_layout = &pipeline_layout_guard[pipeline.layout_id];
|
||||
binder.pipeline_layout_id = Some(pipeline.layout_id);
|
||||
if binder.pipeline_layout_id != Some(pipeline.layout_id.value) {
|
||||
let pipeline_layout = &pipeline_layout_guard[pipeline.layout_id.value];
|
||||
binder.pipeline_layout_id = Some(pipeline.layout_id.value);
|
||||
binder.reset_expectations(pipeline_layout.bind_group_layout_ids.len());
|
||||
let mut is_compatible = true;
|
||||
|
||||
|
@ -896,9 +896,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
}
|
||||
|
||||
// Rebind resource
|
||||
if state.binder.pipeline_layout_id != Some(pipeline.layout_id) {
|
||||
let pipeline_layout = &pipeline_layout_guard[pipeline.layout_id];
|
||||
state.binder.pipeline_layout_id = Some(pipeline.layout_id);
|
||||
if state.binder.pipeline_layout_id != Some(pipeline.layout_id.value) {
|
||||
let pipeline_layout = &pipeline_layout_guard[pipeline.layout_id.value];
|
||||
state.binder.pipeline_layout_id = Some(pipeline.layout_id.value);
|
||||
state
|
||||
.binder
|
||||
.reset_expectations(pipeline_layout.bind_group_layout_ids.len());
|
||||
|
@ -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) pipeline_layouts: Vec<Stored<id::PipelineLayoutId>>,
|
||||
}
|
||||
|
||||
impl SuspectedResources {
|
||||
@ -40,6 +41,7 @@ impl SuspectedResources {
|
||||
self.bind_groups.clear();
|
||||
self.compute_pipelines.clear();
|
||||
self.render_pipelines.clear();
|
||||
self.pipeline_layouts.clear();
|
||||
}
|
||||
|
||||
pub fn extend(&mut self, other: &Self) {
|
||||
@ -52,6 +54,8 @@ impl SuspectedResources {
|
||||
.extend_from_slice(&other.compute_pipelines);
|
||||
self.render_pipelines
|
||||
.extend_from_slice(&other.render_pipelines);
|
||||
self.pipeline_layouts
|
||||
.extend_from_slice(&other.pipeline_layouts);
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,6 +72,7 @@ struct NonReferencedResources<B: hal::Backend> {
|
||||
desc_sets: Vec<DescriptorSet<B>>,
|
||||
compute_pipes: Vec<B::ComputePipeline>,
|
||||
graphics_pipes: Vec<B::GraphicsPipeline>,
|
||||
pipeline_layouts: Vec<B::PipelineLayout>,
|
||||
}
|
||||
|
||||
impl<B: hal::Backend> NonReferencedResources<B> {
|
||||
@ -81,6 +86,7 @@ impl<B: hal::Backend> NonReferencedResources<B> {
|
||||
desc_sets: Vec::new(),
|
||||
compute_pipes: Vec::new(),
|
||||
graphics_pipes: Vec::new(),
|
||||
pipeline_layouts: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,6 +145,9 @@ impl<B: hal::Backend> NonReferencedResources<B> {
|
||||
for raw in self.graphics_pipes.drain(..) {
|
||||
device.destroy_graphics_pipeline(raw);
|
||||
}
|
||||
for raw in self.pipeline_layouts.drain(..) {
|
||||
device.destroy_pipeline_layout(raw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -445,6 +454,23 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !self.suspected_resources.pipeline_layouts.is_empty() {
|
||||
let (mut guard, _) = hub.pipeline_layouts.write(token);
|
||||
|
||||
for Stored {
|
||||
value: id,
|
||||
ref_count,
|
||||
} in self.suspected_resources.pipeline_layouts.drain(..)
|
||||
{
|
||||
//Note: this has to happen after all the suspected pipelines are destroyed
|
||||
if ref_count.load() == 1 {
|
||||
hub.pipeline_layouts.free_id(id);
|
||||
let layout = guard.remove(id).unwrap();
|
||||
self.free_resources.pipeline_layouts.push(layout.raw);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn triage_mapped<G: GlobalIdentityHandlerFactory>(
|
||||
|
@ -1005,6 +1005,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
value: device_id,
|
||||
ref_count: device.life_guard.add_ref(),
|
||||
},
|
||||
life_guard: LifeGuard::new(),
|
||||
bind_group_layout_ids: bind_group_layout_ids.iter().cloned().collect(),
|
||||
};
|
||||
hub.pipeline_layouts
|
||||
@ -1014,15 +1015,24 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub fn pipeline_layout_destroy<B: GfxBackend>(&self, pipeline_layout_id: id::PipelineLayoutId) {
|
||||
let hub = B::hub(self);
|
||||
let mut token = Token::root();
|
||||
let (device_id, ref_count) = {
|
||||
let (mut pipeline_layout_guard, _) = hub.pipeline_layouts.write(&mut token);
|
||||
let layout = &mut pipeline_layout_guard[pipeline_layout_id];
|
||||
(
|
||||
layout.device_id.value,
|
||||
layout.life_guard.ref_count.take().unwrap(),
|
||||
)
|
||||
};
|
||||
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
let (pipeline_layout, _) = hub
|
||||
device_guard[device_id]
|
||||
.lock_life(&mut token)
|
||||
.suspected_resources
|
||||
.pipeline_layouts
|
||||
.unregister(pipeline_layout_id, &mut token);
|
||||
unsafe {
|
||||
device_guard[pipeline_layout.device_id.value]
|
||||
.raw
|
||||
.destroy_pipeline_layout(pipeline_layout.raw);
|
||||
}
|
||||
.push(Stored {
|
||||
value: pipeline_layout_id,
|
||||
ref_count,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn device_create_bind_group<B: GfxBackend>(
|
||||
@ -1667,9 +1677,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
let device = &device_guard[device_id];
|
||||
let raw_pipeline = {
|
||||
let (raw_pipeline, layout_ref_count) = {
|
||||
let (pipeline_layout_guard, mut token) = hub.pipeline_layouts.read(&mut token);
|
||||
let layout = &pipeline_layout_guard[desc.layout].raw;
|
||||
let layout = &pipeline_layout_guard[desc.layout];
|
||||
let (shader_module_guard, _) = hub.shader_modules.read(&mut token);
|
||||
|
||||
let rp_key = RenderPassKey {
|
||||
@ -1777,19 +1787,20 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
depth_stencil,
|
||||
multisampling,
|
||||
baked_states,
|
||||
layout,
|
||||
layout: &layout.raw,
|
||||
subpass,
|
||||
flags,
|
||||
parent,
|
||||
};
|
||||
|
||||
// TODO: cache
|
||||
unsafe {
|
||||
let pipeline = unsafe {
|
||||
device
|
||||
.raw
|
||||
.create_graphics_pipeline(&pipeline_desc, None)
|
||||
.unwrap()
|
||||
}
|
||||
};
|
||||
(pipeline, layout.life_guard.add_ref())
|
||||
};
|
||||
|
||||
let pass_context = RenderPassContext {
|
||||
@ -1812,7 +1823,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
let pipeline = pipeline::RenderPipeline {
|
||||
raw: raw_pipeline,
|
||||
layout_id: desc.layout,
|
||||
layout_id: Stored {
|
||||
value: desc.layout,
|
||||
ref_count: layout_ref_count,
|
||||
},
|
||||
device_id: Stored {
|
||||
value: device_id,
|
||||
ref_count: device.life_guard.add_ref(),
|
||||
@ -1834,18 +1848,22 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let mut token = Token::root();
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
|
||||
let device_id = {
|
||||
let (device_id, layout_id) = {
|
||||
let (mut pipeline_guard, _) = hub.render_pipelines.write(&mut token);
|
||||
let pipeline = &mut pipeline_guard[render_pipeline_id];
|
||||
pipeline.life_guard.ref_count.take();
|
||||
pipeline.device_id.value
|
||||
(pipeline.device_id.value, pipeline.layout_id.clone())
|
||||
};
|
||||
|
||||
device_guard[device_id]
|
||||
.lock_life(&mut token)
|
||||
let mut life_lock = device_guard[device_id].lock_life(&mut token);
|
||||
life_lock
|
||||
.suspected_resources
|
||||
.render_pipelines
|
||||
.push(render_pipeline_id);
|
||||
life_lock
|
||||
.suspected_resources
|
||||
.pipeline_layouts
|
||||
.push(layout_id);
|
||||
}
|
||||
|
||||
pub fn device_create_compute_pipeline<B: GfxBackend>(
|
||||
@ -1859,9 +1877,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
let device = &device_guard[device_id];
|
||||
let raw_pipeline = {
|
||||
let (raw_pipeline, layout_ref_count) = {
|
||||
let (pipeline_layout_guard, mut token) = hub.pipeline_layouts.read(&mut token);
|
||||
let layout = &pipeline_layout_guard[desc.layout].raw;
|
||||
let layout = &pipeline_layout_guard[desc.layout];
|
||||
let pipeline_stage = &desc.compute_stage;
|
||||
let (shader_module_guard, _) = hub.shader_modules.read(&mut token);
|
||||
|
||||
@ -1881,22 +1899,26 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
let pipeline_desc = hal::pso::ComputePipelineDesc {
|
||||
shader,
|
||||
layout,
|
||||
layout: &layout.raw,
|
||||
flags,
|
||||
parent,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let pipeline = unsafe {
|
||||
device
|
||||
.raw
|
||||
.create_compute_pipeline(&pipeline_desc, None)
|
||||
.unwrap()
|
||||
}
|
||||
};
|
||||
(pipeline, layout.life_guard.add_ref())
|
||||
};
|
||||
|
||||
let pipeline = pipeline::ComputePipeline {
|
||||
raw: raw_pipeline,
|
||||
layout_id: desc.layout,
|
||||
layout_id: Stored {
|
||||
value: desc.layout,
|
||||
ref_count: layout_ref_count,
|
||||
},
|
||||
device_id: Stored {
|
||||
value: device_id,
|
||||
ref_count: device.life_guard.add_ref(),
|
||||
@ -1915,18 +1937,22 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let mut token = Token::root();
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
|
||||
let device_id = {
|
||||
let (device_id, layout_id) = {
|
||||
let (mut pipeline_guard, _) = hub.compute_pipelines.write(&mut token);
|
||||
let pipeline = &mut pipeline_guard[compute_pipeline_id];
|
||||
pipeline.life_guard.ref_count.take();
|
||||
pipeline.device_id.value
|
||||
(pipeline.device_id.value, pipeline.layout_id.clone())
|
||||
};
|
||||
|
||||
device_guard[device_id]
|
||||
.lock_life(&mut token)
|
||||
let mut life_lock = device_guard[device_id].lock_life(&mut token);
|
||||
life_lock
|
||||
.suspected_resources
|
||||
.compute_pipelines
|
||||
.push(compute_pipeline_id);
|
||||
life_lock
|
||||
.suspected_resources
|
||||
.pipeline_layouts
|
||||
.push(layout_id);
|
||||
}
|
||||
|
||||
pub fn device_create_swap_chain<B: GfxBackend>(
|
||||
|
@ -59,7 +59,7 @@ pub struct ComputePipelineDescriptor {
|
||||
#[derive(Debug)]
|
||||
pub struct ComputePipeline<B: hal::Backend> {
|
||||
pub(crate) raw: B::ComputePipeline,
|
||||
pub(crate) layout_id: PipelineLayoutId,
|
||||
pub(crate) layout_id: Stored<PipelineLayoutId>,
|
||||
pub(crate) device_id: Stored<DeviceId>,
|
||||
pub(crate) life_guard: LifeGuard,
|
||||
}
|
||||
@ -98,7 +98,7 @@ bitflags::bitflags! {
|
||||
#[derive(Debug)]
|
||||
pub struct RenderPipeline<B: hal::Backend> {
|
||||
pub(crate) raw: B::GraphicsPipeline,
|
||||
pub(crate) layout_id: PipelineLayoutId,
|
||||
pub(crate) layout_id: Stored<PipelineLayoutId>,
|
||||
pub(crate) device_id: Stored<DeviceId>,
|
||||
pub(crate) pass_context: RenderPassContext,
|
||||
pub(crate) flags: PipelineFlags,
|
||||
|
Loading…
Reference in New Issue
Block a user