summaryrefslogtreecommitdiffstats
path: root/wgpu/src/buffer
diff options
context:
space:
mode:
Diffstat (limited to 'wgpu/src/buffer')
-rw-r--r--wgpu/src/buffer/dynamic.rs202
-rw-r--r--wgpu/src/buffer/static.rs107
2 files changed, 0 insertions, 309 deletions
diff --git a/wgpu/src/buffer/dynamic.rs b/wgpu/src/buffer/dynamic.rs
deleted file mode 100644
index 43fc47ac..00000000
--- a/wgpu/src/buffer/dynamic.rs
+++ /dev/null
@@ -1,202 +0,0 @@
-//! Utilities for uniform buffer operations.
-use encase::private::WriteInto;
-use encase::ShaderType;
-
-use std::fmt;
-use std::marker::PhantomData;
-
-/// A dynamic buffer is any type of buffer which does not have a static offset.
-#[derive(Debug)]
-pub struct Buffer<T: ShaderType> {
- offsets: Vec<wgpu::DynamicOffset>,
- cpu: Internal,
- gpu: wgpu::Buffer,
- label: &'static str,
- size: u64,
- _data: PhantomData<T>,
-}
-
-impl<T: ShaderType + WriteInto> Buffer<T> {
- /// Creates a new dynamic uniform buffer.
- pub fn uniform(device: &wgpu::Device, label: &'static str) -> Self {
- Buffer::new(
- device,
- Internal::Uniform(encase::DynamicUniformBuffer::new(Vec::new())),
- label,
- wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
- )
- }
-
- #[cfg(not(target_arch = "wasm32"))]
- /// Creates a new dynamic storage buffer.
- pub fn storage(device: &wgpu::Device, label: &'static str) -> Self {
- Buffer::new(
- device,
- Internal::Storage(encase::DynamicStorageBuffer::new(Vec::new())),
- label,
- wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST,
- )
- }
-
- fn new(
- device: &wgpu::Device,
- dynamic_buffer_type: Internal,
- label: &'static str,
- usage: wgpu::BufferUsages,
- ) -> Self {
- let initial_size = u64::from(T::min_size());
-
- Self {
- offsets: Vec::new(),
- cpu: dynamic_buffer_type,
- gpu: Buffer::<T>::create_gpu_buffer(
- device,
- label,
- usage,
- initial_size,
- ),
- label,
- size: initial_size,
- _data: Default::default(),
- }
- }
-
- fn create_gpu_buffer(
- device: &wgpu::Device,
- label: &'static str,
- usage: wgpu::BufferUsages,
- size: u64,
- ) -> wgpu::Buffer {
- device.create_buffer(&wgpu::BufferDescriptor {
- label: Some(label),
- size,
- usage,
- mapped_at_creation: false,
- })
- }
-
- /// Write a new value to the CPU buffer with proper alignment. Stores the returned offset value
- /// in the buffer for future use.
- pub fn push(&mut self, value: &T) {
- //this write operation on the cpu buffer will adjust for uniform alignment requirements
- let offset = self.cpu.write(value);
- self.offsets.push(offset);
- }
-
- /// Resize buffer contents if necessary. This will re-create the GPU buffer if current size is
- /// less than the newly computed size from the CPU buffer.
- ///
- /// If the gpu buffer is resized, its bind group will need to be recreated!
- pub fn resize(&mut self, device: &wgpu::Device) -> bool {
- let new_size = self.cpu.get_ref().len() as u64;
-
- if self.size < new_size {
- let usages = match self.cpu {
- Internal::Uniform(_) => {
- wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST
- }
- #[cfg(not(target_arch = "wasm32"))]
- Internal::Storage(_) => {
- wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST
- }
- };
-
- self.gpu = Buffer::<T>::create_gpu_buffer(
- device, self.label, usages, new_size,
- );
- self.size = new_size;
- true
- } else {
- false
- }
- }
-
- /// Write the contents of this dynamic buffer to the GPU via staging belt command.
- pub fn write(&mut self, queue: &wgpu::Queue) {
- queue.write_buffer(&self.gpu, 0, self.cpu.get_ref());
- }
-
- // Gets the aligned offset at the given index from the CPU buffer.
- pub fn offset_at_index(&self, index: usize) -> wgpu::DynamicOffset {
- let offset = self
- .offsets
- .get(index)
- .copied()
- .expect("Index not found in offsets.");
-
- offset
- }
-
- /// Returns a reference to the GPU buffer.
- pub fn raw(&self) -> &wgpu::Buffer {
- &self.gpu
- }
-
- /// Reset the buffer.
- pub fn clear(&mut self) {
- self.offsets.clear();
- self.cpu.clear();
- }
-}
-
-// Currently supported dynamic buffers.
-enum Internal {
- Uniform(encase::DynamicUniformBuffer<Vec<u8>>),
- #[cfg(not(target_arch = "wasm32"))]
- //storage buffers are not supported on wgpu wasm target (yet)
- Storage(encase::DynamicStorageBuffer<Vec<u8>>),
-}
-
-impl Internal {
- /// Writes the current value to its CPU buffer with proper alignment.
- pub(super) fn write<T: ShaderType + WriteInto>(
- &mut self,
- value: &T,
- ) -> wgpu::DynamicOffset {
- match self {
- Internal::Uniform(buf) => buf
- .write(value)
- .expect("Error when writing to dynamic uniform buffer.")
- as u32,
- #[cfg(not(target_arch = "wasm32"))]
- Internal::Storage(buf) => buf
- .write(value)
- .expect("Error when writing to dynamic storage buffer.")
- as u32,
- }
- }
-
- /// Returns bytearray of aligned CPU buffer.
- pub(super) fn get_ref(&self) -> &[u8] {
- match self {
- Internal::Uniform(buf) => buf.as_ref(),
- #[cfg(not(target_arch = "wasm32"))]
- Internal::Storage(buf) => buf.as_ref(),
- }
- }
-
- /// Resets the CPU buffer.
- pub(super) fn clear(&mut self) {
- match self {
- Internal::Uniform(buf) => {
- buf.as_mut().clear();
- buf.set_offset(0);
- }
- #[cfg(not(target_arch = "wasm32"))]
- Internal::Storage(buf) => {
- buf.as_mut().clear();
- buf.set_offset(0);
- }
- }
- }
-}
-
-impl fmt::Debug for Internal {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Self::Uniform(_) => write!(f, "Internal::Uniform(_)"),
- #[cfg(not(target_arch = "wasm32"))]
- Self::Storage(_) => write!(f, "Internal::Storage(_)"),
- }
- }
-}
diff --git a/wgpu/src/buffer/static.rs b/wgpu/src/buffer/static.rs
deleted file mode 100644
index d8ae116e..00000000
--- a/wgpu/src/buffer/static.rs
+++ /dev/null
@@ -1,107 +0,0 @@
-use bytemuck::{Pod, Zeroable};
-use std::marker::PhantomData;
-use std::mem;
-
-const DEFAULT_COUNT: wgpu::BufferAddress = 128;
-
-/// A generic buffer struct useful for items which have no alignment requirements
-/// (e.g. Vertex, Index buffers) & no dynamic offsets.
-#[derive(Debug)]
-pub struct Buffer<T> {
- //stored sequentially per mesh iteration; refers to the offset index in the GPU buffer
- offsets: Vec<wgpu::BufferAddress>,
- label: &'static str,
- usages: wgpu::BufferUsages,
- gpu: wgpu::Buffer,
- size: wgpu::BufferAddress,
- _data: PhantomData<T>,
-}
-
-impl<T: Pod + Zeroable> Buffer<T> {
- /// Initialize a new static buffer.
- pub fn new(
- device: &wgpu::Device,
- label: &'static str,
- usages: wgpu::BufferUsages,
- ) -> Self {
- let size = (mem::size_of::<T>() as u64) * DEFAULT_COUNT;
-
- Self {
- offsets: Vec::new(),
- label,
- usages,
- gpu: Self::gpu_buffer(device, label, size, usages),
- size,
- _data: PhantomData,
- }
- }
-
- fn gpu_buffer(
- device: &wgpu::Device,
- label: &'static str,
- size: wgpu::BufferAddress,
- usage: wgpu::BufferUsages,
- ) -> wgpu::Buffer {
- device.create_buffer(&wgpu::BufferDescriptor {
- label: Some(label),
- size,
- usage,
- mapped_at_creation: false,
- })
- }
-
- /// Returns whether or not the buffer needs to be recreated. This can happen whenever mesh data
- /// changes & a redraw is requested.
- pub fn resize(&mut self, device: &wgpu::Device, new_count: usize) -> bool {
- let size = (mem::size_of::<T>() * new_count) as u64;
-
- if self.size < size {
- self.size =
- (mem::size_of::<T>() * (new_count + new_count / 2)) as u64;
-
- self.gpu =
- Self::gpu_buffer(device, self.label, self.size, self.usages);
-
- self.offsets.clear();
- true
- } else {
- false
- }
- }
-
- /// Writes the current vertex data to the gpu buffer with a memcpy & stores its offset.
- ///
- /// Returns the size of the written bytes.
- pub fn write(
- &mut self,
- queue: &wgpu::Queue,
- offset: u64,
- content: &[T],
- ) -> u64 {
- let bytes = bytemuck::cast_slice(content);
- let bytes_size = bytes.len() as u64;
-
- queue.write_buffer(&self.gpu, offset, bytes);
- self.offsets.push(offset);
-
- bytes_size
- }
-
- fn offset_at(&self, index: usize) -> &wgpu::BufferAddress {
- self.offsets
- .get(index)
- .expect("Offset at index does not exist.")
- }
-
- /// Returns the slice calculated from the offset stored at the given index.
- /// e.g. to calculate the slice for the 2nd mesh in the layer, this would be the offset at index
- /// 1 that we stored earlier when writing.
- pub fn slice_from_index(&self, index: usize) -> wgpu::BufferSlice<'_> {
- self.gpu.slice(self.offset_at(index)..)
- }
-
- /// Clears any temporary data from the buffer.
- pub fn clear(&mut self) {
- self.offsets.clear()
- }
-}