bort_vk/
descriptor_layout.rs

1use crate::{Device, DeviceOwned, Sampler, ALLOCATION_CALLBACK_NONE};
2use ash::{
3    prelude::VkResult,
4    vk::{self, Handle},
5};
6use std::sync::Arc;
7
8pub struct DescriptorSetLayout {
9    handle: vk::DescriptorSetLayout,
10    properties: DescriptorSetLayoutProperties,
11
12    // dependencies
13    device: Arc<Device>,
14}
15
16impl DescriptorSetLayout {
17    pub fn new(device: Arc<Device>, properties: DescriptorSetLayoutProperties) -> VkResult<Self> {
18        let mut vk_immutable_samplers = Vec::<Vec<vk::Sampler>>::new();
19        let vk_layout_bindings: Vec<vk::DescriptorSetLayoutBinding> = properties
20            .vk_layout_bindings(&mut vk_immutable_samplers)
21            .into_iter()
22            .map(|builder| builder.build())
23            .collect();
24
25        let create_info_builder = properties.write_create_info_builder(
26            vk::DescriptorSetLayoutCreateInfo::builder(),
27            &vk_layout_bindings,
28        );
29
30        let handle = unsafe {
31            device
32                .inner()
33                .create_descriptor_set_layout(&create_info_builder, ALLOCATION_CALLBACK_NONE)
34        }?;
35
36        Ok(Self {
37            handle,
38            properties,
39            device,
40        })
41    }
42
43    pub unsafe fn new_from_create_info(
44        device: Arc<Device>,
45        create_info_builder: vk::DescriptorSetLayoutCreateInfoBuilder,
46    ) -> VkResult<Self> {
47        let properties =
48            DescriptorSetLayoutProperties::from_create_info_builder(&create_info_builder);
49
50        let handle = unsafe {
51            device
52                .inner()
53                .create_descriptor_set_layout(&create_info_builder, ALLOCATION_CALLBACK_NONE)
54        }?;
55
56        Ok(Self {
57            handle,
58            properties,
59            device,
60        })
61    }
62
63    // Getters
64
65    #[inline]
66    pub fn handle(&self) -> vk::DescriptorSetLayout {
67        self.handle
68    }
69
70    #[inline]
71    pub fn properties(&self) -> &DescriptorSetLayoutProperties {
72        &self.properties
73    }
74}
75
76impl DeviceOwned for DescriptorSetLayout {
77    #[inline]
78    fn device(&self) -> &Arc<Device> {
79        &self.device
80    }
81
82    #[inline]
83    fn handle_raw(&self) -> u64 {
84        self.handle.as_raw()
85    }
86}
87
88impl Drop for DescriptorSetLayout {
89    fn drop(&mut self) {
90        unsafe {
91            self.device
92                .inner()
93                .destroy_descriptor_set_layout(self.handle, ALLOCATION_CALLBACK_NONE);
94        }
95    }
96}
97
98// Properties
99
100/// Note: default has no bindings!
101#[derive(Default, Clone)]
102pub struct DescriptorSetLayoutProperties {
103    pub flags: vk::DescriptorSetLayoutCreateFlags,
104    pub bindings: Vec<DescriptorSetLayoutBinding>,
105}
106
107impl DescriptorSetLayoutProperties {
108    pub fn new_default(bindings: Vec<DescriptorSetLayoutBinding>) -> Self {
109        Self {
110            flags: vk::DescriptorSetLayoutCreateFlags::empty(),
111            bindings,
112        }
113    }
114
115    pub fn write_create_info_builder<'a>(
116        &'a self,
117        builder: vk::DescriptorSetLayoutCreateInfoBuilder<'a>,
118        vk_layout_bindings: &'a [vk::DescriptorSetLayoutBinding],
119    ) -> vk::DescriptorSetLayoutCreateInfoBuilder {
120        builder.flags(self.flags).bindings(vk_layout_bindings)
121    }
122
123    /// Clears `vk_immutable_samplers` and stores in it a vector of sampler handles for each
124    /// binding. The returned builder struct contains references to these vectors with a
125    /// lifetime of `'a`.
126    pub fn vk_layout_bindings<'a>(
127        &'a self,
128        vk_immutable_samplers: &'a mut Vec<Vec<vk::Sampler>>,
129    ) -> Vec<vk::DescriptorSetLayoutBindingBuilder<'a>> {
130        vk_immutable_samplers.clear();
131        let mut vk_layout_bindings = Vec::<vk::DescriptorSetLayoutBindingBuilder>::new();
132
133        for i in 0..self.bindings.len() {
134            let new_immutable_samplers = self.bindings[i].vk_immutable_samplers();
135            vk_immutable_samplers.push(new_immutable_samplers);
136        }
137
138        for i in 0..self.bindings.len() {
139            let vk_layout_binding = self.bindings[i].write_vk_binding_builder(
140                vk::DescriptorSetLayoutBinding::builder(),
141                &vk_immutable_samplers[i],
142            );
143            vk_layout_bindings.push(vk_layout_binding);
144        }
145        vk_layout_bindings
146    }
147
148    pub fn from_create_info_builder(value: &vk::DescriptorSetLayoutCreateInfoBuilder) -> Self {
149        let mut bindings = Vec::<DescriptorSetLayoutBinding>::new();
150        for i in 0..value.binding_count {
151            let vk_binding = unsafe { *value.p_bindings.offset(i as isize) };
152            let binding = DescriptorSetLayoutBinding::from_vk_binding(&vk_binding);
153            bindings.push(binding);
154        }
155
156        Self {
157            flags: value.flags,
158            bindings,
159        }
160    }
161}
162
163// Descriptor set layout binding
164
165/// Note: default values are nothing!
166#[derive(Default, Clone)]
167pub struct DescriptorSetLayoutBinding {
168    pub binding: u32,
169    pub descriptor_type: vk::DescriptorType,
170    pub descriptor_count: u32,
171    pub stage_flags: vk::ShaderStageFlags,
172    pub immutable_samplers: Vec<Arc<Sampler>>,
173}
174
175impl DescriptorSetLayoutBinding {
176    pub fn vk_immutable_samplers(&self) -> Vec<vk::Sampler> {
177        self.immutable_samplers
178            .iter()
179            .map(|sampler| sampler.handle())
180            .collect()
181    }
182
183    /// Note: leaves `immutable_samplers` empty because the create info only provides the handles.
184    pub fn from_vk_binding(value: &vk::DescriptorSetLayoutBinding) -> Self {
185        Self {
186            binding: value.binding,
187            descriptor_type: value.descriptor_type,
188            descriptor_count: value.descriptor_count,
189            stage_flags: value.stage_flags,
190            immutable_samplers: Vec::new(), // because the create info only provides handles
191        }
192    }
193
194    pub fn write_vk_binding_builder<'a>(
195        &self,
196        mut builder: vk::DescriptorSetLayoutBindingBuilder<'a>,
197        vk_immutable_samplers: &'a [vk::Sampler],
198    ) -> vk::DescriptorSetLayoutBindingBuilder<'a> {
199        if vk_immutable_samplers.len() != 0 {
200            builder = builder.immutable_samplers(vk_immutable_samplers); // put before descriptor_count because calling this overrides it
201        }
202        builder
203            .binding(self.binding)
204            .descriptor_type(self.descriptor_type)
205            .descriptor_count(self.descriptor_count)
206            .stage_flags(self.stage_flags)
207    }
208
209    pub fn from_vk_binding_builder(value: &vk::DescriptorSetLayoutBindingBuilder) -> Self {
210        Self::from_vk_binding(value)
211    }
212}