Skip to main content

bedrock/
descriptor.rs

1//! Vulkan Descriptors
2use bedrock_vk::{self as brvk, TypedVulkanStructure, VkRawHandle};
3
4use derives::implements;
5
6use crate::ffi_helper::{ArrayFFIExtensions, slice_as_ptr_empty_null};
7use crate::*;
8
9/// Opaque handle to a descriptor set layout object
10#[derive(VkHandle, VkObject)]
11#[VkObject(type = brvk::VkDescriptorSetLayout::OBJECT_TYPE)]
12pub struct DescriptorSetLayoutObject<Device: VkHandle<Handle = brvk::VkDevice>>(
13    pub(crate) brvk::VkDescriptorSetLayout,
14    pub(crate) Device,
15);
16#[implements]
17impl<Device: VkHandle<Handle = brvk::VkDevice>> Drop for DescriptorSetLayoutObject<Device> {
18    #[inline(always)]
19    fn drop(&mut self) {
20        unsafe {
21            crate::vkfn_wrapper::destroy_descriptor_set_layout(
22                self.1.as_transparent_ref(),
23                VkHandleRefMut::dangling(self.0),
24                None,
25            );
26        }
27    }
28}
29unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Sync> Sync for DescriptorSetLayoutObject<Device> {}
30unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Send> Send for DescriptorSetLayoutObject<Device> {}
31impl<Device: VkHandle<Handle = brvk::VkDevice>> DeviceChildHandle for DescriptorSetLayoutObject<Device> {
32    #[inline(always)]
33    fn device_handle(&self) -> brvk::VkDevice {
34        self.1.native_ptr()
35    }
36}
37impl<Device: crate::Device> DeviceChild for DescriptorSetLayoutObject<Device> {
38    type ConcreteDevice = Device;
39
40    #[inline(always)]
41    fn device(&self) -> &Self::ConcreteDevice {
42        &self.1
43    }
44}
45impl<Device: crate::Device> DescriptorSetLayout for DescriptorSetLayoutObject<Device> {}
46impl<Device: VkHandle<Handle = brvk::VkDevice>> DescriptorSetLayoutObject<Device> {
47    /// Create a new descriptor set layout
48    /// # Failures
49    /// On failure, this command returns
50    ///
51    /// - [`brvk::VK_ERROR_OUT_OF_HOST_MEMORY`]
52    /// - [`brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY`]
53    #[implements]
54    #[inline]
55    pub fn new(device: Device, info: &DescriptorSetLayoutCreateInfo) -> crate::Result<Self> {
56        Ok(Self(
57            crate::vkfn_wrapper::create_descriptor_set_layout(device.as_transparent_ref(), info, None)?,
58            device,
59        ))
60    }
61
62    /// Constructs from raw values
63    /// # Safety
64    /// the resource must be created from the device and not freed anywhere
65    pub const unsafe fn manage(handle: brvk::VkDescriptorSetLayout, parent: Device) -> Self {
66        Self(handle, parent)
67    }
68
69    /// Purges the construct (Drop will not be called for this resource)
70    pub const fn unmanage(self) -> (brvk::VkDescriptorSetLayout, Device) {
71        let h = self.0;
72        let p = unsafe { core::ptr::read(&self.1) };
73        core::mem::forget(self);
74
75        (h, p)
76    }
77}
78impl<Device: VkHandle<Handle = brvk::VkDevice> + Clone> DescriptorSetLayoutObject<&'_ Device> {
79    /// Owning parent object by cloning it.
80    #[inline(always)]
81    pub fn clone_parent(self) -> DescriptorSetLayoutObject<Device> {
82        let r = DescriptorSetLayoutObject(self.0, self.1.clone());
83        core::mem::forget(self);
84
85        r
86    }
87}
88
89#[derive(VkHandle, VkObject)]
90#[VkObject(type = brvk::VkDescriptorPool::OBJECT_TYPE)]
91pub struct DescriptorPoolObject<Device: VkHandle<Handle = brvk::VkDevice>>(
92    pub(crate) brvk::VkDescriptorPool,
93    pub(crate) Device,
94);
95#[implements]
96impl<Device: VkHandle<Handle = brvk::VkDevice>> Drop for DescriptorPoolObject<Device> {
97    #[inline(always)]
98    fn drop(&mut self) {
99        unsafe {
100            crate::vkfn_wrapper::destroy_descriptor_pool(
101                self.1.as_transparent_ref(),
102                VkHandleRefMut::dangling(self.0),
103                None,
104            );
105        }
106    }
107}
108unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Sync> Sync for DescriptorPoolObject<Device> {}
109unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Send> Send for DescriptorPoolObject<Device> {}
110impl<Device: VkHandle<Handle = brvk::VkDevice>> DeviceChildHandle for DescriptorPoolObject<Device> {
111    #[inline(always)]
112    fn device_handle(&self) -> brvk::VkDevice {
113        self.1.native_ptr()
114    }
115}
116impl<Device: crate::Device> DeviceChild for DescriptorPoolObject<Device> {
117    type ConcreteDevice = Device;
118
119    #[inline(always)]
120    fn device(&self) -> &Self::ConcreteDevice {
121        &self.1
122    }
123}
124impl<Device: VkHandle<Handle = brvk::VkDevice>> DescriptorPool for DescriptorPoolObject<Device> {}
125impl<Device: VkHandle<Handle = brvk::VkDevice>> DescriptorPoolMut for DescriptorPoolObject<Device> {}
126impl<Device: VkHandle<Handle = brvk::VkDevice>> DescriptorPoolObject<Device> {
127    /// Creates a descriptor pool object
128    /// # Failures
129    /// On failure, this command returns
130    ///
131    /// - brvk::VK_ERROR_OUT_OF_HOST_MEMORY
132    /// - brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY
133    #[implements]
134    #[inline]
135    pub fn new(device: Device, info: &DescriptorPoolCreateInfo) -> crate::Result<Self> {
136        Ok(Self(
137            crate::vkfn_wrapper::create_descriptor_pool(device.as_transparent_ref(), info, None)?,
138            device,
139        ))
140    }
141
142    /// Constructs from raw values
143    /// # Safety
144    /// the resource must be created from the device and not freed anywhere
145    pub const unsafe fn manage(handle: brvk::VkDescriptorPool, parent: Device) -> Self {
146        Self(handle, parent)
147    }
148
149    /// Purges the construct (Drop will not be called for this resource)
150    pub const fn unmanage(self) -> (brvk::VkDescriptorPool, Device) {
151        let h = self.0;
152        let p = unsafe { core::ptr::read(&self.1) };
153        core::mem::forget(self);
154
155        (h, p)
156    }
157}
158impl<Device: VkHandle<Handle = brvk::VkDevice> + Clone> DescriptorPoolObject<&'_ Device> {
159    /// Owning parent object by cloning it.
160    #[inline(always)]
161    pub fn clone_parent(self) -> DescriptorPoolObject<Device> {
162        let r = DescriptorPoolObject(self.0, self.1.clone());
163        core::mem::forget(self);
164
165        r
166    }
167}
168
169#[repr(transparent)]
170#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
171pub struct DescriptorSet(pub(crate) brvk::VkDescriptorSet);
172unsafe impl Sync for DescriptorSet {}
173unsafe impl Send for DescriptorSet {}
174impl DescriptorSet {
175    #[inline]
176    pub const fn binding_at(&self, b: u32) -> DescriptorPointer {
177        DescriptorPointer::new(self.0, b)
178    }
179}
180
181/// Specified the type of a descriptor in a descriptor set
182#[repr(C)]
183#[derive(Debug, Clone, PartialEq, Eq, Copy, PartialOrd, Ord, Hash)]
184pub enum DescriptorType {
185    Sampler = brvk::VK_DESCRIPTOR_TYPE_SAMPLER as _,
186    CombinedImageSampler = brvk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER as _,
187    SampledImage = brvk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE as _,
188    StorageImage = brvk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE as _,
189    UniformTexelBuffer = brvk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER as _,
190    StorageTexelBuffer = brvk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER as _,
191    UniformBuffer = brvk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER as _,
192    StorageBuffer = brvk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER as _,
193    UniformBufferDynamic = brvk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC as _,
194    StorageBufferDynamic = brvk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC as _,
195    InputAttachment = brvk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT as _,
196}
197impl DescriptorType {
198    pub const fn make_size(self, count: u32) -> brvk::VkDescriptorPoolSize {
199        brvk::VkDescriptorPoolSize {
200            r#type: self as _,
201            descriptorCount: count,
202        }
203    }
204
205    pub const fn make_binding<'a>(self, binding: u32, count: u32) -> DescriptorSetLayoutBinding<'a> {
206        DescriptorSetLayoutBinding::new(binding, self, count, brvk::VK_SHADER_STAGE_ALL)
207    }
208}
209
210#[repr(transparent)]
211#[derive(Clone)]
212pub struct DescriptorSetLayoutBinding<'s> {
213    raw: brvk::VkDescriptorSetLayoutBinding,
214    immutable_samplers: core::marker::PhantomData<&'s dyn VkHandle<Handle = brvk::VkSampler>>,
215}
216impl<'s> DescriptorSetLayoutBinding<'s> {
217    pub const fn new(binding: u32, r#type: DescriptorType, count: u32, shader_stage: brvk::VkShaderStageFlags) -> Self {
218        Self {
219            raw: brvk::VkDescriptorSetLayoutBinding {
220                binding,
221                descriptorType: r#type as _,
222                descriptorCount: count,
223                stageFlags: shader_stage,
224                pImmutableSamplers: core::ptr::null(),
225            },
226            immutable_samplers: core::marker::PhantomData,
227        }
228    }
229
230    #[inline(always)]
231    pub fn with_immutable_samplers(self, samplers: &'s [VkHandleRef<brvk::VkSampler>]) -> Self {
232        assert_eq!(samplers.len(), self.raw.descriptorCount as usize);
233        unsafe { self.with_immutable_samplers_unchecked(samplers) }
234    }
235
236    /// # Safety
237    ///
238    /// The caller must ensure that a number of `samplers` is equal to the descriptor's count.
239    pub const unsafe fn with_immutable_samplers_unchecked(
240        mut self,
241        samplers: &'s [VkHandleRef<brvk::VkSampler>],
242    ) -> Self {
243        self.raw.pImmutableSamplers = slice_as_ptr_empty_null(samplers) as _;
244        self
245    }
246
247    pub const fn for_shader_stage(mut self, mask: brvk::VkShaderStageFlags) -> Self {
248        self.raw.stageFlags = mask;
249        self
250    }
251
252    pub const fn only_for_vertex(self) -> Self {
253        self.for_shader_stage(brvk::VK_SHADER_STAGE_VERTEX_BIT)
254    }
255
256    pub const fn only_for_tess_control(self) -> Self {
257        self.for_shader_stage(brvk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
258    }
259
260    pub const fn only_for_tess_evaluation(self) -> Self {
261        self.for_shader_stage(brvk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
262    }
263
264    pub const fn only_for_tessellation(self) -> Self {
265        self.for_shader_stage(
266            brvk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | brvk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
267        )
268    }
269
270    pub const fn only_for_geometry(self) -> Self {
271        self.for_shader_stage(brvk::VK_SHADER_STAGE_GEOMETRY_BIT)
272    }
273
274    pub const fn only_for_fragment(self) -> Self {
275        self.for_shader_stage(brvk::VK_SHADER_STAGE_FRAGMENT_BIT)
276    }
277
278    pub const fn only_for_compute(self) -> Self {
279        self.for_shader_stage(brvk::VK_SHADER_STAGE_COMPUTE_BIT)
280    }
281}
282
283#[repr(transparent)]
284#[derive(Clone)]
285pub struct DescriptorSetLayoutCreateInfo<'d, 's>(
286    brvk::VkDescriptorSetLayoutCreateInfo,
287    core::marker::PhantomData<&'d [DescriptorSetLayoutBinding<'s>]>,
288);
289impl<'d, 's> DescriptorSetLayoutCreateInfo<'d, 's> {
290    #[inline(always)]
291    pub const fn new(bindings: &'d [DescriptorSetLayoutBinding<'s>]) -> Self {
292        Self(
293            brvk::VkDescriptorSetLayoutCreateInfo {
294                sType: brvk::VkDescriptorSetLayoutCreateInfo::TYPE,
295                pNext: core::ptr::null(),
296                flags: 0,
297                bindingCount: bindings.len() as _,
298                pBindings: slice_as_ptr_empty_null(bindings).cast(),
299            },
300            core::marker::PhantomData,
301        )
302    }
303}
304
305pub trait DescriptorSetLayout: VkHandle<Handle = brvk::VkDescriptorSetLayout> + DeviceChild {}
306DerefContainerBracketImpl!(for DescriptorSetLayout {});
307GuardsImpl!(for DescriptorSetLayout {});
308
309/*
310# DescriptorPoolのフラグメンテーションについてメモ(from `brvk::VkDescriptorPoolCreateInfo` Manual)
311
312`brvk::VkDescriptorPoolSize`構造体が`pPoolSizes`配列内に複数ある場合、プールはそれぞれのタイプの合計分のデスクリプタが十分入るように確保されます。
313
314DescriptorPoolはフラグメンテーションを起こすことがあり、DescriptorSetの確保に失敗することがあります。
315フラグメンテーションに起因する失敗は、確保したDescriptorSetの数+確保を要求したDescriptorSetの数が`maxSets`に満たない場合でも
316"DescriptorSetの確保の失敗"と定義されます。(たぶんあってるはず)
317実装は、以下に記述されるような"フラグメンテーションが確保の失敗を引き起こさない場合"について確固たる保証を提供します。
318(言い換えると、「以下に示す場合はフラグメンテーション状態でも確保に成功する」)
319
320DescriptorPoolが、生成されてから/間近にリセットされてから今までに開放されたDescriptorSetがない場合、
321フラグメンテーションは確保の失敗を引き起こしません。(`brvk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT`を伴わずに生成されたプールに対しては常に満たすものとします?)
322また、
323- プールが生成されてから/間近にリセットされてから確保された、すべてのDescriptorSetが各タイプ同じ数のDescriptorを使う場合、そして
324- 要求した確保も各タイプ同じ数のDescriptorを使う場合、
325フラグメンテーションは確保の失敗を引き起こしません。
326
327もしフラグメンテーションによって確保が失敗した場合、アプリケーションは続けてDescriptorSetの確保を行うために追加のDescriptorPoolを生成することができます
328*/
329
330#[repr(transparent)]
331#[derive(Clone)]
332pub struct DescriptorPoolCreateInfo<'d>(
333    brvk::VkDescriptorPoolCreateInfo,
334    core::marker::PhantomData<&'d [brvk::VkDescriptorPoolSize]>,
335);
336impl<'d> DescriptorPoolCreateInfo<'d> {
337    pub const fn new(max_sets: u32, sizes: &'d [brvk::VkDescriptorPoolSize]) -> Self {
338        Self(
339            brvk::VkDescriptorPoolCreateInfo {
340                sType: brvk::VkDescriptorPoolCreateInfo::TYPE,
341                pNext: core::ptr::null(),
342                flags: 0,
343                maxSets: max_sets,
344                poolSizeCount: sizes.len() as _,
345                pPoolSizes: slice_as_ptr_empty_null(sizes),
346            },
347            core::marker::PhantomData,
348        )
349    }
350
351    /// # Safety
352    ///
353    /// `raw` must be a valid `brvk::VkDescriptorPoolCreateInfo` value.
354    pub const unsafe fn from_raw(raw: brvk::VkDescriptorPoolCreateInfo) -> Self {
355        Self(raw, core::marker::PhantomData)
356    }
357
358    pub const fn into_raw(self) -> brvk::VkDescriptorPoolCreateInfo {
359        self.0
360    }
361
362    pub const fn allow_individual_free(mut self) -> Self {
363        self.0.flags |= brvk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
364        self
365    }
366}
367
368pub trait DescriptorPool: VkHandle<Handle = brvk::VkDescriptorPool> {}
369DerefContainerBracketImpl!(for DescriptorPool {});
370GuardsImpl!(for DescriptorPool {});
371
372pub trait DescriptorPoolMut: DescriptorPool + VkHandleMut + DeviceChildHandle {
373    /// Allocate one or more descriptor sets
374    /// # Failures
375    /// On failure, this command returns
376    /// - brvk::VK_ERROR_OUT_OF_HOST_MEMORY
377    /// - brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY
378    /// - brvk::VK_ERROR_FRAGMENTED_POOL
379    ///
380    /// # Safety
381    /// no guarantees will be provided (simply calls under api)
382    #[implements]
383    #[inline]
384    unsafe fn alloc_raw(
385        &mut self,
386        info: &brvk::VkDescriptorSetAllocateInfo,
387        objects: &mut [core::mem::MaybeUninit<DescriptorSet>],
388    ) -> crate::Result<()> {
389        unsafe { crate::vkfn_wrapper::allocate_descriptor_sets(self.device_transparent_ref(), info, objects) }
390    }
391
392    /// Allocate one or more descriptor sets
393    /// # Failures
394    /// On failure, this command returns
395    /// - brvk::VK_ERROR_OUT_OF_HOST_MEMORY
396    /// - brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY
397    /// - brvk::VK_ERROR_FRAGMENTED_POOL
398    #[implements]
399    #[cfg(feature = "alloc")]
400    fn alloc(&mut self, layouts: &[VkHandleRef<brvk::VkDescriptorSetLayout>]) -> crate::Result<Vec<DescriptorSet>> {
401        let ainfo = brvk::VkDescriptorSetAllocateInfo {
402            sType: brvk::VkDescriptorSetAllocateInfo::TYPE,
403            pNext: core::ptr::null(),
404            descriptorPool: self.native_ptr_mut(),
405            descriptorSetCount: layouts.len() as _,
406            pSetLayouts: layouts.as_ptr_empty_null().cast(),
407        };
408        let mut hs = crate::alloc::reserve(layouts.len());
409
410        unsafe {
411            self.alloc_raw(&ainfo, hs.spare_capacity_mut())?;
412            hs.set_len(layouts.len())
413        }
414
415        Ok(hs)
416    }
417
418    /// Allocate one or more descriptor sets
419    /// # Failures
420    /// On failure, this command returns
421    /// - brvk::VK_ERROR_OUT_OF_HOST_MEMORY
422    /// - brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY
423    /// - brvk::VK_ERROR_FRAGMENTED_POOL
424    #[implements]
425    fn alloc_array<const N: usize>(
426        &mut self,
427        layouts: &[VkHandleRef<brvk::VkDescriptorSetLayout>; N],
428    ) -> crate::Result<[DescriptorSet; N]> {
429        let ainfo = brvk::VkDescriptorSetAllocateInfo {
430            sType: brvk::VkDescriptorSetAllocateInfo::TYPE,
431            pNext: core::ptr::null(),
432            descriptorPool: self.native_ptr_mut(),
433            descriptorSetCount: N as _,
434            pSetLayouts: layouts.as_ptr_empty_null().cast(),
435        };
436
437        let mut hs = [core::mem::MaybeUninit::uninit(); N];
438        unsafe {
439            self.alloc_raw(&ainfo, &mut hs)?;
440        }
441
442        // Note: transmuteだと変換できない(要素数がジェネリックだとダメっぽい?)
443        Ok(core::array::from_fn(|n| unsafe { hs[n].assume_init() }))
444    }
445
446    /// Resets a descriptor pool object
447    /// # Safety
448    /// Application must not use descriptor sets after this call
449    /// # Failures
450    /// On failure, this command returns
451    /// - brvk::VK_ERROR_OUT_OF_HOST_MEMORY
452    /// - brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY
453    #[implements]
454    #[inline]
455    unsafe fn reset(&mut self, flags: brvk::VkDescriptorPoolResetFlags) -> crate::Result<()> {
456        unsafe {
457            crate::vkfn_wrapper::reset_descriptor_pool(
458                self.device_transparent_ref(),
459                VkHandleRefMut::dangling(self.native_ptr()),
460                flags,
461            )
462        }
463    }
464
465    /// Free one or more descriptor sets
466    /// # Safety
467    /// Host access to each member of pDescriptorSets must be externally synchronized
468    /// # Failures
469    /// On failure, this command returns
470    /// - brvk::VK_ERROR_OUT_OF_HOST_MEMORY
471    /// - brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY
472    #[implements]
473    #[inline]
474    unsafe fn free(&mut self, sets: &[DescriptorSet]) -> crate::Result<()> {
475        unsafe {
476            crate::vkfn_wrapper::free_descriptor_sets(
477                self.device_transparent_ref(),
478                VkHandleRefMut::dangling(self.native_ptr()),
479                sets,
480            )
481        }
482    }
483}
484DerefContainerBracketImpl!(for mut DescriptorPoolMut {});
485GuardsImpl!(for mut DescriptorPoolMut {});
486
487/// Pointer for descriptor array in set
488#[derive(Clone)]
489pub struct DescriptorPointer {
490    pub set: brvk::VkDescriptorSet,
491    pub binding: u32,
492    pub array_offset: u32,
493}
494impl DescriptorPointer {
495    pub const fn new(set: brvk::VkDescriptorSet, binding: u32) -> Self {
496        Self {
497            set,
498            binding,
499            array_offset: 0,
500        }
501    }
502
503    pub const fn array_offset(self, offset: u32) -> Self {
504        Self {
505            array_offset: offset,
506            ..self
507        }
508    }
509
510    pub const fn write<'r>(self, contents: DescriptorContents<'r>) -> DescriptorSetWriteInfo<'r> {
511        DescriptorSetWriteInfo(self, contents)
512    }
513
514    pub const fn copy(self, count: u32, dest: DescriptorPointer) -> DescriptorSetCopyInfo {
515        DescriptorSetCopyInfo(self, dest, count)
516    }
517
518    pub fn write_continuous_bindings<'r>(
519        self,
520        contents: impl IntoIterator<Item = DescriptorContents<'r>>,
521    ) -> impl Iterator<Item = DescriptorSetWriteInfo<'r>> {
522        let base_binding = self.binding;
523
524        contents.into_iter().enumerate().map(move |(n, c)| {
525            Self {
526                binding: base_binding + n as u32,
527                ..self.clone()
528            }
529            .write(c)
530        })
531    }
532}
533
534#[repr(transparent)]
535#[derive(Clone)]
536pub struct DescriptorBufferInfo<'r>(
537    brvk::VkDescriptorBufferInfo,
538    core::marker::PhantomData<&'r dyn VkHandle<Handle = brvk::VkBuffer>>,
539);
540impl<'r> DescriptorBufferInfo<'r> {
541    #[inline(always)]
542    pub fn new(
543        r: &'r (impl VkHandle<Handle = brvk::VkBuffer> + ?Sized),
544        range: core::ops::Range<brvk::VkDeviceSize>,
545    ) -> Self {
546        Self(
547            brvk::VkDescriptorBufferInfo {
548                buffer: r.native_ptr(),
549                offset: range.start,
550                range: range.end - range.start,
551            },
552            core::marker::PhantomData,
553        )
554    }
555
556    #[inline(always)]
557    pub const fn unbounded(h: brvk::VkBuffer, range: core::ops::Range<brvk::VkDeviceSize>) -> Self {
558        Self(
559            brvk::VkDescriptorBufferInfo {
560                buffer: h,
561                offset: range.start,
562                range: range.end - range.start,
563            },
564            core::marker::PhantomData,
565        )
566    }
567}
568
569#[repr(transparent)]
570#[derive(Clone)]
571pub struct DescriptorImageInfo<'r>(
572    brvk::VkDescriptorImageInfo,
573    #[allow(clippy::type_complexity)]
574    core::marker::PhantomData<(
575        &'r dyn VkHandle<Handle = brvk::VkImageView>,
576        Option<&'r dyn VkHandle<Handle = brvk::VkSampler>>,
577    )>,
578);
579impl<'r> DescriptorImageInfo<'r> {
580    #[inline(always)]
581    pub fn new(r: &'r (impl VkHandle<Handle = brvk::VkImageView> + ?Sized), layout: ImageLayout) -> Self {
582        Self(
583            brvk::VkDescriptorImageInfo {
584                imageView: r.native_ptr(),
585                imageLayout: layout as _,
586                sampler: None,
587            },
588            core::marker::PhantomData,
589        )
590    }
591
592    #[inline(always)]
593    pub const fn unbounded(h: brvk::VkImageView, layout: ImageLayout) -> Self {
594        Self(
595            brvk::VkDescriptorImageInfo {
596                imageView: h,
597                imageLayout: layout as _,
598                sampler: None,
599            },
600            core::marker::PhantomData,
601        )
602    }
603
604    #[inline(always)]
605    pub fn with_sampler(mut self, sampler: &'r (impl VkHandle<Handle = brvk::VkSampler> + ?Sized)) -> Self {
606        self.0.sampler = Some(sampler.native_ptr());
607        self
608    }
609
610    #[inline(always)]
611    pub const fn with_unbounded_sampler(mut self, sampler: brvk::VkSampler) -> Self {
612        self.0.sampler = Some(sampler);
613        self
614    }
615}
616
617#[derive(Clone)]
618pub enum DescriptorContents<'r> {
619    Sampler(Vec<DescriptorImageInfo<'r>>),
620    CombinedImageSampler(Vec<DescriptorImageInfo<'r>>),
621    SampledImage(Vec<DescriptorImageInfo<'r>>),
622    StorageImage(Vec<DescriptorImageInfo<'r>>),
623    InputAttachment(Vec<DescriptorImageInfo<'r>>),
624    UniformBuffer(Vec<DescriptorBufferInfo<'r>>),
625    StorageBuffer(Vec<DescriptorBufferInfo<'r>>),
626    UniformBufferDynamic(Vec<DescriptorBufferInfo<'r>>),
627    StorageBufferDynamic(Vec<DescriptorBufferInfo<'r>>),
628    UniformTexelBuffer(Vec<VkHandleRef<'r, brvk::VkBufferView>>),
629    StorageTexelBuffer(Vec<VkHandleRef<'r, brvk::VkBufferView>>),
630}
631impl<'d> DescriptorContents<'d> {
632    pub fn type_count(&self) -> (DescriptorType, usize) {
633        match self {
634            Self::Sampler(rs) => (DescriptorType::Sampler, rs.len()),
635            Self::CombinedImageSampler(rs) => (DescriptorType::CombinedImageSampler, rs.len()),
636            Self::SampledImage(rs) => (DescriptorType::SampledImage, rs.len()),
637            Self::StorageImage(rs) => (DescriptorType::StorageImage, rs.len()),
638            Self::InputAttachment(rs) => (DescriptorType::InputAttachment, rs.len()),
639            Self::UniformBuffer(rs) => (DescriptorType::UniformBuffer, rs.len()),
640            Self::StorageBuffer(rs) => (DescriptorType::StorageBuffer, rs.len()),
641            Self::UniformBufferDynamic(rs) => (DescriptorType::UniformBufferDynamic, rs.len()),
642            Self::StorageBufferDynamic(rs) => (DescriptorType::StorageBufferDynamic, rs.len()),
643            Self::UniformTexelBuffer(rs) => (DescriptorType::UniformTexelBuffer, rs.len()),
644            Self::StorageTexelBuffer(rs) => (DescriptorType::StorageTexelBuffer, rs.len()),
645        }
646    }
647
648    // single content utilities
649
650    #[inline(always)]
651    pub fn sampler(obj: &'d (impl VkHandle<Handle = brvk::VkImageView> + ?Sized), layout: ImageLayout) -> Self {
652        Self::Sampler(vec![DescriptorImageInfo::new(obj, layout)])
653    }
654    #[inline(always)]
655    pub fn combined_image_sampler(
656        obj: &'d (impl VkHandle<Handle = brvk::VkImageView> + ?Sized),
657        layout: ImageLayout,
658    ) -> Self {
659        Self::CombinedImageSampler(vec![DescriptorImageInfo::new(obj, layout)])
660    }
661    #[inline(always)]
662    pub fn sampled_image(obj: &'d (impl VkHandle<Handle = brvk::VkImageView> + ?Sized), layout: ImageLayout) -> Self {
663        Self::SampledImage(vec![DescriptorImageInfo::new(obj, layout)])
664    }
665    #[inline(always)]
666    pub fn storage_image(obj: &'d (impl VkHandle<Handle = brvk::VkImageView> + ?Sized), layout: ImageLayout) -> Self {
667        Self::StorageImage(vec![DescriptorImageInfo::new(obj, layout)])
668    }
669    #[inline(always)]
670    pub fn input_attachment(
671        obj: &'d (impl VkHandle<Handle = brvk::VkImageView> + ?Sized),
672        layout: ImageLayout,
673    ) -> Self {
674        Self::InputAttachment(vec![DescriptorImageInfo::new(obj, layout)])
675    }
676    #[inline(always)]
677    pub fn uniform_buffer(
678        obj: &'d (impl VkHandle<Handle = brvk::VkBuffer> + ?Sized),
679        range: core::ops::Range<brvk::VkDeviceSize>,
680    ) -> Self {
681        Self::UniformBuffer(vec![DescriptorBufferInfo::new(obj, range)])
682    }
683    #[inline(always)]
684    pub fn storage_buffer(
685        obj: &'d (impl VkHandle<Handle = brvk::VkBuffer> + ?Sized),
686        range: core::ops::Range<brvk::VkDeviceSize>,
687    ) -> Self {
688        Self::StorageBuffer(vec![DescriptorBufferInfo::new(obj, range)])
689    }
690    #[inline(always)]
691    pub fn uniform_buffer_dynamic(
692        obj: &'d (impl VkHandle<Handle = brvk::VkBuffer> + ?Sized),
693        range: core::ops::Range<brvk::VkDeviceSize>,
694    ) -> Self {
695        Self::UniformBufferDynamic(vec![DescriptorBufferInfo::new(obj, range)])
696    }
697    #[inline(always)]
698    pub fn storage_buffer_dynamic(
699        obj: &'d (impl VkHandle<Handle = brvk::VkBuffer> + ?Sized),
700        range: core::ops::Range<brvk::VkDeviceSize>,
701    ) -> Self {
702        Self::StorageBufferDynamic(vec![DescriptorBufferInfo::new(obj, range)])
703    }
704    #[inline(always)]
705    pub fn uniform_texel_buffer(obj: &'d (impl VkHandle<Handle = brvk::VkBufferView> + ?Sized)) -> Self {
706        Self::UniformTexelBuffer(vec![VkHandleRef::new(obj)])
707    }
708    #[inline(always)]
709    pub fn storage_texel_buffer(obj: &'d (impl VkHandle<Handle = brvk::VkBufferView> + ?Sized)) -> Self {
710        Self::StorageTexelBuffer(vec![VkHandleRef::new(obj)])
711    }
712}
713
714#[derive(Clone)]
715pub struct DescriptorSetWriteInfo<'s>(pub DescriptorPointer, pub DescriptorContents<'s>);
716impl DescriptorSetWriteInfo<'_> {
717    pub fn make_structure(&self) -> brvk::VkWriteDescriptorSet {
718        let (r#type, count) = self.1.type_count();
719        let (buffers, images, buffer_views) = match self.1 {
720            DescriptorContents::Sampler(ref res)
721            | DescriptorContents::CombinedImageSampler(ref res)
722            | DescriptorContents::SampledImage(ref res)
723            | DescriptorContents::StorageImage(ref res)
724            | DescriptorContents::InputAttachment(ref res) => {
725                (core::ptr::null(), res.as_ptr_empty_null(), core::ptr::null())
726            }
727            DescriptorContents::UniformBuffer(ref res)
728            | DescriptorContents::StorageBuffer(ref res)
729            | DescriptorContents::UniformBufferDynamic(ref res)
730            | DescriptorContents::StorageBufferDynamic(ref res) => {
731                (res.as_ptr_empty_null(), core::ptr::null(), core::ptr::null())
732            }
733            DescriptorContents::UniformTexelBuffer(ref res) | DescriptorContents::StorageTexelBuffer(ref res) => {
734                (core::ptr::null(), core::ptr::null(), res.as_ptr_empty_null())
735            }
736        };
737
738        brvk::VkWriteDescriptorSet {
739            sType: brvk::VkWriteDescriptorSet::TYPE,
740            pNext: core::ptr::null(),
741            dstSet: self.0.set,
742            dstBinding: self.0.binding,
743            dstArrayElement: self.0.array_offset,
744            descriptorType: r#type as _,
745            descriptorCount: count as _,
746            pImageInfo: images as _,
747            pBufferInfo: buffers as _,
748            pTexelBufferView: buffer_views as _,
749        }
750    }
751}
752
753#[derive(Clone)]
754pub struct DescriptorSetCopyInfo(pub DescriptorPointer, pub DescriptorPointer, u32);
755impl DescriptorSetCopyInfo {
756    pub fn make_structure(&self) -> brvk::VkCopyDescriptorSet {
757        brvk::VkCopyDescriptorSet {
758            sType: brvk::VkCopyDescriptorSet::TYPE,
759            pNext: core::ptr::null(),
760            srcSet: self.0.set,
761            srcBinding: self.0.binding,
762            srcArrayElement: self.0.array_offset,
763            dstSet: self.1.set,
764            dstBinding: self.1.binding,
765            dstArrayElement: self.1.array_offset,
766            descriptorCount: self.2,
767        }
768    }
769}
770
771#[macro_export]
772macro_rules! DescriptorUpdateTemplateEntry {
773    { ($b: expr, $a: expr) .. : [$ty: expr; $c: expr] = $o: expr, $s: expr } => {
774        brvk::VkDescriptorUpdateTemplateEntry
775        {
776            descriptorType: $ty, descriptorCount: $c,
777            dstBinding: $b, dstArrayElement: $a, offset: $o, stride: $s
778        }
779    };
780}
781#[macro_export]
782macro_rules! DescriptorUpdateTemplateEntries {
783    { { $(($b: expr, $a: expr) .. : [$ty: expr; $c: expr] = $o: expr, $s: expr),* } } => { {
784        $(DescriptorUpdateTemplateEntry! { ($b, $a) ..: [$ty; $c] = $o, $s }),*
785    } };
786}
787
788#[cfg(feature = "VK_KHR_descriptor_update_template")]
789mod update_template;
790#[cfg(feature = "VK_KHR_descriptor_update_template")]
791pub use self::update_template::*;