From 68c81df381d2d2fe76cac2ab135cf78d65bd7d6a Mon Sep 17 00:00:00 2001 From: Jacob Greenfield Date: Thu, 21 Nov 2019 17:43:25 -0500 Subject: [PATCH] Update examples and tests --- examples/cube/main.rs | 32 ++++++------ examples/hello-compute/main.rs | 36 +++++++------ examples/mipmap/main.rs | 26 +++++----- examples/msaa-line/main.rs | 9 ++-- examples/shadow/main.rs | 94 +++++++++++++++++++--------------- examples/skybox/main.rs | 46 +++++++++++------ tests/multithreaded_compute.rs | 46 +++++++++++------ 7 files changed, 164 insertions(+), 125 deletions(-) diff --git a/examples/cube/main.rs b/examples/cube/main.rs index 3e23a5bebb..e629efae31 100644 --- a/examples/cube/main.rs +++ b/examples/cube/main.rs @@ -1,8 +1,10 @@ #[path = "../framework.rs"] mod framework; +use zerocopy::{AsBytes, FromBytes}; + #[repr(C)] -#[derive(Clone, Copy, zerocopy::AsBytes, zerocopy::FromBytes)] +#[derive(Clone, Copy, AsBytes, FromBytes)] struct Vertex { _pos: [f32; 4], _tex_coord: [f32; 2], @@ -119,13 +121,12 @@ impl framework::Example for Example { // Create the vertex and index buffers let vertex_size = mem::size_of::(); let (vertex_data, index_data) = create_vertices(); - let vertex_buf = device - .create_buffer_mapped(vertex_data.len(), wgpu::BufferUsage::VERTEX) - .fill_from_slice(&vertex_data); - let index_buf = device - .create_buffer_mapped(index_data.len(), wgpu::BufferUsage::INDEX) - .fill_from_slice(&index_data); + let vertex_buf = + device.create_buffer_with_data(vertex_data.as_bytes(), wgpu::BufferUsage::VERTEX); + + let index_buf = + device.create_buffer_with_data(index_data.as_bytes(), wgpu::BufferUsage::INDEX); // Create pipeline layout let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { @@ -172,9 +173,8 @@ impl framework::Example for Example { usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST, }); let texture_view = texture.create_default_view(); - let temp_buf = device - .create_buffer_mapped(texels.len(), wgpu::BufferUsage::COPY_SRC) - .fill_from_slice(&texels); + let temp_buf = + device.create_buffer_with_data(texels.as_slice(), wgpu::BufferUsage::COPY_SRC); init_encoder.copy_buffer_to_texture( wgpu::BufferCopyView { buffer: &temp_buf, @@ -209,9 +209,10 @@ impl framework::Example for Example { }); let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); let mx_ref: &[f32; 16] = mx_total.as_ref(); - let uniform_buf = device - .create_buffer_mapped(16, wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST) - .fill_from_slice(mx_ref); + let uniform_buf = device.create_buffer_with_data( + mx_ref.as_bytes(), + wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + ); // Create bind group let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { @@ -316,9 +317,8 @@ impl framework::Example for Example { let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); let mx_ref: &[f32; 16] = mx_total.as_ref(); - let temp_buf = device - .create_buffer_mapped(16, wgpu::BufferUsage::COPY_SRC) - .fill_from_slice(mx_ref); + let temp_buf = + device.create_buffer_with_data(mx_ref.as_bytes(), wgpu::BufferUsage::COPY_SRC); let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); diff --git a/examples/hello-compute/main.rs b/examples/hello-compute/main.rs index 988c349bc8..0b03b97b87 100644 --- a/examples/hello-compute/main.rs +++ b/examples/hello-compute/main.rs @@ -1,4 +1,5 @@ -use std::str::FromStr; +use std::{convert::TryInto as _, str::FromStr}; +use zerocopy::AsBytes as _; fn main() { env_logger::init(); @@ -12,7 +13,8 @@ fn main() { .map(|s| u32::from_str(&s).expect("You must pass a list of positive integers!")) .collect(); - let size = (numbers.len() * std::mem::size_of::()) as wgpu::BufferAddress; + let slice_size = numbers.len() * std::mem::size_of::(); + let size = slice_size as wgpu::BufferAddress; let adapter = wgpu::Adapter::request( &wgpu::RequestAdapterOptions { @@ -33,12 +35,10 @@ fn main() { let cs_module = device.create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(&cs[..])).unwrap()); - let staging_buffer = device - .create_buffer_mapped( - numbers.len(), - wgpu::BufferUsage::MAP_READ | wgpu::BufferUsage::COPY_DST | wgpu::BufferUsage::COPY_SRC, - ) - .fill_from_slice(&numbers); + let staging_buffer = device.create_buffer_with_data( + numbers.as_slice().as_bytes(), + wgpu::BufferUsage::MAP_READ | wgpu::BufferUsage::COPY_DST | wgpu::BufferUsage::COPY_SRC, + ); let storage_buffer = device.create_buffer(&wgpu::BufferDescriptor { size, @@ -93,13 +93,15 @@ fn main() { queue.submit(&[encoder.finish()]); - staging_buffer.map_read_async( - 0, - numbers.len(), - |result: wgpu::BufferMapAsyncResult<&[u32]>| { - if let Ok(mapping) = result { - println!("Times: {:?}", mapping.data); - } - }, - ); + // FIXME: Align and use `LayoutVerified` + staging_buffer.map_read_async(0, slice_size, |result| { + if let Ok(mapping) = result { + let times: Box<[u32]> = mapping + .data + .chunks_exact(4) + .map(|b| u32::from_ne_bytes(b.try_into().unwrap())) + .collect(); + println!("Times: {:?}", times); + } + }); } diff --git a/examples/mipmap/main.rs b/examples/mipmap/main.rs index a769d83a50..2e63aa2c6d 100644 --- a/examples/mipmap/main.rs +++ b/examples/mipmap/main.rs @@ -1,10 +1,12 @@ #[path = "../framework.rs"] mod framework; +use zerocopy::{AsBytes, FromBytes}; + const TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8UnormSrgb; #[repr(C)] -#[derive(Clone, Copy, zerocopy::AsBytes, zerocopy::FromBytes)] +#[derive(Clone, Copy, AsBytes, FromBytes)] struct Vertex { #[allow(dead_code)] pos: [f32; 4], @@ -206,9 +208,8 @@ impl framework::Example for Example { // Create the vertex and index buffers let vertex_size = mem::size_of::(); let vertex_data = create_vertices(); - let vertex_buf = device - .create_buffer_mapped(vertex_data.len(), wgpu::BufferUsage::VERTEX) - .fill_from_slice(&vertex_data); + let vertex_buf = + device.create_buffer_with_data(vertex_data.as_bytes(), wgpu::BufferUsage::VERTEX); // Create pipeline layout let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { @@ -258,9 +259,8 @@ impl framework::Example for Example { | wgpu::TextureUsage::COPY_DST, }); let texture_view = texture.create_default_view(); - let temp_buf = device - .create_buffer_mapped(texels.len(), wgpu::BufferUsage::COPY_SRC) - .fill_from_slice(&texels); + let temp_buf = + device.create_buffer_with_data(texels.as_slice(), wgpu::BufferUsage::COPY_SRC); init_encoder.copy_buffer_to_texture( wgpu::BufferCopyView { buffer: &temp_buf, @@ -295,9 +295,10 @@ impl framework::Example for Example { }); let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); let mx_ref: &[f32; 16] = mx_total.as_ref(); - let uniform_buf = device - .create_buffer_mapped(16, wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST) - .fill_from_slice(mx_ref); + let uniform_buf = device.create_buffer_with_data( + mx_ref.as_bytes(), + wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + ); // Create bind group let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { @@ -393,9 +394,8 @@ impl framework::Example for Example { let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); let mx_ref: &[f32; 16] = mx_total.as_ref(); - let temp_buf = device - .create_buffer_mapped(16, wgpu::BufferUsage::COPY_SRC) - .fill_from_slice(mx_ref); + let temp_buf = + device.create_buffer_with_data(mx_ref.as_bytes(), wgpu::BufferUsage::COPY_SRC); let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); diff --git a/examples/msaa-line/main.rs b/examples/msaa-line/main.rs index fdd7cbd643..caaa70dc05 100644 --- a/examples/msaa-line/main.rs +++ b/examples/msaa-line/main.rs @@ -10,8 +10,10 @@ #[path = "../framework.rs"] mod framework; +use zerocopy::{AsBytes, FromBytes}; + #[repr(C)] -#[derive(Clone, Copy, zerocopy::AsBytes, zerocopy::FromBytes)] +#[derive(Clone, Copy, AsBytes, FromBytes)] struct Vertex { _pos: [f32; 2], _color: [f32; 4], @@ -162,9 +164,8 @@ impl framework::Example for Example { }); } - let vertex_buffer = device - .create_buffer_mapped(vertex_data.len(), wgpu::BufferUsage::VERTEX) - .fill_from_slice(&vertex_data); + let vertex_buffer = + device.create_buffer_with_data(vertex_data.as_bytes(), wgpu::BufferUsage::VERTEX); let vertex_count = vertex_data.len() as u32; let this = Example { diff --git a/examples/shadow/main.rs b/examples/shadow/main.rs index 90abf29e1f..1bda583d64 100644 --- a/examples/shadow/main.rs +++ b/examples/shadow/main.rs @@ -3,8 +3,10 @@ use std::{mem, ops::Range, rc::Rc}; #[path = "../framework.rs"] mod framework; +use zerocopy::{AsBytes, FromBytes}; + #[repr(C)] -#[derive(Clone, Copy, zerocopy::AsBytes, zerocopy::FromBytes)] +#[derive(Clone, Copy, AsBytes, FromBytes)] struct Vertex { _pos: [i8; 4], @@ -97,7 +99,7 @@ struct Light { } #[repr(C)] -#[derive(Clone, Copy, zerocopy::AsBytes, zerocopy::FromBytes)] +#[derive(Clone, Copy, AsBytes, FromBytes)] struct LightRaw { proj: [[f32; 4]; 4], pos: [f32; 4], @@ -132,14 +134,14 @@ impl Light { } #[repr(C)] -#[derive(Clone, Copy, zerocopy::AsBytes, zerocopy::FromBytes)] +#[derive(Clone, Copy, AsBytes, FromBytes)] struct ForwardUniforms { proj: [[f32; 4]; 4], num_lights: [u32; 4], } #[repr(C)] -#[derive(Clone, Copy, zerocopy::AsBytes, zerocopy::FromBytes)] +#[derive(Clone, Copy, AsBytes, FromBytes)] struct EntityUniforms { model: [[f32; 4]; 4], color: [f32; 4], @@ -197,25 +199,19 @@ impl framework::Example for Example { let vertex_size = mem::size_of::(); let (cube_vertex_data, cube_index_data) = create_cube(); let cube_vertex_buf = Rc::new( - device - .create_buffer_mapped(cube_vertex_data.len(), wgpu::BufferUsage::VERTEX) - .fill_from_slice(&cube_vertex_data), + device.create_buffer_with_data(cube_vertex_data.as_bytes(), wgpu::BufferUsage::VERTEX), ); let cube_index_buf = Rc::new( - device - .create_buffer_mapped(cube_index_data.len(), wgpu::BufferUsage::INDEX) - .fill_from_slice(&cube_index_data), + device.create_buffer_with_data(cube_index_data.as_bytes(), wgpu::BufferUsage::INDEX), ); let (plane_vertex_data, plane_index_data) = create_plane(7); - let plane_vertex_buf = device - .create_buffer_mapped(plane_vertex_data.len(), wgpu::BufferUsage::VERTEX) - .fill_from_slice(&plane_vertex_data); + let plane_vertex_buf = + device.create_buffer_with_data(plane_vertex_data.as_bytes(), wgpu::BufferUsage::VERTEX); - let plane_index_buf = device - .create_buffer_mapped(plane_index_data.len(), wgpu::BufferUsage::INDEX) - .fill_from_slice(&plane_index_data); + let plane_index_buf = + device.create_buffer_with_data(plane_index_data.as_bytes(), wgpu::BufferUsage::INDEX); let entity_uniform_size = mem::size_of::() as wgpu::BufferAddress; let plane_uniform_buf = device.create_buffer(&wgpu::BufferDescriptor { @@ -534,9 +530,10 @@ impl framework::Example for Example { num_lights: [lights.len() as u32, 0, 0, 0], }; let uniform_size = mem::size_of::() as wgpu::BufferAddress; - let uniform_buf = device - .create_buffer_mapped(1, wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST) - .fill_from_slice(&[forward_uniforms]); + let uniform_buf = device.create_buffer_with_data( + forward_uniforms.as_bytes(), + wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + ); // Create bind group let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { @@ -662,9 +659,8 @@ impl framework::Example for Example { let command_buf = { let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); let mx_ref: &[f32; 16] = mx_total.as_ref(); - let temp_buf = device - .create_buffer_mapped(16, wgpu::BufferUsage::COPY_SRC) - .fill_from_slice(mx_ref); + let temp_buf = + device.create_buffer_with_data(mx_ref.as_bytes(), wgpu::BufferUsage::COPY_SRC); let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); @@ -699,25 +695,33 @@ impl framework::Example for Example { device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); { - let size = mem::size_of::() as wgpu::BufferAddress; - let temp_buf_data = - device.create_buffer_mapped(self.entities.len(), wgpu::BufferUsage::COPY_SRC); + let size = mem::size_of::(); + let temp_buf_data = device + .create_buffer_mapped(self.entities.len() * size, wgpu::BufferUsage::COPY_SRC); - for (i, entity) in self.entities.iter_mut().enumerate() { + // FIXME: Align and use `LayoutVerified` + for (entity, slot) in self + .entities + .iter_mut() + .zip(temp_buf_data.data.chunks_exact_mut(size)) + { if entity.rotation_speed != 0.0 { let rotation = cgmath::Matrix4::from_angle_x(cgmath::Deg(entity.rotation_speed)); entity.mx_world = entity.mx_world * rotation; } - temp_buf_data.data[i] = EntityUniforms { - model: entity.mx_world.into(), - color: [ - entity.color.r as f32, - entity.color.g as f32, - entity.color.b as f32, - entity.color.a as f32, - ], - }; + slot.copy_from_slice( + EntityUniforms { + model: entity.mx_world.into(), + color: [ + entity.color.r as f32, + entity.color.g as f32, + entity.color.b as f32, + entity.color.a as f32, + ], + } + .as_bytes(), + ); } let temp_buf = temp_buf_data.finish(); @@ -725,28 +729,34 @@ impl framework::Example for Example { for (i, entity) in self.entities.iter().enumerate() { encoder.copy_buffer_to_buffer( &temp_buf, - i as wgpu::BufferAddress * size, + (i * size) as wgpu::BufferAddress, &entity.uniform_buf, 0, - size, + size as wgpu::BufferAddress, ); } } if self.lights_are_dirty { self.lights_are_dirty = false; - let size = (self.lights.len() * mem::size_of::()) as wgpu::BufferAddress; + let size = mem::size_of::(); + let total_size = size * self.lights.len(); let temp_buf_data = - device.create_buffer_mapped(self.lights.len(), wgpu::BufferUsage::COPY_SRC); - for (i, light) in self.lights.iter().enumerate() { - temp_buf_data.data[i] = light.to_raw(); + device.create_buffer_mapped(total_size, wgpu::BufferUsage::COPY_SRC); + // FIXME: Align and use `LayoutVerified` + for (light, slot) in self + .lights + .iter() + .zip(temp_buf_data.data.chunks_exact_mut(size)) + { + slot.copy_from_slice(light.to_raw().as_bytes()); } encoder.copy_buffer_to_buffer( &temp_buf_data.finish(), 0, &self.light_uniform_buf, 0, - size, + total_size as wgpu::BufferAddress, ); } diff --git a/examples/skybox/main.rs b/examples/skybox/main.rs index 2fcb2f6378..89ca3a97ca 100644 --- a/examples/skybox/main.rs +++ b/examples/skybox/main.rs @@ -1,9 +1,12 @@ #[path = "../framework.rs"] mod framework; +use zerocopy::AsBytes as _; + const SKYBOX_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8Unorm; -type Uniforms = [cgmath::Matrix4; 2]; +type Uniform = cgmath::Matrix4; +type Uniforms = [Uniform; 2]; pub struct Skybox { aspect: f32, @@ -26,6 +29,23 @@ impl Skybox { } } +fn buffer_from_uniforms( + device: &wgpu::Device, + uniforms: &Uniforms, + usage: wgpu::BufferUsage, +) -> wgpu::Buffer { + let uniform_buf = device.create_buffer_mapped(std::mem::size_of::(), usage); + // FIXME: Align and use `LayoutVerified` + for (u, slot) in uniforms.iter().zip( + uniform_buf + .data + .chunks_exact_mut(std::mem::size_of::()), + ) { + slot.copy_from_slice(AsRef::<[[f32; 4]; 4]>::as_ref(u).as_bytes()); + } + uniform_buf.finish() +} + impl framework::Example for Skybox { fn init( sc_desc: &wgpu::SwapChainDescriptor, @@ -71,12 +91,11 @@ impl framework::Example for Skybox { let aspect = sc_desc.width as f32 / sc_desc.height as f32; let uniforms = Self::generate_uniforms(aspect); - let uniform_buf = device - .create_buffer_mapped::<[[f32; 4]; 4]>( - uniforms.len(), - wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, - ) - .fill_from_slice(&[uniforms[0].into(), uniforms[1].into()]); + let uniform_buf = buffer_from_uniforms( + &device, + &uniforms, + wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + ); let uniform_buf_size = std::mem::size_of::(); let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { @@ -176,9 +195,7 @@ impl framework::Example for Skybox { image_width, image_height, ); - let image_buf = device - .create_buffer_mapped(image.len(), wgpu::BufferUsage::COPY_SRC) - .fill_from_slice(&image); + let image_buf = device.create_buffer_with_data(image, wgpu::BufferUsage::COPY_SRC); init_encoder.copy_buffer_to_texture( wgpu::BufferCopyView { @@ -256,9 +273,8 @@ impl framework::Example for Skybox { let mx_total = uniforms[0] * uniforms[1]; let mx_ref: &[f32; 16] = mx_total.as_ref(); - let temp_buf = device - .create_buffer_mapped(16, wgpu::BufferUsage::COPY_SRC) - .fill_from_slice(mx_ref); + let temp_buf = + device.create_buffer_with_data(mx_ref.as_bytes(), wgpu::BufferUsage::COPY_SRC); let mut init_encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); @@ -277,9 +293,7 @@ impl framework::Example for Skybox { let rotation = cgmath::Matrix4::::from_angle_x(cgmath::Deg(0.25)); self.uniforms[1] = self.uniforms[1] * rotation; let uniform_buf_size = std::mem::size_of::(); - let temp_buf = device - .create_buffer_mapped::<[[f32; 4]; 4]>(self.uniforms.len(), wgpu::BufferUsage::COPY_SRC) - .fill_from_slice(&[self.uniforms[0].into(), self.uniforms[1].into()]); + let temp_buf = buffer_from_uniforms(&device, &self.uniforms, wgpu::BufferUsage::COPY_SRC); init_encoder.copy_buffer_to_buffer( &temp_buf, diff --git a/tests/multithreaded_compute.rs b/tests/multithreaded_compute.rs index 8e185236ab..820df9cd70 100644 --- a/tests/multithreaded_compute.rs +++ b/tests/multithreaded_compute.rs @@ -1,3 +1,6 @@ +#[cfg(any(feature = "vulkan", feature = "metal", feature = "dx12"))] +use std::convert::TryInto as _; + #[test] #[cfg(any(feature = "vulkan", feature = "metal", feature = "dx12"))] fn multithreaded_compute() { @@ -13,14 +16,18 @@ fn multithreaded_compute() { thread::spawn(move || { let numbers = vec![100, 100, 100]; - let size = (numbers.len() * std::mem::size_of::()) as wgpu::BufferAddress; + let slice_size = numbers.len() * std::mem::size_of::(); + let size = slice_size as wgpu::BufferAddress; - let instance = wgpu::Instance::new(); - let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions { - power_preference: wgpu::PowerPreference::Default, - }); + let adapter = wgpu::Adapter::request( + &wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::Default, + }, + wgpu::BackendBit::PRIMARY, + ) + .unwrap(); - let mut device = adapter.request_device(&wgpu::DeviceDescriptor { + let (device, mut queue) = adapter.request_device(&wgpu::DeviceDescriptor { extensions: wgpu::Extensions { anisotropic_filtering: false, }, @@ -31,14 +38,12 @@ fn multithreaded_compute() { let cs_module = device .create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(&cs[..])).unwrap()); - let staging_buffer = device - .create_buffer_mapped( - numbers.len(), - wgpu::BufferUsage::MAP_READ - | wgpu::BufferUsage::COPY_DST - | wgpu::BufferUsage::COPY_SRC, - ) - .fill_from_slice(&numbers); + let staging_buffer = device.create_buffer_with_data( + numbers.as_slice(), + wgpu::BufferUsage::MAP_READ + | wgpu::BufferUsage::COPY_DST + | wgpu::BufferUsage::COPY_SRC, + ); let storage_buffer = device.create_buffer(&wgpu::BufferDescriptor { size, @@ -94,10 +99,17 @@ fn multithreaded_compute() { } encoder.copy_buffer_to_buffer(&storage_buffer, 0, &staging_buffer, 0, size); - device.get_queue().submit(&[encoder.finish()]); + queue.submit(&[encoder.finish()]); - staging_buffer.map_read_async(0, size, |result: wgpu::BufferMapAsyncResult<&[u32]>| { - assert_eq!(result.unwrap().data, [25, 25, 25]); + // FIXME: Align and use `LayoutVerified` + staging_buffer.map_read_async(0, slice_size, |result| { + let result_data: Box<[u32]> = result + .unwrap() + .data + .chunks_exact(std::mem::size_of::()) + .map(|c| u32::from_ne_bytes(c.try_into().unwrap())) + .collect(); + assert_eq!(&*result_data, &[25, 25, 25]); }); tx.send(true).unwrap(); });