You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

115 lines
2.5 KiB

use crate::render::{Buffer, DescriptorSetLayout, Device, Uniforms};
use ash::{version::DeviceV1_0, vk};
use std::rc::Rc;
pub struct DescriptorSet {
handle: vk::DescriptorSet,
}
pub struct DescriptorPool {
handle: vk::DescriptorPool,
pub device: Rc<Device>,
pub buffers: Vec<Rc<Buffer>>,
pub sets: Vec<DescriptorSet>,
}
impl DescriptorPool {
pub fn create(
device: Rc<Device>,
buffers: Vec<Rc<Buffer>>,
layout: Rc<DescriptorSetLayout>,
) -> Result<Rc<Self>, vk::Result> {
let size_info = [
vk::DescriptorPoolSize {
ty: vk::DescriptorType::UNIFORM_BUFFER,
descriptor_count: buffers.len() as u32,
..Default::default()
}
];
let create_info = vk::DescriptorPoolCreateInfo {
pool_size_count: size_info.len() as u32,
p_pool_sizes: size_info.as_ptr(),
max_sets: buffers.len() as u32,
..Default::default()
};
let handle =
unsafe { device.create_descriptor_pool(&create_info, None)? };
let set_layouts = vec![**layout; buffers.len()];
let alloc_info = vk::DescriptorSetAllocateInfo {
descriptor_pool: handle,
descriptor_set_count: set_layouts.len() as u32,
p_set_layouts: set_layouts.as_ptr(),
..Default::default()
};
let sets = unsafe {
device
.allocate_descriptor_sets(&alloc_info)?
.iter()
.map(|&handle| DescriptorSet { handle })
.collect::<Vec<_>>()
};
let buffer_infos =
buffers
.iter()
.map(|buffer| {
vk::DescriptorBufferInfo {
buffer: ***buffer,
range: std::mem::size_of::<Uniforms>() as vk::DeviceSize,
..Default::default()
}
})
.collect::<Vec<_>>();
let write_descriptors =
sets
.iter()
.zip(&buffer_infos)
.map(|(dst_set, buffer_info)| {
vk::WriteDescriptorSet {
dst_set: **dst_set,
descriptor_type: vk::DescriptorType::UNIFORM_BUFFER,
descriptor_count: 1,
p_buffer_info: &*buffer_info,
..Default::default()
}
})
.collect::<Vec<_>>();
unsafe {
device.update_descriptor_sets(&write_descriptors, &[]);
}
Ok(Rc::new(Self { handle, device, buffers, sets }))
}
}
impl Drop for DescriptorPool {
fn drop(&mut self) {
unsafe {
self.device.destroy_descriptor_pool(self.handle, None);
}
}
}
impl std::ops::Deref for DescriptorSet {
type Target = vk::DescriptorSet;
fn deref(&self) -> &Self::Target {
&self.handle
}
}
impl std::ops::Deref for DescriptorPool {
type Target = vk::DescriptorPool;
fn deref(&self) -> &Self::Target {
&self.handle
}
}
// EOF