diff --git a/crates/renderer/src/commands.rs b/crates/renderer/src/commands.rs index 3fe0a81..d0223c9 100644 --- a/crates/renderer/src/commands.rs +++ b/crates/renderer/src/commands.rs @@ -1,8 +1,7 @@ use std::sync::{Arc, atomic::AtomicU8}; use crate::{ - define_device_owned_handle, - device::DeviceOwned, + device::{DeviceObject, DeviceOwned}, images::{Image, QueueOwnership}, pipeline::{Pipeline, PipelineLayout}, sync::{self, FenceFuture}, @@ -174,15 +173,30 @@ impl CommandBufferState2 { } } -define_device_owned_handle! { - #[derive(Debug)] - pub SingleUseCommand(vk::CommandBuffer) { - pool: Arc, - state: CommandBufferState2, - } => |this| unsafe { - this.pool +#[derive(Debug)] +pub struct SingleUseCommand { + inner: DeviceObject, + pool: Arc, + state: CommandBufferState2, +} + +impl DeviceOwned for SingleUseCommand { + fn device(&self) -> &Device { + self.inner.device() + } + + fn handle(&self) -> vk::CommandBuffer { + *self.inner + } +} + +impl Drop for SingleUseCommand { + fn drop(&mut self) { + unsafe { + self.pool .pool - .with_locked(|&pool| this.device().dev().free_command_buffers(pool, &[this.handle()])) + .with_locked(|&pool| self.device().dev().free_command_buffers(pool, &[self.handle()])) + } } } @@ -208,7 +222,15 @@ impl SingleUseCommand { buffer }; - Self::construct(device, buffer, None, pool, CommandBufferState2::recording()) + Ok(Self { + inner: DeviceObject::new_debug_named( + device, + buffer, + None::>, + ), + pool, + state: CommandBufferState2::recording(), + }) } pub fn state(&self) -> CommandBufferState { @@ -642,8 +664,7 @@ mod command_pools { use thread_local::ThreadLocal; use crate::{ - define_device_owned_handle, - device::{Device, DeviceOwned}, + device::{Device, DeviceObject, DeviceOwned}, queue::Queue, sync, util::MutexExt, @@ -659,13 +680,19 @@ mod command_pools { InvalidQueueSubmission, } - define_device_owned_handle! { - #[derive()] - pub CommandPool(vk::CommandPool) { - family: u32, - free_list: Mutex, Vec)>>, - } => |this| unsafe { - this.device().dev().destroy_command_pool(this.handle(), None); + pub struct CommandPool { + inner: DeviceObject, + family: u32, + free_list: Mutex, Vec)>>, + } + + impl DeviceOwned for CommandPool { + fn device(&self) -> &Device { + self.inner.device() + } + + fn handle(&self) -> vk::CommandPool { + *self.inner } } @@ -684,7 +711,11 @@ mod command_pools { let pool = unsafe { dev.dev().create_command_pool(&pool_info, None)? }; - Self::construct(dev, pool, name, family, Mutex::new(Default::default())) + Ok(Self { + inner: DeviceObject::new_debug_named(dev, pool, name), + family, + free_list: Mutex::new(Default::default()), + }) } #[allow(dead_code)] @@ -761,13 +792,11 @@ mod command_pools { .begin_command_buffer(handle, &begin_info)?; } - Ok(CommandBuffer::construct( - self.device().clone(), - handle, - name, - self.clone(), + Ok(CommandBuffer { + inner: DeviceObject::new_debug_named(self.device().clone(), handle, name), + pool: self.clone(), level, - )?) + }) } pub fn alloc_primary( @@ -861,14 +890,31 @@ mod command_pools { } } - define_device_owned_handle! { - #[derive(Debug)] - pub CommandBuffer(vk::CommandBuffer) { - pool: Arc, - #[allow(unused)] - level: vk::CommandBufferLevel, - } => |this| unsafe { - this.device().dev().free_command_buffers(this.pool.handle(), &[this.handle()]); + #[derive(Debug)] + pub struct CommandBuffer { + inner: DeviceObject, + pool: Arc, + #[allow(unused)] + level: vk::CommandBufferLevel, + } + + impl DeviceOwned for CommandBuffer { + fn device(&self) -> &Device { + self.inner.device() + } + + fn handle(&self) -> vk::CommandBuffer { + *self.inner + } + } + + impl Drop for CommandBuffer { + fn drop(&mut self) { + unsafe { + self.device() + .dev() + .free_command_buffers(self.pool.handle(), &[self.handle()]); + } } } diff --git a/crates/renderer/src/lib.rs b/crates/renderer/src/lib.rs index e590fe2..d67a002 100644 --- a/crates/renderer/src/lib.rs +++ b/crates/renderer/src/lib.rs @@ -25,7 +25,7 @@ pub mod util; pub use renderer_device::{device, instance, queue, sync}; pub use renderer_device::{ - compatible_extension_properties, define_device_owned_handle, extension_intersection, + compatible_extension_properties, extension_intersection, get_physical_device_features, get_physical_device_properties, make_extension, DebugUtils, DebugUtilsCreateInfo, Device, DeviceOwned, DeviceRef, Error, ExtendsDeviceFeatures2Debug, ExtendsDeviceProperties2Debug, Extension, Instance, diff --git a/crates/renderer_device/src/device.rs b/crates/renderer_device/src/device.rs index f39bff3..c223581 100644 --- a/crates/renderer_device/src/device.rs +++ b/crates/renderer_device/src/device.rs @@ -897,63 +897,6 @@ impl Pool { } } -// Macro for helping create and destroy Vulkan objects which are owned by a device. -#[macro_export] -macro_rules! define_device_owned_handle { - ($(#[$attr:meta])* - $ty_vis:vis $ty:ident($handle:ty) { - $($(#[$field_attr:meta])* $field_vis:vis $field_name:ident : $field_ty:ty),* - $(,)? - } $(=> |$this:ident| $dtor:stmt)?) => { - $(#[$attr])* - $ty_vis struct $ty { - inner: $crate::device::DeviceObject<$handle>, - $( - $(#[$field_attr])* - $field_vis $field_name: $field_ty, - )* - } - - impl $crate::device::DeviceOwned<$handle> for $ty { - fn device(&self) -> &$crate::device::Device { - self.inner.device() - } - fn handle(&self) -> $handle { - *self.inner - } - } - - impl $ty { - #[allow(clippy::too_many_arguments, reason = "This function is generated by a macro")] - fn construct( - device: $crate::device::Device, - handle: $handle, - name: Option<::std::borrow::Cow<'static, str>>, - $($field_name: $field_ty,)* - ) -> ::ash::prelude::VkResult { - Ok(Self { - inner: $crate::device::DeviceObject::new_debug_named( - device, - handle, - name, - ), - $($field_name,)* - }) - } - } - - $( - impl Drop for $ty { - fn drop(&mut self) { - #[allow(unused_mut)] - let mut $this = self; - $dtor - } - } - )? - }; -} - pub mod asdf { use std::{ mem::ManuallyDrop, @@ -1129,11 +1072,14 @@ pub mod asdf { } impl traits::ExternallyManagedObject for vk::CommandBuffer { + // Command buffers cannot be destroyed individually; their outer wrappers free them in Drop. unsafe fn destroy(self, _: &Device) {} } impl traits::ExternallyManagedObject for vk::CommandPool { - unsafe fn destroy(self, _: &Device) {} + unsafe fn destroy(self, device: &Device) { + unsafe { device.raw.destroy_command_pool(self, None) }; + } } impl crate::device::DeviceOwned for DeviceObject