mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Improve shutdown cleanup (#532)
This commit is contained in:
@@ -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]>,
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user