[rs] cargo fmt the code and tweak format rules

This commit is contained in:
Hackpoetic
2020-04-10 22:52:59 -04:00
parent 877e0016eb
commit 1927fe6586
14 changed files with 372 additions and 367 deletions

View File

@@ -7,11 +7,10 @@ extern crate rand;
mod framework;
use std::fmt::Write;
use zerocopy::{AsBytes};
use zerocopy::AsBytes;
use wgpu::vertex_attr_array;
// number of boid particles to simulate
const NUM_PARTICLES: u32 = 1500;
@@ -20,7 +19,6 @@ const NUM_PARTICLES: u32 = 1500;
const PARTICLES_PER_GROUP: u32 = 64;
/// Example struct holds references to wgpu resources and frame persistent data
struct Example {
particle_bind_groups: Vec<wgpu::BindGroup>,
@@ -32,15 +30,12 @@ struct Example {
frame_num: usize,
}
impl framework::Example for Example {
/// constructs initial instance of Example struct
fn init(
sc_desc: &wgpu::SwapChainDescriptor,
device: &wgpu::Device,
) -> (Self, Option<wgpu::CommandBuffer>) {
// loads comp shader source and adds shared constants as defines to comp shader
const BOIDS_SOURCE: &str = include_str!("boids.comp");
@@ -48,7 +43,12 @@ impl framework::Example for Example {
assert_eq!(BOIDS_SOURCE.lines().next(), Some(HEADER));
let mut boids_source_str = String::from(HEADER);
write!(boids_source_str, "\n#define NUM_PARTICLES {}\n#define PARTICLES_PER_GROUP {}", NUM_PARTICLES, PARTICLES_PER_GROUP).unwrap();
write!(
boids_source_str,
"\n#define NUM_PARTICLES {}\n#define PARTICLES_PER_GROUP {}",
NUM_PARTICLES, PARTICLES_PER_GROUP
)
.unwrap();
boids_source_str += &BOIDS_SOURCE[HEADER.len()..];
// load (and compile) shaders and create shader modules
@@ -59,42 +59,52 @@ impl framework::Example for Example {
let vs = framework::load_glsl(include_str!("shader.vert"), framework::ShaderStage::Vertex);
let vs_module = device.create_shader_module(&vs);
let fs = framework::load_glsl(include_str!("shader.frag"), framework::ShaderStage::Fragment);
let fs = framework::load_glsl(
include_str!("shader.frag"),
framework::ShaderStage::Fragment,
);
let fs_module = device.create_shader_module(&fs);
// create compute bind layout group and compute pipeline layout
let compute_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
bindings: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::COMPUTE,
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::COMPUTE,
ty: wgpu::BindingType::StorageBuffer { dynamic: false, readonly: false },
},
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStage::COMPUTE,
ty: wgpu::BindingType::StorageBuffer { dynamic: false, readonly: false },
},
],
label: None,
});
let compute_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
bind_group_layouts: &[&compute_bind_group_layout],
});
let compute_bind_group_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
bindings: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::COMPUTE,
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::COMPUTE,
ty: wgpu::BindingType::StorageBuffer {
dynamic: false,
readonly: false,
},
},
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStage::COMPUTE,
ty: wgpu::BindingType::StorageBuffer {
dynamic: false,
readonly: false,
},
},
],
label: None,
});
let compute_pipeline_layout =
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
bind_group_layouts: &[&compute_bind_group_layout],
});
// create render pipeline with empty bind group layout
let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
bind_group_layouts: &[],
});
let render_pipeline_layout =
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
bind_group_layouts: &[],
});
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
layout: &render_pipeline_layout,
@@ -141,7 +151,6 @@ impl framework::Example for Example {
alpha_to_coverage_enabled: false,
});
// create compute pipeline
let compute_pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
@@ -152,7 +161,6 @@ impl framework::Example for Example {
},
});
// buffer for the three 2d triangle vertices of each instance
let vertex_buffer_data = [-0.01f32, -0.02, 0.01, -0.02, 0.00, 0.02];
@@ -161,7 +169,6 @@ impl framework::Example for Example {
wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST,
);
// buffer for simulation parameters uniform
let sim_param_data = [
@@ -171,14 +178,14 @@ impl framework::Example for Example {
0.025, // rule3Distance
0.02, // rule1Scale
0.05, // rule2Scale
0.005 // rule3Scale
].to_vec();
0.005, // rule3Scale
]
.to_vec();
let sim_param_buffer = device.create_buffer_with_data(
sim_param_data.as_bytes(),
wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
);
// buffer for all particles data of type [(posx,posy,velx,vely),...]
let mut initial_particle_data = vec![0.0f32; (4 * NUM_PARTICLES) as usize];
@@ -186,77 +193,75 @@ impl framework::Example for Example {
particle_instance_chunk[0] = 2.0 * (rand::random::<f32>() - 0.5); // posx
particle_instance_chunk[1] = 2.0 * (rand::random::<f32>() - 0.5); // posy
particle_instance_chunk[2] = 2.0 * (rand::random::<f32>() - 0.5) * 0.1; // velx
particle_instance_chunk[3] = 2.0 * (rand::random::<f32>() - 0.5) * 0.1; // vely
particle_instance_chunk[3] = 2.0 * (rand::random::<f32>() - 0.5) * 0.1;
// vely
}
// creates two buffers of particle data each of size NUM_PARTICLES
// the two buffers alternate as dst and src for each frame
let mut particle_buffers = Vec::<wgpu::Buffer>::new();
let mut particle_bind_groups = Vec::<wgpu::BindGroup>::new();
for _i in 0..2 {
particle_buffers.push(
device.create_buffer_with_data(
initial_particle_data.as_bytes(),
wgpu::BufferUsage::VERTEX
| wgpu::BufferUsage::STORAGE
| wgpu::BufferUsage::COPY_DST,
)
);
particle_buffers.push(device.create_buffer_with_data(
initial_particle_data.as_bytes(),
wgpu::BufferUsage::VERTEX
| wgpu::BufferUsage::STORAGE
| wgpu::BufferUsage::COPY_DST,
));
}
// create two bind groups, one for each buffer as the src
// where the alternate buffer is used as the dst
for i in 0..2 {
particle_bind_groups.push(device.create_bind_group(
&wgpu::BindGroupDescriptor {
layout: &compute_bind_group_layout,
bindings: &[
wgpu::Binding {
binding: 0,
resource: wgpu::BindingResource::Buffer {
buffer: &sim_param_buffer,
range: 0 .. (4 * sim_param_data.len() as u64), // 4 = size_of f32
},
particle_bind_groups.push(device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &compute_bind_group_layout,
bindings: &[
wgpu::Binding {
binding: 0,
resource: wgpu::BindingResource::Buffer {
buffer: &sim_param_buffer,
range: 0..(4 * sim_param_data.len() as u64), // 4 = size_of f32
},
wgpu::Binding {
binding: 1,
resource: wgpu::BindingResource::Buffer {
buffer: &particle_buffers[i],
range: 0 .. (4 * initial_particle_data.len() as u64), // 4 = size_of f32
},
},
wgpu::Binding {
binding: 1,
resource: wgpu::BindingResource::Buffer {
buffer: &particle_buffers[i],
range: 0..(4 * initial_particle_data.len() as u64), // 4 = size_of f32
},
wgpu::Binding {
binding: 2,
resource: wgpu::BindingResource::Buffer {
buffer: &particle_buffers[(i + 1) % 2], // bind to opposite buffer
range: 0 .. (4 * initial_particle_data.len() as u64), // 4 = size_of f32
},
},
wgpu::Binding {
binding: 2,
resource: wgpu::BindingResource::Buffer {
buffer: &particle_buffers[(i + 1) % 2], // bind to opposite buffer
range: 0..(4 * initial_particle_data.len() as u64), // 4 = size_of f32
},
],
label: None,
}
));
},
],
label: None,
}));
}
// calculates number of work groups from PARTICLES_PER_GROUP constant
let work_group_count = ((NUM_PARTICLES as f32) / (PARTICLES_PER_GROUP as f32)).ceil() as u32;
let work_group_count =
((NUM_PARTICLES as f32) / (PARTICLES_PER_GROUP as f32)).ceil() as u32;
// returns Example struct and No encoder commands
(Example {
particle_bind_groups,
particle_buffers,
vertices_buffer,
compute_pipeline,
render_pipeline,
work_group_count,
frame_num: 0,
}, None)
(
Example {
particle_bind_groups,
particle_buffers,
vertices_buffer,
compute_pipeline,
render_pipeline,
work_group_count,
frame_num: 0,
},
None,
)
}
/// update is called for any WindowEvent not handled by the framework
@@ -273,7 +278,6 @@ impl framework::Example for Example {
None
}
/// render is called each frame, dispatching compute groups proportional
/// a TriangleList draw call for all NUM_PARTICLES at 3 vertices each
fn render(
@@ -281,7 +285,6 @@ impl framework::Example for Example {
frame: &wgpu::SwapChainOutput,
device: &wgpu::Device,
) -> wgpu::CommandBuffer {
// create render pass descriptor
let render_pass_descriptor = wgpu::RenderPassDescriptor {
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
@@ -323,10 +326,8 @@ impl framework::Example for Example {
// done
command_encoder.finish()
}
}
/// run example
fn main() {
framework::run::<Example>("boids");

View File

@@ -15,13 +15,14 @@ async fn run() {
.await
.unwrap();
let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: wgpu::Limits::default(),
})
.await;
let (device, queue) = adapter
.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: wgpu::Limits::default(),
})
.await;
// Rendered image is 256×256 with 32-bit RGBA color
let size = 256u32;

