use super::{
pool::{DescriptorPool, DescriptorPoolAlloc},
sys::UnsafeDescriptorSet,
CopyDescriptorSet,
};
use crate::{
descriptor_set::{
allocator::{DescriptorSetAlloc, DescriptorSetAllocator, StandardDescriptorSetAlloc},
update::WriteDescriptorSet,
DescriptorSet, DescriptorSetLayout, DescriptorSetResources,
},
device::{Device, DeviceOwned},
Validated, ValidationError, VulkanError, VulkanObject,
};
use smallvec::SmallVec;
use std::{
hash::{Hash, Hasher},
sync::Arc,
};
pub struct PersistentDescriptorSet<P = StandardDescriptorSetAlloc> {
inner: UnsafeDescriptorSet<P>,
resources: DescriptorSetResources,
}
impl PersistentDescriptorSet {
#[inline]
pub fn new<A>(
allocator: &A,
layout: Arc<DescriptorSetLayout>,
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
descriptor_copies: impl IntoIterator<Item = CopyDescriptorSet>,
) -> Result<Arc<PersistentDescriptorSet<A::Alloc>>, Validated<VulkanError>>
where
A: DescriptorSetAllocator + ?Sized,
{
Self::new_variable(allocator, layout, 0, descriptor_writes, descriptor_copies)
}
pub fn new_variable<A>(
allocator: &A,
layout: Arc<DescriptorSetLayout>,
variable_descriptor_count: u32,
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
descriptor_copies: impl IntoIterator<Item = CopyDescriptorSet>,
) -> Result<Arc<PersistentDescriptorSet<A::Alloc>>, Validated<VulkanError>>
where
A: DescriptorSetAllocator + ?Sized,
{
let mut set = PersistentDescriptorSet {
inner: UnsafeDescriptorSet::new(allocator, &layout, variable_descriptor_count)?,
resources: DescriptorSetResources::new(&layout, variable_descriptor_count),
};
unsafe {
set.update(descriptor_writes, descriptor_copies)?;
}
Ok(Arc::new(set))
}
}
impl<P> PersistentDescriptorSet<P>
where
P: DescriptorSetAlloc,
{
unsafe fn update(
&mut self,
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
descriptor_copies: impl IntoIterator<Item = CopyDescriptorSet>,
) -> Result<(), Box<ValidationError>> {
let descriptor_writes: SmallVec<[_; 8]> = descriptor_writes.into_iter().collect();
let descriptor_copies: SmallVec<[_; 8]> = descriptor_copies.into_iter().collect();
unsafe {
self.inner.update(&descriptor_writes, &descriptor_copies)?;
}
for write in descriptor_writes {
self.resources.write(&write, self.inner.layout());
}
for copy in descriptor_copies {
self.resources.copy(©);
}
Ok(())
}
}
unsafe impl<P> DescriptorSet for PersistentDescriptorSet<P>
where
P: DescriptorSetAlloc,
{
fn alloc(&self) -> &DescriptorPoolAlloc {
self.inner.alloc().inner()
}
fn pool(&self) -> &DescriptorPool {
self.inner.alloc().pool()
}
fn resources(&self) -> &DescriptorSetResources {
&self.resources
}
}
unsafe impl<P> VulkanObject for PersistentDescriptorSet<P>
where
P: DescriptorSetAlloc,
{
type Handle = ash::vk::DescriptorSet;
fn handle(&self) -> Self::Handle {
self.inner.handle()
}
}
unsafe impl<P> DeviceOwned for PersistentDescriptorSet<P>
where
P: DescriptorSetAlloc,
{
fn device(&self) -> &Arc<Device> {
self.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);
}
}