simplify device ownership logic
This commit is contained in:
parent
ce46ca1801
commit
dd02ea23cf
|
|
@ -223,7 +223,7 @@ impl SingleUseCommand {
|
||||||
pub fn end(&self) -> VkResult<()> {
|
pub fn end(&self) -> VkResult<()> {
|
||||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
unsafe {
|
unsafe {
|
||||||
self.inner.dev().dev().end_command_buffer(self.handle())?;
|
self.device().dev().end_command_buffer(self.handle())?;
|
||||||
}
|
}
|
||||||
self.state.set_executable();
|
self.state.set_executable();
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -288,7 +288,7 @@ impl SingleUseCommand {
|
||||||
wait: Option<(vk::Semaphore, vk::PipelineStageFlags)>,
|
wait: Option<(vk::Semaphore, vk::PipelineStageFlags)>,
|
||||||
signal: Option<vk::Semaphore>,
|
signal: Option<vk::Semaphore>,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
let fence = Arc::new(sync::Fence::from_pool(&self.device().pools().fences, None)?);
|
let fence = Arc::new(sync::Fence::from_pool(self.device(), None)?);
|
||||||
let future = self.submit_async(wait, signal, fence)?;
|
let future = self.submit_async(wait, signal, fence)?;
|
||||||
future.block()?;
|
future.block()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -460,7 +460,7 @@ impl Renderer2 {
|
||||||
let future = cmds.submit(
|
let future = cmds.submit(
|
||||||
Some((frame.acquire, vk::PipelineStageFlags::TRANSFER)),
|
Some((frame.acquire, vk::PipelineStageFlags::TRANSFER)),
|
||||||
Some(frame.release),
|
Some(frame.release),
|
||||||
Arc::new(sync::Fence::from_pool(&self.device.pools().fences, None)?),
|
Arc::new(sync::Fence::from_pool(&self.device, None)?),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
future.await;
|
future.await;
|
||||||
|
|
|
||||||
|
|
@ -521,7 +521,7 @@ impl Pipeline {
|
||||||
device
|
device
|
||||||
.dev()
|
.dev()
|
||||||
.create_compute_pipelines(
|
.create_compute_pipelines(
|
||||||
device.pools().pipeline_cache.raw,
|
device.pools.pipeline_cache.raw,
|
||||||
core::slice::from_ref(info),
|
core::slice::from_ref(info),
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
|
@ -690,7 +690,7 @@ impl Pipeline {
|
||||||
device
|
device
|
||||||
.dev()
|
.dev()
|
||||||
.create_graphics_pipelines(
|
.create_graphics_pipelines(
|
||||||
device.pools().pipeline_cache.raw,
|
device.pools.pipeline_cache.raw,
|
||||||
core::slice::from_ref(&info),
|
core::slice::from_ref(&info),
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ impl Wireframe {
|
||||||
let future = cmd.submit_async(
|
let future = cmd.submit_async(
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
Arc::new(sync::Fence::from_pool(&dev.pools().fences, None)?),
|
Arc::new(sync::Fence::from_pool(&dev, None)?),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let pipeline = Self::create_pipeline(dev.clone())?;
|
let pipeline = Self::create_pipeline(dev.clone())?;
|
||||||
|
|
|
||||||
|
|
@ -542,7 +542,7 @@ impl Swapchain {
|
||||||
tracing::trace!(frame, "acquiring image for frame {frame}");
|
tracing::trace!(frame, "acquiring image for frame {frame}");
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
let fence = Fence::from_pool(&self.swapchain.device().pools().fences, None)?;
|
let fence = Fence::from_pool(self.swapchain.device(), None)?;
|
||||||
let acquire = self.acquire_semaphores[frame];
|
let acquire = self.acquire_semaphores[frame];
|
||||||
|
|
||||||
// spawn on threadpool because it might block.
|
// spawn on threadpool because it might block.
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,13 @@ use std::{
|
||||||
collections::{BTreeSet, HashMap, HashSet},
|
collections::{BTreeSet, HashMap, HashSet},
|
||||||
ffi::CStr,
|
ffi::CStr,
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
sync::Arc,
|
sync::{Arc, Weak},
|
||||||
};
|
};
|
||||||
|
|
||||||
use ash::{
|
use ash::{
|
||||||
ext, khr,
|
ext, khr,
|
||||||
prelude::VkResult,
|
prelude::VkResult,
|
||||||
vk::{self, Handle},
|
vk,
|
||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use raw_window_handle::RawDisplayHandle;
|
use raw_window_handle::RawDisplayHandle;
|
||||||
|
|
@ -93,12 +93,16 @@ bitflags::bitflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DeviceDrop(ash::Device);
|
struct DeviceDrop {
|
||||||
|
device: ash::Device,
|
||||||
|
pipeline_cache: PipelineCache,
|
||||||
|
}
|
||||||
impl Drop for DeviceDrop {
|
impl Drop for DeviceDrop {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
_ = self.0.device_wait_idle();
|
_ = self.device.device_wait_idle();
|
||||||
self.0.destroy_device(None);
|
self.pipeline_cache.destroy(&self.device);
|
||||||
|
self.device.destroy_device(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -157,6 +161,7 @@ pub struct DeviceInner {
|
||||||
pub queues: DeviceQueues,
|
pub queues: DeviceQueues,
|
||||||
pub sync_threadpool: sync::SyncThreadpool,
|
pub sync_threadpool: sync::SyncThreadpool,
|
||||||
pub device_extensions: DeviceExtensions,
|
pub device_extensions: DeviceExtensions,
|
||||||
|
pub pools: DevicePools,
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub enabled_extensions: Vec<&'static CStr>,
|
pub enabled_extensions: Vec<&'static CStr>,
|
||||||
|
|
||||||
|
|
@ -450,7 +455,8 @@ impl PhysicalDeviceInfo {
|
||||||
},
|
},
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let inner = DeviceInner {
|
let pipeline_cache = PipelineCache::new(&device, &self).unwrap();
|
||||||
|
let shared = Arc::new_cyclic(|inner: &Weak<DeviceInner>| DeviceInner {
|
||||||
raw: device.clone(),
|
raw: device.clone(),
|
||||||
alloc2: Mutex::new(alloc2),
|
alloc2: Mutex::new(alloc2),
|
||||||
instance: instance.clone(),
|
instance: instance.clone(),
|
||||||
|
|
@ -459,14 +465,13 @@ impl PhysicalDeviceInfo {
|
||||||
device_extensions,
|
device_extensions,
|
||||||
enabled_extensions,
|
enabled_extensions,
|
||||||
sync_threadpool: sync::SyncThreadpool::new(),
|
sync_threadpool: sync::SyncThreadpool::new(),
|
||||||
_drop: DeviceDrop(device),
|
pools: DevicePools::new(inner.clone(), pipeline_cache),
|
||||||
};
|
_drop: DeviceDrop {
|
||||||
|
device,
|
||||||
let shared = Arc::new(inner);
|
pipeline_cache,
|
||||||
Ok(Device {
|
},
|
||||||
pools: Arc::new(DevicePools::new(shared.clone())),
|
});
|
||||||
shared,
|
Ok(Device(shared))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn required_extensions(&self, requested_extensions: &[Extension<'static>]) -> Vec<*const i8> {
|
fn required_extensions(&self, requested_extensions: &[Extension<'static>]) -> Vec<*const i8> {
|
||||||
|
|
@ -496,28 +501,19 @@ impl PhysicalDeviceInfo {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DevicePools {
|
pub struct DevicePools {
|
||||||
pub pipeline_cache: asdf::DeviceObject<PipelineCache, Arc<DeviceInner>>,
|
pub pipeline_cache: PipelineCache,
|
||||||
pub fences: Arc<Pool<vk::Fence>>,
|
pub fences: Pool<vk::Fence>,
|
||||||
pub binary_semaphores: Pool<BinarySemaphore>,
|
pub binary_semaphores: Pool<BinarySemaphore>,
|
||||||
pub timeline_semaphores: Pool<TimelineSemaphore>,
|
pub timeline_semaphores: Pool<TimelineSemaphore>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRef<DevicePools> for DevicePools {
|
|
||||||
fn as_ref(&self) -> &DevicePools {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DevicePools {
|
impl DevicePools {
|
||||||
pub fn new(device: Arc<DeviceInner>) -> Self {
|
fn new(device: Weak<DeviceInner>, pipeline_cache: PipelineCache) -> Self {
|
||||||
Self {
|
Self {
|
||||||
fences: Arc::new(Pool::new(device.clone())),
|
fences: Pool::new(device.clone()),
|
||||||
binary_semaphores: Pool::new(device.clone()),
|
binary_semaphores: Pool::new(device.clone()),
|
||||||
timeline_semaphores: Pool::new(device.clone()),
|
timeline_semaphores: Pool::new(device.clone()),
|
||||||
pipeline_cache: asdf::DeviceObject::new(
|
pipeline_cache,
|
||||||
device.clone(),
|
|
||||||
PipelineCache::new(&device.raw, &device.adapter).unwrap(),
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -551,20 +547,11 @@ impl DeviceRef for &Arc<Device> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Device {
|
pub struct Device(Arc<DeviceInner>);
|
||||||
pub(crate) shared: Arc<DeviceInner>,
|
|
||||||
pools: Arc<DevicePools>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Device {
|
|
||||||
pub fn pools(&self) -> &Arc<DevicePools> {
|
|
||||||
&self.pools
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq for Device {
|
impl PartialEq for Device {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
Arc::ptr_eq(&self.shared, &other.shared)
|
Arc::ptr_eq(&self.0, &other.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -574,7 +561,7 @@ impl core::ops::Deref for Device {
|
||||||
type Target = DeviceInner;
|
type Target = DeviceInner;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.shared
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -716,75 +703,7 @@ impl DeviceInner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub use asdf::DeviceObject;
|
||||||
pub struct DeviceOwnedDebugObject<T> {
|
|
||||||
pub device: Device,
|
|
||||||
pub object: T,
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
name: Option<Cow<'static, str>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Eq> Eq for DeviceOwnedDebugObject<T> {}
|
|
||||||
impl<T: PartialEq> PartialEq for DeviceOwnedDebugObject<T> {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
std::sync::Arc::ptr_eq(&self.device.shared, &other.device.shared)
|
|
||||||
&& self.object == other.object
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: std::fmt::Debug + vk::Handle + Copy> std::fmt::Debug for DeviceOwnedDebugObject<T> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
let mut fmt = f.debug_struct(core::any::type_name::<T>());
|
|
||||||
|
|
||||||
fmt.field_with("device", |f| {
|
|
||||||
write!(f, "0x{:x}", self.device.raw.handle().as_raw())
|
|
||||||
})
|
|
||||||
.field_with("handle", |f| write!(f, "0x{:x}", &self.object.as_raw()));
|
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
{
|
|
||||||
fmt.field("name", &self.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> DeviceOwnedDebugObject<T> {
|
|
||||||
pub fn new(
|
|
||||||
device: crate::Device,
|
|
||||||
object: T,
|
|
||||||
name: Option<Cow<'static, str>>,
|
|
||||||
) -> ash::prelude::VkResult<Self>
|
|
||||||
where
|
|
||||||
T: vk::Handle + Copy,
|
|
||||||
{
|
|
||||||
if let Some(name) = name.as_ref() {
|
|
||||||
unsafe {
|
|
||||||
device.debug_name_object(object, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
device,
|
|
||||||
object,
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
name,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dev(&self) -> &crate::Device {
|
|
||||||
&self.device
|
|
||||||
}
|
|
||||||
pub fn handle(&self) -> T
|
|
||||||
where
|
|
||||||
T: Copy,
|
|
||||||
{
|
|
||||||
self.object
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub use asdf::{DeviceObject, InnerDeviceObject};
|
|
||||||
|
|
||||||
pub trait DeviceHandle {
|
pub trait DeviceHandle {
|
||||||
/// # Safety
|
/// # Safety
|
||||||
|
|
@ -799,23 +718,19 @@ impl<O, T: ExternallyManagedObject<O>> ExternallyManagedObject<O> for Mutex<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsRef<DeviceInner>> ExternallyManagedObject<T> for vk::Buffer {
|
impl ExternallyManagedObject<Device> for vk::Buffer {
|
||||||
unsafe fn destroy(self, device: &T) {
|
unsafe fn destroy(self, device: &Device) {
|
||||||
unsafe {
|
unsafe { device.raw.destroy_buffer(self, None) };
|
||||||
device.as_ref().raw.destroy_buffer(self, None);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
impl ExternallyManagedObject<Device> for vk::Image {
|
||||||
|
unsafe fn destroy(self, device: &Device) {
|
||||||
impl<T: AsRef<DeviceInner>> ExternallyManagedObject<T> for vk::Image {
|
unsafe { device.raw.destroy_image(self, None) };
|
||||||
unsafe fn destroy(self, device: &T) {
|
|
||||||
unsafe { device.as_ref().raw.destroy_image(self, None) };
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl ExternallyManagedObject<Device> for vk::ImageView {
|
||||||
impl<T: AsRef<DeviceInner>> ExternallyManagedObject<T> for vk::ImageView {
|
unsafe fn destroy(self, device: &Device) {
|
||||||
unsafe fn destroy(self, device: &T) {
|
unsafe { device.raw.destroy_image_view(self, None) };
|
||||||
unsafe { device.as_ref().raw.destroy_image_view(self, None) };
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -825,46 +740,46 @@ impl DeviceHandle for vk::DescriptorPool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsRef<DeviceInner>> ExternallyManagedObject<T> for vk::DescriptorPool {
|
impl ExternallyManagedObject<Device> for vk::DescriptorPool {
|
||||||
unsafe fn destroy(self, device: &T) {
|
unsafe fn destroy(self, device: &Device) {
|
||||||
unsafe { device.as_ref().raw.destroy_descriptor_pool(self, None) };
|
unsafe { device.raw.destroy_descriptor_pool(self, None) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsRef<DeviceInner>> ExternallyManagedObject<T> for vk::DescriptorSetLayout {
|
impl ExternallyManagedObject<Device> for vk::DescriptorSetLayout {
|
||||||
unsafe fn destroy(self, device: &T) {
|
unsafe fn destroy(self, device: &Device) {
|
||||||
unsafe { device.as_ref().raw.destroy_descriptor_set_layout(self, None) };
|
unsafe { device.raw.destroy_descriptor_set_layout(self, None) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsRef<DeviceInner>> ExternallyManagedObject<T> for vk::PipelineLayout {
|
impl ExternallyManagedObject<Device> for vk::PipelineLayout {
|
||||||
unsafe fn destroy(self, device: &T) {
|
unsafe fn destroy(self, device: &Device) {
|
||||||
unsafe { device.as_ref().raw.destroy_pipeline_layout(self, None) };
|
unsafe { device.raw.destroy_pipeline_layout(self, None) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsRef<DeviceInner>> ExternallyManagedObject<T> for vk::Sampler {
|
impl ExternallyManagedObject<Device> for vk::Sampler {
|
||||||
unsafe fn destroy(self, device: &T) {
|
unsafe fn destroy(self, device: &Device) {
|
||||||
unsafe { device.as_ref().raw.destroy_sampler(self, None) };
|
unsafe { device.raw.destroy_sampler(self, None) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsRef<DeviceInner>> ExternallyManagedObject<T> for vk::ShaderModule {
|
impl ExternallyManagedObject<Device> for vk::ShaderModule {
|
||||||
unsafe fn destroy(self, device: &T) {
|
unsafe fn destroy(self, device: &Device) {
|
||||||
unsafe { device.as_ref().raw.destroy_shader_module(self, None) };
|
unsafe { device.raw.destroy_shader_module(self, None) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsRef<DeviceInner>> ExternallyManagedObject<T> for vk::Pipeline {
|
impl ExternallyManagedObject<Device> for vk::Pipeline {
|
||||||
unsafe fn destroy(self, device: &T) {
|
unsafe fn destroy(self, device: &Device) {
|
||||||
unsafe { device.as_ref().raw.destroy_pipeline(self, None) };
|
unsafe { device.raw.destroy_pipeline(self, None) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsRef<DeviceInner>> ExternallyManagedObject<T> for vk::SwapchainKHR {
|
impl ExternallyManagedObject<Device> for vk::SwapchainKHR {
|
||||||
unsafe fn destroy(self, device: &T) {
|
unsafe fn destroy(self, device: &Device) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(swapchain) = device.as_ref().device_extensions.swapchain.as_ref() {
|
if let Some(swapchain) = device.device_extensions.swapchain.as_ref() {
|
||||||
swapchain.destroy_swapchain(self, None)
|
swapchain.destroy_swapchain(self, None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -880,17 +795,22 @@ pub trait Pooled: Sized {
|
||||||
fn create_from_pool(pool: &Pool<Self>) -> Result<Self>;
|
fn create_from_pool(pool: &Pool<Self>) -> Result<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A pooled handle which knows how to return itself to its pool.
|
||||||
|
pub trait Recycle: Sized {
|
||||||
|
fn recycle(self, device: &Device);
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Pool<T> {
|
pub struct Pool<T> {
|
||||||
pub pool: Mutex<Vec<T>>,
|
pub pool: Mutex<Vec<T>>,
|
||||||
pub device: Arc<DeviceInner>,
|
device: Weak<DeviceInner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Pool<T> {
|
impl<T> Pool<T> {
|
||||||
pub fn push(&self, item: T) {
|
pub fn push(&self, item: T) {
|
||||||
self.pool.lock().push(item);
|
self.pool.lock().push(item);
|
||||||
}
|
}
|
||||||
pub fn new(device: Arc<DeviceInner>) -> Self {
|
pub fn new(device: Weak<DeviceInner>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
pool: Mutex::new(Vec::new()),
|
pool: Mutex::new(Vec::new()),
|
||||||
device,
|
device,
|
||||||
|
|
@ -899,6 +819,10 @@ impl<T> Pool<T> {
|
||||||
pub fn pop(&self) -> Option<T> {
|
pub fn pop(&self) -> Option<T> {
|
||||||
self.pool.lock().pop()
|
self.pool.lock().pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn device(&self) -> Arc<DeviceInner> {
|
||||||
|
self.device.upgrade().expect("pool outlived its device")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> AsRef<Pool<T>> for Pool<T> {
|
impl<T> AsRef<Pool<T>> for Pool<T> {
|
||||||
|
|
@ -907,7 +831,43 @@ impl<T> AsRef<Pool<T>> for Pool<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PoolObject<T, U = Arc<Pool<T>>> = asdf::ExternallyManagedObject<T, U>;
|
pub struct PoolObject<T: Recycle> {
|
||||||
|
inner: std::mem::ManuallyDrop<T>,
|
||||||
|
device: Device,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Recycle> PoolObject<T> {
|
||||||
|
pub fn new(inner: T, device: Device) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: std::mem::ManuallyDrop::new(inner),
|
||||||
|
device,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn device(&self) -> &Device {
|
||||||
|
&self.device
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Recycle> Deref for PoolObject<T> {
|
||||||
|
type Target = T;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Recycle> DerefMut for PoolObject<T> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Recycle> Drop for PoolObject<T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let inner = unsafe { std::mem::ManuallyDrop::take(&mut self.inner) };
|
||||||
|
inner.recycle(&self.device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Pooled> Pool<T> {
|
impl<T: Pooled> Pool<T> {
|
||||||
pub fn get(&self) -> Result<T> {
|
pub fn get(&self) -> Result<T> {
|
||||||
|
|
@ -929,7 +889,8 @@ impl<T: Pooled> Pool<T> {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
let name = name.map(Into::into).unwrap_or_default();
|
let name = name.map(Into::into).unwrap_or_default();
|
||||||
<T as asdf::traits::DebugNameable>::debug_name(&obj, &self.device, &name);
|
let device = self.device();
|
||||||
|
<T as asdf::traits::DebugNameable>::debug_name(&obj, &device, &name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(obj)
|
Ok(obj)
|
||||||
|
|
@ -946,7 +907,7 @@ macro_rules! define_device_owned_handle {
|
||||||
} $(=> |$this:ident| $dtor:stmt)?) => {
|
} $(=> |$this:ident| $dtor:stmt)?) => {
|
||||||
$(#[$attr])*
|
$(#[$attr])*
|
||||||
$ty_vis struct $ty {
|
$ty_vis struct $ty {
|
||||||
inner: $crate::device::DeviceOwnedDebugObject<$handle>,
|
inner: $crate::device::DeviceObject<$handle>,
|
||||||
$(
|
$(
|
||||||
$(#[$field_attr])*
|
$(#[$field_attr])*
|
||||||
$field_vis $field_name: $field_ty,
|
$field_vis $field_name: $field_ty,
|
||||||
|
|
@ -955,10 +916,10 @@ macro_rules! define_device_owned_handle {
|
||||||
|
|
||||||
impl $crate::device::DeviceOwned<$handle> for $ty {
|
impl $crate::device::DeviceOwned<$handle> for $ty {
|
||||||
fn device(&self) -> &$crate::device::Device {
|
fn device(&self) -> &$crate::device::Device {
|
||||||
self.inner.dev()
|
self.inner.device()
|
||||||
}
|
}
|
||||||
fn handle(&self) -> $handle {
|
fn handle(&self) -> $handle {
|
||||||
self.inner.handle()
|
*self.inner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -971,11 +932,11 @@ macro_rules! define_device_owned_handle {
|
||||||
$($field_name: $field_ty,)*
|
$($field_name: $field_ty,)*
|
||||||
) -> ::ash::prelude::VkResult<Self> {
|
) -> ::ash::prelude::VkResult<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
inner: $crate::device::DeviceOwnedDebugObject::new(
|
inner: $crate::device::DeviceObject::new_debug_named(
|
||||||
device,
|
device,
|
||||||
handle,
|
handle,
|
||||||
name,
|
name,
|
||||||
)?,
|
),
|
||||||
$($field_name,)*
|
$($field_name,)*
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -993,19 +954,17 @@ macro_rules! define_device_owned_handle {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// This module is an experiment in a more generic way to manage device-owned resources.
|
|
||||||
// #[cfg(false)]
|
|
||||||
pub mod asdf {
|
pub mod asdf {
|
||||||
use std::{
|
use std::{
|
||||||
mem::{ManuallyDrop, MaybeUninit},
|
mem::ManuallyDrop,
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
sync::Arc,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
use ash::vk::Handle;
|
use ash::vk::Handle;
|
||||||
|
|
||||||
use crate::device::{DebugName, DeviceInner};
|
use crate::device::{DebugName, DeviceInner};
|
||||||
|
use crate::Device;
|
||||||
|
|
||||||
pub mod traits {
|
pub mod traits {
|
||||||
/// A trait describing an object owned by some manager-type, which is
|
/// A trait describing an object owned by some manager-type, which is
|
||||||
|
|
@ -1050,45 +1009,6 @@ pub mod asdf {
|
||||||
owner,
|
owner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn owner(&self) -> &O {
|
|
||||||
&self.owner
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn map_inner<U>(self, f: impl FnOnce(T) -> U) -> ExternallyManagedObject<U, O>
|
|
||||||
where
|
|
||||||
U: traits::ExternallyManagedObject<O>,
|
|
||||||
{
|
|
||||||
unsafe {
|
|
||||||
let mut this = MaybeUninit::new(self);
|
|
||||||
let inner = ManuallyDrop::take(&mut this.assume_init_mut().inner);
|
|
||||||
let owner = core::ptr::read(&raw const this.assume_init_mut().owner);
|
|
||||||
|
|
||||||
let new_inner = f(inner);
|
|
||||||
|
|
||||||
ExternallyManagedObject {
|
|
||||||
inner: ManuallyDrop::new(new_inner),
|
|
||||||
owner,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn map_owner<U>(self, f: impl FnOnce(O) -> U) -> ExternallyManagedObject<T, U>
|
|
||||||
where
|
|
||||||
T: traits::ExternallyManagedObject<U>,
|
|
||||||
{
|
|
||||||
unsafe {
|
|
||||||
let mut this = MaybeUninit::new(self);
|
|
||||||
let inner = ManuallyDrop::take(&mut this.assume_init_mut().inner);
|
|
||||||
|
|
||||||
// get the old owner without calling `Self::drop`
|
|
||||||
let owner = core::ptr::read(&raw const this.assume_init_mut().owner);
|
|
||||||
|
|
||||||
ExternallyManagedObject {
|
|
||||||
inner: ManuallyDrop::new(inner),
|
|
||||||
owner: f(owner),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, O> Drop for ExternallyManagedObject<T, O>
|
impl<T, O> Drop for ExternallyManagedObject<T, O>
|
||||||
|
|
@ -1103,95 +1023,56 @@ pub mod asdf {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type InnerDeviceObject<T> = DeviceObject<T, Arc<DeviceInner>>;
|
|
||||||
|
|
||||||
/// A wrapper for vulkan types which are owned by the device, taking care of destruction.
|
/// A wrapper for vulkan types which are owned by the device, taking care of destruction.
|
||||||
pub struct DeviceObject<
|
pub struct DeviceObject<T: traits::ExternallyManagedObject<Device>> {
|
||||||
T: traits::ExternallyManagedObject<O>,
|
inner: ExternallyManagedObject<T, Device>,
|
||||||
O: AsRef<super::DeviceInner> = super::Device,
|
|
||||||
> {
|
|
||||||
inner: ExternallyManagedObject<T, O>,
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
name: Option<DebugName>,
|
name: Option<DebugName>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<T: traits::ExternallyManagedObject<Device> + traits::DebugNameable> DeviceObject<T> {
|
||||||
T: traits::ExternallyManagedObject<O> + traits::DebugNameable,
|
pub fn new_debug_named(
|
||||||
O: AsRef<super::DeviceInner>,
|
device: Device,
|
||||||
> DeviceObject<T, O>
|
inner: T,
|
||||||
{
|
name: Option<impl Into<DebugName>>,
|
||||||
pub fn new_debug_named(owner: O, inner: T, name: Option<impl Into<DebugName>>) -> Self {
|
) -> Self {
|
||||||
let name = name.map(Into::into);
|
let name = name.map(Into::into);
|
||||||
if let Some(ref name) = name {
|
if let Some(ref name) = name {
|
||||||
traits::DebugNameable::debug_name(&inner, owner.as_ref(), name);
|
traits::DebugNameable::debug_name(&inner, &device, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
let obj = ExternallyManagedObject::new(inner, owner);
|
let obj = ExternallyManagedObject::new(inner, device);
|
||||||
|
|
||||||
Self { inner: obj, name }
|
Self { inner: obj, name }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: traits::ExternallyManagedObject<O>, O: AsRef<super::DeviceInner>> DeviceObject<T, O> {
|
impl<T: traits::ExternallyManagedObject<Device>> DeviceObject<T> {
|
||||||
pub fn new(owner: O, inner: T) -> Self {
|
pub fn new(device: Device, inner: T) -> Self {
|
||||||
let inner = ExternallyManagedObject::new(inner, owner);
|
let inner = ExternallyManagedObject::new(inner, device);
|
||||||
|
|
||||||
Self { inner, name: None }
|
Self { inner, name: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_debug_named_with<D>(
|
pub fn device(&self) -> &Device {
|
||||||
owner: O,
|
&self.inner.owner
|
||||||
inner: T,
|
}
|
||||||
name: Option<impl Into<DebugName>>,
|
|
||||||
debug_namable: impl FnOnce(&T) -> D,
|
pub fn handle(&self) -> T
|
||||||
) -> Self
|
|
||||||
where
|
where
|
||||||
D: traits::DebugNameable,
|
T: Copy,
|
||||||
{
|
{
|
||||||
let name = name.map(Into::into);
|
*Deref::deref(self)
|
||||||
if let Some(ref name) = name {
|
|
||||||
traits::DebugNameable::debug_name(&debug_namable(&inner), owner.as_ref(), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
let obj = ExternallyManagedObject::new(inner, owner);
|
|
||||||
|
|
||||||
Self { inner: obj, name }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn device(&self) -> &O {
|
|
||||||
self.inner.owner()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> Option<&str> {
|
pub fn name(&self) -> Option<&str> {
|
||||||
self.name.as_ref().map(|n| &**n)
|
self.name.as_deref()
|
||||||
}
|
|
||||||
|
|
||||||
pub fn map_inner<U>(self, f: impl FnOnce(T) -> U) -> DeviceObject<U, O>
|
|
||||||
where
|
|
||||||
U: traits::ExternallyManagedObject<O>,
|
|
||||||
{
|
|
||||||
DeviceObject {
|
|
||||||
inner: self.inner.map_inner(f),
|
|
||||||
name: self.name,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_owner<U>(self, f: impl FnOnce(O) -> U) -> DeviceObject<T, U>
|
impl<T> std::fmt::Debug for DeviceObject<T>
|
||||||
where
|
where
|
||||||
T: traits::ExternallyManagedObject<U>,
|
T: std::fmt::Debug + traits::ExternallyManagedObject<Device>,
|
||||||
U: AsRef<super::DeviceInner>,
|
|
||||||
{
|
|
||||||
DeviceObject {
|
|
||||||
inner: self.inner.map_owner(f),
|
|
||||||
name: self.name,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, O> std::fmt::Debug for DeviceObject<T, O>
|
|
||||||
where
|
|
||||||
T: std::fmt::Debug + traits::ExternallyManagedObject<O>,
|
|
||||||
O: AsRef<super::DeviceInner>,
|
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let mut fmt = f.debug_struct(core::any::type_name::<T>());
|
let mut fmt = f.debug_struct(core::any::type_name::<T>());
|
||||||
|
|
@ -1200,8 +1081,7 @@ pub mod asdf {
|
||||||
fmt.field_with("device", |f| {
|
fmt.field_with("device", |f| {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"0x{:x}",
|
"0x{:x}", self.inner.owner.raw.handle().as_raw()
|
||||||
self.inner.owner().as_ref().raw.handle().as_raw()
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.field_with("handle", |f| write!(f, "{inner:?}"))
|
.field_with("handle", |f| write!(f, "{inner:?}"))
|
||||||
|
|
@ -1211,10 +1091,9 @@ pub mod asdf {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, O> Deref for DeviceObject<T, O>
|
impl<T> Deref for DeviceObject<T>
|
||||||
where
|
where
|
||||||
T: traits::ExternallyManagedObject<O>,
|
T: traits::ExternallyManagedObject<Device>,
|
||||||
O: AsRef<super::DeviceInner>,
|
|
||||||
{
|
{
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
|
|
@ -1223,10 +1102,9 @@ pub mod asdf {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, O> DerefMut for DeviceObject<T, O>
|
impl<T> DerefMut for DeviceObject<T>
|
||||||
where
|
where
|
||||||
T: traits::ExternallyManagedObject<O>,
|
T: traits::ExternallyManagedObject<Device>,
|
||||||
O: AsRef<super::DeviceInner>,
|
|
||||||
{
|
{
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut self.inner
|
&mut self.inner
|
||||||
|
|
@ -1234,29 +1112,39 @@ pub mod asdf {
|
||||||
}
|
}
|
||||||
|
|
||||||
mod impls {
|
mod impls {
|
||||||
use crate::device::{DeviceInner, DevicePools, GpuAllocation};
|
use crate::device::GpuAllocation;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
impl<T: AsRef<DeviceInner>> traits::ExternallyManagedObject<T> for vk::Semaphore {
|
impl traits::ExternallyManagedObject<Device> for vk::Semaphore {
|
||||||
unsafe fn destroy(self, device: &T) {
|
unsafe fn destroy(self, device: &Device) {
|
||||||
unsafe {
|
unsafe { device.raw.destroy_semaphore(self, None) };
|
||||||
device.as_ref().raw.destroy_semaphore(self, None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: AsRef<DeviceInner>> traits::ExternallyManagedObject<T> for GpuAllocation {
|
|
||||||
unsafe fn destroy(self, device: &T) {
|
|
||||||
_ = device.as_ref().alloc2.lock().free(self);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl traits::ExternallyManagedObject<DevicePools> for vk::Semaphore {
|
impl traits::ExternallyManagedObject<Device> for GpuAllocation {
|
||||||
unsafe fn destroy(self, owner: &DevicePools) {
|
unsafe fn destroy(self, device: &Device) {
|
||||||
owner
|
_ = device.alloc2.lock().free(self);
|
||||||
.binary_semaphores
|
}
|
||||||
.push(crate::sync::BinarySemaphore(self));
|
}
|
||||||
|
|
||||||
|
impl traits::ExternallyManagedObject<Device> for vk::CommandBuffer {
|
||||||
|
unsafe fn destroy(self, _: &Device) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl traits::ExternallyManagedObject<Device> for vk::CommandPool {
|
||||||
|
unsafe fn destroy(self, _: &Device) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> crate::device::DeviceOwned<T> for DeviceObject<T>
|
||||||
|
where
|
||||||
|
T: vk::Handle + Copy + traits::ExternallyManagedObject<Device>,
|
||||||
|
{
|
||||||
|
fn device(&self) -> &Device {
|
||||||
|
self.device()
|
||||||
|
}
|
||||||
|
fn handle(&self) -> T {
|
||||||
|
self.handle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1275,30 +1163,27 @@ pub mod asdf {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn asdf() {
|
fn asdf() {
|
||||||
use crate::device::{DevicePools, GpuAllocation};
|
use crate::device::GpuAllocation;
|
||||||
fn summon<T>() -> T {
|
fn summon<T>() -> T {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
let _inner_ref: DeviceObject<vk::Semaphore, &DeviceInner> = DeviceObject::new_debug_named(
|
let _inner_ref: DeviceObject<vk::Semaphore> = DeviceObject::new_debug_named(
|
||||||
summon::<&DeviceInner>(),
|
summon::<Device>(),
|
||||||
summon::<vk::Semaphore>(),
|
summon::<vk::Semaphore>(),
|
||||||
Some("my semaphore"),
|
Some("my semaphore"),
|
||||||
);
|
);
|
||||||
|
|
||||||
let _device_owned: DeviceObject<vk::Semaphore, super::Device> =
|
let _device_owned: DeviceObject<vk::Semaphore> = DeviceObject::new_debug_named(
|
||||||
DeviceObject::new_debug_named(
|
|
||||||
summon::<super::Device>(),
|
summon::<super::Device>(),
|
||||||
summon::<vk::Semaphore>(),
|
summon::<vk::Semaphore>(),
|
||||||
Some("my other semaphore"),
|
Some("my other semaphore"),
|
||||||
);
|
);
|
||||||
|
|
||||||
let _allocation: DeviceObject<GpuAllocation, Arc<super::DeviceInner>> = DeviceObject::new(
|
let _allocation: DeviceObject<GpuAllocation> =
|
||||||
summon::<Arc<super::DeviceInner>>(),
|
DeviceObject::new(summon::<Device>(), summon::<GpuAllocation>());
|
||||||
summon::<GpuAllocation>(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let _pool_owned: ExternallyManagedObject<vk::Semaphore, DevicePools> =
|
let _pool_owned: DeviceObject<vk::Semaphore> =
|
||||||
ExternallyManagedObject::new(summon::<vk::Semaphore>(), summon::<DevicePools>());
|
DeviceObject::new(summon::<Device>(), summon::<vk::Semaphore>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ mod device_ref_derive_tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(renderer_macros::DeviceRef)]
|
#[derive(renderer_macros::DeviceRef)]
|
||||||
struct GenericWrapper<D> {
|
struct GenericWrapper<D: DeviceRef> {
|
||||||
#[device]
|
#[device]
|
||||||
device: D,
|
device: D,
|
||||||
tag: &'static str,
|
tag: &'static str,
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,19 @@
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
|
|
||||||
use ash::Device;
|
use ash::Device;
|
||||||
|
|
||||||
use crate::PhysicalDeviceInfo;
|
use crate::PhysicalDeviceInfo;
|
||||||
use crate::device::DeviceInner;
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct PipelineCache {
|
pub struct PipelineCache {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
key: u128,
|
key: u128,
|
||||||
pub raw: vk::PipelineCache,
|
pub raw: vk::PipelineCache,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::device::asdf::traits::ExternallyManagedObject<Arc<DeviceInner>> for PipelineCache {
|
impl PipelineCache {
|
||||||
unsafe fn destroy(self, owner: &Arc<DeviceInner>) {
|
pub(crate) unsafe fn destroy(self, device: &ash::Device) {
|
||||||
tracing::info!("destroying pipeline cache with key {:x}", self.key);
|
tracing::info!("destroying pipeline cache with key {:x}", self.key);
|
||||||
if let Ok(data) = self.export(&owner.raw) {
|
if let Ok(data) = self.export(device) {
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
"exported pipeline cache with key {:x} and size {} bytes",
|
"exported pipeline cache with key {:x} and size {} bytes",
|
||||||
self.key,
|
self.key,
|
||||||
|
|
@ -27,11 +23,9 @@ impl crate::device::asdf::traits::ExternallyManagedObject<Arc<DeviceInner>> for
|
||||||
tracing::error!("failed to write pipeline cache to disk: {err}");
|
tracing::error!("failed to write pipeline cache to disk: {err}");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
unsafe { owner.raw.destroy_pipeline_cache(self.raw, None) };
|
unsafe { device.destroy_pipeline_cache(self.raw, None) };
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PipelineCache {
|
|
||||||
const MAGIC: [u8; 4] = *b"VYPC";
|
const MAGIC: [u8; 4] = *b"VYPC";
|
||||||
const KEY_VERSION: u32 = 1;
|
const KEY_VERSION: u32 = 1;
|
||||||
const PATH: &'static str = "pipeline_cache.bin";
|
const PATH: &'static str = "pipeline_cache.bin";
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::device::{
|
use crate::device::{
|
||||||
DevicePools, Pool, PoolObject, Pooled,
|
Pool, PoolObject, Pooled, Recycle,
|
||||||
asdf::{
|
asdf::{
|
||||||
DeviceObject, InnerDeviceObject,
|
DeviceObject,
|
||||||
traits::ExternallyManagedObject as ExternallyManagedObjectTrait,
|
traits::ExternallyManagedObject as ExternallyManagedObjectTrait,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -160,17 +160,17 @@ impl SyncThreadpool {
|
||||||
|
|
||||||
pub enum Fence {
|
pub enum Fence {
|
||||||
Dedicated {
|
Dedicated {
|
||||||
fence: InnerDeviceObject<vk::Fence>,
|
fence: DeviceObject<vk::Fence>,
|
||||||
},
|
},
|
||||||
Pooled {
|
Pooled {
|
||||||
fence: PoolObject<vk::Fence, Arc<Pool<vk::Fence>>>,
|
fence: PoolObject<vk::Fence>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pooled for vk::Fence {
|
impl Pooled for vk::Fence {
|
||||||
fn create_from_pool(pool: &Pool<Self>) -> Result<Self> {
|
fn create_from_pool(pool: &Pool<Self>) -> Result<Self> {
|
||||||
let fence = unsafe {
|
let fence = unsafe {
|
||||||
pool.device
|
pool.device()
|
||||||
.raw
|
.raw
|
||||||
.create_fence(&vk::FenceCreateInfo::default(), None)?
|
.create_fence(&vk::FenceCreateInfo::default(), None)?
|
||||||
};
|
};
|
||||||
|
|
@ -179,17 +179,15 @@ impl Pooled for vk::Fence {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExternallyManagedObjectTrait<Arc<Pool<vk::Fence>>> for vk::Fence {
|
impl Recycle for vk::Fence {
|
||||||
unsafe fn destroy(self, pool: &Arc<Pool<vk::Fence>>) {
|
fn recycle(self, device: &Device) {
|
||||||
pool.push(self);
|
device.pools.fences.push(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsRef<DeviceInner>> ExternallyManagedObjectTrait<T> for vk::Fence {
|
impl ExternallyManagedObjectTrait<Device> for vk::Fence {
|
||||||
unsafe fn destroy(self, device: &T) {
|
unsafe fn destroy(self, device: &Device) {
|
||||||
unsafe {
|
unsafe { device.raw.destroy_fence(self, None) };
|
||||||
device.as_ref().raw.destroy_fence(self, None);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -207,14 +205,14 @@ impl Fence {
|
||||||
.create_fence(&vk::FenceCreateInfo::default(), None)?
|
.create_fence(&vk::FenceCreateInfo::default(), None)?
|
||||||
};
|
};
|
||||||
Ok(Self::Dedicated {
|
Ok(Self::Dedicated {
|
||||||
fence: DeviceObject::new_debug_named(device.shared.clone(), fence, name),
|
fence: DeviceObject::new_debug_named(device, fence, name),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn from_pool(pool: &Arc<Pool<vk::Fence>>, name: Option<&'static str>) -> Result<Fence> {
|
pub fn from_pool(device: &Device, name: Option<&'static str>) -> Result<Fence> {
|
||||||
let fence = pool.get_debug_named(name)?;
|
let fence = device.pools.fences.get_debug_named(name)?;
|
||||||
|
|
||||||
Ok(Self::Pooled {
|
Ok(Self::Pooled {
|
||||||
fence: PoolObject::new(fence, pool.clone()),
|
fence: PoolObject::new(fence, device.clone()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -225,10 +223,10 @@ impl Fence {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn device(&self) -> &Arc<DeviceInner> {
|
fn device(&self) -> &Device {
|
||||||
match self {
|
match self {
|
||||||
Fence::Dedicated { fence } => &fence.device(),
|
Fence::Dedicated { fence } => fence.device(),
|
||||||
Fence::Pooled { fence } => &fence.owner().device,
|
Fence::Pooled { fence } => fence.device(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -278,21 +276,21 @@ pub enum SemaphoreInner {
|
||||||
Timeline(vk::Semaphore),
|
Timeline(vk::Semaphore),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExternallyManagedObjectTrait<Arc<DevicePools>> for SemaphoreInner {
|
impl Recycle for SemaphoreInner {
|
||||||
unsafe fn destroy(self, owner: &Arc<DevicePools>) {
|
fn recycle(self, owner: &Device) {
|
||||||
match self {
|
match self {
|
||||||
SemaphoreInner::Binary(semaphore) => {
|
SemaphoreInner::Binary(semaphore) => {
|
||||||
owner.binary_semaphores.push(BinarySemaphore(semaphore))
|
owner.pools.binary_semaphores.push(BinarySemaphore(semaphore))
|
||||||
}
|
}
|
||||||
SemaphoreInner::Timeline(semaphore) => {
|
SemaphoreInner::Timeline(semaphore) => {
|
||||||
owner.timeline_semaphores.push(TimelineSemaphore(semaphore))
|
owner.pools.timeline_semaphores.push(TimelineSemaphore(semaphore))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExternallyManagedObjectTrait<Arc<DeviceInner>> for SemaphoreInner {
|
impl ExternallyManagedObjectTrait<Device> for SemaphoreInner {
|
||||||
unsafe fn destroy(self, owner: &Arc<DeviceInner>) {
|
unsafe fn destroy(self, owner: &Device) {
|
||||||
match self {
|
match self {
|
||||||
SemaphoreInner::Binary(semaphore) | SemaphoreInner::Timeline(semaphore) => {
|
SemaphoreInner::Binary(semaphore) | SemaphoreInner::Timeline(semaphore) => {
|
||||||
unsafe { owner.raw.destroy_semaphore(semaphore, None) };
|
unsafe { owner.raw.destroy_semaphore(semaphore, None) };
|
||||||
|
|
@ -336,11 +334,11 @@ impl From<TimelineSemaphore> for SemaphoreInner {
|
||||||
|
|
||||||
pub enum Semaphore {
|
pub enum Semaphore {
|
||||||
Dedicated {
|
Dedicated {
|
||||||
semaphore: InnerDeviceObject<SemaphoreInner>,
|
semaphore: DeviceObject<SemaphoreInner>,
|
||||||
},
|
},
|
||||||
Pooled {
|
Pooled {
|
||||||
#[allow(private_interfaces)]
|
#[allow(private_interfaces)]
|
||||||
semaphore: PoolObject<SemaphoreInner, Arc<DevicePools>>,
|
semaphore: PoolObject<SemaphoreInner>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -379,7 +377,7 @@ impl Pooled for BinarySemaphore {
|
||||||
let mut type_info =
|
let mut type_info =
|
||||||
vk::SemaphoreTypeCreateInfo::default().semaphore_type(vk::SemaphoreType::BINARY);
|
vk::SemaphoreTypeCreateInfo::default().semaphore_type(vk::SemaphoreType::BINARY);
|
||||||
let create_info = vk::SemaphoreCreateInfo::default().push_next(&mut type_info);
|
let create_info = vk::SemaphoreCreateInfo::default().push_next(&mut type_info);
|
||||||
let inner = unsafe { pool.device.raw.create_semaphore(&create_info, None)? };
|
let inner = unsafe { pool.device().raw.create_semaphore(&create_info, None)? };
|
||||||
Ok(Self(inner))
|
Ok(Self(inner))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -390,7 +388,7 @@ impl Pooled for TimelineSemaphore {
|
||||||
.semaphore_type(vk::SemaphoreType::TIMELINE)
|
.semaphore_type(vk::SemaphoreType::TIMELINE)
|
||||||
.initial_value(0);
|
.initial_value(0);
|
||||||
let create_info = vk::SemaphoreCreateInfo::default().push_next(&mut type_info);
|
let create_info = vk::SemaphoreCreateInfo::default().push_next(&mut type_info);
|
||||||
let inner = unsafe { pool.device.raw.create_semaphore(&create_info, None)? };
|
let inner = unsafe { pool.device().raw.create_semaphore(&create_info, None)? };
|
||||||
Ok(Self(inner))
|
Ok(Self(inner))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -421,7 +419,7 @@ impl Semaphore {
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Self::Dedicated {
|
Ok(Self::Dedicated {
|
||||||
semaphore: DeviceObject::new_debug_named(device.shared.clone(), inner, name),
|
semaphore: DeviceObject::new_debug_named(device, inner, name),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -433,12 +431,12 @@ impl Semaphore {
|
||||||
let semaphore = match semaphore_type {
|
let semaphore = match semaphore_type {
|
||||||
SemaphoreType::Binary => {
|
SemaphoreType::Binary => {
|
||||||
let semaphore: SemaphoreInner =
|
let semaphore: SemaphoreInner =
|
||||||
device.pools().binary_semaphores.get_debug_named(name)?.into();
|
device.pools.binary_semaphores.get_debug_named(name)?.into();
|
||||||
PoolObject::new(semaphore, device.pools().clone())
|
PoolObject::new(semaphore, device)
|
||||||
}
|
}
|
||||||
SemaphoreType::Timeline(value) => {
|
SemaphoreType::Timeline(value) => {
|
||||||
let semaphore: SemaphoreInner = device
|
let semaphore: SemaphoreInner = device
|
||||||
.pools()
|
.pools
|
||||||
.timeline_semaphores
|
.timeline_semaphores
|
||||||
.get_debug_named(name)?
|
.get_debug_named(name)?
|
||||||
.into();
|
.into();
|
||||||
|
|
@ -450,7 +448,7 @@ impl Semaphore {
|
||||||
device.raw.signal_semaphore(&info)?;
|
device.raw.signal_semaphore(&info)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
PoolObject::new(semaphore, device.pools().clone())
|
PoolObject::new(semaphore, device)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue