tutorial3 migrated

pull/25/head
Ben Hansen 4 years ago
parent f8738e4850
commit baa9e2656a

3
Cargo.lock generated

@ -1810,9 +1810,10 @@ name = "tutorial3-pipeline"
version = "0.1.0"
dependencies = [
"cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"glsl-to-spirv 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.22.4 (registry+https://github.com/rust-lang/crates.io-index)",
"wgpu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wgpu 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winit 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

@ -11,7 +11,8 @@ image = "0.22"
winit = "0.20"
glsl-to-spirv = "0.1"
cgmath = "0.17"
wgpu = "0.4"
wgpu = "0.5.0"
futures = "0.3.4"
[[bin]]
name = "tutorial3-pipeline"

@ -19,28 +19,32 @@ struct State {
}
impl State {
fn new(window: &Window) -> Self {
async fn new(window: &Window) -> Self {
let size = window.inner_size();
let surface = wgpu::Surface::create(window);
let adapter = wgpu::Adapter::request(&wgpu::RequestAdapterOptions {
..Default::default()
}).unwrap();
let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: Some(&surface),
},
wgpu::BackendBit::PRIMARY, // Vulkan + Metal + DX12 + Browser WebGPU
).await.unwrap();
let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: Default::default(),
});
}).await;
let sc_desc = wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
format: wgpu::TextureFormat::Bgra8UnormSrgb,
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Vsync,
present_mode: wgpu::PresentMode::Fifo,
};
let swap_chain = device.create_swap_chain(&surface, &sc_desc);
@ -84,8 +88,10 @@ impl State {
},
],
depth_stencil_state: None,
index_format: wgpu::IndexFormat::Uint16,
vertex_buffers: &[],
vertex_state: wgpu::VertexStateDescriptor {
index_format: wgpu::IndexFormat::Uint16,
vertex_buffers: &[],
},
sample_count: 1,
sample_mask: !0,
alpha_to_coverage_enabled: false,
@ -131,8 +137,10 @@ impl State {
},
],
depth_stencil_state: None,
index_format: wgpu::IndexFormat::Uint16,
vertex_buffers: &[],
vertex_state: wgpu::VertexStateDescriptor {
index_format: wgpu::IndexFormat::Uint16,
vertex_buffers: &[],
},
sample_count: 1,
sample_mask: !0,
alpha_to_coverage_enabled: false,
@ -154,7 +162,7 @@ impl State {
}
fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
async fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
self.size = new_size;
self.sc_desc.width = new_size.width;
self.sc_desc.height = new_size.height;
@ -180,15 +188,16 @@ impl State {
}
}
fn update(&mut self) {
async fn update(&mut self) {
}
fn render(&mut self) {
let frame = self.swap_chain.get_next_texture();
async fn render(&mut self) {
let frame = self.swap_chain.get_next_texture()
.expect("Timeout getting texture");
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
todo: 0,
label: Some("Render Encoder"),
});
{
@ -230,16 +239,17 @@ fn main() {
.build(&event_loop)
.unwrap();
let mut state = State::new(&window);
use futures::executor::block_on;
// Since main can't be async, we're going to need to block
let mut state = block_on(State::new(&window));
event_loop.run(move |event, _, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == window.id() => if state.input(event) {
*control_flow = ControlFlow::Wait;
} else {
} if window_id == window.id() => if !state.input(event) {
match event {
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
WindowEvent::KeyboardInput {
@ -252,26 +262,29 @@ fn main() {
virtual_keycode: Some(VirtualKeyCode::Escape),
..
} => *control_flow = ControlFlow::Exit,
_ => *control_flow = ControlFlow::Wait,
_ => {}
}
}
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
*control_flow = ControlFlow::Wait;
block_on(state.resize(*physical_size));
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
state.resize(**new_inner_size);
*control_flow = ControlFlow::Wait;
// new_inner_size is &mut so w have to dereference it twice
block_on(state.resize(**new_inner_size));
}
_ => *control_flow = ControlFlow::Wait,
_ => {}
}
}
Event::RedrawRequested(_) => {
block_on(state.update());
block_on(state.render());
}
Event::MainEventsCleared => {
state.update();
state.render();
*control_flow = ControlFlow::Wait;
// RedrawRequested will only trigger once, unless we manually
// request it.
window.request_redraw();
}
_ => *control_flow = ControlFlow::Wait,
_ => {}
}
});
}
}

@ -1,9 +1,9 @@
#version 450
const vec2 positions[3] = vec2[3](
vec2(0.0, -0.5),
vec2(-0.5, 0.5),
vec2(0.5, 0.5)
vec2(0.0, 0.5),
vec2(-0.5, -0.5),
vec2(0.5, -0.5)
);
layout(location=0) out vec2 v_position;

