Skip to main content

rotex_vulkan/backend/vulkan/
descriptor.rs

1use ash::vk;
2
3use super::buffer::RotexBuffer;
4use super::device::Device;
5use crate::error::vk_error;
6use crate::Error;
7
8pub struct DescriptorSet {
9    handle: vk::DescriptorSet,
10}
11
12impl DescriptorSet {
13    pub fn handle(&self) -> vk::DescriptorSet {
14        self.handle
15    }
16
17    pub fn write_buffer(
18        &self,
19        device: &Device,
20        binding: u32,
21        buffer: &RotexBuffer,
22        offset: vk::DeviceSize,
23        range: vk::DeviceSize,
24        descriptor_type: vk::DescriptorType,
25    ) {
26        let buffer_info = [vk::DescriptorBufferInfo::default()
27            .buffer(buffer.handle())
28            .offset(offset)
29            .range(range)];
30
31        let write = [vk::WriteDescriptorSet::default()
32            .dst_set(self.handle)
33            .dst_binding(binding)
34            .descriptor_type(descriptor_type)
35            .buffer_info(&buffer_info)];
36
37        unsafe {
38            device.logical_device().update_descriptor_sets(&write, &[]);
39        }
40    }
41
42    pub fn write_image_sampler(
43        &self,
44        device: &Device,
45        binding: u32,
46        image_view: vk::ImageView,
47        sampler: vk::Sampler,
48        image_layout: vk::ImageLayout,
49    ) {
50        let image_info = [vk::DescriptorImageInfo::default()
51            .image_layout(image_layout)
52            .image_view(image_view)
53            .sampler(sampler)];
54
55        let write = [vk::WriteDescriptorSet::default()
56            .dst_set(self.handle)
57            .dst_binding(binding)
58            .descriptor_type(vk::DescriptorType::COMBINED_IMAGE_SAMPLER)
59            .image_info(&image_info)];
60
61        unsafe {
62            device.logical_device().update_descriptor_sets(&write, &[]);
63        }
64    }
65}
66
67pub struct DescriptorPool {
68    handle: vk::DescriptorPool,
69}
70
71impl DescriptorPool {
72    pub fn new(
73        device: &Device,
74        max_sets: u32,
75        pool_sizes: &[vk::DescriptorPoolSize],
76    ) -> Result<Self, Error> {
77        let create_info = vk::DescriptorPoolCreateInfo::default()
78            .max_sets(max_sets)
79            .pool_sizes(pool_sizes)
80            .flags(vk::DescriptorPoolCreateFlags::FREE_DESCRIPTOR_SET);
81
82        let handle = unsafe {
83            device
84                .logical_device()
85                .create_descriptor_pool(&create_info, None)
86        }
87        .map_err(vk_error)?;
88
89        Ok(Self { handle })
90    }
91
92    pub fn allocate_sets(
93        &self,
94        device: &Device,
95        layouts: &[vk::DescriptorSetLayout],
96    ) -> Result<Vec<DescriptorSet>, Error> {
97        let alloc_info = vk::DescriptorSetAllocateInfo::default()
98            .descriptor_pool(self.handle)
99            .set_layouts(layouts);
100
101        let sets = unsafe {
102            device
103                .logical_device()
104                .allocate_descriptor_sets(&alloc_info)
105        }
106        .map_err(vk_error)?;
107
108        Ok(sets
109            .into_iter()
110            .map(|handle| DescriptorSet { handle })
111            .collect())
112    }
113
114    pub fn handle(&self) -> vk::DescriptorPool {
115        self.handle
116    }
117
118    pub fn free_sets(&self, device: &Device, sets: &[DescriptorSet]) -> Result<(), Error> {
119        if sets.is_empty() {
120            return Ok(());
121        }
122        let set_handles = sets.iter().map(|set| set.handle).collect::<Vec<_>>();
123        unsafe {
124            device
125                .logical_device()
126                .free_descriptor_sets(self.handle, &set_handles)
127        }
128        .map_err(vk_error)
129    }
130
131    pub fn destroy(&self, device: &Device) {
132        unsafe {
133            device
134                .logical_device()
135                .destroy_descriptor_pool(self.handle, None);
136        }
137    }
138}