1pub use rendy_core::hal::buffer::*;
4
5use {
6 crate::{
7 core::{device_owned, Device, DeviceId},
8 memory::{Block, Heaps, MappedRange, MemoryBlock, MemoryUsage},
9 CreationError,
10 },
11 relevant::Relevant,
12 rendy_core::hal::{device::Device as _, Backend},
13};
14
15#[derive(Clone, Copy, Debug)]
17pub struct BufferInfo {
18 pub size: u64,
20
21 pub usage: Usage,
23}
24
25#[derive(Debug)]
31pub struct Buffer<B: Backend> {
32 device: DeviceId,
33 raw: B::Buffer,
34 block: MemoryBlock<B>,
35 info: BufferInfo,
36 relevant: Relevant,
37}
38
39device_owned!(Buffer<B>);
40pub type BufferCreationError = CreationError<rendy_core::hal::buffer::CreationError>;
42
43impl<B> Buffer<B>
44where
45 B: Backend,
46{
47 pub unsafe fn create(
57 device: &Device<B>,
58 heaps: &mut Heaps<B>,
59 info: BufferInfo,
60 memory_usage: impl MemoryUsage,
61 ) -> Result<Self, BufferCreationError> {
62 log::trace!("{:#?}@{:#?}", info, memory_usage);
63 assert_ne!(info.size, 0);
64
65 let mut buf = device
66 .create_buffer(info.size, info.usage)
67 .map_err(CreationError::Create)?;
68 let reqs = device.get_buffer_requirements(&buf);
69 let block = heaps
70 .allocate(
71 device,
72 reqs.type_mask as u32,
73 memory_usage,
74 reqs.size,
75 reqs.alignment,
76 )
77 .map_err(CreationError::Allocate)?;
78
79 device
80 .bind_buffer_memory(block.memory(), block.range().start, &mut buf)
81 .map_err(CreationError::Bind)?;
82
83 Ok(Buffer {
84 device: device.id(),
85 raw: buf,
86 block,
87 info,
88 relevant: Relevant,
89 })
90 }
91
92 pub unsafe fn dispose(self, device: &Device<B>, heaps: &mut Heaps<B>) {
95 self.assert_device_owner(device);
96 device.destroy_buffer(self.raw);
97 heaps.free(device, self.block);
98 self.relevant.dispose();
99 }
100
101 pub fn raw(&self) -> &B::Buffer {
103 &self.raw
104 }
105
106 pub unsafe fn raw_mut(&mut self) -> &mut B::Buffer {
108 &mut self.raw
109 }
110
111 pub fn block(&self) -> &MemoryBlock<B> {
113 &self.block
114 }
115
116 pub unsafe fn block_mut(&mut self) -> &mut MemoryBlock<B> {
118 &mut self.block
119 }
120
121 pub fn info(&self) -> &BufferInfo {
123 &self.info
124 }
125
126 pub fn visible(&self) -> bool {
132 self.block
133 .properties()
134 .contains(rendy_core::hal::memory::Properties::CPU_VISIBLE)
135 }
136
137 pub fn map<'a>(
139 &'a mut self,
140 device: &Device<B>,
141 range: std::ops::Range<u64>,
142 ) -> Result<MappedRange<'a, B>, rendy_core::hal::device::MapError> {
143 self.block.map(device, range)
144 }
145
146 pub fn size(&self) -> u64 {
148 self.info().size
149 }
150}