bort_vk/
descriptor_pool.rs1use 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 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 #[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#[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}