diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index ba3974fa9..efcf50752 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -41,7 +41,7 @@ use thiserror::Error; use super::{life::LifetimeTracker, Device}; pub struct Queue { - raw: ManuallyDrop>, + raw: Box, pub(crate) device: Arc, pub(crate) pending_writes: Mutex>, life_tracker: Mutex, @@ -60,7 +60,6 @@ impl Queue { let pending_encoder = match pending_encoder { Ok(pending_encoder) => pending_encoder, Err(e) => { - device.release_queue(raw); return Err(e); } }; @@ -93,7 +92,7 @@ impl Queue { ); Ok(Queue { - raw: ManuallyDrop::new(raw), + raw, device, pending_writes, life_tracker: Mutex::new(rank::QUEUE_LIFE_TRACKER, LifetimeTracker::new()), @@ -198,9 +197,6 @@ impl Drop for Queue { // SAFETY: We are in the Drop impl and we don't use self.pending_writes anymore after this point. let pending_writes = unsafe { ManuallyDrop::take(&mut self.pending_writes.lock()) }; pending_writes.dispose(self.device.raw()); - // SAFETY: we never access `self.raw` beyond this point. - let queue = unsafe { ManuallyDrop::take(&mut self.raw) }; - self.device.release_queue(queue); closures.fire(); } diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 2abc9ddaa..618cfb6ea 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -57,10 +57,9 @@ use super::{ /// Structure describing a logical device. Some members are internally mutable, /// stored behind mutexes. pub struct Device { - raw: ManuallyDrop>, + raw: Box, pub(crate) adapter: Arc, pub(crate) queue: OnceLock>, - queue_to_drop: OnceLock>, pub(crate) zero_buffer: ManuallyDrop>, /// The `label` from the descriptor used to create the resource. label: String, @@ -154,23 +153,19 @@ impl Drop for Device { closure.call(DeviceLostReason::Dropped, String::from("Device dropped.")); } - // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. - let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; // SAFETY: We are in the Drop impl and we don't use self.zero_buffer anymore after this point. let zero_buffer = unsafe { ManuallyDrop::take(&mut self.zero_buffer) }; // SAFETY: We are in the Drop impl and we don't use self.fence anymore after this point. let fence = unsafe { ManuallyDrop::take(&mut self.fence.write()) }; - self.command_allocator.dispose(raw.as_ref()); + self.command_allocator.dispose(self.raw.as_ref()); #[cfg(feature = "indirect-validation")] self.indirect_validation .take() .unwrap() - .dispose(raw.as_ref()); + .dispose(self.raw.as_ref()); unsafe { - raw.destroy_buffer(zero_buffer); - raw.destroy_fence(fence); - let queue = self.queue_to_drop.take().unwrap(); - raw.exit(queue); + self.raw.destroy_buffer(zero_buffer); + self.raw.destroy_fence(fence); } } } @@ -249,10 +244,9 @@ impl Device { }; Ok(Self { - raw: ManuallyDrop::new(raw_device), + raw: raw_device, adapter: adapter.clone(), queue: OnceLock::new(), - queue_to_drop: OnceLock::new(), zero_buffer: ManuallyDrop::new(zero_buffer), label: desc.label.to_string(), command_allocator, @@ -325,10 +319,6 @@ impl Device { DeviceError::from_hal(error) } - pub(crate) fn release_queue(&self, queue: Box) { - assert!(self.queue_to_drop.set(queue).is_ok()); - } - /// Run some destroy operations that were deferred. /// /// Destroying the resources requires taking a write lock on the device's snatch lock, diff --git a/wgpu-hal/examples/halmark/main.rs b/wgpu-hal/examples/halmark/main.rs index 8ab7f1cb4..020d362e8 100644 --- a/wgpu-hal/examples/halmark/main.rs +++ b/wgpu-hal/examples/halmark/main.rs @@ -579,7 +579,8 @@ impl Example { self.device.destroy_pipeline_layout(self.pipeline_layout); self.surface.unconfigure(&self.device); - self.device.exit(self.queue); + drop(self.queue); + drop(self.device); drop(self.surface); drop(self.adapter); } diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 4eedfe781..7212988f4 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -1068,7 +1068,8 @@ impl Example { self.device.destroy_shader_module(self.shader_module); self.surface.unconfigure(&self.device); - self.device.exit(self.queue); + drop(self.queue); + drop(self.device); drop(self.surface); drop(self.adapter); } diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 12edf6179..b2b9629ed 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -391,10 +391,6 @@ impl super::Device { impl crate::Device for super::Device { type A = super::Api; - unsafe fn exit(self, _queue: super::Queue) { - self.rtv_pool.lock().free_handle(self.null_rtv_handle); - } - unsafe fn create_buffer( &self, desc: &crate::BufferDescriptor, diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index bc9f0db15..fdda89b16 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -602,6 +602,12 @@ pub struct Device { counters: wgt::HalCounters, } +impl Drop for Device { + fn drop(&mut self) { + self.rtv_pool.lock().free_handle(self.null_rtv_handle); + } +} + unsafe impl Send for Device {} unsafe impl Sync for Device {} diff --git a/wgpu-hal/src/dynamic/device.rs b/wgpu-hal/src/dynamic/device.rs index f044a001d..f38d9fd32 100644 --- a/wgpu-hal/src/dynamic/device.rs +++ b/wgpu-hal/src/dynamic/device.rs @@ -16,8 +16,6 @@ use super::{ }; pub trait DynDevice: DynResource { - unsafe fn exit(self: Box, queue: Box); - unsafe fn create_buffer( &self, desc: &BufferDescriptor, @@ -166,10 +164,6 @@ pub trait DynDevice: DynResource { } impl DynDevice for D { - unsafe fn exit(self: Box, queue: Box) { - unsafe { D::exit(*self, queue.unbox()) } - } - unsafe fn create_buffer( &self, desc: &BufferDescriptor, diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 72d9784d6..e74c91c07 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -163,7 +163,6 @@ impl crate::Queue for Context { impl crate::Device for Context { type A = Api; - unsafe fn exit(self, queue: Context) {} unsafe fn create_buffer(&self, desc: &crate::BufferDescriptor) -> DeviceResult { Ok(Resource) } diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 27aabc51e..365ac7d72 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -501,14 +501,6 @@ impl super::Device { impl crate::Device for super::Device { type A = super::Api; - unsafe fn exit(self, queue: super::Queue) { - let gl = &self.shared.context.lock(); - unsafe { gl.delete_vertex_array(self.main_vao) }; - unsafe { gl.delete_framebuffer(queue.draw_fbo) }; - unsafe { gl.delete_framebuffer(queue.copy_fbo) }; - unsafe { gl.delete_buffer(queue.zero_buffer) }; - } - unsafe fn create_buffer( &self, desc: &crate::BufferDescriptor, diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 55f853715..b6e690a5f 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -295,6 +295,13 @@ pub struct Device { counters: wgt::HalCounters, } +impl Drop for Device { + fn drop(&mut self) { + let gl = &self.shared.context.lock(); + unsafe { gl.delete_vertex_array(self.main_vao) }; + } +} + pub struct ShaderClearProgram { pub program: glow::Program, pub color_uniform_location: glow::UniformLocation, @@ -316,6 +323,15 @@ pub struct Queue { current_index_buffer: Mutex>, } +impl Drop for Queue { + fn drop(&mut self) { + let gl = &self.shared.context.lock(); + unsafe { gl.delete_framebuffer(self.draw_fbo) }; + unsafe { gl.delete_framebuffer(self.copy_fbo) }; + unsafe { gl.delete_buffer(self.zero_buffer) }; + } +} + #[derive(Clone, Debug)] pub struct Buffer { raw: Option, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 0cddb6997..ad4b458cd 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -676,7 +676,7 @@ pub trait Adapter: WasmNotSendSync { /// 1) Free resources with methods like [`Device::destroy_texture`] or /// [`Device::destroy_shader_module`]. /// -/// 1) Shut down the device by calling [`Device::exit`]. +/// 1) Drop the device. /// /// [`vkDevice`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VkDevice /// [`ID3D12Device`]: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/nn-d3d12-id3d12device @@ -706,8 +706,6 @@ pub trait Adapter: WasmNotSendSync { pub trait Device: WasmNotSendSync { type A: Api; - /// Exit connection to this logical device. - unsafe fn exit(self, queue: ::Queue); /// Creates a new buffer. /// /// The initial usage is `BufferUses::empty()`. diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index 4cc8ef0eb..81887aac7 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -320,8 +320,6 @@ impl super::Device { impl crate::Device for super::Device { type A = super::Api; - unsafe fn exit(self, _queue: super::Queue) {} - unsafe fn create_buffer(&self, desc: &crate::BufferDescriptor) -> DeviceResult { let map_read = desc.usage.contains(crate::BufferUses::MAP_READ); let map_write = desc.usage.contains(crate::BufferUses::MAP_WRITE); diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 39afe88ef..fe72ec40f 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -289,18 +289,6 @@ impl super::DeviceShared { .size((range.end - range.start + mask) & !mask) })) } - - unsafe fn free_resources(&self) { - for &raw in self.render_passes.lock().values() { - unsafe { self.raw.destroy_render_pass(raw, None) }; - } - for &raw in self.framebuffers.lock().values() { - unsafe { self.raw.destroy_framebuffer(raw, None) }; - } - if self.drop_guard.is_none() { - unsafe { self.raw.destroy_device(None) }; - } - } } impl gpu_alloc::MemoryDevice for super::DeviceShared { @@ -1023,18 +1011,6 @@ impl super::Device { impl crate::Device for super::Device { type A = super::Api; - unsafe fn exit(self, queue: super::Queue) { - unsafe { self.mem_allocator.into_inner().cleanup(&*self.shared) }; - unsafe { self.desc_allocator.into_inner().cleanup(&*self.shared) }; - unsafe { - queue - .relay_semaphores - .into_inner() - .destroy(&self.shared.raw) - }; - unsafe { self.shared.free_resources() }; - } - unsafe fn create_buffer( &self, desc: &crate::BufferDescriptor, diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index f81dc0893..ff3c865fc 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -646,6 +646,20 @@ struct DeviceShared { memory_allocations_counter: InternalCounter, } +impl Drop for DeviceShared { + fn drop(&mut self) { + for &raw in self.render_passes.lock().values() { + unsafe { self.raw.destroy_render_pass(raw, None) }; + } + for &raw in self.framebuffers.lock().values() { + unsafe { self.raw.destroy_framebuffer(raw, None) }; + } + if self.drop_guard.is_none() { + unsafe { self.raw.destroy_device(None) }; + } + } +} + pub struct Device { shared: Arc, mem_allocator: Mutex>, @@ -658,6 +672,13 @@ pub struct Device { counters: wgt::HalCounters, } +impl Drop for Device { + fn drop(&mut self) { + unsafe { self.mem_allocator.lock().cleanup(&*self.shared) }; + unsafe { self.desc_allocator.lock().cleanup(&*self.shared) }; + } +} + /// Semaphores for forcing queue submissions to run in order. /// /// The [`wgpu_hal::Queue`] trait promises that if two calls to [`submit`] are @@ -741,6 +762,12 @@ pub struct Queue { relay_semaphores: Mutex, } +impl Drop for Queue { + fn drop(&mut self) { + unsafe { self.relay_semaphores.lock().destroy(&self.device.raw) }; + } +} + #[derive(Debug)] pub struct Buffer { raw: vk::Buffer,