ribir_gpu 0.3.0

A non-intrusive declarative GUI framework, to build modern native/wasm cross-platform applications.
Documentation
use std::{any::type_name, marker::PhantomData, mem::size_of};

use ribir_painter::Vertex;
use zerocopy::AsBytes;

pub struct VerticesBuffer<T: AsBytes> {
  vertices: wgpu::Buffer,
  indices: wgpu::Buffer,
  _phantom: PhantomData<T>,
}

impl<T: AsBytes> VerticesBuffer<T> {
  pub fn new(init_vertices_cnt: usize, init_indices_cnt: usize, device: &wgpu::Device) -> Self {
    Self {
      vertices: new_vertices::<T>(device, init_vertices_cnt),
      indices: new_indices(device, init_indices_cnt),
      _phantom: PhantomData,
    }
  }

  pub fn write_buffer(
    &mut self, data: &ribir_painter::VertexBuffers<T>, device: &wgpu::Device, queue: &wgpu::Queue,
  ) {
    let vertices_data = data.vertices.as_bytes();
    let indices_data = data.indices.as_bytes();

    if self.vertices.size() < vertices_data.len() as wgpu::BufferAddress {
      self.vertices = new_vertices::<T>(device, data.vertices.len());
    }
    queue.write_buffer(&self.vertices, 0, vertices_data);

    if self.indices.size() < indices_data.len() as wgpu::BufferAddress {
      self.indices = new_indices(device, data.indices.len());
    }
    queue.write_buffer(&self.indices, 0, indices_data);
  }

  pub fn vertices(&self) -> &wgpu::Buffer { &self.vertices }

  pub fn indices(&self) -> &wgpu::Buffer { &self.indices }
}

pub(crate) fn new_vertices<T>(device: &wgpu::Device, len: usize) -> wgpu::Buffer {
  let label = format!("{} vertices buffer", type_name::<T>());
  device.create_buffer(&wgpu::BufferDescriptor {
    label: Some(&label),
    size: (len * size_of::<Vertex<T>>()) as u64,
    usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
    mapped_at_creation: false,
  })
}

fn new_indices(device: &wgpu::Device, len: usize) -> wgpu::Buffer {
  device.create_buffer(&wgpu::BufferDescriptor {
    label: Some("indices buffer"),
    size: (len * size_of::<u32>()) as u64,
    usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
    mapped_at_creation: false,
  })
}