veloren_voxygen/render/
instances.rs

1use super::buffer::DynamicBuffer;
2use bytemuck::Pod;
3use std::ops::Range;
4
5/// Represents a set of instances that has been sent to the GPU.
6pub struct SubInstances<'a, T: Copy + Pod> {
7    pub inst_range: Range<u32>,
8    buf: &'a wgpu::Buffer,
9    phantom_data: std::marker::PhantomData<T>,
10}
11
12impl<'a, T: Copy + Pod> SubInstances<'a, T> {
13    pub(super) fn buf(&self) -> wgpu::BufferSlice<'a> {
14        let start = self.inst_range.start as wgpu::BufferAddress
15            * std::mem::size_of::<T>() as wgpu::BufferAddress;
16        let end = self.inst_range.end as wgpu::BufferAddress
17            * std::mem::size_of::<T>() as wgpu::BufferAddress;
18        self.buf.slice(start..end)
19    }
20
21    pub fn count(&self) -> u32 { self.inst_range.end - self.inst_range.start }
22}
23
24/// Represents a mesh that has been sent to the GPU.
25pub struct Instances<T: Copy + Pod> {
26    buf: DynamicBuffer<T>,
27}
28
29impl<T: Copy + Pod> Instances<T> {
30    pub fn new(device: &wgpu::Device, len: usize) -> Self {
31        Self {
32            // TODO: examine if we have Instances that are not updated (e.g. sprites) and if there
33            // would be any gains from separating those out
34            buf: DynamicBuffer::new(device, len, wgpu::BufferUsages::VERTEX),
35        }
36    }
37
38    /// Create a set of instances with a slice of a portion of these instances
39    /// to send to the renderer.
40    pub fn subinstances(&self, inst_range: Range<u32>) -> SubInstances<T> {
41        SubInstances {
42            inst_range,
43            buf: self.buf(),
44            phantom_data: std::marker::PhantomData,
45        }
46    }
47
48    // TODO: count vs len naming scheme??
49    pub fn count(&self) -> usize { self.buf.len() }
50
51    pub fn update(&mut self, queue: &wgpu::Queue, vals: &[T], offset: usize) {
52        self.buf.update(queue, vals, offset)
53    }
54
55    pub fn buf(&self) -> &wgpu::Buffer { &self.buf.buf }
56}