1use crate::ffi_helper::slice_as_ptr_empty_null;
2use crate::*;
3use derives::implements;
4
5pub trait Buffer: VkHandle<Handle = VkBuffer> + DeviceChildHandle {}
6DerefContainerBracketImpl!(for Buffer {});
7GuardsImpl!(for Buffer {});
8
9pub trait BufferView: VkHandle<Handle = VkBufferView> {}
10DerefContainerBracketImpl!(for BufferView {});
11GuardsImpl!(for BufferView {});
12
13#[derive(VkHandle, VkObject)]
15#[VkObject(type = VkBuffer::OBJECT_TYPE)]
16pub struct BufferObject<Device: VkHandle<Handle = VkDevice>>(pub(crate) VkBuffer, pub(crate) Device);
17#[implements]
18impl<Device: VkHandle<Handle = VkDevice>> Drop for BufferObject<Device> {
19 #[inline(always)]
20 fn drop(&mut self) {
21 unsafe {
22 crate::vkfn::destroy_buffer(self.1.native_ptr(), self.0, core::ptr::null());
23 }
24 }
25}
26unsafe impl<Device: VkHandle<Handle = VkDevice> + Sync> Sync for BufferObject<Device> {}
27unsafe impl<Device: VkHandle<Handle = VkDevice> + Send> Send for BufferObject<Device> {}
28impl<Device: VkHandle<Handle = VkDevice>> DeviceChildHandle for BufferObject<Device> {
29 #[inline(always)]
30 fn device_handle(&self) -> VkDevice {
31 self.1.native_ptr()
32 }
33}
34impl<Device: crate::Device> DeviceChild for BufferObject<Device> {
35 type ConcreteDevice = Device;
36
37 #[inline(always)]
38 fn device(&self) -> &Self::ConcreteDevice {
39 &self.1
40 }
41}
42impl<Device: VkHandle<Handle = VkDevice>> Buffer for BufferObject<Device> {}
43impl<Device: VkHandle<Handle = VkDevice>> MemoryBound for BufferObject<Device> {
44 #[cfg(feature = "VK_KHR_get_memory_requirements2")]
45 type MemoryRequirementsInfo2<'b>
46 = BufferMemoryRequirementsInfo2<'b, Self>
47 where
48 Device: 'b;
49
50 #[implements]
51 fn requirements(&self) -> VkMemoryRequirements {
52 let mut p = core::mem::MaybeUninit::uninit();
53 unsafe {
54 crate::vkfn::get_buffer_memory_requirements(self.1.native_ptr(), self.0, p.as_mut_ptr());
55
56 p.assume_init()
57 }
58 }
59
60 #[cfg(feature = "VK_KHR_get_memory_requirements2")]
61 fn requirements2<'b>(&'b self) -> Self::MemoryRequirementsInfo2<'b> {
62 BufferMemoryRequirementsInfo2::new(self)
63 }
64
65 #[inline(always)]
66 #[implements]
67 fn bind(&mut self, memory: &(impl VkHandle<Handle = VkDeviceMemory> + ?Sized), offset: usize) -> crate::Result<()>
68 where
69 Self: VkHandleMut,
70 {
71 unsafe {
72 crate::vkfn::bind_buffer_memory(self.1.native_ptr(), self.0, memory.native_ptr(), offset as _)
73 .into_result()
74 .map(drop)
75 }
76 }
77}
78impl<Device: VkHandle<Handle = VkDevice>> BufferObject<Device> {
79 pub const unsafe fn manage(handle: VkBuffer, parent: Device) -> Self {
83 Self(handle, parent)
84 }
85
86 pub const fn unmanage(self) -> (VkBuffer, Device) {
88 let v = self.0;
89 let p = unsafe { core::ptr::read(&self.1) };
90 core::mem::forget(self);
91
92 (v, p)
93 }
94}
95impl<Device: VkHandle<Handle = VkDevice> + Clone> BufferObject<&'_ Device> {
96 #[inline(always)]
98 pub fn clone_parent(self) -> BufferObject<Device> {
99 let r = BufferObject(self.0, self.1.clone());
100 core::mem::forget(self);
101
102 r
103 }
104}
105impl<Device: crate::Device> BufferObject<Device> {
106 #[implements]
113 #[inline]
114 pub fn new(device: Device, info: &BufferCreateInfo) -> crate::Result<Self> {
115 Ok(unsafe { Self::manage(device.new_buffer_raw(info, None)?, device) })
116 }
117}
118
119#[derive(VkHandle, VkObject)]
120#[VkObject(type = VkBufferView::OBJECT_TYPE)]
121pub struct BufferViewObject<Buffer: DeviceChildHandle>(VkBufferView, Buffer);
123#[implements]
124impl<Buffer: DeviceChildHandle> Drop for BufferViewObject<Buffer> {
125 fn drop(&mut self) {
126 unsafe {
127 crate::vkfn::destroy_buffer_view(self.1.device_handle(), self.0, core::ptr::null());
128 }
129 }
130}
131unsafe impl<Buffer: DeviceChildHandle + Sync> Sync for BufferViewObject<Buffer> {}
132unsafe impl<Buffer: DeviceChildHandle + Send> Send for BufferViewObject<Buffer> {}
133impl<Buffer: DeviceChildHandle> DeviceChildHandle for BufferViewObject<Buffer> {
134 #[inline(always)]
135 fn device_handle(&self) -> VkDevice {
136 self.1.device_handle()
137 }
138}
139impl<Buffer: DeviceChild> DeviceChild for BufferViewObject<Buffer> {
140 type ConcreteDevice = Buffer::ConcreteDevice;
141
142 #[inline(always)]
143 fn device(&self) -> &Self::ConcreteDevice {
144 self.1.device()
145 }
146}
147impl<Buffer: DeviceChildHandle> BufferView for BufferViewObject<Buffer> {}
148impl<Buffer: DeviceChildHandle> core::ops::Deref for BufferViewObject<Buffer> {
149 type Target = Buffer;
150
151 #[inline(always)]
152 fn deref(&self) -> &Buffer {
153 &self.1
154 }
155}
156impl<Buffer: DeviceChildHandle> BufferViewObject<Buffer> {
157 pub const unsafe fn manage(handle: VkBufferView, parent: Buffer) -> Self {
161 Self(handle, parent)
162 }
163
164 pub const fn unmanage(self) -> (VkBufferView, Buffer) {
166 let v = self.0;
167 let p = unsafe { core::ptr::read(&self.1) };
168 core::mem::forget(self);
169
170 (v, p)
171 }
172}
173impl<Buffer: DeviceChildHandle + Clone> BufferViewObject<&'_ Buffer> {
174 #[inline(always)]
176 pub fn clone_parent(self) -> BufferViewObject<Buffer> {
177 let r = BufferViewObject(self.0, self.1.clone());
178 core::mem::forget(self);
179
180 r
181 }
182}
183impl<Buffer: DeviceChild> BufferViewObject<Buffer> {
184 #[implements]
191 #[inline]
192 pub fn new(buffer: Buffer, info: &BufferViewCreateInfo) -> crate::Result<Self> {
193 use crate::Device;
194
195 Ok(unsafe { Self::manage(buffer.device().new_buffer_view_raw(info, None)?, buffer) })
196 }
197}
198
199#[repr(transparent)]
201#[derive(Clone)]
202pub struct BufferCreateInfo<'s>(VkBufferCreateInfo, core::marker::PhantomData<Option<&'s [u32]>>);
203impl<'s> BufferCreateInfo<'s> {
204 pub const fn new(byte_size: usize, usage: BufferUsage) -> Self {
206 Self(
207 VkBufferCreateInfo {
208 sType: VkBufferCreateInfo::TYPE,
209 pNext: core::ptr::null(),
210 flags: 0,
211 size: byte_size as _,
212 usage: usage.0,
213 sharingMode: VK_SHARING_MODE_EXCLUSIVE,
214 queueFamilyIndexCount: 0,
215 pQueueFamilyIndices: core::ptr::null(),
216 },
217 core::marker::PhantomData,
218 )
219 }
220
221 #[inline(always)]
223 pub const fn new_for_type<T>(usage: BufferUsage) -> Self {
224 Self::new(core::mem::size_of::<T>(), usage)
225 }
226
227 pub const unsafe fn from_raw(s: VkBufferCreateInfo) -> Self {
231 Self(s, core::marker::PhantomData)
232 }
233
234 pub const unsafe fn into_raw(self) -> VkBufferCreateInfo {
238 self.0
239 }
240
241 pub const fn sharing_queue_families(mut self, indices: &'s [u32]) -> Self {
243 self.0.sharingMode = if indices.is_empty() {
244 VK_SHARING_MODE_EXCLUSIVE
245 } else {
246 VK_SHARING_MODE_CONCURRENT
247 };
248 self.0.queueFamilyIndexCount = indices.len() as _;
249 self.0.pQueueFamilyIndices = slice_as_ptr_empty_null(indices);
250
251 self
252 }
253
254 pub const fn sparse_binding_opt(mut self, opt: BufferSparseBinding) -> Self {
256 self.0.flags = opt as _;
257 self
258 }
259
260 pub const fn with_usage(mut self, usage: BufferUsage) -> Self {
262 self.0.usage |= usage.0;
263 self
264 }
265
266 pub const fn set_usage(mut self, usage: BufferUsage) -> Self {
268 self.0.usage = usage.0;
269 self
270 }
271
272 pub const fn size(&self) -> VkDeviceSize {
273 self.0.size
274 }
275
276 pub const fn usage(&self) -> BufferUsage {
277 BufferUsage(self.0.usage)
278 }
279}
280impl crate::VulkanStructureProvider for BufferCreateInfo<'_> {
281 type RootStructure = VkBufferCreateInfo;
282
283 fn build<'r, 's: 'r>(&'s mut self, root: &'s mut Self::RootStructure) -> &'r mut crate::GenericVulkanStructure {
284 *root = self.0.clone();
285 root.as_generic_mut()
286 }
287}
288
289#[repr(transparent)]
290#[derive(Clone)]
291pub struct BufferViewCreateInfo<'d>(
292 VkBufferViewCreateInfo,
293 core::marker::PhantomData<&'d dyn VkHandle<Handle = VkBuffer>>,
294);
295impl<'d> BufferViewCreateInfo<'d> {
296 #[inline]
297 pub fn new(
298 buffer: &'d (impl VkHandle<Handle = VkBuffer> + ?Sized),
299 format: VkFormat,
300 range: core::ops::Range<VkDeviceSize>,
301 ) -> Self {
302 Self(
303 VkBufferViewCreateInfo {
304 sType: VkBufferViewCreateInfo::TYPE,
305 pNext: core::ptr::null(),
306 flags: 0,
307 buffer: buffer.native_ptr(),
308 format,
309 offset: range.start,
310 range: range.end - range.start,
311 },
312 core::marker::PhantomData,
313 )
314 }
315
316 pub const unsafe fn from_raw(raw: VkBufferViewCreateInfo) -> Self {
317 Self(raw, core::marker::PhantomData)
318 }
319
320 pub const fn into_raw(self) -> VkBufferViewCreateInfo {
321 self.0
322 }
323}
324
325#[cfg(feature = "VK_KHR_get_memory_requirements2")]
326pub struct BufferMemoryRequirementsInfo2<'b, Buffer: VkHandle<Handle = VkBuffer> + 'b>(
327 VkBufferMemoryRequirementsInfo2KHR,
328 &'b Buffer,
329);
330#[cfg(feature = "VK_KHR_get_memory_requirements2")]
331impl<'b, Buffer: VkHandle<Handle = VkBuffer> + 'b> BufferMemoryRequirementsInfo2<'b, Buffer> {
332 pub fn new(buffer: &'b Buffer) -> Self {
333 Self(
334 VkBufferMemoryRequirementsInfo2KHR {
335 sType: VkBufferMemoryRequirementsInfo2KHR::TYPE,
336 pNext: core::ptr::null(),
337 buffer: buffer.native_ptr(),
338 },
339 buffer,
340 )
341 }
342
343 #[implements("Allow1_1APIs")]
344 pub fn query(self, sink: &mut core::mem::MaybeUninit<VkMemoryRequirements2KHR>)
345 where
346 Buffer: crate::DeviceChild,
347 {
348 unsafe {
349 crate::vkfn::get_buffer_memory_requirements2(self.1.device().native_ptr(), &self.0, sink.as_mut_ptr());
350 }
351 }
352}
353#[cfg(feature = "VK_KHR_get_memory_requirements2")]
354impl<Buffer: VkHandle<Handle = VkBuffer>> AsRef<VkBufferMemoryRequirementsInfo2KHR>
355 for BufferMemoryRequirementsInfo2<'_, Buffer>
356{
357 fn as_ref(&self) -> &VkBufferMemoryRequirementsInfo2KHR {
358 &self.0
359 }
360}
361
362#[cfg(feature = "VK_KHR_bind_memory2")]
363#[repr(transparent)]
364pub struct BindBufferMemoryInfo<'b>(
365 VkBindBufferMemoryInfoKHR,
366 core::marker::PhantomData<(VkHandleRef<'b, VkBuffer>, VkHandleRef<'b, VkDeviceMemory>)>,
367);
368#[cfg(feature = "VK_KHR_bind_memory2")]
369impl<'b> BindBufferMemoryInfo<'b> {
370 pub fn new(
371 buffer: &'b (impl VkHandle<Handle = VkBuffer> + ?Sized),
372 memory: &'b (impl VkHandle<Handle = VkDeviceMemory> + ?Sized),
373 offset: DeviceSize,
374 ) -> Self {
375 Self(
376 VkBindBufferMemoryInfoKHR {
377 sType: VkBindBufferMemoryInfoKHR::TYPE,
378 pNext: core::ptr::null(),
379 buffer: buffer.native_ptr(),
380 memory: memory.native_ptr(),
381 memoryOffset: offset,
382 },
383 core::marker::PhantomData,
384 )
385 }
386
387 pub const unsafe fn from_raw(raw: VkBindBufferMemoryInfoKHR) -> Self {
388 Self(raw, core::marker::PhantomData)
389 }
390
391 pub const fn into_raw(self) -> VkBindBufferMemoryInfoKHR {
392 self.0
393 }
394}
395
396#[derive(Clone, Copy, PartialEq, Eq, Debug)]
398#[repr(transparent)]
399pub struct BufferUsage(pub VkBufferUsageFlags);
400impl BufferUsage {
401 pub const TRANSFER_SRC: Self = Self(VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
403 pub const TRANSFER_DEST: Self = Self(VK_BUFFER_USAGE_TRANSFER_DST_BIT);
405 pub const UNIFORM_TEXEL_BUFFER: Self = Self(VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
408 pub const STORAGE_TEXEL_BUFFER: Self = Self(VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
411 pub const UNIFORM_BUFFER: Self = Self(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
414 pub const STORAGE_BUFFER: Self = Self(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
417 pub const INDEX_BUFFER: Self = Self(VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
419 pub const VERTEX_BUFFER: Self = Self(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
421 pub const INDIRECT_BUFFER: Self = Self(VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
424
425 pub const fn transfer_src(self) -> Self {
427 Self(self.0 | Self::TRANSFER_SRC.0)
428 }
429 pub const fn transfer_dest(self) -> Self {
431 Self(self.0 | Self::TRANSFER_DEST.0)
432 }
433 pub const fn uniform_texel_buffer(self) -> Self {
436 Self(self.0 | Self::UNIFORM_TEXEL_BUFFER.0)
437 }
438 pub const fn storage_texel_buffer(self) -> Self {
441 Self(self.0 | Self::STORAGE_TEXEL_BUFFER.0)
442 }
443 pub const fn uniform_buffer(self) -> Self {
446 Self(self.0 | Self::UNIFORM_BUFFER.0)
447 }
448 pub const fn storage_buffer(self) -> Self {
451 Self(self.0 | Self::STORAGE_BUFFER.0)
452 }
453 pub const fn index_buffer(self) -> Self {
455 Self(self.0 | Self::INDEX_BUFFER.0)
456 }
457 pub const fn vertex_buffer(self) -> Self {
459 Self(self.0 | Self::VERTEX_BUFFER.0)
460 }
461 pub const fn indirect_buffer(self) -> Self {
464 Self(self.0 | Self::INDIRECT_BUFFER.0)
465 }
466
467 pub const fn merge(self, other: Self) -> Self {
469 Self(self.0 | other.0)
470 }
471
472 pub const fn default_access_mask(self) -> VkAccessFlags {
474 let mut bits = 0;
475 if (self.0 & Self::TRANSFER_SRC.0) != 0 {
476 bits |= VK_ACCESS_TRANSFER_READ_BIT;
477 }
478 if (self.0 & Self::TRANSFER_DEST.0) != 0 {
479 bits |= VK_ACCESS_TRANSFER_WRITE_BIT;
480 }
481 if (self.0 & Self::UNIFORM_TEXEL_BUFFER.0) != 0 {
482 bits |= VK_ACCESS_UNIFORM_READ_BIT;
483 }
484 if (self.0 & Self::STORAGE_TEXEL_BUFFER.0) != 0 {
485 bits |= VK_ACCESS_UNIFORM_READ_BIT;
486 }
487 if (self.0 & Self::UNIFORM_BUFFER.0) != 0 {
488 bits |= VK_ACCESS_UNIFORM_READ_BIT;
489 }
490 if (self.0 & Self::STORAGE_BUFFER.0) != 0 {
491 bits |= VK_ACCESS_UNIFORM_READ_BIT;
492 }
493 if (self.0 & Self::INDEX_BUFFER.0) != 0 {
494 bits |= VK_ACCESS_INDEX_READ_BIT;
495 }
496 if (self.0 & Self::VERTEX_BUFFER.0) != 0 {
497 bits |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
498 }
499 if (self.0 & Self::INDIRECT_BUFFER.0) != 0 {
500 bits |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
501 }
502 bits
503 }
504
505 pub const fn is_uniform(self) -> bool {
507 (self.0 & (Self::UNIFORM_BUFFER.0 | Self::UNIFORM_TEXEL_BUFFER.0)) != 0
508 }
509 pub const fn is_storage(self) -> bool {
511 (self.0 & (Self::STORAGE_BUFFER.0 | Self::STORAGE_TEXEL_BUFFER.0)) != 0
512 }
513}
514impl core::ops::BitOr for BufferUsage {
515 type Output = Self;
516
517 #[inline(always)]
518 fn bitor(self, other: Self) -> Self {
519 BufferUsage(self.0 | other.0)
520 }
521}
522impl core::ops::BitOrAssign for BufferUsage {
523 #[inline(always)]
524 fn bitor_assign(&mut self, other: Self) {
525 self.0 |= other.0;
526 }
527}
528impl From<BufferUsage> for VkBufferUsageFlags {
529 #[inline(always)]
530 fn from(value: BufferUsage) -> Self {
531 value.0
532 }
533}
534
535#[derive(Debug, Clone, Copy, PartialEq, Eq)]
537#[repr(C)]
538pub enum BufferSparseBinding {
539 None = 0,
541 Bound = VK_BUFFER_CREATE_SPARSE_BINDING_BIT as _,
543 Residency = (VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) as _,
545 Aliased = (VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) as _,
548 Both = (VK_BUFFER_CREATE_SPARSE_BINDING_BIT
550 | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT
551 | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) as _,
552}