[rs] Update examples and tests

This commit is contained in:
Jacob Greenfield 2019-11-21 17:43:25 -05:00
parent ae18c20fa2
commit 9cc89d6ccf
7 changed files with 164 additions and 125 deletions

View File

@ -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::<Vertex>();
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 });

View File

@ -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::<u32>()) as wgpu::BufferAddress;
let slice_size = numbers.len() * std::mem::size_of::<u32>();
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);
}
});
}

View File

@ -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::<Vertex>();
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 });

View File

@ -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 {

View File

@ -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::<Vertex>();
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::<EntityUniforms>() 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::<ForwardUniforms>() 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::<EntityUniforms>() as wgpu::BufferAddress;
let temp_buf_data =
device.create_buffer_mapped(self.entities.len(), wgpu::BufferUsage::COPY_SRC);
let size = mem::size_of::<EntityUniforms>();
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::<LightRaw>()) as wgpu::BufferAddress;
let size = mem::size_of::<LightRaw>();
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,
);
}

View File

@ -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<f32>; 2];
type Uniform = cgmath::Matrix4<f32>;
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::<Uniforms>(), usage);
// FIXME: Align and use `LayoutVerified`
for (u, slot) in uniforms.iter().zip(
uniform_buf
.data
.chunks_exact_mut(std::mem::size_of::<Uniform>()),
) {
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::<Uniforms>();
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::<f32>::from_angle_x(cgmath::Deg(0.25));
self.uniforms[1] = self.uniforms[1] * rotation;
let uniform_buf_size = std::mem::size_of::<Uniforms>();
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,

View File

@ -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::<u32>()) as wgpu::BufferAddress;
let slice_size = numbers.len() * std::mem::size_of::<u32>();
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::<u32>())
.map(|c| u32::from_ne_bytes(c.try_into().unwrap()))
.collect();
assert_eq!(&*result_data, &[25, 25, 25]);
});
tx.send(true).unwrap();
});