use crate::prelude::*; use anyhow::Result; use std::sync::Arc; pub struct DescriptorPoolBuilder { layout: Option>, flags: VkDescriptorPoolCreateFlagBits, } impl DescriptorPoolBuilder { pub fn set_flags(mut self, flags: impl Into) -> Self { self.flags |= flags.into(); self } pub fn set_layout(mut self, layout: Arc) -> Self { self.layout = Some(layout); self } pub fn build(self, device: Arc) -> Result> { if cfg!(debug_assertions) { if self.layout.is_none() { panic!("no layout set!"); } } let layout = self.layout.expect("descriptor set layout was not set!"); let descriptor_count: u32 = layout .pool_sizes() .iter() .map(|pool| pool.descriptorCount) .sum(); if cfg!(debug_assertions) { if descriptor_count == 0 { panic!("descriptor count must be greater than 0"); } } let descriptor_pool_ci = VkDescriptorPoolCreateInfo::new(self.flags, descriptor_count, layout.pool_sizes()); let descriptor_pool = device.create_descriptor_pool(&descriptor_pool_ci)?; Ok(Arc::new(DescriptorPool { device, descriptor_pool, descriptor_set_layout: layout, })) } } #[derive(Debug)] pub struct DescriptorPool { device: Arc, descriptor_pool: VkDescriptorPool, descriptor_set_layout: Arc, } impl DescriptorPool { pub fn builder() -> DescriptorPoolBuilder { DescriptorPoolBuilder { layout: None, flags: VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT.into(), } } pub fn reset(&self) -> Result<()> { self.device .reset_descriptor_pool(self.descriptor_pool, VK_DESCRIPTOR_POOL_RESET_NULL_BIT) } pub fn prepare_set(self: &Arc) -> DescriptorSetBuilder { DescriptorSet::builder(self.device.clone(), self.clone()) } } impl VulkanDevice for DescriptorPool { fn device(&self) -> &Arc { &self.device } } impl_vk_handle!(DescriptorPool, VkDescriptorPool, descriptor_pool); impl VkHandle for DescriptorPool { fn vk_handle(&self) -> VkDescriptorSetLayout { self.descriptor_set_layout.vk_handle() } } impl<'a> VkHandle for &'a DescriptorPool { fn vk_handle(&self) -> VkDescriptorSetLayout { self.descriptor_set_layout.vk_handle() } } impl VkHandle for Arc { fn vk_handle(&self) -> VkDescriptorSetLayout { self.descriptor_set_layout.vk_handle() } } impl<'a> VkHandle for &'a Arc { fn vk_handle(&self) -> VkDescriptorSetLayout { self.descriptor_set_layout.vk_handle() } } impl Drop for DescriptorPool { fn drop(&mut self) { self.device.destroy_descriptor_pool(self.descriptor_pool); } } use crate::{ffi::*, handle_ffi_result}; #[no_mangle] pub extern "C" fn create_descriptor_pool( flags: VkDescriptorPoolCreateFlagBits, descriptor_set_layout: *const DescriptorSetLayout, device: *const Device, ) -> *const DescriptorPool { let device = unsafe { Arc::from_raw(device) }; let layout = unsafe { Arc::from_raw(descriptor_set_layout) }; let pool_res = DescriptorPool::builder() .set_flags(flags) .set_layout(layout) .build(device); handle_ffi_result!(pool_res) } #[no_mangle] pub extern "C" fn reset_descriptor_pool(descriptor_pool: *const DescriptorPool) -> bool { let pool = unsafe { Arc::from_raw(descriptor_pool) }; match pool.reset() { Ok(_) => true, Err(err) => { update_last_error(err); false } } } #[no_mangle] pub extern "C" fn destroy_descriptor_pool(descriptor_pool: *const DescriptorPool) { let _pool = unsafe { Arc::from_raw(descriptor_pool) }; }