hexga_wgpu 0.0.11-beta.47

wgpu wrapped for hexga
Documentation
use super::*;



#[derive(Clone, Debug, PartialEq, Hash)]
pub struct GpuVec<T>
{
    pub(crate) buffer : GpuBuffer<T>,
    pub(crate) len    : usize,
    pub(crate) desc   : GpuBufferDesc,
}
impl<T> GpuVec<T>
where
    T: BitAllUsed,
{
    pub fn update_part(&mut self, offset: usize, data: &[T]) { self.try_update_part(offset, data).expect("failed to update the gpu vec"); }
    pub fn try_update_part(&mut self, offset: usize, data: &[T]) -> Result<(), ()> where T: BitAllUsed,
    {
        let elem_size = std::mem::size_of::<T>().max(1);
        let required_len = offset.checked_add(data.len()).ok_or(())?;

        if required_len > self.capacity() {
            let new_capacity = required_len.next_power_of_two();
            let new_byte_size =
                (new_capacity * elem_size) as wgpu::BufferAddress;

            let new_buffer = Gpu.wgpu.device.create_buffer(&wgpu::BufferDescriptor {
                label: None,
                size: new_byte_size,
                usage: self.desc.usages,
                mapped_at_creation: false,
            });

            if self.len > 0 {
                if !self.desc.usages.contains(GpuBufferUsages::COPY_SRC)
                    || !self.desc.usages.contains(GpuBufferUsages::COPY_DST)
                {
                    return Err(());
                }

                let copy_byte_len =
                    (self.len * elem_size) as wgpu::BufferAddress;

                let mut encoder =
                    Gpu.wgpu.device.create_command_encoder(
                        &wgpu::CommandEncoderDescriptor { label: None },
                    );

                encoder.copy_buffer_to_buffer(
                    &self.buffer.wgpu,
                    0,
                    &new_buffer,
                    0,
                    copy_byte_len,
                );

                Gpu.wgpu.queue.submit(Some(encoder.finish()));
            }

            self.buffer.wgpu = new_buffer;
        }

        let write_byte_offset =
            (offset * elem_size) as wgpu::BufferAddress;

        let write_bytes = bit::try_transmute_slice(data).map_err(|e|())?;

        Gpu.wgpu.queue.write_buffer(
            &self.buffer.wgpu,
            write_byte_offset,
            write_bytes,
        );

        if required_len > self.len {
            self.len = required_len;
        }

        Ok(())
    }
}


impl<T> Clear for GpuVec<T>
{
    fn clear(&mut self) {
        self.len = 0;
    }
}



pub trait ToGpuVec<T> where T:BitAllUsed
{
    fn to_gpu_vec(self, desc: GpuBufferDesc) -> GpuVec<T>;
}
impl<T> ToGpuVec<T> for &[T] where T:BitAllUsed
{
    fn to_gpu_vec(self, desc: GpuBufferDesc) -> GpuVec<T> {
        GpuVec::new(self, desc)
    }
}

impl<T> GpuBufferNew<T> for GpuVec<T> where GpuBuffer<T>: GpuBufferNew<T>
{
    fn new(value: &[T], desc: GpuBufferDesc) -> Self {
        let len = value.len();
        Self { buffer: GpuBuffer::new(value, desc), len, desc }
    }

    fn with_capacity(capacity: usize, desc: GpuBufferDesc) -> Self {
        Self { buffer: GpuBuffer::with_capacity(capacity, desc), len: capacity, desc }
    }
}
impl<T> GpuBufferByte for GpuVec<T> where GpuBuffer<T>: GpuBufferByte
{
    fn wgpu_bytes_len(&self) -> GpuBufferAddress { (self.len * std::mem::size_of::<T>()) as GpuBufferAddress }
    fn wgpu_bytes_capacity(&self) -> GpuBufferAddress { self.buffer.wgpu_bytes_capacity() }
}
impl<T> GpuAsUntypedSlice for GpuVec<T> where GpuBuffer<T>: GpuBufferByte
{
    fn untyped_slice<S: RangeBounds<usize>>(&self, bounds: S) -> GpuUntypedSlice<'_> { self.buffer.untyped_slice(bounds) }
    fn try_untyped_update<T2>(&mut self, values: &[T2]) -> Result<(),()> where T2: BitAllUsed {
        self.buffer.try_untyped_update(values)
    }
}
impl<T> GpuBufferRead<T> for GpuVec<T> where wgpu::Buffer: GpuBufferRead<T>
{
    fn read_in(&self, vec: &mut Vec<T>) -> GpuResult where T: BitZero + BitPattern
    {
        self.buffer.read_in(vec)
    }

    fn slice<S: RangeBounds<usize>>(&self, bounds: S) -> GpuSlice<'_,T> {
        self.buffer.slice(bounds)
    }
    fn try_update(&mut self, values: &[T]) -> Result<(),()> where T: BitAllUsed {
        self.try_update_part(0, values)
    }
}