Improve shutdown cleanup (#532)

This commit is contained in:
Dzmitry Malyshau
2020-03-24 18:03:25 -04:00
committed by GitHub
parent bf9e2db4b3
commit 272e423a5c
6 changed files with 115 additions and 43 deletions

View File

@@ -66,6 +66,7 @@ pub struct BindGroupLayoutDescriptor {
#[derive(Debug)]
pub struct BindGroupLayout<B: hal::Backend> {
pub(crate) raw: B::DescriptorSetLayout,
pub(crate) device_id: Stored<DeviceId>,
pub(crate) entries: FastHashMap<u32, BindGroupLayoutEntry>,
pub(crate) desc_ranges: DescriptorRanges,
pub(crate) dynamic_count: usize,
@@ -81,6 +82,7 @@ pub struct PipelineLayoutDescriptor {
#[derive(Debug)]
pub struct PipelineLayout<B: hal::Backend> {
pub(crate) raw: B::PipelineLayout,
pub(crate) device_id: Stored<DeviceId>,
pub(crate) bind_group_layout_ids: ArrayVec<[BindGroupLayoutId; wgt::MAX_BIND_GROUPS]>,
}

View File

@@ -466,6 +466,7 @@ impl<B: GfxBackend> LifetimeTracker<B> {
})
.collect::<FastHashMap<_, _>>();
log::debug!("Free framebuffers {:?}", remove_list);
for (ref key, submit_index) in remove_list {
let framebuffer = framebuffers.remove(key).unwrap();
self.active

View File

@@ -479,15 +479,16 @@ impl<B: hal::Backend> Device<B> {
unsafe {
desc_alloc.dispose(&self.raw);
mem_alloc.dispose(&self.raw);
for (_, rp) in self.render_passes.lock().drain() {
self.raw.destroy_render_pass(rp);
}
for (_, fbo) in self.framebuffers.lock().drain() {
self.raw.destroy_framebuffer(fbo);
}
}
}
}
#[derive(Debug)]
pub struct ShaderModule<B: hal::Backend> {
pub(crate) raw: B::ShaderModule,
}
impl<F: IdentityFilter<id::BufferId>> Global<F> {
pub fn device_create_buffer<B: GfxBackend>(
@@ -908,9 +909,10 @@ impl<F: IdentityFilter<id::BindGroupLayoutId>> Global<F> {
})
.collect::<Vec<_>>(); //TODO: avoid heap allocation
let (device_guard, mut token) = hub.devices.read(&mut token);
let device = &device_guard[device_id];
let raw = unsafe {
let (device_guard, _) = hub.devices.read(&mut token);
device_guard[device_id]
device
.raw
.create_descriptor_set_layout(&raw_bindings, &[])
.unwrap()
@@ -918,6 +920,10 @@ impl<F: IdentityFilter<id::BindGroupLayoutId>> Global<F> {
let layout = binding_model::BindGroupLayout {
raw,
device_id: Stored {
value: device_id,
ref_count: device.life_guard.add_ref(),
},
entries: entry_map,
desc_ranges: DescriptorRanges::from_bindings(&raw_bindings),
dynamic_count: entries.iter().filter(|b| b.has_dynamic_offset).count(),
@@ -930,8 +936,11 @@ impl<F: IdentityFilter<id::BindGroupLayoutId>> Global<F> {
pub fn bind_group_layout_destroy<B: GfxBackend>(&self, bind_group_layout_id: id::BindGroupLayoutId) {
let hub = B::hub(self);
let mut token = Token::root();
//TODO: track usage by GPU
hub.bind_group_layouts.unregister(bind_group_layout_id, &mut token);
let (device_guard, mut token) = hub.devices.read(&mut token);
let (bgl, _) = hub.bind_group_layouts.unregister(bind_group_layout_id, &mut token);
unsafe {
device_guard[bgl.device_id.value].raw.destroy_descriptor_set_layout(bgl.raw);
}
}
}
@@ -970,6 +979,10 @@ impl<F: IdentityFilter<id::PipelineLayoutId>> Global<F> {
let layout = binding_model::PipelineLayout {
raw: pipeline_layout,
device_id: Stored {
value: device_id,
ref_count: device.life_guard.add_ref(),
},
bind_group_layout_ids: bind_group_layout_ids.iter().cloned().collect(),
};
hub.pipeline_layouts
@@ -979,8 +992,11 @@ impl<F: IdentityFilter<id::PipelineLayoutId>> Global<F> {
pub fn pipeline_layout_destroy<B: GfxBackend>(&self, pipeline_layout_id: id::PipelineLayoutId) {
let hub = B::hub(self);
let mut token = Token::root();
//TODO: track usage by GPU
hub.pipeline_layouts.unregister(pipeline_layout_id, &mut token);
let (device_guard, mut token) = hub.devices.read(&mut token);
let (pipeline_layout, _) = hub.pipeline_layouts.unregister(pipeline_layout_id, &mut token);
unsafe {
device_guard[pipeline_layout.device_id.value].raw.destroy_pipeline_layout(pipeline_layout.raw);
}
}
}
@@ -1206,19 +1222,24 @@ impl<F: IdentityFilter<id::ShaderModuleId>> Global<F> {
) -> id::ShaderModuleId {
let hub = B::hub(self);
let mut token = Token::root();
let (device_guard, mut token) = hub.devices.read(&mut token);
let device = &device_guard[device_id];
let spv = unsafe { slice::from_raw_parts(desc.code.bytes, desc.code.length) };
let shader = {
let (device_guard, _) = hub.devices.read(&mut token);
ShaderModule {
raw: unsafe {
device_guard[device_id]
.raw
.create_shader_module(spv)
.unwrap()
},
}
let raw = unsafe {
device
.raw
.create_shader_module(spv)
.unwrap()
};
let shader = pipeline::ShaderModule {
raw,
device_id: Stored {
value: device_id,
ref_count: device.life_guard.add_ref(),
},
};
hub.shader_modules
.register_identity(id_in, shader, &mut token)
}
@@ -1226,8 +1247,11 @@ impl<F: IdentityFilter<id::ShaderModuleId>> Global<F> {
pub fn shader_module_destroy<B: GfxBackend>(&self, shader_module_id: id::ShaderModuleId) {
let hub = B::hub(self);
let mut token = Token::root();
//TODO: track usage by GPU
hub.shader_modules.unregister(shader_module_id, &mut token);
let (device_guard, mut token) = hub.devices.read(&mut token);
let (module, _) = hub.shader_modules.unregister(shader_module_id, &mut token);
unsafe {
device_guard[module.device_id.value].raw.destroy_shader_module(module.raw);
}
}
}
@@ -1586,9 +1610,9 @@ impl<F: IdentityFilter<id::RenderPipelineId>> Global<F> {
depth_bounds: None,
};
let (device_guard, mut token) = hub.devices.read(&mut token);
let device = &device_guard[device_id];
let raw_pipeline = {
let (device_guard, mut token) = hub.devices.read(&mut token);
let device = &device_guard[device_id];
let (pipeline_layout_guard, mut token) = hub.pipeline_layouts.read(&mut token);
let layout = &pipeline_layout_guard[desc.layout].raw;
let (shader_module_guard, _) = hub.shader_modules.read(&mut token);
@@ -1734,6 +1758,10 @@ impl<F: IdentityFilter<id::RenderPipelineId>> Global<F> {
let pipeline = pipeline::RenderPipeline {
raw: raw_pipeline,
layout_id: desc.layout,
device_id: Stored {
value: device_id,
ref_count: device.life_guard.add_ref(),
},
pass_context,
flags,
index_format: desc.vertex_state.index_format,
@@ -1748,6 +1776,7 @@ impl<F: IdentityFilter<id::RenderPipelineId>> Global<F> {
pub fn render_pipeline_destroy<B: GfxBackend>(&self, render_pipeline_id: id::RenderPipelineId) {
let hub = B::hub(self);
let mut token = Token::root();
let (_, mut token) = hub.devices.read(&mut token);
//TODO: track usage by GPU
hub.render_pipelines.unregister(render_pipeline_id, &mut token);
}
@@ -1763,9 +1792,9 @@ impl<F: IdentityFilter<id::ComputePipelineId>> Global<F> {
let hub = B::hub(self);
let mut token = Token::root();
let (device_guard, mut token) = hub.devices.read(&mut token);
let device = &device_guard[device_id];
let raw_pipeline = {
let (device_guard, mut token) = hub.devices.read(&mut token);
let device = &device_guard[device_id].raw;
let (pipeline_layout_guard, mut token) = hub.pipeline_layouts.read(&mut token);
let layout = &pipeline_layout_guard[desc.layout].raw;
let pipeline_stage = &desc.compute_stage;
@@ -1794,6 +1823,7 @@ impl<F: IdentityFilter<id::ComputePipelineId>> Global<F> {
unsafe {
device
.raw
.create_compute_pipeline(&pipeline_desc, None)
.unwrap()
}
@@ -1802,6 +1832,10 @@ impl<F: IdentityFilter<id::ComputePipelineId>> Global<F> {
let pipeline = pipeline::ComputePipeline {
raw: raw_pipeline,
layout_id: desc.layout,
device_id: Stored {
value: device_id,
ref_count: device.life_guard.add_ref(),
},
};
hub.compute_pipelines
.register_identity(id_in, pipeline, &mut token)
@@ -1810,6 +1844,7 @@ impl<F: IdentityFilter<id::ComputePipelineId>> Global<F> {
pub fn compute_pipeline_destroy<B: GfxBackend>(&self, compute_pipeline_id: id::ComputePipelineId) {
let hub = B::hub(self);
let mut token = Token::root();
let (_, mut token) = hub.devices.read(&mut token);
//TODO: track usage by GPU
hub.compute_pipelines.unregister(compute_pipeline_id, &mut token);
}
@@ -1964,7 +1999,7 @@ impl<F: AllIdentityFilter + IdentityFilter<id::DeviceId>> Global<F> {
let (device, mut token) = hub.devices.unregister(device_id, &mut token);
device.maintain(self, true, &mut token);
drop(token);
device.com_allocator.destroy(&device.raw);
device.dispose();
}
}

View File

@@ -6,7 +6,7 @@ use crate::{
backend,
binding_model::{BindGroup, BindGroupLayout, PipelineLayout},
command::CommandBuffer,
device::{Device, ShaderModule},
device::Device,
id::{
AdapterId,
BindGroupId,
@@ -26,7 +26,7 @@ use crate::{
TypedId,
},
instance::{Adapter, Instance, Surface},
pipeline::{ComputePipeline, RenderPipeline},
pipeline::{ComputePipeline, RenderPipeline, ShaderModule},
resource::{Buffer, Sampler, Texture, TextureView},
swap_chain::SwapChain,
Epoch,
@@ -180,11 +180,11 @@ impl<B: hal::Backend> Access<BindGroup<B>> for CommandBuffer<B> {}
impl<B: hal::Backend> Access<CommandBuffer<B>> for Root {}
impl<B: hal::Backend> Access<CommandBuffer<B>> for Device<B> {}
impl<B: hal::Backend> Access<CommandBuffer<B>> for SwapChain<B> {}
impl<B: hal::Backend> Access<ComputePipeline<B>> for Root {}
impl<B: hal::Backend> Access<ComputePipeline<B>> for Device<B> {}
impl<B: hal::Backend> Access<ComputePipeline<B>> for BindGroup<B> {}
impl<B: hal::Backend> Access<RenderPipeline<B>> for Root {}
impl<B: hal::Backend> Access<RenderPipeline<B>> for Device<B> {}
impl<B: hal::Backend> Access<RenderPipeline<B>> for BindGroup<B> {}
impl<B: hal::Backend> Access<ShaderModule<B>> for Root {}
impl<B: hal::Backend> Access<ShaderModule<B>> for Device<B> {}
impl<B: hal::Backend> Access<ShaderModule<B>> for PipelineLayout<B> {}
impl<B: hal::Backend> Access<Buffer<B>> for Root {}
impl<B: hal::Backend> Access<Buffer<B>> for Device<B> {}
@@ -425,6 +425,7 @@ impl<B: hal::Backend, F> Drop for Hub<B, F> {
}
}
}
for (_, (texture, _)) in self.textures.data.write().map.drain() {
devices[texture.device_id.value].destroy_texture(texture);
}
@@ -442,14 +443,38 @@ impl<B: hal::Backend, F> Drop for Hub<B, F> {
device.destroy_bind_group(bind_group);
}
//TODO:
// self.compute_pipelines
// self.render_pipelines
// self.bind_group_layouts
// self.pipeline_layouts
// self.shader_modules
// self.swap_chains
// self.adapters
for (_, (module, _)) in self.shader_modules.data.write().map.drain() {
let device = &devices[module.device_id.value];
unsafe {
device.raw.destroy_shader_module(module.raw);
}
}
for (_, (bgl, _)) in self.bind_group_layouts.data.write().map.drain() {
let device = &devices[bgl.device_id.value];
unsafe {
device.raw.destroy_descriptor_set_layout(bgl.raw);
}
}
for (_, (pipeline_layout, _)) in self.pipeline_layouts.data.write().map.drain() {
let device = &devices[pipeline_layout.device_id.value];
unsafe {
device.raw.destroy_pipeline_layout(pipeline_layout.raw);
}
}
for (_, (pipeline, _)) in self.compute_pipelines.data.write().map.drain() {
let device = &devices[pipeline.device_id.value];
unsafe {
device.raw.destroy_compute_pipeline(pipeline.raw);
}
}
for (_, (pipeline, _)) in self.render_pipelines.data.write().map.drain() {
let device = &devices[pipeline.device_id.value];
unsafe {
device.raw.destroy_graphics_pipeline(pipeline.raw);
}
}
//TODO: self.swap_chains
for (_, (device, _)) in devices.map.drain() {
device.dispose();

View File

@@ -100,7 +100,6 @@ pub type SurfaceId = Id<crate::instance::Surface>;
// Device
pub type DeviceId = Id<crate::device::Device<Dummy>>;
pub type QueueId = DeviceId;
pub type ShaderModuleId = Id<crate::device::ShaderModule<Dummy>>;
// Resource
pub type BufferId = Id<crate::resource::Buffer<Dummy>>;
pub type TextureViewId = Id<crate::resource::TextureView<Dummy>>;
@@ -111,6 +110,7 @@ pub type BindGroupLayoutId = Id<crate::binding_model::BindGroupLayout<Dummy>>;
pub type PipelineLayoutId = Id<crate::binding_model::PipelineLayout<Dummy>>;
pub type BindGroupId = Id<crate::binding_model::BindGroup<Dummy>>;
// Pipeline
pub type ShaderModuleId = Id<crate::pipeline::ShaderModule<Dummy>>;
pub type RenderPipelineId = Id<crate::pipeline::RenderPipeline<Dummy>>;
pub type ComputePipelineId = Id<crate::pipeline::ComputePipeline<Dummy>>;
// Command

View File

@@ -4,8 +4,9 @@
use crate::{
device::RenderPassContext,
id::{PipelineLayoutId, ShaderModuleId},
id::{DeviceId, PipelineLayoutId, ShaderModuleId},
RawString,
Stored,
U32Array
};
use wgt::{BufferAddress, ColorStateDescriptor, DepthStencilStateDescriptor, IndexFormat, InputStepMode, PrimitiveTopology, RasterizationStateDescriptor, VertexAttributeDescriptor};
@@ -33,6 +34,12 @@ pub struct ShaderModuleDescriptor {
pub code: U32Array,
}
#[derive(Debug)]
pub struct ShaderModule<B: hal::Backend> {
pub(crate) raw: B::ShaderModule,
pub(crate) device_id: Stored<DeviceId>
}
#[repr(C)]
#[derive(Debug)]
pub struct ProgrammableStageDescriptor {
@@ -51,6 +58,7 @@ pub struct ComputePipelineDescriptor {
pub struct ComputePipeline<B: hal::Backend> {
pub(crate) raw: B::ComputePipeline,
pub(crate) layout_id: PipelineLayoutId,
pub(crate) device_id: Stored<DeviceId>,
}
#[repr(C)]
@@ -82,6 +90,7 @@ bitflags::bitflags! {
pub struct RenderPipeline<B: hal::Backend> {
pub(crate) raw: B::GraphicsPipeline,
pub(crate) layout_id: PipelineLayoutId,
pub(crate) device_id: Stored<DeviceId>,
pub(crate) pass_context: RenderPassContext,
pub(crate) flags: PipelineFlags,
pub(crate) index_format: IndexFormat,