@ -17,28 +17,32 @@ struct State {
}
impl State {
fn new(window: &Window) -> Self {
async fn new(window: &Window) -> Self {
let size = window.inner_size();
let surface = wgpu::Surface::create(window);
let adapter = wgpu::Adapter::request(&wgpu::RequestAdapterOptions {
..Default::default()
}).unwrap();
let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: Some(&surface),
},
wgpu::BackendBit::PRIMARY, // Vulkan + Metal + DX12 + Browser WebGPU
).await.unwrap();
let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: Default::default(),
});
}).await;
let sc_desc = wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
format: wgpu::TextureFormat::Bgra8UnormSrgb,
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Vsync,
present_mode: wgpu::PresentMode::Fifo,
};
let swap_chain = device.create_swap_chain(&surface, &sc_desc);
@ -82,8 +86,10 @@ impl State {
},
],
depth_stencil_state: None,
index_format: wgpu::IndexFormat::Uint16,
vertex_buffers: &[],
vertex_state: wgpu::VertexStateDescriptor {
index_format: wgpu::IndexFormat::Uint16,
vertex_buffers: &[],
},
sample_count: 1,
sample_mask: !0,
alpha_to_coverage_enabled: false,
@ -101,7 +107,7 @@ impl State {
}
fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
async fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
self.size = new_size;
self.sc_desc.width = new_size.width;
self.sc_desc.height = new_size.height;
@ -112,15 +118,16 @@ impl State {
false
}
fn update(&mut self) {
async fn update(&mut self) {
}
fn render(&mut self) {
let frame = self.swap_chain.get_next_texture();
async fn render(&mut self) {
let frame = self.swap_chain.get_next_texture()
.expect("Timeout getting texture");
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
todo: 0,
label: Some("Render Encoder"),
});
{
@ -158,16 +165,17 @@ fn main() {
.build(&event_loop)
.unwrap();
let mut state = State::new(&window);
use futures::executor::block_on;
// Since main can't be async, we're going to need to block
let mut state = block_on(State::new(&window));
event_loop.run(move |event, _, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == window.id() => if state.input(event) {
*control_flow = ControlFlow::Wait;
} else {
} if window_id == window.id() => if !state.input(event) {
match event {
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
WindowEvent::KeyboardInput {
@ -180,26 +188,29 @@ fn main() {
virtual_keycode: Some(VirtualKeyCode::Escape),
..
} => *control_flow = ControlFlow::Exit,
_ => *control_flow = ControlFlow::Wait,
_ => {}
}
}
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
*control_flow = ControlFlow::Wait;
block_on(state.resize(*physical_size));
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
state.resize(**new_inner_size);
*control_flow = ControlFlow::Wait;
// new_inner_size is &mut so w have to dereference it twice
block_on(state.resize(**new_inner_size));
}
_ => *control_flow = ControlFlow::Wait,
_ => {}
}
}
Event::RedrawRequested(_) => {
block_on(state.update());
block_on(state.render());
}
Event::MainEventsCleared => {
state.update();
state.render();
*control_flow = ControlFlow::Wait;
// RedrawRequested will only trigger once, unless we manually
// request it.
window.request_redraw();
}
_ => *control_flow = ControlFlow::Wait,
_ => {}
}
});
}

@ -1,9 +1,9 @@
#version 450
const vec2 positions[3] = vec2[3](
vec2(0.0, -0.5),
vec2(-0.5, 0.5),
vec2(0.5, 0.5)
vec2(0.0, 0.5),
vec2(-0.5, -0.5),
vec2(0.5, -0.5)
);
void main() {

@ -93,7 +93,29 @@ The `format` defines how the `swap_chain`s textures will be stored on the gpu. U
`width` and `height`, are self explanatory.
There's no documentation on `present_mode` as of writing, but my guess is that it defines the rate at which you can acquire images from the `swap_chain`.
The `present_mode` uses the `wgpu::PresentMode` enum which is defined as follows.
```rust
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum PresentMode {
/// The presentation engine does **not** wait for a vertical blanking period and
/// the request is presented immediately. This is a low-latency presentation mode,
/// but visible tearing may be observed. Will fallback to `Fifo` if unavailable on the
/// selected platform and backend. Not optimal for mobile.
Immediate = 0,
/// The presentation engine waits for the next vertical blanking period to update
/// the current image, but frames may be submitted without delay. This is a low-latency
/// presentation mode and visible tearing will **not** be observed. Will fallback to `Fifo`
/// if unavailable on the selected platform and backend. Not optimal for mobile.
Mailbox = 1,
/// The presentation engine waits for the next vertical blanking period to update
/// the current image. The framerate will be capped at the display refresh rate,
/// corresponding to the `VSync`. Tearing cannot be observed. Optimal for mobile.
Fifo = 2,
}
```
At the end of the method, we simply return the resulting struct.

@ -40,9 +40,9 @@ In the same folder as `main.rs`, create two (2) files: `shader.vert`, and `shade
#version 450
const vec2 positions[3] = vec2[3](
vec2(0.0, -0.5),
vec2(-0.5, 0.5),
vec2(0.5, 0.5)
vec2(0.0, 0.5),
vec2(-0.5, -0.5),
vec2(0.5, -0.5)
);
void main() {
@ -179,8 +179,10 @@ A `color_state` describes how colors are stored and processed throughout the pip
// continued ...
primitive_topology: wgpu::PrimitiveTopology::TriangleList, // 1.
depth_stencil_state: None, // 2.
index_format: wgpu::IndexFormat::Uint16, // 3.
vertex_buffers: &[], // 4.
vertex_state: wgpu::VertexStateDescriptor {
index_format: wgpu::IndexFormat::Uint16, // 3.
vertex_buffers: &[], // 4.
},
sample_count: 1, // 5.
sample_mask: !0, // 6.
alpha_to_coverage_enabled: false, // 7.

Loading…
Cancel
Save