2021-10-07 19:24:48 +00:00
|
|
|
use crate::{
|
|
|
|
render_resource::Buffer,
|
|
|
|
renderer::{RenderDevice, RenderQueue},
|
|
|
|
};
|
2021-05-30 22:54:48 +00:00
|
|
|
use bevy_core::{cast_slice, Pod};
|
2021-10-08 19:55:24 +00:00
|
|
|
use wgpu::BufferUsages;
|
2021-04-11 20:13:07 +00:00
|
|
|
|
|
|
|
pub struct BufferVec<T: Pod> {
|
|
|
|
values: Vec<T>,
|
2021-06-21 23:28:52 +00:00
|
|
|
buffer: Option<Buffer>,
|
2021-04-11 20:13:07 +00:00
|
|
|
capacity: usize,
|
|
|
|
item_size: usize,
|
2021-10-08 19:55:24 +00:00
|
|
|
buffer_usage: BufferUsages,
|
2021-04-11 20:13:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Pod> Default for BufferVec<T> {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
|
|
|
values: Vec::new(),
|
|
|
|
buffer: None,
|
|
|
|
capacity: 0,
|
2021-10-08 19:55:24 +00:00
|
|
|
buffer_usage: BufferUsages::all(),
|
2021-04-11 20:13:07 +00:00
|
|
|
item_size: std::mem::size_of::<T>(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Pod> BufferVec<T> {
|
2021-10-08 19:55:24 +00:00
|
|
|
pub fn new(buffer_usage: BufferUsages) -> Self {
|
2021-04-11 20:13:07 +00:00
|
|
|
Self {
|
|
|
|
buffer_usage,
|
|
|
|
..Default::default()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2021-06-21 23:28:52 +00:00
|
|
|
pub fn buffer(&self) -> Option<&Buffer> {
|
|
|
|
self.buffer.as_ref()
|
2021-04-11 20:13:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn capacity(&self) -> usize {
|
|
|
|
self.capacity
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn push(&mut self, value: T) -> usize {
|
2021-10-07 19:24:48 +00:00
|
|
|
let len = self.values.len();
|
|
|
|
if len < self.capacity {
|
2021-04-11 20:13:07 +00:00
|
|
|
self.values.push(value);
|
2021-10-07 19:24:48 +00:00
|
|
|
len
|
2021-04-11 20:13:07 +00:00
|
|
|
} else {
|
|
|
|
panic!(
|
|
|
|
"Cannot push value because capacity of {} has been reached",
|
|
|
|
self.capacity
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-21 23:28:52 +00:00
|
|
|
pub fn reserve(&mut self, capacity: usize, device: &RenderDevice) {
|
2021-04-11 20:13:07 +00:00
|
|
|
if capacity > self.capacity {
|
|
|
|
self.capacity = capacity;
|
2021-10-07 19:24:48 +00:00
|
|
|
let size = self.item_size * capacity;
|
2021-06-21 23:28:52 +00:00
|
|
|
self.buffer = Some(device.create_buffer(&wgpu::BufferDescriptor {
|
|
|
|
label: None,
|
2021-10-07 19:24:48 +00:00
|
|
|
size: size as wgpu::BufferAddress,
|
2021-10-08 19:55:24 +00:00
|
|
|
usage: BufferUsages::COPY_DST | self.buffer_usage,
|
2021-04-11 20:13:07 +00:00
|
|
|
mapped_at_creation: false,
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-21 23:28:52 +00:00
|
|
|
pub fn reserve_and_clear(&mut self, capacity: usize, device: &RenderDevice) {
|
2021-04-11 20:13:07 +00:00
|
|
|
self.clear();
|
2021-06-21 23:28:52 +00:00
|
|
|
self.reserve(capacity, device);
|
2021-04-11 20:13:07 +00:00
|
|
|
}
|
|
|
|
|
2021-10-07 19:24:48 +00:00
|
|
|
pub fn write_buffer(&mut self, queue: &RenderQueue) {
|
|
|
|
if let Some(buffer) = &self.buffer {
|
|
|
|
let range = 0..self.item_size * self.values.len();
|
|
|
|
let bytes: &[u8] = cast_slice(&self.values);
|
|
|
|
queue.write_buffer(buffer, 0, &bytes[range]);
|
2021-04-11 20:13:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn clear(&mut self) {
|
|
|
|
self.values.clear();
|
|
|
|
}
|
|
|
|
}
|