Skip to main content

bedrock/resources/
buffer.rs

1use bedrock_vk::{self as brvk, TypedVulkanStructure, VkRawHandle, VulkanStructure};
2
3use crate::ffi_helper::slice_as_ptr_empty_null;
4use crate::*;
5use derives::implements;
6
7pub trait Buffer: VkHandle<Handle = brvk::VkBuffer> + DeviceChildHandle {}
8DerefContainerBracketImpl!(for Buffer {});
9GuardsImpl!(for Buffer {});
10
11pub trait BufferView: VkHandle<Handle = brvk::VkBufferView> {}
12DerefContainerBracketImpl!(for BufferView {});
13GuardsImpl!(for BufferView {});
14
15/// Opaque handle to a buffer object(constructed via [`BufferDesc`])
16#[derive(VkHandle, VkObject)]
17#[VkObject(type = brvk::VkBuffer::OBJECT_TYPE)]
18pub struct BufferObject<Device: VkHandle<Handle = brvk::VkDevice>>(pub(crate) brvk::VkBuffer, pub(crate) Device);
19#[implements]
20impl<Device: VkHandle<Handle = brvk::VkDevice>> Drop for BufferObject<Device> {
21    #[inline(always)]
22    fn drop(&mut self) {
23        unsafe {
24            crate::vkfn_wrapper::destroy_buffer(self.1.as_transparent_ref(), VkHandleRefMut::dangling(self.0), None);
25        }
26    }
27}
28unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Sync> Sync for BufferObject<Device> {}
29unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Send> Send for BufferObject<Device> {}
30impl<Device: VkHandle<Handle = brvk::VkDevice>> DeviceChildHandle for BufferObject<Device> {
31    #[inline(always)]
32    fn device_handle(&self) -> brvk::VkDevice {
33        self.1.native_ptr()
34    }
35}
36impl<Device: crate::Device> DeviceChild for BufferObject<Device> {
37    type ConcreteDevice = Device;
38
39    #[inline(always)]
40    fn device(&self) -> &Self::ConcreteDevice {
41        &self.1
42    }
43}
44impl<Device: VkHandle<Handle = brvk::VkDevice>> Buffer for BufferObject<Device> {}
45impl<Device: VkHandle<Handle = brvk::VkDevice>> MemoryBound for BufferObject<Device> {
46    #[cfg(feature = "VK_KHR_get_memory_requirements2")]
47    type MemoryRequirementsInfo2<'b>
48        = BufferMemoryRequirementsInfo2<'b, Self>
49    where
50        Device: 'b;
51
52    #[implements]
53    #[inline(always)]
54    fn requirements(&self) -> brvk::VkMemoryRequirements {
55        unsafe {
56            crate::vkfn_wrapper::get_buffer_memory_requirements(
57                self.device_transparent_ref(),
58                self.as_transparent_ref(),
59            )
60        }
61    }
62
63    #[cfg(feature = "VK_KHR_get_memory_requirements2")]
64    fn requirements2<'b>(&'b self) -> Self::MemoryRequirementsInfo2<'b> {
65        BufferMemoryRequirementsInfo2::new(self)
66    }
67
68    #[implements]
69    #[inline(always)]
70    fn bind(
71        &mut self,
72        memory: &(impl VkHandle<Handle = brvk::VkDeviceMemory> + ?Sized),
73        offset: DeviceSize,
74    ) -> crate::Result<()>
75    where
76        Self: VkHandleMut,
77    {
78        unsafe {
79            crate::vkfn_wrapper::bind_buffer_memory(
80                self.1.as_transparent_ref(),
81                VkHandleRefMut::dangling(self.0),
82                memory.as_transparent_ref(),
83                offset,
84            )
85        }
86    }
87}
88impl<Device: VkHandle<Handle = brvk::VkDevice>> BufferObject<Device> {
89    /// Constructs from raw values
90    /// # Safety
91    /// the resource must be created from the parent
92    pub const unsafe fn manage(handle: brvk::VkBuffer, parent: Device) -> Self {
93        Self(handle, parent)
94    }
95
96    /// Purges internal values (Drop will not be called for this resource)
97    pub const fn unmanage(self) -> (brvk::VkBuffer, Device) {
98        let v = self.0;
99        let p = unsafe { core::ptr::read(&self.1) };
100        core::mem::forget(self);
101
102        (v, p)
103    }
104}
105impl<Device: VkHandle<Handle = brvk::VkDevice> + Clone> BufferObject<&'_ Device> {
106    /// Owning parent object by cloning it.
107    #[inline(always)]
108    pub fn clone_parent(self) -> BufferObject<Device> {
109        let r = BufferObject(self.0, self.1.clone());
110        core::mem::forget(self);
111
112        r
113    }
114}
115impl<Device: crate::Device> BufferObject<Device> {
116    /// Create a new buffer object
117    /// # Failure
118    /// On failure, this command returns
119    ///
120    /// * `brvk::VK_ERROR_OUT_OF_HOST_MEMORY`
121    /// * `brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY`
122    #[implements]
123    #[inline]
124    pub fn new(device: Device, info: &BufferCreateInfo) -> crate::Result<Self> {
125        Ok(unsafe { Self::manage(device.new_buffer_raw(info, None)?, device) })
126    }
127}
128
129#[derive(VkHandle, VkObject)]
130#[VkObject(type = brvk::VkBufferView::OBJECT_TYPE)]
131/// Opaque handle to a buffer view object
132pub struct BufferViewObject<Buffer: DeviceChildHandle>(brvk::VkBufferView, Buffer);
133#[implements]
134impl<Buffer: DeviceChildHandle> Drop for BufferViewObject<Buffer> {
135    fn drop(&mut self) {
136        unsafe {
137            crate::vkfn_wrapper::destroy_buffer_view(
138                self.1.device_transparent_ref(),
139                VkHandleRefMut::dangling(self.0),
140                None,
141            );
142        }
143    }
144}
145unsafe impl<Buffer: DeviceChildHandle + Sync> Sync for BufferViewObject<Buffer> {}
146unsafe impl<Buffer: DeviceChildHandle + Send> Send for BufferViewObject<Buffer> {}
147impl<Buffer: DeviceChildHandle> DeviceChildHandle for BufferViewObject<Buffer> {
148    #[inline(always)]
149    fn device_handle(&self) -> brvk::VkDevice {
150        self.1.device_handle()
151    }
152}
153impl<Buffer: DeviceChild> DeviceChild for BufferViewObject<Buffer> {
154    type ConcreteDevice = Buffer::ConcreteDevice;
155
156    #[inline(always)]
157    fn device(&self) -> &Self::ConcreteDevice {
158        self.1.device()
159    }
160}
161impl<Buffer: DeviceChildHandle> BufferView for BufferViewObject<Buffer> {}
162impl<Buffer: DeviceChildHandle> core::ops::Deref for BufferViewObject<Buffer> {
163    type Target = Buffer;
164
165    #[inline(always)]
166    fn deref(&self) -> &Buffer {
167        &self.1
168    }
169}
170impl<Buffer: DeviceChildHandle> BufferViewObject<Buffer> {
171    /// Constructs from raw values
172    /// # Safety
173    /// the resource must be created from the parent
174    pub const unsafe fn manage(handle: brvk::VkBufferView, parent: Buffer) -> Self {
175        Self(handle, parent)
176    }
177
178    /// Purges internal values (Drop will not be called for this resource)
179    pub const fn unmanage(self) -> (brvk::VkBufferView, Buffer) {
180        let v = self.0;
181        let p = unsafe { core::ptr::read(&self.1) };
182        core::mem::forget(self);
183
184        (v, p)
185    }
186}
187impl<Buffer: DeviceChildHandle + Clone> BufferViewObject<&'_ Buffer> {
188    /// Owning parent object by cloning it.
189    #[inline(always)]
190    pub fn clone_parent(self) -> BufferViewObject<Buffer> {
191        let r = BufferViewObject(self.0, self.1.clone());
192        core::mem::forget(self);
193
194        r
195    }
196}
197impl<Buffer: DeviceChild> BufferViewObject<Buffer> {
198    /// Create a new buffer view object
199    /// # Failure
200    /// On failure, this command returns
201    ///
202    /// * [`brvk::VK_ERROR_OUT_OF_HOST_MEMORY`]
203    /// * [`brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY`]
204    #[implements]
205    #[inline]
206    pub fn new(buffer: Buffer, info: &BufferViewCreateInfo) -> crate::Result<Self> {
207        use crate::Device;
208
209        Ok(unsafe { Self::manage(buffer.device().new_buffer_view_raw(info, None)?, buffer) })
210    }
211}
212
213/// Builder structure specifying the parameters of a newly created buffer object
214#[repr(transparent)]
215#[derive(Clone)]
216pub struct BufferCreateInfo<'s>(brvk::VkBufferCreateInfo, core::marker::PhantomData<Option<&'s [u32]>>);
217impl<'s> BufferCreateInfo<'s> {
218    /// Creates a new buffer description with provided byte-size and usage flags
219    pub const fn new(byte_size: DeviceSize, usage: BufferUsage) -> Self {
220        Self(
221            brvk::VkBufferCreateInfo {
222                sType: brvk::VkBufferCreateInfo::TYPE,
223                pNext: core::ptr::null(),
224                flags: 0,
225                size: byte_size,
226                usage: usage.0,
227                sharingMode: brvk::VK_SHARING_MODE_EXCLUSIVE,
228                queueFamilyIndexCount: 0,
229                pQueueFamilyIndices: core::ptr::null(),
230            },
231            core::marker::PhantomData,
232        )
233    }
234
235    /// Creates a new buffer description which fits for a type
236    #[inline(always)]
237    pub const fn new_for_type<T>(usage: BufferUsage) -> Self {
238        Self::new(core::mem::size_of::<T>() as _, usage)
239    }
240
241    /// Wraps raw vulkan structure
242    /// # Safety
243    /// This function does not check any references/constraints
244    pub const unsafe fn from_raw(s: brvk::VkBufferCreateInfo) -> Self {
245        Self(s, core::marker::PhantomData)
246    }
247
248    /// Unwraps raw vulkan structure
249    /// # Safety
250    /// Lifetime constraints are removed
251    pub const unsafe fn into_raw(self) -> brvk::VkBufferCreateInfo {
252        self.0
253    }
254
255    /// A list of queue families that will access this buffer
256    pub const fn sharing_queue_families(mut self, indices: &'s [u32]) -> Self {
257        self.0.sharingMode = if indices.is_empty() {
258            brvk::VK_SHARING_MODE_EXCLUSIVE
259        } else {
260            brvk::VK_SHARING_MODE_CONCURRENT
261        };
262        self.0.queueFamilyIndexCount = indices.len() as _;
263        self.0.pQueueFamilyIndices = slice_as_ptr_empty_null(indices);
264
265        self
266    }
267
268    /// A bitmask of `BufferSparseBinding` specifying additional parameters of the buffer
269    pub const fn sparse_binding_opt(mut self, opt: BufferSparseBinding) -> Self {
270        self.0.flags = opt as _;
271        self
272    }
273
274    /// Merges usage flags
275    pub const fn with_usage(mut self, usage: BufferUsage) -> Self {
276        self.0.usage |= usage.0;
277        self
278    }
279
280    /// Overwrites usage flags
281    pub const fn set_usage(mut self, usage: BufferUsage) -> Self {
282        self.0.usage = usage.0;
283        self
284    }
285
286    pub const fn size(&self) -> DeviceSize {
287        self.0.size
288    }
289
290    pub const fn usage(&self) -> BufferUsage {
291        BufferUsage(self.0.usage)
292    }
293}
294impl crate::VulkanStructureProvider for BufferCreateInfo<'_> {
295    type RootStructure = brvk::VkBufferCreateInfo;
296
297    fn build<'r, 's: 'r>(&'s mut self, root: &'s mut Self::RootStructure) -> &'r mut brvk::GenericVulkanStructure {
298        *root = self.0.clone();
299        root.as_generic_mut()
300    }
301}
302
303#[repr(transparent)]
304#[derive(Clone)]
305pub struct BufferViewCreateInfo<'d>(
306    brvk::VkBufferViewCreateInfo,
307    core::marker::PhantomData<&'d dyn VkHandle<Handle = brvk::VkBuffer>>,
308);
309impl<'d> BufferViewCreateInfo<'d> {
310    #[inline]
311    pub fn new(
312        buffer: &'d (impl VkHandle<Handle = brvk::VkBuffer> + ?Sized),
313        format: brvk::VkFormat,
314        range: core::ops::Range<brvk::VkDeviceSize>,
315    ) -> Self {
316        Self(
317            brvk::VkBufferViewCreateInfo {
318                sType: brvk::VkBufferViewCreateInfo::TYPE,
319                pNext: core::ptr::null(),
320                flags: 0,
321                buffer: buffer.native_ptr(),
322                format,
323                offset: range.start,
324                range: range.end - range.start,
325            },
326            core::marker::PhantomData,
327        )
328    }
329
330    /// # Safety
331    ///
332    /// `raw` must be a valid [`brvk::VkBufferViewCreateInfo`] struct.
333    pub const unsafe fn from_raw(raw: brvk::VkBufferViewCreateInfo) -> Self {
334        Self(raw, core::marker::PhantomData)
335    }
336
337    pub const fn into_raw(self) -> brvk::VkBufferViewCreateInfo {
338        self.0
339    }
340}
341
342#[cfg(feature = "VK_KHR_get_memory_requirements2")]
343pub struct BufferMemoryRequirementsInfo2<'b, Buffer: VkHandle<Handle = brvk::VkBuffer> + 'b>(
344    brvk::VkBufferMemoryRequirementsInfo2KHR,
345    &'b Buffer,
346);
347#[cfg(feature = "VK_KHR_get_memory_requirements2")]
348impl<'b, Buffer: VkHandle<Handle = brvk::VkBuffer> + 'b> BufferMemoryRequirementsInfo2<'b, Buffer> {
349    pub fn new(buffer: &'b Buffer) -> Self {
350        Self(
351            brvk::VkBufferMemoryRequirementsInfo2KHR {
352                sType: brvk::VkBufferMemoryRequirementsInfo2KHR::TYPE,
353                pNext: core::ptr::null(),
354                buffer: buffer.native_ptr(),
355            },
356            buffer,
357        )
358    }
359
360    #[implements("Allow1_1APIs")]
361    #[inline(always)]
362    pub fn query(self, sink: &mut core::mem::MaybeUninit<brvk::VkMemoryRequirements2KHR>)
363    where
364        Buffer: crate::DeviceChild,
365    {
366        unsafe { crate::vkfn_wrapper::get_buffer_memory_requirements2(self.1.device_transparent_ref(), &self, sink) }
367    }
368}
369#[cfg(feature = "VK_KHR_get_memory_requirements2")]
370impl<Buffer: VkHandle<Handle = brvk::VkBuffer>> AsRef<brvk::VkBufferMemoryRequirementsInfo2KHR>
371    for BufferMemoryRequirementsInfo2<'_, Buffer>
372{
373    fn as_ref(&self) -> &brvk::VkBufferMemoryRequirementsInfo2KHR {
374        &self.0
375    }
376}
377
378#[cfg(feature = "VK_KHR_bind_memory2")]
379#[repr(transparent)]
380pub struct BindBufferMemoryInfo<'b>(
381    brvk::VkBindBufferMemoryInfoKHR,
382    core::marker::PhantomData<(VkHandleRef<'b, brvk::VkBuffer>, VkHandleRef<'b, brvk::VkDeviceMemory>)>,
383);
384#[cfg(feature = "VK_KHR_bind_memory2")]
385impl<'b> BindBufferMemoryInfo<'b> {
386    pub fn new(
387        buffer: &'b (impl VkHandle<Handle = brvk::VkBuffer> + ?Sized),
388        memory: &'b (impl VkHandle<Handle = brvk::VkDeviceMemory> + ?Sized),
389        offset: brvk::VkDeviceSize,
390    ) -> Self {
391        Self(
392            brvk::VkBindBufferMemoryInfoKHR {
393                sType: brvk::VkBindBufferMemoryInfoKHR::TYPE,
394                pNext: core::ptr::null(),
395                buffer: buffer.native_ptr(),
396                memory: memory.native_ptr(),
397                memoryOffset: offset,
398            },
399            core::marker::PhantomData,
400        )
401    }
402
403    /// # Safety
404    ///
405    /// `raw` must be a valid [`VkBindBufferMemoryInfoKHR`] struct.
406    pub const unsafe fn from_raw(raw: brvk::VkBindBufferMemoryInfoKHR) -> Self {
407        Self(raw, core::marker::PhantomData)
408    }
409
410    pub const fn into_raw(self) -> brvk::VkBindBufferMemoryInfoKHR {
411        self.0
412    }
413}
414#[cfg(feature = "VK_KHR_bind_memory2")]
415impl AsRef<brvk::VkBindBufferMemoryInfoKHR> for BindBufferMemoryInfo<'_> {
416    #[inline(always)]
417    fn as_ref(&self) -> &brvk::VkBindBufferMemoryInfoKHR {
418        &self.0
419    }
420}
421
422/// Bitmask specifying allowed usage of a buffer
423#[derive(Clone, Copy, PartialEq, Eq, Debug)]
424#[repr(transparent)]
425pub struct BufferUsage(pub brvk::VkBufferUsageFlags);
426impl BufferUsage {
427    /// Specifies that the buffer can be used as the source of a transfer command
428    pub const TRANSFER_SRC: Self = Self(brvk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
429    /// Specifies that the buffer can be used as the destination of a transfer command
430    pub const TRANSFER_DEST: Self = Self(brvk::VK_BUFFER_USAGE_TRANSFER_DST_BIT);
431    /// Specifies that the buffer can be used to create a `BufferView` suitable for
432    /// occupying a `DescriptorSet` slot of type `brvk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER`
433    pub const UNIFORM_TEXEL_BUFFER: Self = Self(brvk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
434    /// Specifies that the buffer can be used to create a `BufferView` suitable for
435    /// occupying a `DescriptorSet` slot of type `brvk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER`
436    pub const STORAGE_TEXEL_BUFFER: Self = Self(brvk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
437    /// Specifies that the buffer can be used in a `DescriptorBufferInfo` suitable for
438    /// occupying a `DescriptorSet` slot either of type `brvk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER` or `brvk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC`
439    pub const UNIFORM_BUFFER: Self = Self(brvk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
440    /// Specifies that the buffer can be used in a `DescriptorBufferInfo` suitable for
441    /// occupying a `DescriptorSet` slot either of type `brvk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER` or `brvk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC`
442    pub const STORAGE_BUFFER: Self = Self(brvk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
443    /// Specifies that the buffer is suitable for passing as the `buffer` parameter to `DrawCommandBuffer::bind_index_buffer`
444    pub const INDEX_BUFFER: Self = Self(brvk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
445    /// Specifies that the buffer is suitable for passing as an element of the `buffers` array to `DrawCommandBuffer::bind_vertex_buffers`
446    pub const VERTEX_BUFFER: Self = Self(brvk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
447    /// Specifies that the buffer is suitable for passing as the `buffer` parameter to
448    /// `DrawCommandBuffer::draw_indirect`, `DrawCommandBuffer::draw_indexed_indirect`, or `ComputeCommandBuffer::dispatch_indirect`
449    pub const INDIRECT_BUFFER: Self = Self(brvk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
450
451    /// Specifies that the buffer can be used as the source of a transfer command
452    pub const fn transfer_src(self) -> Self {
453        Self(self.0 | Self::TRANSFER_SRC.0)
454    }
455    /// Specifies that the buffer can be used as the destination of a transfer command
456    pub const fn transfer_dest(self) -> Self {
457        Self(self.0 | Self::TRANSFER_DEST.0)
458    }
459    /// Specifies that the buffer can be used to create a `BufferView` suitable for
460    /// occupying a `DescriptorSet` slot of type `brvk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER`
461    pub const fn uniform_texel_buffer(self) -> Self {
462        Self(self.0 | Self::UNIFORM_TEXEL_BUFFER.0)
463    }
464    /// Specifies that the buffer can be used to create a `BufferView` suitable for
465    /// occupying a `DescriptorSet` slot of type `brvk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER`
466    pub const fn storage_texel_buffer(self) -> Self {
467        Self(self.0 | Self::STORAGE_TEXEL_BUFFER.0)
468    }
469    /// Specifies that the buffer can be used in a `DescriptorBufferInfo` suitable for
470    /// occupying a `DescriptorSet` slot either of type `brvk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER` or `brvk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC`
471    pub const fn uniform_buffer(self) -> Self {
472        Self(self.0 | Self::UNIFORM_BUFFER.0)
473    }
474    /// Specifies that the buffer can be used in a `DescriptorBufferInfo` suitable for
475    /// occupying a `DescriptorSet` slot either of type `brvk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER` or `brvk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC`
476    pub const fn storage_buffer(self) -> Self {
477        Self(self.0 | Self::STORAGE_BUFFER.0)
478    }
479    /// Specifies that the buffer is suitable for passing as the `buffer` parameter to `DrawCommandBuffer::bind_index_buffer`
480    pub const fn index_buffer(self) -> Self {
481        Self(self.0 | Self::INDEX_BUFFER.0)
482    }
483    /// Specifies that the buffer is suitable for passing as an element of the `buffers` array to `DrawCommandBuffer::bind_vertex_buffers`
484    pub const fn vertex_buffer(self) -> Self {
485        Self(self.0 | Self::VERTEX_BUFFER.0)
486    }
487    /// Specifies that the buffer is suitable for passing as the `buffer` parameter to
488    /// `DrawCommandBuffer::draw_indirect`, `DrawCommandBuffer::draw_indexed_indirect`, or `ComputeCommandBuffer::dispatch_indirect`
489    pub const fn indirect_buffer(self) -> Self {
490        Self(self.0 | Self::INDIRECT_BUFFER.0)
491    }
492
493    /// merge two flags (const alias of BitOr)
494    pub const fn merge(self, other: Self) -> Self {
495        Self(self.0 | other.0)
496    }
497
498    /// Generates a default access type mask
499    pub const fn default_access_mask(self) -> brvk::VkAccessFlags {
500        let mut bits = 0;
501        if (self.0 & Self::TRANSFER_SRC.0) != 0 {
502            bits |= brvk::VK_ACCESS_TRANSFER_READ_BIT;
503        }
504        if (self.0 & Self::TRANSFER_DEST.0) != 0 {
505            bits |= brvk::VK_ACCESS_TRANSFER_WRITE_BIT;
506        }
507        if (self.0 & Self::UNIFORM_TEXEL_BUFFER.0) != 0 {
508            bits |= brvk::VK_ACCESS_UNIFORM_READ_BIT;
509        }
510        if (self.0 & Self::STORAGE_TEXEL_BUFFER.0) != 0 {
511            bits |= brvk::VK_ACCESS_UNIFORM_READ_BIT;
512        }
513        if (self.0 & Self::UNIFORM_BUFFER.0) != 0 {
514            bits |= brvk::VK_ACCESS_UNIFORM_READ_BIT;
515        }
516        if (self.0 & Self::STORAGE_BUFFER.0) != 0 {
517            bits |= brvk::VK_ACCESS_UNIFORM_READ_BIT;
518        }
519        if (self.0 & Self::INDEX_BUFFER.0) != 0 {
520            bits |= brvk::VK_ACCESS_INDEX_READ_BIT;
521        }
522        if (self.0 & Self::VERTEX_BUFFER.0) != 0 {
523            bits |= brvk::VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
524        }
525        if (self.0 & Self::INDIRECT_BUFFER.0) != 0 {
526            bits |= brvk::VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
527        }
528        bits
529    }
530
531    /// Determines if flag contains usage of uniform-buffer
532    pub const fn is_uniform(self) -> bool {
533        (self.0 & (Self::UNIFORM_BUFFER.0 | Self::UNIFORM_TEXEL_BUFFER.0)) != 0
534    }
535    /// Determines if flag contains usage of storage-buffer
536    pub const fn is_storage(self) -> bool {
537        (self.0 & (Self::STORAGE_BUFFER.0 | Self::STORAGE_TEXEL_BUFFER.0)) != 0
538    }
539}
540impl core::ops::BitOr for BufferUsage {
541    type Output = Self;
542
543    #[inline(always)]
544    fn bitor(self, other: Self) -> Self {
545        BufferUsage(self.0 | other.0)
546    }
547}
548impl core::ops::BitOrAssign for BufferUsage {
549    #[inline(always)]
550    fn bitor_assign(&mut self, other: Self) {
551        self.0 |= other.0;
552    }
553}
554impl From<BufferUsage> for brvk::VkBufferUsageFlags {
555    #[inline(always)]
556    fn from(value: BufferUsage) -> Self {
557        value.0
558    }
559}
560
561/// Bitset specifying additional parameters of a buffer
562#[derive(Debug, Clone, Copy, PartialEq, Eq)]
563#[repr(C)]
564pub enum BufferSparseBinding {
565    /// No sparse binding features
566    None = 0,
567    /// the buffer will be backed using sparse memory binding
568    Bound = brvk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT as _,
569    /// the buffer can be partially backed using sparse memory binding.
570    Residency = (brvk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT | brvk::VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) as _,
571    /// the buffer will be backed using sparse memory binding with memory ranges
572    /// that might also simultaneously be backing another buffer (or another portion of the same buffer)
573    Aliased = (brvk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT | brvk::VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) as _,
574    /// Aliased and Residency
575    Both = (brvk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT
576        | brvk::VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT
577        | brvk::VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) as _,
578}