diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index 98d9180038..051ee31ccf 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -66,6 +66,7 @@ pub struct BindGroupLayoutDescriptor { #[derive(Debug)] pub struct BindGroupLayout { pub(crate) raw: B::DescriptorSetLayout, + pub(crate) device_id: Stored, pub(crate) entries: FastHashMap, pub(crate) desc_ranges: DescriptorRanges, pub(crate) dynamic_count: usize, @@ -81,6 +82,7 @@ pub struct PipelineLayoutDescriptor { #[derive(Debug)] pub struct PipelineLayout { pub(crate) raw: B::PipelineLayout, + pub(crate) device_id: Stored, pub(crate) bind_group_layout_ids: ArrayVec<[BindGroupLayoutId; wgt::MAX_BIND_GROUPS]>, } diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 76cae1510b..2fb2717a66 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -466,6 +466,7 @@ impl LifetimeTracker { }) .collect::>(); + log::debug!("Free framebuffers {:?}", remove_list); for (ref key, submit_index) in remove_list { let framebuffer = framebuffers.remove(key).unwrap(); self.active diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index f138b6d282..bfcfe91c3b 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -479,15 +479,16 @@ impl Device { 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 { - pub(crate) raw: B::ShaderModule, -} - impl> Global { pub fn device_create_buffer( @@ -908,9 +909,10 @@ impl> Global { }) .collect::>(); //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> Global { 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> Global { pub fn bind_group_layout_destroy(&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> Global { 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> Global { pub fn pipeline_layout_destroy(&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> Global { ) -> 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> Global { pub fn shader_module_destroy(&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> Global { 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> Global { 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> Global { pub fn render_pipeline_destroy(&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> Global { 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> Global { unsafe { device + .raw .create_compute_pipeline(&pipeline_desc, None) .unwrap() } @@ -1802,6 +1832,10 @@ impl> Global { 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> Global { pub fn compute_pipeline_destroy(&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> Global { 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(); } } diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index f9d94cb7fe..a7ad5f0b59 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -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 Access> for CommandBuffer {} impl Access> for Root {} impl Access> for Device {} impl Access> for SwapChain {} -impl Access> for Root {} +impl Access> for Device {} impl Access> for BindGroup {} -impl Access> for Root {} +impl Access> for Device {} impl Access> for BindGroup {} -impl Access> for Root {} +impl Access> for Device {} impl Access> for PipelineLayout {} impl Access> for Root {} impl Access> for Device {} @@ -425,6 +425,7 @@ impl Drop for Hub { } } } + for (_, (texture, _)) in self.textures.data.write().map.drain() { devices[texture.device_id.value].destroy_texture(texture); } @@ -442,14 +443,38 @@ impl Drop for Hub { 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(); diff --git a/wgpu-core/src/id.rs b/wgpu-core/src/id.rs index 4a217be052..68c4e4ce56 100644 --- a/wgpu-core/src/id.rs +++ b/wgpu-core/src/id.rs @@ -100,7 +100,6 @@ pub type SurfaceId = Id; // Device pub type DeviceId = Id>; pub type QueueId = DeviceId; -pub type ShaderModuleId = Id>; // Resource pub type BufferId = Id>; pub type TextureViewId = Id>; @@ -111,6 +110,7 @@ pub type BindGroupLayoutId = Id>; pub type PipelineLayoutId = Id>; pub type BindGroupId = Id>; // Pipeline +pub type ShaderModuleId = Id>; pub type RenderPipelineId = Id>; pub type ComputePipelineId = Id>; // Command diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index b641840c59..274bbe2d01 100644 --- a/wgpu-core/src/pipeline.rs +++ b/wgpu-core/src/pipeline.rs @@ -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 { + pub(crate) raw: B::ShaderModule, + pub(crate) device_id: Stored +} + #[repr(C)] #[derive(Debug)] pub struct ProgrammableStageDescriptor { @@ -51,6 +58,7 @@ pub struct ComputePipelineDescriptor { pub struct ComputePipeline { pub(crate) raw: B::ComputePipeline, pub(crate) layout_id: PipelineLayoutId, + pub(crate) device_id: Stored, } #[repr(C)] @@ -82,6 +90,7 @@ bitflags::bitflags! { pub struct RenderPipeline { pub(crate) raw: B::GraphicsPipeline, pub(crate) layout_id: PipelineLayoutId, + pub(crate) device_id: Stored, pub(crate) pass_context: RenderPassContext, pub(crate) flags: PipelineFlags, pub(crate) index_format: IndexFormat,