use crate::{
descriptor_set::{
layout::DescriptorSetLayout,
update::{DescriptorWriteInfo, WriteDescriptorSet},
},
device::DeviceOwned,
VulkanObject,
};
use smallvec::SmallVec;
use std::{
fmt::{Debug, Error as FmtError, Formatter},
num::NonZeroU64,
ptr,
};
pub struct UnsafeDescriptorSet {
handle: ash::vk::DescriptorSet,
id: NonZeroU64,
}
impl UnsafeDescriptorSet {
pub(crate) fn new(handle: ash::vk::DescriptorSet) -> Self {
Self {
handle,
id: Self::next_id(),
}
}
pub unsafe fn write<'a>(
&mut self,
layout: &DescriptorSetLayout,
writes: impl IntoIterator<Item = &'a WriteDescriptorSet>,
) {
let (infos, mut writes): (SmallVec<[_; 8]>, SmallVec<[_; 8]>) = writes
.into_iter()
.map(|write| {
let descriptor_type = layout.bindings()[&write.binding()].descriptor_type;
(
write.to_vulkan_info(descriptor_type),
write.to_vulkan(self.handle, descriptor_type),
)
})
.unzip();
if writes.is_empty() {
return;
}
for (info, write) in infos.iter().zip(writes.iter_mut()) {
match info {
DescriptorWriteInfo::Image(info) => {
write.descriptor_count = info.len() as u32;
write.p_image_info = info.as_ptr();
}
DescriptorWriteInfo::Buffer(info) => {
write.descriptor_count = info.len() as u32;
write.p_buffer_info = info.as_ptr();
}
DescriptorWriteInfo::BufferView(info) => {
write.descriptor_count = info.len() as u32;
write.p_texel_buffer_view = info.as_ptr();
}
}
debug_assert!(write.descriptor_count != 0);
}
let fns = layout.device().fns();
(fns.v1_0.update_descriptor_sets)(
layout.device().handle(),
writes.len() as u32,
writes.as_ptr(),
0,
ptr::null(),
);
}
}
unsafe impl VulkanObject for UnsafeDescriptorSet {
type Handle = ash::vk::DescriptorSet;
#[inline]
fn handle(&self) -> Self::Handle {
self.handle
}
}
impl Debug for UnsafeDescriptorSet {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(f, "<Vulkan descriptor set {:?}>", self.handle)
}
}
crate::impl_id_counter!(UnsafeDescriptorSet);