diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 71b7bf12ee..e00aba38fa 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -37,7 +37,6 @@ rev = "73b33ea76e2f91b3114aa7640b1d60518d39f915" [dependencies] arrayvec = "0.5" raw-window-handle = "0.3" -zerocopy = "0.2" [dev-dependencies] cgmath = "0.17" @@ -46,3 +45,4 @@ glsl-to-spirv = "0.1" log = "0.4" png = "0.15" winit = "0.20.0-alpha4" +zerocopy = "0.2" diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index ec30809a66..2360726f47 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -1,9 +1,7 @@ //! A cross-platform graphics and compute library based on WebGPU. use arrayvec::ArrayVec; -use zerocopy::{AsBytes, FromBytes, LayoutVerified}; -use std::convert::TryFrom; use std::ffi::CString; use std::ops::Range; use std::ptr; @@ -493,27 +491,12 @@ impl<'a> TextureCopyView<'a> { } /// A buffer being created, mapped in host memory. -pub struct CreateBufferMapped<'a, T> { +pub struct CreateBufferMapped<'a> { id: wgc::id::BufferId, - pub data: &'a mut [T], + pub data: &'a mut [u8], } -impl<'a, T> CreateBufferMapped<'a, T> -where - T: Copy, -{ - /// Copies a slice into the mapped buffer and unmaps it, returning a [`Buffer`]. - /// - /// `slice` and `self.data` must have the same length. - /// - /// # Panics - /// - /// Panics if the slices have different lengths. - pub fn fill_from_slice(self, slice: &[T]) -> Buffer { - self.data.copy_from_slice(slice); - self.finish() - } - +impl CreateBufferMapped<'_> { /// Unmaps the buffer from host memory and returns a [`Buffer`]. pub fn finish(self) -> Buffer { wgn::wgpu_buffer_unmap(self.id); @@ -813,32 +796,32 @@ impl Device { /// Creates a new buffer and maps it into host-visible memory. /// - /// This returns a [`CreateBufferMapped`], which exposes a `&mut [T]`. The actual [`Buffer`] + /// This returns a [`CreateBufferMapped`], which exposes a `&mut [u8]`. The actual [`Buffer`] /// will not be created until calling [`CreateBufferMapped::finish`]. - pub fn create_buffer_mapped<'a, T>( - &'a self, - count: usize, - usage: BufferUsage, - ) -> CreateBufferMapped<'a, T> - where - T: 'static + Copy + AsBytes + FromBytes, - { - let type_size = std::mem::size_of::() as BufferAddress; - assert_ne!(type_size, 0); + pub fn create_buffer_mapped(&self, size: usize, usage: BufferUsage) -> CreateBufferMapped<'_> { + assert_ne!(size, 0); let desc = BufferDescriptor { - size: (type_size * count as BufferAddress).max(1), + size: size as BufferAddress, usage, }; let mut ptr: *mut u8 = std::ptr::null_mut(); let id = wgn::wgpu_device_create_buffer_mapped(self.id, &desc, &mut ptr as *mut *mut u8); - let data = unsafe { std::slice::from_raw_parts_mut(ptr as *mut T, count) }; + let data = unsafe { std::slice::from_raw_parts_mut(ptr as *mut u8, size) }; CreateBufferMapped { id, data } } + /// Creates a new buffer, maps it into host-visible memory, copies data from the given slice, + /// and finally unmaps it, returning a [`Buffer`]. + pub fn create_buffer_with_data(&self, data: &[u8], usage: BufferUsage) -> Buffer { + let mapped = self.create_buffer_mapped(data.len(), usage); + mapped.data.copy_from_slice(data); + mapped.finish() + } + /// Creates a new [`Texture`]. /// /// `desc` specifies the general format of the texture. @@ -888,50 +871,39 @@ impl Drop for BufferAsyncMapping { } } -struct BufferMapReadAsyncUserData +struct BufferMapReadAsyncUserData where - T: FromBytes, - F: FnOnce(BufferMapAsyncResult<&[T]>), + F: FnOnce(BufferMapAsyncResult<&[u8]>), { - size: BufferAddress, + size: usize, callback: F, buffer_id: wgc::id::BufferId, - phantom: std::marker::PhantomData, } -struct BufferMapWriteAsyncUserData +struct BufferMapWriteAsyncUserData where - T: AsBytes + FromBytes, - F: FnOnce(BufferMapAsyncResult<&mut [T]>), + F: FnOnce(BufferMapAsyncResult<&mut [u8]>), { - size: BufferAddress, + size: usize, callback: F, buffer_id: wgc::id::BufferId, - phantom: std::marker::PhantomData, } impl Buffer { - pub fn map_read_async(&self, start: BufferAddress, count: usize, callback: F) + pub fn map_read_async(&self, start: BufferAddress, size: usize, callback: F) where - T: 'static + FromBytes, - F: FnOnce(BufferMapAsyncResult<&[T]>), + F: FnOnce(BufferMapAsyncResult<&[u8]>), { - extern "C" fn buffer_map_read_callback_wrapper( + extern "C" fn buffer_map_read_callback_wrapper( status: BufferMapAsyncStatus, data: *const u8, user_data: *mut u8, ) where - T: FromBytes, - F: FnOnce(BufferMapAsyncResult<&[T]>), + F: FnOnce(BufferMapAsyncResult<&[u8]>), { let user_data = - unsafe { Box::from_raw(user_data as *mut BufferMapReadAsyncUserData) }; - let data: &[u8] = unsafe { - slice::from_raw_parts(data as *const u8, usize::try_from(user_data.size).unwrap()) - }; - let data = LayoutVerified::new_slice(data) - .expect("could not interpret bytes as &[T]") - .into_slice(); + unsafe { Box::from_raw(user_data as *mut BufferMapReadAsyncUserData) }; + let data: &[u8] = unsafe { slice::from_raw_parts(data as *const u8, user_data.size) }; match status { BufferMapAsyncStatus::Success => (user_data.callback)(Ok(BufferAsyncMapping { data, @@ -941,44 +913,34 @@ impl Buffer { } } - let size = (count * std::mem::size_of::()) as BufferAddress; - let user_data = Box::new(BufferMapReadAsyncUserData { size, callback, buffer_id: self.id, - phantom: std::marker::PhantomData, }); wgn::wgpu_buffer_map_read_async( self.id, start, - size, - buffer_map_read_callback_wrapper::, + size as BufferAddress, + buffer_map_read_callback_wrapper::, Box::into_raw(user_data) as *mut u8, ); } - pub fn map_write_async(&self, start: BufferAddress, count: usize, callback: F) + pub fn map_write_async(&self, start: BufferAddress, size: usize, callback: F) where - T: 'static + AsBytes + FromBytes, - F: FnOnce(BufferMapAsyncResult<&mut [T]>), + F: FnOnce(BufferMapAsyncResult<&mut [u8]>), { - extern "C" fn buffer_map_write_callback_wrapper( + extern "C" fn buffer_map_write_callback_wrapper( status: BufferMapAsyncStatus, data: *mut u8, user_data: *mut u8, ) where - T: AsBytes + FromBytes, - F: FnOnce(BufferMapAsyncResult<&mut [T]>), + F: FnOnce(BufferMapAsyncResult<&mut [u8]>), { let user_data = - unsafe { Box::from_raw(user_data as *mut BufferMapWriteAsyncUserData) }; - let data = unsafe { - slice::from_raw_parts_mut(data as *mut u8, usize::try_from(user_data.size).unwrap()) - }; - let data = LayoutVerified::new_slice(data) - .expect("could not interpret bytes as &mut [T]") - .into_mut_slice(); + unsafe { Box::from_raw(user_data as *mut BufferMapWriteAsyncUserData) }; + let data = unsafe { slice::from_raw_parts_mut(data as *mut u8, user_data.size) }; match status { BufferMapAsyncStatus::Success => (user_data.callback)(Ok(BufferAsyncMapping { data, @@ -988,19 +950,16 @@ impl Buffer { } } - let size = (count * std::mem::size_of::()) as BufferAddress; - let user_data = Box::new(BufferMapWriteAsyncUserData { size, callback, buffer_id: self.id, - phantom: std::marker::PhantomData, }); wgn::wgpu_buffer_map_write_async( self.id, start, - size, - buffer_map_write_callback_wrapper::, + size as BufferAddress, + buffer_map_write_callback_wrapper::, Box::into_raw(user_data) as *mut u8, ); }