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