device handle experiment
This commit is contained in:
parent
cf7f5152bc
commit
7503a73a57
|
|
@ -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<T> {
|
||||
/// # 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<T: traits::ExternallyManagedObject<O>, O> {
|
||||
inner: T,
|
||||
owner: O,
|
||||
}
|
||||
|
||||
impl<T: traits::ExternallyManagedObject<O>, O> Deref for ExternallyManagedObject<T, O> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: traits::ExternallyManagedObject<O>, O> DerefMut for ExternallyManagedObject<T, O> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: traits::ExternallyManagedObject<O>, O> ExternallyManagedObject<T, O> {
|
||||
fn new(inner: T, owner: O) -> Self {
|
||||
Self { inner, owner }
|
||||
}
|
||||
fn owner(&self) -> &O {
|
||||
&self.owner
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, O> Drop for ExternallyManagedObject<T, O>
|
||||
where
|
||||
T: traits::ExternallyManagedObject<O>,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
self.inner.destroy(&self.owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct DeviceObject<T: traits::ExternallyManagedObject<O>, O: AsRef<super::DeviceInner>> {
|
||||
inner: ExternallyManagedObject<T, O>,
|
||||
name: Option<DebugName>,
|
||||
}
|
||||
|
||||
impl<
|
||||
T: traits::ExternallyManagedObject<O> + traits::DebugNameable,
|
||||
O: AsRef<super::DeviceInner>,
|
||||
> DeviceObject<T, O>
|
||||
{
|
||||
fn new_debug_named(owner: O, inner: T, name: Option<impl Into<DebugName>>) -> 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<T: traits::ExternallyManagedObject<O>, O: AsRef<super::DeviceInner>> DeviceObject<T, O> {
|
||||
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<T, O> Deref for DeviceObject<T, O>
|
||||
where
|
||||
T: traits::ExternallyManagedObject<O>,
|
||||
O: AsRef<super::DeviceInner>,
|
||||
{
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
mod impls {
|
||||
use crate::device::{DeviceInner, GpuAllocation};
|
||||
|
||||
use super::*;
|
||||
|
||||
impl<T: AsRef<DeviceInner>> traits::ExternallyManagedObject<T> for ash::vk::Semaphore {
|
||||
unsafe fn destroy(&mut self, device: &T) {
|
||||
unsafe {
|
||||
device.as_ref().raw.destroy_semaphore(*self, None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsRef<DeviceInner>> traits::ExternallyManagedObject<T> 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<DeviceInner> for DeviceInner {
|
||||
fn as_ref(&self) -> &DeviceInner {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> 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>() -> T {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn asdf() {
|
||||
let inner_ref: DeviceObject<vk::Semaphore, &DeviceInner> = DeviceObject::new_debug_named(
|
||||
summon::<&DeviceInner>(),
|
||||
summon::<vk::Semaphore>(),
|
||||
Some("my semaphore"),
|
||||
);
|
||||
|
||||
let device_owned: DeviceObject<vk::Semaphore, super::Device> =
|
||||
DeviceObject::new_debug_named(
|
||||
summon::<super::Device>(),
|
||||
summon::<vk::Semaphore>(),
|
||||
Some("my other semaphore"),
|
||||
);
|
||||
|
||||
let allocation: DeviceObject<GpuAllocation, Arc<super::DeviceInner>> = DeviceObject::new(
|
||||
summon::<Arc<super::DeviceInner>>(),
|
||||
summon::<GpuAllocation>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue