srs2dge_core/buffer/
mod.rs1use crate::{label, target::Target, Frame};
2use bytemuck::Pod;
3use std::{marker::PhantomData, mem, num::NonZeroU64, ops::RangeBounds};
4use wgpu::{
5 util::{BufferInitDescriptor, DeviceExt},
6 BufferAddress, BufferDescriptor, BufferUsages,
7};
8
9pub use index::*;
12pub use indirect::*;
13pub use uniform::*;
14pub use vertex::*;
15
16pub mod index;
19pub mod indirect;
20pub mod prelude;
21pub mod uniform;
22pub mod vertex;
23
24#[derive(Debug)]
27pub struct Buffer<T, const USAGE: u32> {
28 buffer: wgpu::Buffer,
29 elements: usize,
30 _p: PhantomData<T>,
31}
32
33#[derive(Debug, Clone, Copy)]
34pub struct BufferSlice<'b, T, const USAGE: u32> {
35 slice: wgpu::BufferSlice<'b>,
36 _p: PhantomData<T>,
37}
38
39impl<T, const USAGE: u32> Buffer<T, USAGE>
42where
43 T: Pod,
44{
45 pub fn new_with(target: &Target, data: &[T]) -> Self {
46 let buffer = target.device.create_buffer_init(&BufferInitDescriptor {
47 label: label!(),
48 usage: BufferUsages::from_bits_truncate(USAGE),
49 contents: bytemuck::cast_slice(data),
50 });
51
52 Self::with_buffer(buffer, data.len())
53 }
54
55 pub fn new_single(target: &Target, data: T) -> Self {
56 let buffer = target.device.create_buffer_init(&BufferInitDescriptor {
57 label: label!(),
58 usage: BufferUsages::from_bits_truncate(USAGE),
59 contents: bytemuck::cast_slice(&[data]),
60 });
61
62 Self::with_buffer(buffer, 1)
63 }
64
65 pub fn upload(&self, target: &mut Target, frame: &mut Frame, new_data: &[T]) {
66 let mut mapping = frame.write_buffer(
67 &self.buffer,
68 0,
69 NonZeroU64::new(Self::size_of(self.elements) as _).unwrap(),
70 &target.device,
71 );
72
73 let new_data = bytemuck::cast_slice(new_data);
74 mapping[..new_data.len()].copy_from_slice(new_data);
75 }
76}
77
78impl<T, const USAGE: u32> Buffer<T, USAGE>
79where
80 T: Pod,
81{
82 pub fn new(target: &Target, elements: usize) -> Self {
83 let buffer = target.device.create_buffer(&BufferDescriptor {
84 label: label!(),
85 size: Self::size_of(elements) as _,
86 usage: BufferUsages::from_bits_truncate(USAGE),
87 mapped_at_creation: false,
88 });
89
90 Self::with_buffer(buffer, elements)
91 }
92
93 pub fn inner(&self) -> &wgpu::Buffer {
94 &self.buffer
95 }
96
97 pub fn capacity(&self) -> usize {
98 self.elements
99 }
100
101 pub fn slice<S>(&self, range: S) -> BufferSlice<T, USAGE>
102 where
103 S: RangeBounds<BufferAddress>,
104 {
105 BufferSlice {
106 slice: self.buffer.slice(range),
107 _p: PhantomData::default(),
108 }
109 }
110
111 fn with_buffer(buffer: wgpu::Buffer, elements: usize) -> Self {
112 Self {
113 buffer,
114 elements,
115 _p: Default::default(),
116 }
117 }
118
119 fn size_of(elements: usize) -> usize {
120 mem::size_of::<T>() * elements
121 }
122}
123
124impl<'b, T, const USAGE: u32> BufferSlice<'b, T, USAGE> {
125 pub fn inner(&self) -> wgpu::BufferSlice {
126 self.slice
127 }
128}
129
130pub trait AsBufferSlice<T, const USAGE: u32> {
133 fn as_slice(&self) -> BufferSlice<T, USAGE>;
134}
135
136impl<T, const USAGE: u32> AsBufferSlice<T, USAGE> for Buffer<T, USAGE>
139where
140 T: Pod,
141{
142 fn as_slice(&self) -> BufferSlice<T, USAGE> {
143 self.slice(..)
144 }
145}
146
147impl<'b, T, const USAGE: u32> AsBufferSlice<T, USAGE> for BufferSlice<'b, T, USAGE>
148where
149 T: Pod,
150{
151 fn as_slice(&self) -> Self {
152 *self
153 }
154}