bort_vk/
descriptor_pool.rs

1use crate::{DescriptorSet, DescriptorSetLayout, Device, DeviceOwned, ALLOCATION_CALLBACK_NONE};
2use ash::{
3    prelude::VkResult,
4    vk::{self, Handle},
5};
6use std::sync::Arc;
7
8pub struct DescriptorPool {
9    handle: vk::DescriptorPool,
10    properties: DescriptorPoolProperties,
11
12    // dependencies
13    device: Arc<Device>,
14}
15
16impl DescriptorPool {
17    pub fn new(device: Arc<Device>, properties: DescriptorPoolProperties) -> VkResult<Self> {
18        let create_info_builder = properties.create_info_builder();
19
20        let handle = unsafe {
21            device
22                .inner()
23                .create_descriptor_pool(&create_info_builder, ALLOCATION_CALLBACK_NONE)
24        }?;
25
26        Ok(Self {
27            handle,
28            properties,
29            device,
30        })
31    }
32
33    pub unsafe fn new_from_create_info(
34        device: Arc<Device>,
35        create_info_builder: vk::DescriptorPoolCreateInfoBuilder,
36    ) -> VkResult<Self> {
37        let properties = DescriptorPoolProperties::from_create_info_builder(&create_info_builder);
38
39        let handle = unsafe {
40            device
41                .inner()
42                .create_descriptor_pool(&create_info_builder, ALLOCATION_CALLBACK_NONE)
43        }?;
44
45        Ok(Self {
46            handle,
47            properties,
48            device,
49        })
50    }
51
52    pub fn allocate_descriptor_set(
53        self: &Arc<Self>,
54        layout: Arc<DescriptorSetLayout>,
55    ) -> VkResult<DescriptorSet> {
56        let layout_handles = [layout.handle()];
57        let create_info = vk::DescriptorSetAllocateInfo::builder()
58            .descriptor_pool(self.handle)
59            .set_layouts(&layout_handles);
60
61        let descriptor_set_handle =
62            unsafe { self.device().inner().allocate_descriptor_sets(&create_info) }?[0];
63
64        Ok(unsafe { DescriptorSet::from_handle(descriptor_set_handle, layout, self.clone()) })
65    }
66
67    pub fn allocate_descriptor_sets(
68        self: &Arc<Self>,
69        layouts: Vec<Arc<DescriptorSetLayout>>,
70    ) -> VkResult<Vec<DescriptorSet>> {
71        let layout_handles: Vec<vk::DescriptorSetLayout> =
72            layouts.iter().map(|l| l.handle()).collect();
73        let create_info = vk::DescriptorSetAllocateInfo::builder()
74            .descriptor_pool(self.handle)
75            .set_layouts(&layout_handles);
76
77        let descriptor_set_handles =
78            unsafe { self.device().inner().allocate_descriptor_sets(&create_info) }?;
79
80        let mut descriptor_sets = Vec::<DescriptorSet>::new();
81        for i in 0..layouts.len() {
82            let descriptor_set = unsafe {
83                DescriptorSet::from_handle(
84                    descriptor_set_handles[i],
85                    layouts[i].clone(),
86                    self.clone(),
87                )
88            };
89            descriptor_sets.push(descriptor_set);
90        }
91
92        Ok(descriptor_sets)
93    }
94
95    // Getters
96
97    #[inline]
98    pub fn handle(&self) -> vk::DescriptorPool {
99        self.handle
100    }
101
102    #[inline]
103    pub fn properties(&self) -> &DescriptorPoolProperties {
104        &self.properties
105    }
106}
107
108impl DeviceOwned for DescriptorPool {
109    #[inline]
110    fn device(&self) -> &Arc<Device> {
111        &self.device
112    }
113
114    #[inline]
115    fn handle_raw(&self) -> u64 {
116        self.handle.as_raw()
117    }
118}
119
120impl Drop for DescriptorPool {
121    fn drop(&mut self) {
122        unsafe {
123            self.device
124                .inner()
125                .destroy_descriptor_pool(self.handle, ALLOCATION_CALLBACK_NONE)
126        }
127    }
128}
129
130/// Note: default values are nothing!
131#[derive(Default, Clone)]
132pub struct DescriptorPoolProperties {
133    pub flags: vk::DescriptorPoolCreateFlags,
134    pub max_sets: u32,
135    pub pool_sizes: Vec<vk::DescriptorPoolSize>,
136}
137
138impl DescriptorPoolProperties {
139    pub fn new_default(max_sets: u32, pool_sizes: Vec<vk::DescriptorPoolSize>) -> Self {
140        Self {
141            max_sets,
142            pool_sizes,
143            ..Default::default()
144        }
145    }
146
147    pub fn write_create_info_builder<'a>(
148        &'a self,
149        builder: vk::DescriptorPoolCreateInfoBuilder<'a>,
150    ) -> vk::DescriptorPoolCreateInfoBuilder<'a> {
151        builder
152            .flags(self.flags)
153            .max_sets(self.max_sets)
154            .pool_sizes(&self.pool_sizes)
155    }
156
157    pub fn create_info_builder(&self) -> vk::DescriptorPoolCreateInfoBuilder {
158        self.write_create_info_builder(vk::DescriptorPoolCreateInfo::builder())
159    }
160
161    pub fn from_create_info_builder(value: &vk::DescriptorPoolCreateInfoBuilder) -> Self {
162        let mut pool_sizes = Vec::<vk::DescriptorPoolSize>::new();
163        for i in 0..value.pool_size_count {
164            let pool_size = unsafe { *value.p_pool_sizes.offset(i as isize) };
165            pool_sizes.push(pool_size);
166        }
167
168        Self {
169            flags: value.flags,
170            max_sets: value.max_sets,
171            pool_sizes,
172        }
173    }
174}