summaryrefslogtreecommitdiffstats
path: root/wgpu/src/buffer.rs
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-02-06 22:21:27 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-02-24 13:37:30 +0100
commit680ea5dcca37ecf71ab2e5194e907d9414715d22 (patch)
tree690d41d9bd5ef5b40285af75ef930d5088b896ba /wgpu/src/buffer.rs
parentc8befa8d95890eb22972f487e08974e962028eda (diff)
downloadiced-680ea5dcca37ecf71ab2e5194e907d9414715d22.tar.gz
iced-680ea5dcca37ecf71ab2e5194e907d9414715d22.tar.bz2
iced-680ea5dcca37ecf71ab2e5194e907d9414715d22.zip
Refactor `quad::Pipeline` to `prepare` and `render` architecture
Diffstat (limited to 'wgpu/src/buffer.rs')
-rw-r--r--wgpu/src/buffer.rs86
1 files changed, 86 insertions, 0 deletions
diff --git a/wgpu/src/buffer.rs b/wgpu/src/buffer.rs
index 7c092d0b..c210dd4e 100644
--- a/wgpu/src/buffer.rs
+++ b/wgpu/src/buffer.rs
@@ -1,3 +1,89 @@
//! Utilities for buffer operations.
pub mod dynamic;
pub mod r#static;
+
+use std::marker::PhantomData;
+use std::ops::RangeBounds;
+
+#[derive(Debug)]
+pub struct Buffer<T> {
+ label: &'static str,
+ size: u64,
+ usage: wgpu::BufferUsages,
+ raw: wgpu::Buffer,
+ type_: PhantomData<T>,
+}
+
+impl<T: bytemuck::Pod> Buffer<T> {
+ pub fn new(
+ device: &wgpu::Device,
+ label: &'static str,
+ amount: usize,
+ usage: wgpu::BufferUsages,
+ ) -> Self {
+ let size = next_copy_size::<T>(amount);
+
+ let raw = device.create_buffer(&wgpu::BufferDescriptor {
+ label: Some(label),
+ size,
+ usage,
+ mapped_at_creation: false,
+ });
+
+ Self {
+ label,
+ size,
+ usage,
+ raw,
+ type_: PhantomData,
+ }
+ }
+
+ pub fn resize(&mut self, device: &wgpu::Device, new_count: usize) -> bool {
+ let new_size = (std::mem::size_of::<T>() * new_count) as u64;
+
+ if self.size < new_size {
+ self.raw = device.create_buffer(&wgpu::BufferDescriptor {
+ label: Some(self.label),
+ size: new_size,
+ usage: self.usage,
+ mapped_at_creation: false,
+ });
+
+ self.size = new_size;
+
+ true
+ } else {
+ false
+ }
+ }
+
+ pub fn write(
+ &self,
+ queue: &wgpu::Queue,
+ offset_count: usize,
+ contents: &[T],
+ ) {
+ queue.write_buffer(
+ &self.raw,
+ (std::mem::size_of::<T>() * offset_count) as u64,
+ bytemuck::cast_slice(contents),
+ );
+ }
+
+ pub fn slice(
+ &self,
+ bounds: impl RangeBounds<wgpu::BufferAddress>,
+ ) -> wgpu::BufferSlice<'_> {
+ self.raw.slice(bounds)
+ }
+}
+
+fn next_copy_size<T>(amount: usize) -> u64 {
+ let align_mask = wgpu::COPY_BUFFER_ALIGNMENT - 1;
+
+ (((std::mem::size_of::<T>() * amount).next_power_of_two() as u64
+ + align_mask)
+ & !align_mask)
+ .max(wgpu::COPY_BUFFER_ALIGNMENT)
+}