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