diff --git a/CHANGELOG.md b/CHANGELOG.md index 16d7bb93cd..c9d92595b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -153,6 +153,7 @@ By @cwfitzgerald in [#3610](https://github.com/gfx-rs/wgpu/pull/3610). - Validate before extracting texture selectors. By @teoxoy in [#3487](https://github.com/gfx-rs/wgpu/pull/3487) - Fix fatal errors (those which panic even if an error handler is set) not including all of the details. By @kpreid in [#3563](https://github.com/gfx-rs/wgpu/pull/3563) - Validate shader location clashes. By @emilk in [#3613](https://github.com/gfx-rs/wgpu/pull/3613) +- Fix surfaces not being dropped until exit. By @benjaminschaaf in [#3647](https://github.com/gfx-rs/wgpu/pull/3647) #### Vulkan diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index 655a47ad18..4d008b6e24 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -1035,6 +1035,14 @@ impl Hub { } } + pub(crate) fn surface_unconfigure(&self, device_id: id::Valid, surface: &mut HalSurface) { + use hal::{Surface as _}; + + let devices = self.devices.data.read(); + let device = &devices[device_id]; + unsafe { surface.raw.unconfigure(&device.raw); } + } + pub fn generate_report(&self) -> HubReport { HubReport { adapters: self.adapters.data.read().generate_report(), diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index d987f45edc..c5c93a518f 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -627,7 +627,33 @@ impl Global { profiling::scope!("Surface::drop"); let mut token = Token::root(); let (surface, _) = self.surfaces.unregister(id, &mut token); - self.instance.destroy_surface(surface.unwrap()); + let mut surface = surface.unwrap(); + + fn unconfigure( + global: &Global, + surface: &mut HalSurface, + present: &Presentation) { + let hub = HalApi::hub(global); + hub.surface_unconfigure(present.device_id.value, surface); + } + + if let Some(present) = surface.presentation.take() { + match present.backend() { + #[cfg(all(feature = "vulkan", not(target_arch = "wasm32")))] + Backend::Vulkan => unconfigure(self, surface.vulkan.as_mut().unwrap(), &present), + #[cfg(all(feature = "metal", any(target_os = "macos", target_os = "ios")))] + Backend::Metal => unconfigure(self, surface.metal.as_mut().unwrap(), &present), + #[cfg(all(feature = "dx12", windows))] + Backend::Dx12 => unconfigure(self, surface.dx12.as_mut().unwrap(), &present), + #[cfg(all(feature = "dx11", windows))] + Backend::Dx11 => unconfigure(self, surface.dx11.as_mut().unwrap(), &present), + #[cfg(feature = "gles")] + Backend::Gl => unconfigure(self, surface.gl.as_mut().unwrap(), &present), + _ => unreachable!(), + } + } + + self.instance.destroy_surface(surface); } fn enumerate( diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 1b688b14a9..1ba9d8a98d 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -1549,9 +1549,8 @@ impl crate::Context for Context { (id, ()) } - fn surface_drop(&self, _surface: &Self::SurfaceId, _surface_data: &Self::SurfaceData) { - //TODO: swapchain needs to hold the surface alive - //self.0.surface_drop(*surface) + fn surface_drop(&self, surface: &Self::SurfaceId, _surface_data: &Self::SurfaceData) { + self.0.surface_drop(*surface) } fn adapter_drop(&self, adapter: &Self::AdapterId, _adapter_data: &Self::AdapterData) {