voodoo/
buffer.rs

1use std::sync::Arc;
2use std::marker::PhantomData;
3use vks;
4use ::{VdResult, Device, DeviceMemory, Handle};
5
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8#[repr(C)]
9pub struct BufferHandle(pub(crate) vks::VkBuffer);
10
11impl BufferHandle {
12    pub fn to_raw(&self) -> vks::VkBuffer {
13        self.0
14    }
15}
16
17unsafe impl Handle for BufferHandle {
18    type Target = BufferHandle;
19
20    #[inline(always)]
21    fn handle(&self) -> Self::Target {
22        *self
23    }
24}
25
26
27#[derive(Debug)]
28struct Inner {
29    handle: BufferHandle,
30    memory_requirements: ::MemoryRequirements,
31    device: Device,
32}
33
34impl Drop for Inner {
35    fn drop(&mut self) {
36        unsafe {
37            self.device.destroy_buffer(self.handle, None);
38        }
39    }
40}
41
42
43/// A buffer.
44///
45///
46/// ### Destruction
47/// 
48/// Dropping this `Buffer` will cause `Device::destroy_buffer` to be called, 
49/// automatically releasing any resources associated with it.
50///
51#[derive(Debug, Clone)]
52pub struct Buffer {
53    inner: Arc<Inner>,
54}
55
56impl Buffer {
57    /// Returns a new `BufferBuilder`.
58    pub fn builder<'b>() -> BufferBuilder<'b> {
59        BufferBuilder::new()
60    }
61
62    /// Returns this object's handle.
63    pub fn handle(&self) -> BufferHandle {
64        self.inner.handle
65    }
66
67    /// Returns this buffer's memory requirements.
68    pub fn memory_requirements(&self) -> &::MemoryRequirements {
69        &self.inner.memory_requirements
70    }
71
72    /// Binds this buffer to device memory. `offset` is the start offset of the
73    /// region of memory which is to be bound. The number of bytes returned in
74    /// the VkMemoryRequirements::size member in memory, starting from
75    /// memoryOffset bytes, will be bound to the specified buffer.
76    ///
77    /// ## Safety
78    ///
79    /// The caller must ensure that the bound memory is not in use when it is
80    /// dropped.
81    ///
82    pub unsafe fn bind_memory(&self, memory: &DeviceMemory, offset: ::DeviceSize)
83            -> VdResult<()> {
84        self.inner.device.bind_buffer_memory(self.inner.handle, memory.handle(), offset)
85    }
86
87    /// Returns a reference to the associated device.
88    pub fn device(&self) -> &Device {
89        &self.inner.device
90    }
91}
92
93unsafe impl<'b> Handle for &'b Buffer {
94    type Target = BufferHandle;
95
96    #[inline(always)]
97    fn handle(&self) -> Self::Target {
98        self.inner.handle
99    }
100}
101
102
103/// A builder for `Buffer`.
104#[derive(Debug, Clone)]
105pub struct BufferBuilder<'b> {
106    create_info: ::BufferCreateInfo<'b>,
107    _p: PhantomData<&'b ()>,
108}
109
110impl<'b> BufferBuilder<'b> {
111    /// Returns a new render pass builder.
112    pub fn new() -> BufferBuilder<'b> {
113        BufferBuilder {
114            create_info: ::BufferCreateInfo::default(),
115            _p: PhantomData,
116        }
117    }
118
119    /// Specifies additional parameters of the buffer.
120    pub fn flags<'s>(&'s mut self, flags: ::BufferCreateFlags)
121            -> &'s mut BufferBuilder<'b> {
122        self.create_info.set_flags(flags);
123        self
124    }
125
126    /// Specifies the size in bytes of the buffer to be created.
127    pub fn size<'s>(&'s mut self, size: ::DeviceSize)
128            -> &'s mut BufferBuilder<'b> {
129        self.create_info.set_size(size);
130        self
131    }
132
133    /// Specifies allowed usages of the buffer.
134    pub fn usage<'s>(&'s mut self, usage: ::BufferUsageFlags)
135            -> &'s mut BufferBuilder<'b> {
136        self.create_info.set_usage(usage);
137        self
138    }
139
140    /// Specifies the sharing mode of the buffer when it will be accessed by
141    /// multiple queue families.
142    pub fn sharing_mode<'s>(&'s mut self, sharing_mode: ::SharingMode)
143            -> &'s mut BufferBuilder<'b> {
144        self.create_info.set_sharing_mode(sharing_mode);
145        self
146    }
147
148    /// Specifies a list of queue families that will access this buffer
149    /// (ignored if sharing_mode is not VK_SHARING_MODE_CONCURRENT).
150    pub fn queue_family_indices<'s, 'p>(&'s mut self, queue_family_indices: &'p [u32])
151            -> &'s mut BufferBuilder<'b>
152            where 'p: 'b {
153        self.create_info.set_queue_family_indices(queue_family_indices);
154        self
155    }
156
157    /// Creates and returns a new `Buffer`
158    pub fn build(&self, device: Device) -> VdResult<Buffer> {
159        let handle = unsafe { device.create_buffer(&self.create_info, None)? };
160        let memory_requirements = unsafe { device.get_buffer_memory_requirements(handle) };
161
162        Ok(Buffer {
163            inner: Arc::new(Inner {
164                handle,
165                device,
166                memory_requirements,
167            })
168        })
169    }
170}