mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
[rs] cargo fmt the code and tweak format rules
This commit is contained in:
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
|
||||
@@ -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()]);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
imports_layout = "HorizontalVertical"
|
||||
newline_style = "Native"
|
||||
spaces_around_ranges = true
|
||||
@@ -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 _),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
267
wgpu/src/lib.rs
267
wgpu/src/lib.rs
@@ -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]>>();
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user