View File

@@ -66,7 +66,7 @@ fn create_vertices() -> (Vec<Vertex>, Vec<u16>) {
fn create_texels(size: usize) -> Vec<u8> {
use std::iter;
(0 .. size * size)
(0..size * size)
.flat_map(|id| {
// get high five for recognizing this ;)
let cx = 3.0 * (id % size) as f32 / (size - 1) as f32 - 2.0;
@@ -221,7 +221,7 @@ impl framework::Example for Example {
binding: 0,
resource: wgpu::BindingResource::Buffer {
buffer: &uniform_buf,
range: 0 .. 64,
range: 0..64,
},
},
wgpu::Binding {
@@ -353,9 +353,9 @@ impl framework::Example for Example {
});
rpass.set_pipeline(&self.pipeline);
rpass.set_bind_group(0, &self.bind_group, &[]);
rpass.set_index_buffer(&self.index_buf, 0,0 );
rpass.set_index_buffer(&self.index_buf, 0, 0);
rpass.set_vertex_buffer(0, &self.vertex_buf, 0, 0);
rpass.draw_indexed(0 .. self.index_count as u32, 0, 0 .. 1);
rpass.draw_indexed(0..self.index_count as u32, 0, 0..1);
}
encoder.finish()

View File

@@ -109,13 +109,14 @@ async fn run_async<E: Example>(title: &str) {
.await
.unwrap();
let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: wgpu::Limits::default(),
})
.await;
let (device, queue) = adapter
.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: wgpu::Limits::default(),
})
.await;
let mut sc_desc = wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
@@ -170,7 +171,7 @@ async fn run_async<E: Example>(title: &str) {
_ => {
example.update(event);
}
}
},
event::Event::RedrawRequested(_) => {
let frame = swap_chain
.get_next_texture()

View File

@@ -31,13 +31,14 @@ async fn execute_gpu(numbers: Vec<u32>) -> Vec<u32> {
.await
.unwrap();
let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: wgpu::Limits::default(),
})
.await;
let (device, queue) = adapter
.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: wgpu::Limits::default(),
})
.await;
let cs = include_bytes!("shader.comp.spv");
let cs_module =
@@ -74,7 +75,7 @@ async fn execute_gpu(numbers: Vec<u32>) -> Vec<u32> {
binding: 0,
resource: wgpu::BindingResource::Buffer {
buffer: &storage_buffer,
range: 0 .. size,
range: 0..size,
},
}],
label: None,
@@ -92,7 +93,8 @@ async fn execute_gpu(numbers: Vec<u32>) -> Vec<u32> {
},
});
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
let mut encoder =
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
encoder.copy_buffer_to_buffer(&staging_buffer, 0, &storage_buffer, 0, size);
{
let mut cpass = encoder.begin_compute_pass();
@@ -134,15 +136,15 @@ mod tests {
use super::*;
#[test]
fn test_compute_1(){
let input = vec!(1, 2, 3, 4);
futures::executor::block_on(assert_execute_gpu(input, vec!(0, 1, 7, 2)));
fn test_compute_1() {
let input = vec![1, 2, 3, 4];
futures::executor::block_on(assert_execute_gpu(input, vec![0, 1, 7, 2]));
}
#[test]
fn test_compute_2(){
let input = vec!(5, 23, 10, 9);
futures::executor::block_on(assert_execute_gpu(input, vec!(5, 15, 6, 19)));
fn test_compute_2() {
let input = vec![5, 23, 10, 9];
futures::executor::block_on(assert_execute_gpu(input, vec![5, 15, 6, 19]));
}
#[test]
@@ -154,16 +156,16 @@ mod tests {
let thread_count = 8;
let (tx, rx) = mpsc::channel();
for _ in 0 .. thread_count {
for _ in 0..thread_count {
let tx = tx.clone();
thread::spawn(move || {
let input = vec![100, 100, 100];
futures::executor::block_on(assert_execute_gpu(input, vec!(25, 25, 25)));
futures::executor::block_on(assert_execute_gpu(input, vec![25, 25, 25]));
tx.send(true).unwrap();
});
}
for _ in 0 .. thread_count {
for _ in 0..thread_count {
rx.recv_timeout(Duration::from_secs(10))
.expect("A thread never completed.");
}

View File

@@ -1,7 +1,7 @@
use winit::{
event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::Window
window::Window,
};
async fn run(event_loop: EventLoop<()>, window: Window) {
@@ -18,13 +18,14 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
.await
.unwrap();
let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: wgpu::Limits::default(),
})
.await;
let (device, queue) = adapter
.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: wgpu::Limits::default(),
})
.await;
let vs = include_bytes!("shader.vert.spv");
let vs_module =
@@ -95,7 +96,10 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
*control_flow = ControlFlow::Poll;
match event {
Event::MainEventsCleared => window.request_redraw(),
Event::WindowEvent { event: WindowEvent::Resized(size), .. } => {
Event::WindowEvent {
event: WindowEvent::Resized(size),
..
} => {
sc_desc.width = size.width;
sc_desc.height = size.height;
swap_chain = device.create_swap_chain(&surface, &sc_desc);
@@ -104,9 +108,8 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
let frame = swap_chain
.get_next_texture()
.expect("Timeout when acquiring next swap chain texture");
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: None,
});
let mut encoder =
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
{
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
@@ -120,7 +123,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
});
rpass.set_pipeline(&render_pipeline);
rpass.set_bind_group(0, &bind_group, &[]);
rpass.draw(0 .. 3, 0 .. 1);
rpass.draw(0..3, 0..1);
}
queue.submit(&[encoder.finish()]);

View File

@@ -34,7 +34,7 @@ fn create_vertices() -> Vec<Vertex> {
fn create_texels(size: usize, cx: f32, cy: f32) -> Vec<u8> {
use std::iter;
(0 .. size * size)
(0..size * size)
.flat_map(|id| {
// get high five for recognizing this ;)
let mut x = 4.0 * (id % size) as f32 / (size - 1) as f32 - 2.0;
@@ -155,7 +155,7 @@ impl Example {
compare: wgpu::CompareFunction::Undefined,
});
let views = (0 .. mip_count)
let views = (0..mip_count)
.map(|mip| {
texture.create_view(&wgpu::TextureViewDescriptor {
format: TEXTURE_FORMAT,
@@ -169,7 +169,7 @@ impl Example {
})
.collect::<Vec<_>>();
for target_mip in 1 .. mip_count as usize {
for target_mip in 1..mip_count as usize {
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &bind_group_layout,
bindings: &[
@@ -197,7 +197,7 @@ impl Example {
});
rpass.set_pipeline(&pipeline);
rpass.set_bind_group(0, &bind_group, &[]);
rpass.draw(0 .. 4, 0 .. 1);
rpass.draw(0..4, 0..1);
}
}
}
@@ -314,7 +314,7 @@ impl framework::Example for Example {
binding: 0,
resource: wgpu::BindingResource::Buffer {
buffer: &uniform_buf,
range: 0 .. 64,
range: 0..64,
},
},
wgpu::Binding {
@@ -434,7 +434,7 @@ impl framework::Example for Example {
rpass.set_pipeline(&self.draw_pipeline);
rpass.set_bind_group(0, &self.bind_group, &[]);
rpass.set_vertex_buffer(0, &self.vertex_buf, 0, 0);
rpass.draw(0 .. 4, 0 .. 1);
rpass.draw(0..4, 0..1);
}
encoder.finish()

View File

@@ -145,7 +145,7 @@ impl framework::Example for Example {
let mut vertex_data = vec![];
let max = 50;
for i in 0 .. max {
for i in 0..max {
let percent = i as f32 / max as f32;
let (sin, cos) = (percent * 2.0 * std::f32::consts::PI).sin_cos();
vertex_data.push(Vertex {
@@ -259,7 +259,7 @@ impl framework::Example for Example {
});
rpass.set_pipeline(&self.pipeline);
rpass.set_vertex_buffer(0, &self.vertex_buffer, 0, 0);
rpass.draw(0 .. self.vertex_count, 0 .. 1);
rpass.draw(0..self.vertex_count, 0..1);
}
encoder.finish()

View File

@@ -241,7 +241,7 @@ impl framework::Example for Example {
binding: 0,
resource: wgpu::BindingResource::Buffer {
buffer: &plane_uniform_buf,
range: 0 .. entity_uniform_size,
range: 0..entity_uniform_size,
},
}],
label: None,
@@ -317,7 +317,7 @@ impl framework::Example for Example {
binding: 0,
resource: wgpu::BindingResource::Buffer {
buffer: &uniform_buf,
range: 0 .. entity_uniform_size,
range: 0..entity_uniform_size,
},
}],
label: None,
@@ -351,7 +351,7 @@ impl framework::Example for Example {
});
let shadow_view = shadow_texture.create_default_view();
let mut shadow_target_views = (0 .. 2)
let mut shadow_target_views = (0..2)
.map(|i| {
Some(shadow_texture.create_view(&wgpu::TextureViewDescriptor {
format: Self::SHADOW_FORMAT,
@@ -374,7 +374,7 @@ impl framework::Example for Example {
a: 1.0,
},
fov: 60.0,
depth: 1.0 .. 20.0,
depth: 1.0..20.0,
target_view: shadow_target_views[0].take().unwrap(),
},
Light {
@@ -386,7 +386,7 @@ impl framework::Example for Example {
a: 1.0,
},
fov: 45.0,
depth: 1.0 .. 20.0,
depth: 1.0..20.0,
target_view: shadow_target_views[1].take().unwrap(),
},
];
@@ -435,7 +435,7 @@ impl framework::Example for Example {
binding: 0,
resource: wgpu::BindingResource::Buffer {
buffer: &uniform_buf,
range: 0 .. uniform_size,
range: 0..uniform_size,
},
}],
label: None,
@@ -548,14 +548,14 @@ impl framework::Example for Example {
binding: 0,
resource: wgpu::BindingResource::Buffer {
buffer: &uniform_buf,
range: 0 .. uniform_size,
range: 0..uniform_size,
},
},
wgpu::Binding {
binding: 1,
resource: wgpu::BindingResource::Buffer {
buffer: &light_uniform_buf,
range: 0 .. light_uniform_size,
range: 0..light_uniform_size,
},
},
wgpu::Binding {
@@ -757,7 +757,7 @@ impl framework::Example for Example {
let temp_buf_data = device.create_buffer_mapped(&wgpu::BufferDescriptor {
size: total_size as u64,
usage: wgpu::BufferUsage::COPY_SRC,
label: None
label: None,
});
// FIXME: Align and use `LayoutVerified`
for (light, slot) in self
@@ -806,7 +806,7 @@ impl framework::Example for Example {
pass.set_bind_group(1, &entity.bind_group, &[]);
pass.set_index_buffer(&entity.index_buf, 0, 0);
pass.set_vertex_buffer(0, &entity.vertex_buf, 0, 0);
pass.draw_indexed(0 .. entity.index_count as u32, 0, 0 .. 1);
pass.draw_indexed(0..entity.index_count as u32, 0, 0..1);
}
}
@@ -842,7 +842,7 @@ impl framework::Example for Example {
pass.set_bind_group(1, &entity.bind_group, &[]);
pass.set_index_buffer(&entity.index_buf, 0, 0);
pass.set_vertex_buffer(0, &entity.vertex_buf, 0, 0);
pass.draw_indexed(0 .. entity.index_count as u32, 0, 0 .. 1);
pass.draw_indexed(0..entity.index_count as u32, 0, 0..1);
}
}

View File

@@ -239,7 +239,7 @@ impl framework::Example for Skybox {
binding: 0,
resource: wgpu::BindingResource::Buffer {
buffer: &uniform_buf,
range: 0 .. uniform_buf_size as wgpu::BufferAddress,
range: 0..uniform_buf_size as wgpu::BufferAddress,
},
},
wgpu::Binding {
@@ -328,7 +328,7 @@ impl framework::Example for Skybox {
rpass.set_pipeline(&self.pipeline);
rpass.set_bind_group(0, &self.bind_group, &[]);
rpass.draw(0 .. 3 as u32, 0 .. 1);
rpass.draw(0..3 as u32, 0..1);
}
init_encoder.finish()
}

View File

@@ -1,3 +0,0 @@
imports_layout = "HorizontalVertical"
newline_style = "Native"
spaces_around_ranges = true

View File

@@ -1,9 +1,9 @@
use crate::BufferAddress;
use parking_lot::Mutex;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use std::task::{Context, Poll, Waker};
use parking_lot::Mutex;
use crate::BufferAddress;
enum WakerOrResult<T> {
Waker(Waker),
@@ -28,8 +28,7 @@ pub struct GpuFutureCompletion<T> {
data: Arc<Data<T>>,
}
impl<T> Future for GpuFuture<T>
{
impl<T> Future for GpuFuture<T> {
type Output = T;
fn poll(self: Pin<&mut Self>, context: &mut Context) -> Poll<Self::Output> {
@@ -56,7 +55,7 @@ impl<T> GpuFutureCompletion<T> {
// Drop before panicking. Not sure if this is necessary, but it makes me feel better.
drop(waker_or_result);
unreachable!()
},
}
};
}
@@ -66,7 +65,7 @@ impl<T> GpuFutureCompletion<T> {
pub(crate) unsafe fn from_raw(this: *mut OpaqueData) -> Self {
Self {
data: Arc::from_raw(this as _)
data: Arc::from_raw(this as _),
}
}

View File

@@ -9,76 +9,26 @@ mod macros;
use arrayvec::ArrayVec;
use smallvec::SmallVec;
use std::{
ffi::CString,
ops::Range,
future::Future,
ptr,
slice,
thread,
};
use std::{ffi::CString, future::Future, ops::Range, ptr, slice, thread};
pub use wgc::instance::{AdapterInfo, DeviceType};
pub use wgt::{
AddressMode,
Backend,
BackendBit,
BlendDescriptor,
BlendFactor,
BlendOperation,
BufferAddress,
BufferUsage,
Color,
ColorStateDescriptor,
ColorWrite,
CommandBufferDescriptor,
CompareFunction,
CullMode,
DepthStencilStateDescriptor,
DeviceDescriptor,
DynamicOffset,
Extensions,
Extent3d,
FilterMode,
FrontFace,
IndexFormat,
InputStepMode,
Limits,
LoadOp,
Origin3d,
PowerPreference,
PresentMode,
PrimitiveTopology,
RasterizationStateDescriptor,
SamplerDescriptor,
ShaderLocation,
ShaderStage,
StencilOperation,
StencilStateFaceDescriptor,
StoreOp,
SwapChainDescriptor,
TextureAspect,
TextureComponentType,
TextureDimension,
TextureFormat,
TextureUsage,
TextureViewDescriptor,
TextureViewDimension,
VertexAttributeDescriptor,
VertexFormat,
BIND_BUFFER_ALIGNMENT,
MAX_BIND_GROUPS,
read_spirv,
};
pub use wgc::instance::{
AdapterInfo,
DeviceType,
read_spirv, AddressMode, Backend, BackendBit, BlendDescriptor, BlendFactor, BlendOperation,
BufferAddress, BufferUsage, Color, ColorStateDescriptor, ColorWrite, CommandBufferDescriptor,
CompareFunction, CullMode, DepthStencilStateDescriptor, DeviceDescriptor, DynamicOffset,
Extensions, Extent3d, FilterMode, FrontFace, IndexFormat, InputStepMode, Limits, LoadOp,
Origin3d, PowerPreference, PresentMode, PrimitiveTopology, RasterizationStateDescriptor,
SamplerDescriptor, ShaderLocation, ShaderStage, StencilOperation, StencilStateFaceDescriptor,
StoreOp, SwapChainDescriptor, TextureAspect, TextureComponentType, TextureDimension,
TextureFormat, TextureUsage, TextureViewDescriptor, TextureViewDimension,
VertexAttributeDescriptor, VertexFormat, BIND_BUFFER_ALIGNMENT, MAX_BIND_GROUPS,
};
//TODO: avoid heap allocating vectors during resource creation.
#[derive(Default, Debug)]
struct Temp {
//bind_group_descriptors: Vec<wgn::BindGroupDescriptor>,
//vertex_buffers: Vec<wgn::VertexBufferDescriptor>,
//vertex_buffers: Vec<wgn::VertexBufferDescriptor>,
}
/// A handle to a physical graphics and/or compute device.
@@ -457,8 +407,7 @@ pub struct RenderPassDescriptor<'a, 'b> {
pub color_attachments: &'b [RenderPassColorAttachmentDescriptor<'a>],
/// The depth and stencil attachment of the render pass, if any.
pub depth_stencil_attachment:
Option<RenderPassDepthStencilAttachmentDescriptor<'a>>,
pub depth_stencil_attachment: Option<RenderPassDepthStencilAttachmentDescriptor<'a>>,
}
/// A description of a buffer.
@@ -587,7 +536,10 @@ impl CreateBufferMapped<'_> {
/// Unmaps the buffer from host memory and returns a [`Buffer`].
pub fn finish(self) -> Buffer {
wgn::wgpu_buffer_unmap(self.id);
Buffer { device_id: self.device_id, id: self.id }
Buffer {
device_id: self.device_id,
id: self.id,
}
}
}
@@ -621,7 +573,10 @@ impl Adapter {
/// Some options are "soft", so treated as non-mandatory. Others are "hard".
///
/// If no adapters are found that suffice all the "hard" options, `None` is returned.
pub async fn request(options: &RequestAdapterOptions<'_>, backends: BackendBit) -> Option<Self> {
pub async fn request(
options: &RequestAdapterOptions<'_>,
backends: BackendBit,
) -> Option<Self> {
unsafe extern "C" fn adapter_callback(
id: Option<wgc::id::AdapterId>,
user_data: *mut std::ffi::c_void,
@@ -634,8 +589,7 @@ impl Adapter {
wgn::wgpu_request_adapter_async(
Some(&wgc::instance::RequestAdapterOptions {
power_preference: options.power_preference,
compatible_surface: options.compatible_surface
.map(|surface| surface.id),
compatible_surface: options.compatible_surface.map(|surface| surface.id),
}),
backends,
adapter_callback,
@@ -670,10 +624,13 @@ impl Adapter {
impl Device {
/// Check for resource cleanups and mapping callbacks.
pub fn poll(&self, maintain: Maintain) {
wgn::wgpu_device_poll(self.id, match maintain {
Maintain::Poll => false,
Maintain::Wait => true,
});
wgn::wgpu_device_poll(
self.id,
match maintain {
Maintain::Poll => false,
Maintain::Wait => true,
},
);
}
/// Creates a shader module from SPIR-V source code.
@@ -769,13 +726,11 @@ impl Device {
BindingType::StorageTexture { readonly: true, .. } => {
bm::BindingType::ReadonlyStorageTexture
}
BindingType::StorageTexture { .. } => {
bm::BindingType::WriteonlyStorageTexture
}
BindingType::StorageTexture { .. } => bm::BindingType::WriteonlyStorageTexture,
},
has_dynamic_offset: match bind.ty {
BindingType::UniformBuffer { dynamic } |
BindingType::StorageBuffer { dynamic, .. } => dynamic,
BindingType::UniformBuffer { dynamic }
| BindingType::StorageBuffer { dynamic, .. } => dynamic,
_ => false,
},
multisampled: match bind.ty {
@@ -783,13 +738,13 @@ impl Device {
_ => false,
},
view_dimension: match bind.ty {
BindingType::SampledTexture { dimension, .. } |
BindingType::StorageTexture { dimension, .. } => dimension,
BindingType::SampledTexture { dimension, .. }
| BindingType::StorageTexture { dimension, .. } => dimension,
_ => TextureViewDimension::D2,
},
texture_component_type: match bind.ty {
BindingType::SampledTexture { component_type, .. } |
BindingType::StorageTexture { component_type, .. } => component_type,
BindingType::SampledTexture { component_type, .. }
| BindingType::StorageTexture { component_type, .. } => component_type,
_ => TextureComponentType::Float,
},
storage_texture_format: match bind.ty {
@@ -853,7 +808,8 @@ impl Device {
let temp_color_states = desc.color_states.to_vec();
let temp_vertex_buffers = desc
.vertex_state.vertex_buffers
.vertex_state
.vertex_buffers
.iter()
.map(|vbuf| pipe::VertexBufferLayoutDescriptor {
array_stride: vbuf.stride,
@@ -927,7 +883,7 @@ impl Device {
label: owned_label.as_ptr(),
size: desc.size,
usage: desc.usage,
}
},
),
}
}
@@ -950,12 +906,17 @@ impl Device {
size: desc.size,
usage: desc.usage,
},
&mut data_ptr as *mut *mut u8);
&mut data_ptr as *mut *mut u8,
);
let data = std::slice::from_raw_parts_mut(data_ptr as *mut u8, desc.size as usize);
(id, data)
};
CreateBufferMapped { device_id: self.id, id, data }
CreateBufferMapped {
device_id: self.id,
id,
data,
}
}
/// Creates a new buffer, maps it into host-visible memory, copies data from the given slice,
@@ -976,16 +937,19 @@ impl Device {
pub fn create_texture(&self, desc: &TextureDescriptor) -> Texture {
let owned_label = OwnedLabel::new(desc.label.as_deref());
Texture {
id: wgn::wgpu_device_create_texture(self.id, &wgt::TextureDescriptor {
label: owned_label.as_ptr(),
size: desc.size,
array_layer_count: desc.array_layer_count,
mip_level_count: desc.mip_level_count,
sample_count: desc.sample_count,
dimension: desc.dimension,
format: desc.format,
usage: desc.usage,
}),
id: wgn::wgpu_device_create_texture(
self.id,
&wgt::TextureDescriptor {
label: owned_label.as_ptr(),
size: desc.size,
array_layer_count: desc.array_layer_count,
mip_level_count: desc.mip_level_count,
sample_count: desc.sample_count,
dimension: desc.dimension,
format: desc.format,
usage: desc.usage,
},
),
owned: true,
}
}
@@ -1028,12 +992,9 @@ pub struct BufferReadMapping {
unsafe impl Send for BufferReadMapping {}
unsafe impl Sync for BufferReadMapping {}
impl BufferReadMapping
{
impl BufferReadMapping {
pub fn as_slice(&self) -> &[u8] {
unsafe {
slice::from_raw_parts(self.data as *const u8, self.size)
}
unsafe { slice::from_raw_parts(self.data as *const u8, self.size) }
}
}
@@ -1052,12 +1013,9 @@ pub struct BufferWriteMapping {
unsafe impl Send for BufferWriteMapping {}
unsafe impl Sync for BufferWriteMapping {}
impl BufferWriteMapping
{
impl BufferWriteMapping {
pub fn as_slice(&mut self) -> &mut [u8] {
unsafe {
slice::from_raw_parts_mut(self.data as *mut u8, self.size)
}
unsafe { slice::from_raw_parts_mut(self.data as *mut u8, self.size) }
}
}
@@ -1067,33 +1025,29 @@ impl Drop for BufferWriteMapping {
}
}
impl Buffer {
/// Map the buffer for reading. The result is returned in a future.
///
///
/// For the future to complete, `device.poll(...)` must be called elsewhere in the runtime, possibly integrated
/// into an event loop, run on a separate thread, or continually polled in the same task runtime that this
/// future will be run on.
///
///
/// It's expected that wgpu will eventually supply its own event loop infrastructure that will be easy to integrate
/// into other event loops, like winit's.
pub fn map_read(&self, start: BufferAddress, size: BufferAddress) -> impl Future<Output = Result<BufferReadMapping, BufferAsyncErr>>
{
let (future, completion) = native_gpu_future::new_gpu_future(
self.id,
size,
);
pub fn map_read(
&self,
start: BufferAddress,
size: BufferAddress,
) -> impl Future<Output = Result<BufferReadMapping, BufferAsyncErr>> {
let (future, completion) = native_gpu_future::new_gpu_future(self.id, size);
extern "C" fn buffer_map_read_future_wrapper(
status: wgc::resource::BufferMapAsyncStatus,
data: *const u8,
user_data: *mut u8,
)
{
let completion = unsafe {
native_gpu_future::GpuFutureCompletion::from_raw(user_data as _)
};
) {
let completion =
unsafe { native_gpu_future::GpuFutureCompletion::from_raw(user_data as _) };
let (buffer_id, size) = completion.get_buffer_info();
if let wgc::resource::BufferMapAsyncStatus::Success = status {
@@ -1119,25 +1073,23 @@ impl Buffer {
}
/// Map the buffer for writing. The result is returned in a future.
///
///
/// See the documentation of (map_read)[#method.map_read] for more information about
/// how to run this future.
pub fn map_write(&self, start: BufferAddress, size: BufferAddress) -> impl Future<Output = Result<BufferWriteMapping, BufferAsyncErr>>
{
let (future, completion) = native_gpu_future::new_gpu_future(
self.id,
size,
);
pub fn map_write(
&self,
start: BufferAddress,
size: BufferAddress,
) -> impl Future<Output = Result<BufferWriteMapping, BufferAsyncErr>> {
let (future, completion) = native_gpu_future::new_gpu_future(self.id, size);
extern "C" fn buffer_map_write_future_wrapper(
status: wgc::resource::BufferMapAsyncStatus,
data: *mut u8,
user_data: *mut u8,
)
{
let completion = unsafe {
native_gpu_future::GpuFutureCompletion::from_raw(user_data as _)
};
) {
let completion =
unsafe { native_gpu_future::GpuFutureCompletion::from_raw(user_data as _) };
let (buffer_id, size) = completion.get_buffer_info();
if let wgc::resource::BufferMapAsyncStatus::Success = status {
@@ -1267,9 +1219,7 @@ impl CommandEncoder {
/// This function returns a [`ComputePass`] object which records a single compute pass.
pub fn begin_compute_pass(&mut self) -> ComputePass {
ComputePass {
id: unsafe {
wgn::wgpu_command_encoder_begin_compute_pass(self.id, None)
},
id: unsafe { wgn::wgpu_command_encoder_begin_compute_pass(self.id, None) },
_parent: self,
}
}
@@ -1363,19 +1313,13 @@ impl<'a> RenderPass<'a> {
/// Subsequent draw calls will exhibit the behavior defined by `pipeline`.
pub fn set_pipeline(&mut self, pipeline: &'a RenderPipeline) {
unsafe {
wgn::wgpu_render_pass_set_pipeline(
self.id.as_mut().unwrap(),
pipeline.id,
);
wgn::wgpu_render_pass_set_pipeline(self.id.as_mut().unwrap(), pipeline.id);
}
}
pub fn set_blend_color(&mut self, color: Color) {
unsafe {
wgn::wgpu_render_pass_set_blend_color(
self.id.as_mut().unwrap(),
&color,
);
wgn::wgpu_render_pass_set_blend_color(self.id.as_mut().unwrap(), &color);
}
}
@@ -1438,10 +1382,7 @@ impl<'a> RenderPass<'a> {
/// Subsequent draw calls will discard any fragments that fall outside this region.
pub fn set_scissor_rect(&mut self, x: u32, y: u32, w: u32, h: u32) {
unsafe {
wgn::wgpu_render_pass_set_scissor_rect(
self.id.as_mut().unwrap(),
x, y, w, h,
);
wgn::wgpu_render_pass_set_scissor_rect(self.id.as_mut().unwrap(), x, y, w, h);
}
}
@@ -1452,8 +1393,12 @@ impl<'a> RenderPass<'a> {
unsafe {
wgn::wgpu_render_pass_set_viewport(
self.id.as_mut().unwrap(),
x, y, w, h,
min_depth, max_depth,
x,
y,
w,
h,
min_depth,
max_depth,
);
}
}
@@ -1463,10 +1408,7 @@ impl<'a> RenderPass<'a> {
/// Subsequent stencil tests will test against this value.
pub fn set_stencil_reference(&mut self, reference: u32) {
unsafe {
wgn::wgpu_render_pass_set_stencil_reference(
self.id.as_mut().unwrap(),
reference,
);
wgn::wgpu_render_pass_set_stencil_reference(self.id.as_mut().unwrap(), reference);
}
}
@@ -1567,10 +1509,7 @@ impl<'a> ComputePass<'a> {
/// Sets the active compute pipeline.
pub fn set_pipeline(&mut self, pipeline: &'a ComputePipeline) {
unsafe {
wgn::wgpu_compute_pass_set_pipeline(
self.id.as_mut().unwrap(),
pipeline.id,
);
wgn::wgpu_compute_pass_set_pipeline(self.id.as_mut().unwrap(), pipeline.id);
}
}
@@ -1579,15 +1518,16 @@ impl<'a> ComputePass<'a> {
/// `x`, `y` and `z` denote the number of work groups to dispatch in each dimension.
pub fn dispatch(&mut self, x: u32, y: u32, z: u32) {
unsafe {
wgn::wgpu_compute_pass_dispatch(
self.id.as_mut().unwrap(),
x, y, z,
);
wgn::wgpu_compute_pass_dispatch(self.id.as_mut().unwrap(), x, y, z);
}
}
/// Dispatches compute work operations, based on the contents of the `indirect_buffer`.
pub fn dispatch_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: BufferAddress) {
pub fn dispatch_indirect(
&mut self,
indirect_buffer: &'a Buffer,
indirect_offset: BufferAddress,
) {
unsafe {
wgn::wgpu_compute_pass_dispatch_indirect(
self.id.as_mut().unwrap(),
@@ -1611,7 +1551,8 @@ impl<'a> Drop for ComputePass<'a> {
impl Queue {
/// Submits a series of finished command buffers for execution.
pub fn submit(&self, command_buffers: &[CommandBuffer]) {
let temp_command_buffers = command_buffers.iter()
let temp_command_buffers = command_buffers
.iter()
.map(|cb| cb.id)
.collect::<SmallVec<[_; 4]>>();

View File

@@ -33,36 +33,96 @@ macro_rules! vertex_attr_array {
// For internal usage
#[macro_export]
macro_rules! vertex_format_size {
(Uchar2) => { 2 };
(Uchar4) => { 4 };
(Char2) => { 2 };
(Char4) => { 4 };
(Uchar2Norm) => { 2 };
(Uchar4Norm) => { 4 };
(Char2Norm) => { 2 };
(Char4Norm) => { 4 };
(Ushort2) => { 4 };
(Ushort4) => { 8 };
(Short2) => { 4 };
(Short4) => { 8 };
(Ushort2Norm) => { 4 };
(Ushort4Norm) => { 8 };
(Short2Norm) => { 4 };
(Short4Norm) => { 8 };
(Half2) => { 4 };
(Half4) => { 8 };
(Float) => { 4 };
(Float2) => { 8 };
(Float3) => { 12 };
(Float4) => { 16 };
(Uint) => { 4 };
(Uint2) => { 8 };
(Uint3) => { 12 };
(Uint4) => { 16 };
(Int) => { 4 };
(Int2) => { 8 };
(Int3) => { 12 };
(Int4) => { 16 };
(Uchar2) => {
2
};
(Uchar4) => {
4
};
(Char2) => {
2
};
(Char4) => {
4
};
(Uchar2Norm) => {
2
};
(Uchar4Norm) => {
4
};
(Char2Norm) => {
2
};
(Char4Norm) => {
4
};
(Ushort2) => {
4
};
(Ushort4) => {
8
};
(Short2) => {
4
};
(Short4) => {
8
};
(Ushort2Norm) => {
4
};
(Ushort4Norm) => {
8
};
(Short2Norm) => {
4
};
(Short4Norm) => {
8
};
(Half2) => {
4
};
(Half4) => {
8
};
(Float) => {
4
};
(Float2) => {
8
};
(Float3) => {
12
};
(Float4) => {
16
};
(Uint) => {
4
};
(Uint2) => {
8
};
(Uint3) => {
12
};
(Uint4) => {
16
};
(Int) => {
4
};
(Int2) => {
8
};
(Int3) => {
12
};
(Int4) => {
16
};
}
#[test]