Skip to main content

steamengine_renderer_util/
simple_buffer.rs

1use std::sync::Arc;
2use steamengine_renderer::Renderer;
3use tracing::*;
4use wgpu::Buffer;
5use wgpu::BufferUsages;
6use wgpu::util::DrawIndexedIndirectArgs;
7
8/// Abstraction of a buffer
9pub trait SimpleBuffer<'a, T: bytemuck::NoUninit> {
10    /// create a new buffer with limit of objects inside the buffer
11    /// limit = size_of<T>() * limit;
12    fn new(renderer: Arc<Renderer<'a>>, limit: u64) -> Self;
13    /// Sets a unic entry inside the buffer
14    fn set(&self, index: u64, data: T) {
15        if index > self.limit() {
16            error!(
17                "attempt to nest an entity outside the limits of the buffer, SimpleBuffer Overflow"
18            );
19            return;
20        }
21        self.renderer()
22            .update_buffer_entry(self.buffer(), index, data);
23    }
24    /// Sets all the buffer
25    fn set_all(&self, data: &[T]) {
26        if data.len() as u64 > self.limit() {
27            error!(
28                "attempt to nest an entity outside the limits of the buffer, SimpleBuffer Overflow"
29            );
30            return;
31        }
32        self.renderer().update_buffer(self.buffer(), data);
33    }
34    /// Fill a entry with zeros
35    fn free_entry(&self, index: u64) {
36        if index > self.limit() {
37            error!(
38                "attempt to nest an entity outside the limits of the buffer, SimpleBuffer Overflow"
39            );
40            return;
41        }
42        let size = std::mem::size_of::<T>() as u64;
43        let offset = size * index;
44        let zeros = vec![0u8; size as usize];
45        self.renderer().queue().write_buffer(self.buffer(), offset, &zeros);
46    }
47    /// Fill all the buffer with zeros
48    fn free(&self) {
49        let size = std::mem::size_of::<T>();
50        let zeros = vec![0u8; size * self.limit() as usize];
51        self.renderer().queue().write_buffer(self.buffer(), 0, &zeros);
52    } 
53    /// Converts the buffert to a binding resource
54    fn as_entrie(&self) -> wgpu::BindingResource {
55        self.buffer().as_entire_binding()
56    }
57    /// Gets the buffer
58    fn buffer(&self) -> &wgpu::Buffer;
59    fn renderer(&self) -> Arc<Renderer<'a>>;
60    fn limit(&self) -> u64;
61}
62
63/// Implementation of simple buffer for commands buffer
64pub struct DrawQueueBuffer<'a> {
65    /// Wgpu Buffer
66    buffer: Buffer,
67    /// Renderer
68    renderer: Arc<Renderer<'a>>,
69    /// Limit of the buffer
70    limit: u64,
71}
72impl<'a> SimpleBuffer<'a, DrawIndexedIndirectArgs> for DrawQueueBuffer<'a> {
73    fn new(renderer: Arc<Renderer<'a>>, limit: u64) -> Self {
74        let lock = renderer.clone();
75        let buffer = lock.create_buffer(
76            "Indexed Indirect Buffer",
77            BufferUsages::INDIRECT | BufferUsages::COPY_DST,
78            limit * std::mem::size_of::<DrawIndexedIndirectArgs>() as u64,
79        );
80
81        Self {
82            buffer,
83            renderer,
84            limit,
85        }
86    }
87    fn buffer(&self) -> &wgpu::Buffer {
88        &self.buffer
89    }
90    fn renderer(&self) -> Arc<Renderer<'a>> {
91        self.renderer.clone()
92    }
93    fn limit(&self) -> u64 {
94        self.limit
95    }
96}