ascending_graphics/systems/buffer.rs
1use crate::GpuDevice;
2use std::{marker::PhantomData, ops::Range};
3use wgpu::{Queue, util::DeviceExt};
4
5/// BufferStore is Storage used to hold and modify the byte arrays that get sent to the GPU.
6///
7#[derive(Default, Debug)]
8pub struct BufferStore {
9 /// Storage used for Vertex or Indicies.
10 pub store: Vec<u8>,
11 /// Storage used for index's
12 pub indexs: Vec<u8>,
13 /// Boolean used to deturmine if it got changed to tell
14 /// the system if we need to reupload the data to the gpu.
15 pub changed: bool,
16 /// Location Range within GPU this is Stored At
17 /// if this does not match the current location internally we will resend
18 /// the data to the gpu at the new location.
19 pub store_pos: Range<usize>,
20 /// Location Range within GPU this is Stored At
21 /// if this does not match the current location internally we will resend
22 /// the data to the gpu at the new location.
23 pub index_pos: Range<usize>,
24}
25
26impl BufferStore {
27 /// Used to create a [`BufferStore`].
28 ///
29 /// # Arguments
30 /// - store_size: Preset and filled Size of the buffer to avoid reallocating.
31 /// - index_size: Preset and filled Size of the buffer to avoid reallocating.
32 ///
33 pub fn new(store_size: usize, index_size: usize) -> Self {
34 let mut store = Vec::with_capacity(store_size);
35 let mut indexs = Vec::with_capacity(index_size);
36
37 store.resize_with(store_size, || 0);
38 indexs.resize_with(index_size, || 0);
39
40 Self {
41 store,
42 indexs,
43 changed: false,
44 store_pos: Range::default(),
45 index_pos: Range::default(),
46 }
47 }
48}
49
50/// Pass of Data from a Vertex or Static Vertex used to Set the
51/// renderers Vertex and Index buffer Objects.
52///
53pub struct BufferPass<'a> {
54 pub vertex_buffer: &'a wgpu::Buffer,
55 pub index_buffer: &'a wgpu::Buffer,
56}
57
58/// Trait used to create Passing [`BufferPass`] from their Structs.
59pub trait AsBufferPass<'a> {
60 /// Creates a [`BufferPass`] from the Holding Object.
61 fn as_buffer_pass(&'a self) -> BufferPass<'a>;
62}
63
64/// Hold for the Layouts in memory version of Vertex's, indices or Index's.
65/// Data of Each object within the same Layout.
66///
67#[derive(Default)]
68pub struct BufferData {
69 pub vertexs: Vec<u8>,
70 pub indexs: Vec<u8>,
71}
72
73/// GPU Buffer Management Struct. Used to keep track of Counts, Length and The Buffer in the GPU.
74///
75#[derive(Debug)]
76pub struct Buffer<K: BufferLayout> {
77 pub buffer: wgpu::Buffer,
78 pub count: usize,
79 pub len: usize,
80 pub max: usize,
81 phantom_data: PhantomData<K>,
82}
83
84impl<K: BufferLayout> Buffer<K> {
85 /// Used to create a [`Buffer`].
86 ///
87 /// # Arguments
88 /// - contents: The contents to Create the Buffer with.
89 /// - usage: wgpu usage flags [`wgpu::BufferUsages`]
90 /// - label: Label to be seen in GPU debugging.
91 ///
92 pub fn new(
93 gpu_device: &GpuDevice,
94 contents: &[u8],
95 usage: wgpu::BufferUsages,
96 label: Option<&str>,
97 ) -> Self {
98 Self {
99 buffer: gpu_device.device().create_buffer_init(
100 &wgpu::util::BufferInitDescriptor {
101 label,
102 contents,
103 usage,
104 },
105 ),
106 count: 0,
107 len: 0,
108 max: contents.len(),
109 phantom_data: PhantomData,
110 }
111 }
112
113 /// Writes Data into the Buffer from its Position.
114 ///
115 /// # Panics
116 /// - This method fails if data overruns the size of buffer starting at pos.
117 ///
118 /// # Arguments
119 /// - data: the contents to write to the Buffer.
120 /// - pos: Position to write to the buffer from.
121 ///
122 pub fn write(&self, queue: &Queue, data: &[u8], pos: u64) {
123 if !data.is_empty() {
124 queue.write_buffer(&self.buffer, pos, data);
125 }
126 }
127
128 /// If the buffer len is empty.
129 ///
130 pub fn is_empty(&self) -> bool {
131 self.len == 0
132 }
133
134 /// Returns a [`wgpu::BufferSlice`] of the buffer to hand off to the GPU.
135 ///
136 pub fn buffer_slice(&self, range: Range<u64>) -> wgpu::BufferSlice<'_> {
137 self.buffer.slice(range)
138 }
139}
140
141pub trait BufferLayout {
142 ///WGPU's Shader Attributes
143 fn attributes() -> Vec<wgpu::VertexAttribute>;
144
145 ///Default Buffer set to a large size.
146 fn default_buffer() -> BufferData;
147
148 ///The size in bytes the vertex is
149 fn stride() -> usize;
150
151 /// Creates a Buffer at a capacity
152 /// Capacity is a count of objects.
153 fn with_capacity(
154 vertex_capacity: usize,
155 index_capacity: usize,
156 ) -> BufferData;
157}