mepeyew 0.3.5

mepeyew - Small But Powerful Graphics Library
Documentation
use super::*;
use context::extensions::*;

impl WebGpuContext {
    pub fn new_shader_storage_buffer<T: Copy>(
        &mut self,
        data: &T,
        _ext: Option<NewShaderStorageBufferExt>,
    ) -> GResult<ShaderStorageBufferId> {
        let size = std::mem::size_of::<T>();
        let buffer = WebGpuBuffer::new(
            &self.device,
            size as u32,
            GpuBufferUsageFlags::Storage as u32
                | GpuBufferUsageFlags::CopyDst as u32
                | GpuBufferUsageFlags::CopySrc as u32,
            unsafe { std::slice::from_raw_parts(data as *const T as *const u8, size) },
            true,
        );
        self.ssbos.push(buffer);
        Ok(ShaderStorageBufferId::from_id(self.ssbos.len() - 1))
    }

    pub fn read_synced_shader_storage_buffer<T: Copy>(
        &self,
        _ssbo: ShaderStorageBufferId,
        _ext: Option<ReadSyncedShaderStorageBufferExt>,
    ) -> GResult<T> {
        Err(gpu_api_err!(
            "webgpu does not support this operation, please use async_read_synced_shader_storage_buffer instead"
        ))
    }

    pub async fn async_read_synced_shader_storage_buffer<T: Copy>(
        &self,
        ssbo: ShaderStorageBufferId,
        _ext: Option<ReadSyncedShaderStorageBufferExt>,
    ) -> GResult<T> {
        let ssbo = self.ssbos.get(ssbo.id()).ok_or(gpu_api_err!(
            "webgpu read synced shader buffer id {:?} does not exist",
            ssbo
        ))?;

        let readable_buffer = ssbo.readable_buffer.as_ref().unwrap();

        let command_encoder = self.device.create_command_encoder();
        command_encoder.copy_buffer_to_buffer_with_u32_and_u32_and_u32(
            &ssbo.buffer,
            0,
            readable_buffer,
            0,
            ssbo.size,
        );
        let command_buffer = command_encoder.finish();
        let commands = Array::new();
        commands.push(&command_buffer);
        self.device.queue().submit(&commands);

        JsFuture::from(readable_buffer.map_async(GpuMapModeFlags::Read as u32))
            .await
            .map_err(|e| {
                gpu_api_err!(
                    "webgpu failed to map buffer in async_read_synced_shader_storage_buffer: {:?}",
                    e
                )
            })?;

        let mapped_buf = readable_buffer.get_mapped_range();
        let u8_js_buf = Uint8Array::new(&mapped_buf);
        let mut u8_rs_buf = vec![0u8; u8_js_buf.length() as usize];
        for i in 0..u8_js_buf.length() {
            u8_rs_buf[i as usize] = u8_js_buf.get_index(i);
        }

        ssbo.buffer.unmap();

        Ok(unsafe { std::ptr::read(u8_rs_buf.as_ptr() as *const T) })
    }
}