1use super::{
2 AlignmentValue, BufferMut, BufferRef, CreateFrom, ReadFrom, Reader, Result, ShaderType,
3 WriteInto, Writer,
4};
5
6pub struct StorageBuffer<B> {
8 inner: B,
9}
10
11impl<B> StorageBuffer<B> {
12 pub const fn new(buffer: B) -> Self {
13 Self { inner: buffer }
14 }
15
16 pub fn into_inner(self) -> B {
17 self.inner
18 }
19
20 pub fn content_of<T, U>(item: &T) -> Result<U>
21 where
22 T: ShaderType + WriteInto,
23 U: BufferMut + Default,
24 {
25 let mut buffer = StorageBuffer::new(U::default());
26 buffer.write(item)?;
27 Ok(buffer.into_inner())
28 }
29}
30
31impl<B> From<B> for StorageBuffer<B> {
32 fn from(buffer: B) -> Self {
33 Self::new(buffer)
34 }
35}
36
37impl<B> AsRef<B> for StorageBuffer<B> {
38 fn as_ref(&self) -> &B {
39 &self.inner
40 }
41}
42
43impl<B> AsMut<B> for StorageBuffer<B> {
44 fn as_mut(&mut self) -> &mut B {
45 &mut self.inner
46 }
47}
48
49impl<B: BufferMut> StorageBuffer<B> {
50 pub fn write<T>(&mut self, value: &T) -> Result<()>
51 where
52 T: ?Sized + ShaderType + WriteInto,
53 {
54 let mut writer = Writer::new(value, &mut self.inner, 0)?;
55 value.write_into(&mut writer);
56 Ok(())
57 }
58}
59
60impl<B: BufferRef> StorageBuffer<B> {
61 pub fn read<T>(&self, value: &mut T) -> Result<()>
62 where
63 T: ?Sized + ShaderType + ReadFrom,
64 {
65 let mut writer = Reader::new::<T>(&self.inner, 0)?;
66 value.read_from(&mut writer);
67 Ok(())
68 }
69
70 pub fn create<T>(&self) -> Result<T>
71 where
72 T: ShaderType + CreateFrom,
73 {
74 let mut writer = Reader::new::<T>(&self.inner, 0)?;
75 Ok(T::create_from(&mut writer))
76 }
77}
78
79pub struct UniformBuffer<B> {
81 inner: StorageBuffer<B>,
82}
83
84impl<B> UniformBuffer<B> {
85 pub const fn new(buffer: B) -> Self {
86 Self {
87 inner: StorageBuffer::new(buffer),
88 }
89 }
90
91 pub fn into_inner(self) -> B {
92 self.inner.inner
93 }
94
95 pub fn content_of<T, U>(item: &T) -> Result<U>
96 where
97 T: ShaderType + WriteInto,
98 U: BufferMut + Default,
99 {
100 let mut buffer = UniformBuffer::new(U::default());
101 buffer.write(item)?;
102 Ok(buffer.into_inner())
103 }
104}
105
106impl<B> From<B> for UniformBuffer<B> {
107 fn from(buffer: B) -> Self {
108 Self::new(buffer)
109 }
110}
111
112impl<B> AsRef<B> for UniformBuffer<B> {
113 fn as_ref(&self) -> &B {
114 &self.inner.inner
115 }
116}
117
118impl<B> AsMut<B> for UniformBuffer<B> {
119 fn as_mut(&mut self) -> &mut B {
120 &mut self.inner.inner
121 }
122}
123
124impl<B: BufferMut> UniformBuffer<B> {
125 pub fn write<T>(&mut self, value: &T) -> Result<()>
126 where
127 T: ?Sized + ShaderType + WriteInto,
128 {
129 T::assert_uniform_compat();
130 self.inner.write(value)
131 }
132}
133
134impl<B: BufferRef> UniformBuffer<B> {
135 pub fn read<T>(&self, value: &mut T) -> Result<()>
136 where
137 T: ?Sized + ShaderType + ReadFrom,
138 {
139 T::assert_uniform_compat();
140 self.inner.read(value)
141 }
142
143 pub fn create<T>(&self) -> Result<T>
144 where
145 T: ShaderType + CreateFrom,
146 {
147 T::assert_uniform_compat();
148 self.inner.create()
149 }
150}
151
152pub struct DynamicStorageBuffer<B> {
154 inner: B,
155 alignment: AlignmentValue,
156 offset: usize,
157}
158
159impl<B> DynamicStorageBuffer<B> {
160 pub const fn new(buffer: B) -> Self {
163 Self::new_with_alignment(buffer, 256)
164 }
165
166 pub const fn new_with_alignment(buffer: B, alignment: u64) -> Self {
172 if alignment < 32 {
173 panic!("Alignment must be at least 32!");
174 }
175 Self {
176 inner: buffer,
177 alignment: AlignmentValue::new(alignment),
178 offset: 0,
179 }
180 }
181
182 pub fn set_offset(&mut self, offset: u64) {
183 if !self.alignment.is_aligned(offset) {
184 panic!(
185 "offset of {} bytes is not aligned to alignment of {} bytes",
186 offset,
187 self.alignment.get()
188 );
189 }
190
191 self.offset = offset as usize;
192 }
193
194 pub fn into_inner(self) -> B {
195 self.inner
196 }
197}
198
199impl<B> From<B> for DynamicStorageBuffer<B> {
200 fn from(buffer: B) -> Self {
201 Self::new(buffer)
202 }
203}
204
205impl<B> AsRef<B> for DynamicStorageBuffer<B> {
206 fn as_ref(&self) -> &B {
207 &self.inner
208 }
209}
210
211impl<B> AsMut<B> for DynamicStorageBuffer<B> {
212 fn as_mut(&mut self) -> &mut B {
213 &mut self.inner
214 }
215}
216
217impl<B: BufferMut> DynamicStorageBuffer<B> {
218 pub fn write<T>(&mut self, value: &T) -> Result<u64>
219 where
220 T: ?Sized + ShaderType + WriteInto,
221 {
222 let offset = self.offset;
223
224 let mut writer = Writer::new(value, &mut self.inner, offset)?;
225 value.write_into(&mut writer);
226
227 self.offset += self.alignment.round_up(value.size().get()) as usize;
228
229 Ok(offset as u64)
230 }
231}
232
233impl<B: BufferRef> DynamicStorageBuffer<B> {
234 pub fn read<T>(&mut self, value: &mut T) -> Result<()>
235 where
236 T: ?Sized + ShaderType + ReadFrom,
237 {
238 let mut writer = Reader::new::<T>(&self.inner, self.offset)?;
239 value.read_from(&mut writer);
240
241 self.offset += self.alignment.round_up(value.size().get()) as usize;
242
243 Ok(())
244 }
245
246 pub fn create<T>(&mut self) -> Result<T>
247 where
248 T: ShaderType + CreateFrom,
249 {
250 let mut writer = Reader::new::<T>(&self.inner, self.offset)?;
251 let value = T::create_from(&mut writer);
252
253 self.offset += self.alignment.round_up(value.size().get()) as usize;
254
255 Ok(value)
256 }
257}
258
259pub struct DynamicUniformBuffer<B> {
261 inner: DynamicStorageBuffer<B>,
262}
263
264impl<B> DynamicUniformBuffer<B> {
265 pub const fn new(buffer: B) -> Self {
268 Self {
269 inner: DynamicStorageBuffer::new(buffer),
270 }
271 }
272
273 pub const fn new_with_alignment(buffer: B, alignment: u64) -> Self {
279 Self {
280 inner: DynamicStorageBuffer::new_with_alignment(buffer, alignment),
281 }
282 }
283
284 pub fn set_offset(&mut self, offset: u64) {
285 self.inner.set_offset(offset);
286 }
287
288 pub fn into_inner(self) -> B {
289 self.inner.inner
290 }
291}
292
293impl<B> From<B> for DynamicUniformBuffer<B> {
294 fn from(buffer: B) -> Self {
295 Self::new(buffer)
296 }
297}
298
299impl<B> AsRef<B> for DynamicUniformBuffer<B> {
300 fn as_ref(&self) -> &B {
301 &self.inner.inner
302 }
303}
304
305impl<B> AsMut<B> for DynamicUniformBuffer<B> {
306 fn as_mut(&mut self) -> &mut B {
307 &mut self.inner.inner
308 }
309}
310
311impl<B: BufferMut> DynamicUniformBuffer<B> {
312 pub fn write<T>(&mut self, value: &T) -> Result<u64>
313 where
314 T: ?Sized + ShaderType + WriteInto,
315 {
316 T::assert_uniform_compat();
317 self.inner.write(value)
318 }
319}
320
321impl<B: BufferRef> DynamicUniformBuffer<B> {
322 pub fn read<T>(&mut self, value: &mut T) -> Result<()>
323 where
324 T: ?Sized + ShaderType + ReadFrom,
325 {
326 T::assert_uniform_compat();
327 self.inner.read(value)
328 }
329
330 pub fn create<T>(&mut self) -> Result<T>
331 where
332 T: ShaderType + CreateFrom,
333 {
334 T::assert_uniform_compat();
335 self.inner.create()
336 }
337}