use crate::{
descriptor_set::{
allocator::{DescriptorSetAlloc, DescriptorSetAllocator, StandardDescriptorSetAlloc},
update::WriteDescriptorSet,
DescriptorSet, DescriptorSetCreationError, DescriptorSetInner, DescriptorSetLayout,
DescriptorSetResources, UnsafeDescriptorSet,
},
device::{Device, DeviceOwned},
VulkanObject,
};
use std::{
hash::{Hash, Hasher},
sync::Arc,
};
pub struct PersistentDescriptorSet<P = StandardDescriptorSetAlloc> {
alloc: P,
inner: DescriptorSetInner,
}
impl PersistentDescriptorSet {
#[inline]
pub fn new<A>(
allocator: &A,
layout: Arc<DescriptorSetLayout>,
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
) -> Result<Arc<PersistentDescriptorSet<A::Alloc>>, DescriptorSetCreationError>
where
A: DescriptorSetAllocator + ?Sized,
{
Self::new_variable(allocator, layout, 0, descriptor_writes)
}
pub fn new_variable<A>(
allocator: &A,
layout: Arc<DescriptorSetLayout>,
variable_descriptor_count: u32,
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
) -> Result<Arc<PersistentDescriptorSet<A::Alloc>>, DescriptorSetCreationError>
where
A: DescriptorSetAllocator + ?Sized,
{
assert!(
!layout.push_descriptor(),
"the provided descriptor set layout is for push descriptors, and cannot be used to \
build a descriptor set object",
);
let max_count = layout.variable_descriptor_count();
assert!(
variable_descriptor_count <= max_count,
"the provided variable_descriptor_count ({}) is greater than the maximum number of \
variable count descriptors in the set ({})",
variable_descriptor_count,
max_count,
);
let alloc = allocator.allocate(&layout, variable_descriptor_count)?;
let inner = DescriptorSetInner::new(
alloc.inner().handle(),
layout,
variable_descriptor_count,
descriptor_writes,
)?;
Ok(Arc::new(PersistentDescriptorSet { alloc, inner }))
}
}
unsafe impl<P> DescriptorSet for PersistentDescriptorSet<P>
where
P: DescriptorSetAlloc,
{
fn inner(&self) -> &UnsafeDescriptorSet {
self.alloc.inner()
}
fn layout(&self) -> &Arc<DescriptorSetLayout> {
self.inner.layout()
}
fn resources(&self) -> &DescriptorSetResources {
self.inner.resources()
}
}
unsafe impl<P> DeviceOwned for PersistentDescriptorSet<P>
where
P: DescriptorSetAlloc,
{
fn device(&self) -> &Arc<Device> {
self.inner.layout().device()
}
}
impl<P> PartialEq for PersistentDescriptorSet<P>
where
P: DescriptorSetAlloc,
{
fn eq(&self, other: &Self) -> bool {
self.inner() == other.inner()
}
}
impl<P> Eq for PersistentDescriptorSet<P> where P: DescriptorSetAlloc {}
impl<P> Hash for PersistentDescriptorSet<P>
where
P: DescriptorSetAlloc,
{
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner().hash(state);
}
}