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