From 5138c488c62dc4cccd1b8bbd2c93fb709b719fa8 Mon Sep 17 00:00:00 2001 From: Paul Kernfeld Date: Sat, 27 Jul 2019 13:33:45 -0400 Subject: [PATCH] Replace Pod using zerocopy crate See https://github.com/gfx-rs/wgpu/pull/256#issuecomment-515277497 --- Cargo.toml | 1 + src/lib.rs | 43 ++++++++++++++++++------------------------- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 84f63e1497..1a80d17aa4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ gl = ["wgn/gfx-backend-gl"] #TODO: only depend on the published version wgn = { package = "wgpu-native", version = "0.2.6", features = ["local", "window-winit"], git = "https://github.com/gfx-rs/wgpu", rev = "5224bb812420e420485ee08ad8cb820695a3e6eb" } arrayvec = "0.4" +zerocopy = "0.2" [dev-dependencies] cgmath = "0.17" diff --git a/src/lib.rs b/src/lib.rs index 80eb52874d..bdad80d05e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,9 @@ //! 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; @@ -37,8 +39,8 @@ pub use wgn::{ Limits, LoadOp, Origin3d, - Pod, PowerPreference, + PresentMode, PrimitiveTopology, RasterizationStateDescriptor, RenderPassDepthStencilAttachmentDescriptor, @@ -59,7 +61,6 @@ pub use wgn::{ TextureViewDimension, VertexAttributeDescriptor, VertexFormat, - PresentMode, }; #[cfg(feature = "gl")] @@ -814,7 +815,7 @@ impl Drop for BufferAsyncMapping { struct BufferMapReadAsyncUserData where - T: Pod, + T: FromBytes, F: FnOnce(BufferMapAsyncResult<&[T]>), { size: BufferAddress, @@ -825,7 +826,7 @@ where struct BufferMapWriteAsyncUserData where - T: Pod, + T: AsBytes + FromBytes, F: FnOnce(BufferMapAsyncResult<&mut [T]>), { size: BufferAddress, @@ -837,29 +838,25 @@ where impl Buffer { pub fn map_read_async(&self, start: BufferAddress, size: BufferAddress, callback: F) where - T: 'static + Pod, + T: 'static + FromBytes, F: FnOnce(BufferMapAsyncResult<&[T]>) + 'static, { - let type_size = std::mem::size_of::() as BufferAddress; - assert_ne!(type_size, 0); - assert_eq!(size % type_size, 0); - extern "C" fn buffer_map_read_callback_wrapper( status: wgn::BufferMapAsyncStatus, data: *const u8, user_data: *mut u8, ) where - T: Pod, + T: FromBytes, F: FnOnce(BufferMapAsyncResult<&[T]>), { let user_data = unsafe { Box::from_raw(user_data as *mut BufferMapReadAsyncUserData) }; - let data = unsafe { - slice::from_raw_parts( - data as *const T, - user_data.size as usize / std::mem::size_of::(), - ) + 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(); if let wgn::BufferMapAsyncStatus::Success = status { (user_data.callback)(Ok(BufferAsyncMapping { data, @@ -887,29 +884,25 @@ impl Buffer { pub fn map_write_async(&self, start: BufferAddress, size: BufferAddress, callback: F) where - T: 'static + Pod, + T: 'static + AsBytes + FromBytes, F: FnOnce(BufferMapAsyncResult<&mut [T]>) + 'static, { - let type_size = std::mem::size_of::() as BufferAddress; - assert_ne!(type_size, 0); - assert_eq!(size % type_size, 0); - extern "C" fn buffer_map_write_callback_wrapper( status: wgn::BufferMapAsyncStatus, data: *mut u8, user_data: *mut u8, ) where - T: Pod, + T: AsBytes + FromBytes, F: FnOnce(BufferMapAsyncResult<&mut [T]>), { let user_data = unsafe { Box::from_raw(user_data as *mut BufferMapWriteAsyncUserData) }; let data = unsafe { - slice::from_raw_parts_mut( - data as *mut T, - user_data.size as usize / std::mem::size_of::(), - ) + 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(); if let wgn::BufferMapAsyncStatus::Success = status { (user_data.callback)(Ok(BufferAsyncMapping { data,