From 7503a73a57805e6176c276d29214db3b90ee97ac Mon Sep 17 00:00:00 2001 From: janis Date: Sat, 4 Apr 2026 16:24:42 +0200 Subject: [PATCH] device handle experiment --- crates/renderer/src/device.rs | 175 ++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) diff --git a/crates/renderer/src/device.rs b/crates/renderer/src/device.rs index c1fad2b..066cb5f 100644 --- a/crates/renderer/src/device.rs +++ b/crates/renderer/src/device.rs @@ -952,3 +952,178 @@ macro_rules! define_device_owned_handle { )? }; } + +// This module is an experiment in a more generic way to manage device-owned resources. +#[cfg(false)] +mod asdf { + use std::{ + ops::{Deref, DerefMut}, + sync::Arc, + }; + + use ash::vk; + + use crate::{ + device::{DeviceInner, GpuAllocation}, + util::DebugName, + }; + + mod traits { + pub trait ExternallyManagedObject { + /// # Safety + /// The caller must ensure this function is only called once for a given object. + unsafe fn destroy(&mut self, owner: &T); + } + + pub trait DebugNameable { + fn debug_name(&self, device: &super::DeviceInner, name: &str); + } + } + + struct ExternallyManagedObject, O> { + inner: T, + owner: O, + } + + impl, O> Deref for ExternallyManagedObject { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner + } + } + + impl, O> DerefMut for ExternallyManagedObject { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } + } + + impl, O> ExternallyManagedObject { + fn new(inner: T, owner: O) -> Self { + Self { inner, owner } + } + fn owner(&self) -> &O { + &self.owner + } + } + + impl Drop for ExternallyManagedObject + where + T: traits::ExternallyManagedObject, + { + fn drop(&mut self) { + unsafe { + self.inner.destroy(&self.owner); + } + } + } + + struct DeviceObject, O: AsRef> { + inner: ExternallyManagedObject, + name: Option, + } + + impl< + T: traits::ExternallyManagedObject + traits::DebugNameable, + O: AsRef, + > DeviceObject + { + fn new_debug_named(owner: O, inner: T, name: Option>) -> Self { + let name = name.map(Into::into); + if let Some(ref name) = name { + traits::DebugNameable::debug_name(&inner, owner.as_ref(), name); + } + + let obj = ExternallyManagedObject::new(inner, owner); + + Self { inner: obj, name } + } + } + + impl, O: AsRef> DeviceObject { + fn new(owner: O, inner: T) -> Self { + let inner = ExternallyManagedObject::new(inner, owner); + + Self { inner, name: None } + } + fn device(&self) -> &O { + self.inner.owner() + } + } + + impl Deref for DeviceObject + where + T: traits::ExternallyManagedObject, + O: AsRef, + { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner + } + } + + mod impls { + use crate::device::{DeviceInner, GpuAllocation}; + + use super::*; + + impl> traits::ExternallyManagedObject for ash::vk::Semaphore { + unsafe fn destroy(&mut self, device: &T) { + unsafe { + device.as_ref().raw.destroy_semaphore(*self, None); + } + } + } + + impl> traits::ExternallyManagedObject for GpuAllocation { + unsafe fn destroy(&mut self, device: &T) { + let mut swapped = GpuAllocation::default(); + std::mem::swap(self, &mut swapped); + _ = device.as_ref().alloc2.lock().free(swapped); + } + } + + impl AsRef for DeviceInner { + fn as_ref(&self) -> &DeviceInner { + self + } + } + + impl traits::DebugNameable for T + where + T: vk::Handle + Copy, + { + fn debug_name(&self, device: &super::DeviceInner, name: &str) { + unsafe { + device.debug_name_object(*self, name); + } + } + } + } + + fn summon() -> T { + unimplemented!() + } + + fn asdf() { + let inner_ref: DeviceObject = DeviceObject::new_debug_named( + summon::<&DeviceInner>(), + summon::(), + Some("my semaphore"), + ); + + let device_owned: DeviceObject = + DeviceObject::new_debug_named( + summon::(), + summon::(), + Some("my other semaphore"), + ); + + let allocation: DeviceObject> = DeviceObject::new( + summon::>(), + summon::(), + ); + } +}