diff --git a/CHANGELOG.md b/CHANGELOG.md index 202221fb15..eb16ddbf1d 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..d3f089f2f7 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -1035,6 +1035,20 @@ 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..5fd55bfb48 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -627,7 +627,34 @@ 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 e3f6bbc6c5..028bdaebe9 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) {