mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Merge #70
70: Wholesome update for wgpu-0.3 r=everyone a=kvark ~~This update is a little more opinionated, i.e. the BGL creation just accepts a slice of things instead of a descriptor. I believe the reason for descriptors in the upstream API is mostly techincal - it's more convenient to generate bindings in Googles giant codegen. Following it verbatim doesn't appear to be strictly necessary, especially if we can extract better usability from Rust features.~~ The change also disables "gl" feature for the release. We'll re-enable it once we can provide it nicely, it will not be a breaking change. I also noticed that barriers are not working correctly on the mipmap example. Will investigate separately - the native part is already published anyway. Edit: fixed by https://github.com/gfx-rs/wgpu/pull/302 Co-authored-by: Dzmitry Malyshau <dmalyshau@mozilla.com>
This commit is contained in:
@@ -10,6 +10,7 @@ branches:
|
||||
- staging.tmp
|
||||
|
||||
script:
|
||||
- cargo test
|
||||
- cargo check
|
||||
- if [[ $TRAVIS_OS_NAME == "linux" ]]; then cargo test --no-run --features vulkan; fi
|
||||
- if [[ $TRAVIS_OS_NAME == "windows" ]]; then cargo test --no-run --features vulkan; fi
|
||||
- if [[ $TRAVIS_OS_NAME == "osx" ]]; then cargo test --no-run --features metal; fi
|
||||
- if [[ $TRAVIS_OS_NAME == "windows" ]]; then cargo test --no-run --features dx12; fi
|
||||
|
||||
13
Cargo.toml
13
Cargo.toml
@@ -4,9 +4,12 @@ version = "0.3.0"
|
||||
authors = [
|
||||
"Dzmitry Malyshau <kvark@mozilla.com>",
|
||||
"Joshua Groves <josh@joshgroves.com>",
|
||||
"Lucas Kent <rubickent@gmail.com>",
|
||||
"kyren <kerriganw@gmail.com>",
|
||||
"Cormac O'Brien <cormac@c-obrien.org>",
|
||||
]
|
||||
edition = "2018"
|
||||
description = "Rusty wgpu API wrapper"
|
||||
description = "Rusty WebGPU API wrapper"
|
||||
homepage = "https://github.com/gfx-rs/wgpu-rs"
|
||||
repository = "https://github.com/gfx-rs/wgpu-rs"
|
||||
keywords = ["graphics"]
|
||||
@@ -20,12 +23,13 @@ metal = ["wgn/gfx-backend-metal"]
|
||||
dx11 = ["wgn/gfx-backend-dx11"]
|
||||
dx12 = ["wgn/gfx-backend-dx12"]
|
||||
vulkan = ["wgn/gfx-backend-vulkan"]
|
||||
gl = ["wgn/gfx-backend-gl"]
|
||||
#TODO: there is no way to use glutin-0.20 with GL backend v0.3 yet
|
||||
#gl = ["wgn/gfx-backend-gl"]
|
||||
|
||||
[dependencies]
|
||||
#TODO: only depend on the published version
|
||||
wgn = { package = "wgpu-native", version = "0.2.6", features = ["local", "window-winit"], git = "https://github.com/gfx-rs/wgpu", rev = "a47ff090bb042f1cb2ad7b13c76eca228390a311"}
|
||||
wgn = { package = "wgpu-native", version = "0.3.1", features = ["local"] }
|
||||
arrayvec = "0.4"
|
||||
raw-window-handle = "0.1"
|
||||
zerocopy = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
@@ -34,3 +38,4 @@ env_logger = "0.6"
|
||||
glsl-to-spirv = "0.1"
|
||||
log = "0.4"
|
||||
png = "0.15"
|
||||
winit = "0.20.0-alpha3"
|
||||
|
||||
@@ -9,16 +9,16 @@ fn main() {
|
||||
|
||||
let instance = wgpu::Instance::new();
|
||||
|
||||
let adapter = instance.get_adapter(Some(&wgpu::RequestAdapterOptions {
|
||||
let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
power_preference: wgpu::PowerPreference::LowPower,
|
||||
}));
|
||||
});
|
||||
|
||||
let mut device = adapter.request_device(Some(&wgpu::DeviceDescriptor {
|
||||
let mut device = adapter.request_device(&wgpu::DeviceDescriptor {
|
||||
extensions: wgpu::Extensions {
|
||||
anisotropic_filtering: false,
|
||||
},
|
||||
limits: wgpu::Limits::default(),
|
||||
}));
|
||||
});
|
||||
|
||||
// Rendered image is 256×256 with 32-bit RGBA color
|
||||
let size = 256u32;
|
||||
@@ -52,7 +52,7 @@ fn main() {
|
||||
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
|
||||
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
||||
attachment: &texture.create_view(None),
|
||||
attachment: &texture.create_default_view(),
|
||||
resolve_target: None,
|
||||
load_op: wgpu::LoadOp::Clear,
|
||||
store_op: wgpu::StoreOp::Store,
|
||||
@@ -78,7 +78,7 @@ fn main() {
|
||||
texture_extent,
|
||||
);
|
||||
|
||||
encoder.finish(None)
|
||||
encoder.finish()
|
||||
};
|
||||
|
||||
device.get_queue().submit(&[command_buffer]);
|
||||
|
||||
@@ -129,26 +129,22 @@ impl framework::Example for Example {
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX,
|
||||
ty: wgpu::BindingType::UniformBuffer,
|
||||
dynamic: false,
|
||||
multisampled: false,
|
||||
texture_dimension: wgpu::TextureViewDimension::D2,
|
||||
ty: wgpu::BindingType::UniformBuffer {
|
||||
dynamic: false,
|
||||
},
|
||||
},
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture,
|
||||
dynamic: false,
|
||||
multisampled: false,
|
||||
texture_dimension: wgpu::TextureViewDimension::D2,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
multisampled: false,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
},
|
||||
},
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 2,
|
||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler,
|
||||
dynamic: false,
|
||||
multisampled: false,
|
||||
texture_dimension: wgpu::TextureViewDimension::D2,
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -173,7 +169,7 @@ impl framework::Example for Example {
|
||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
|
||||
});
|
||||
let texture_view = texture.create_view(None);
|
||||
let texture_view = texture.create_default_view();
|
||||
let temp_buf = device
|
||||
.create_buffer_mapped(texels.len(), wgpu::BufferUsage::COPY_SRC)
|
||||
.fill_from_slice(&texels);
|
||||
@@ -298,7 +294,7 @@ impl framework::Example for Example {
|
||||
});
|
||||
|
||||
// Done
|
||||
let init_command_buf = init_encoder.finish(None);
|
||||
let init_command_buf = init_encoder.finish();
|
||||
device.get_queue().submit(&[init_command_buf]);
|
||||
Example {
|
||||
vertex_buf,
|
||||
@@ -310,7 +306,7 @@ impl framework::Example for Example {
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, _event: wgpu::winit::WindowEvent) {
|
||||
fn update(&mut self, _event: winit::event::WindowEvent) {
|
||||
//empty
|
||||
}
|
||||
|
||||
@@ -325,7 +321,7 @@ impl framework::Example for Example {
|
||||
let mut encoder =
|
||||
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
|
||||
encoder.copy_buffer_to_buffer(&temp_buf, 0, &self.uniform_buf, 0, 64);
|
||||
device.get_queue().submit(&[encoder.finish(None)]);
|
||||
device.get_queue().submit(&[encoder.finish()]);
|
||||
}
|
||||
|
||||
fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) {
|
||||
@@ -354,7 +350,7 @@ impl framework::Example for Example {
|
||||
rpass.draw_indexed(0 .. self.index_count as u32, 0, 0 .. 1);
|
||||
}
|
||||
|
||||
device.get_queue().submit(&[encoder.finish(None)]);
|
||||
device.get_queue().submit(&[encoder.finish()]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use log::info;
|
||||
use winit::event::WindowEvent;
|
||||
|
||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
#[allow(unused)]
|
||||
pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, -1.0, 0.0, 0.0,
|
||||
@@ -33,53 +35,47 @@ pub fn load_glsl(code: &str, stage: ShaderStage) -> Vec<u32> {
|
||||
wgpu::read_spirv(glsl_to_spirv::compile(&code, ty).unwrap()).unwrap()
|
||||
}
|
||||
|
||||
pub trait Example {
|
||||
pub trait Example: 'static {
|
||||
fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) -> Self;
|
||||
fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device);
|
||||
fn update(&mut self, event: wgpu::winit::WindowEvent);
|
||||
fn update(&mut self, event: WindowEvent);
|
||||
fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device);
|
||||
}
|
||||
|
||||
pub fn run<E: Example>(title: &str) {
|
||||
use wgpu::winit::{
|
||||
ElementState,
|
||||
Event,
|
||||
EventsLoop,
|
||||
KeyboardInput,
|
||||
VirtualKeyCode,
|
||||
WindowEvent,
|
||||
use winit::{
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
event,
|
||||
};
|
||||
|
||||
env_logger::init();
|
||||
|
||||
let mut events_loop = EventsLoop::new();
|
||||
|
||||
let event_loop = EventLoop::new();
|
||||
info!("Initializing the window...");
|
||||
|
||||
#[cfg(not(feature = "gl"))]
|
||||
let (_window, instance, hidpi_factor, size, surface) = {
|
||||
use wgpu::winit::Window;
|
||||
use raw_window_handle::HasRawWindowHandle as _;
|
||||
|
||||
|
||||
let window = winit::window::Window::new(&event_loop).unwrap();
|
||||
window.set_title(title);
|
||||
let hidpi_factor = window.hidpi_factor();
|
||||
let size = window.inner_size().to_physical(hidpi_factor);
|
||||
|
||||
let instance = wgpu::Instance::new();
|
||||
|
||||
let window = Window::new(&events_loop).unwrap();
|
||||
window.set_title(title);
|
||||
let hidpi_factor = window.get_hidpi_factor();
|
||||
let size = window.get_inner_size().unwrap().to_physical(hidpi_factor);
|
||||
|
||||
let surface = instance.create_surface(&window);
|
||||
let surface = instance.create_surface(window.raw_window_handle());
|
||||
|
||||
(window, instance, hidpi_factor, size, surface)
|
||||
};
|
||||
|
||||
#[cfg(feature = "gl")]
|
||||
let (_window, instance, hidpi_factor, size, surface) = {
|
||||
let wb = wgpu::winit::WindowBuilder::new();
|
||||
let wb = winit::WindowBuilder::new();
|
||||
let cb = wgpu::glutin::ContextBuilder::new().with_vsync(true);
|
||||
let context = cb.build_windowed(wb, &events_loop).unwrap();
|
||||
let context = cb.build_windowed(wb, &event_loop).unwrap();
|
||||
context.window().set_title(title);
|
||||
|
||||
let hidpi_factor = context.window().get_hidpi_factor();
|
||||
let hidpi_factor = context.window().hidpi_factor();
|
||||
let size = context
|
||||
.window()
|
||||
.get_inner_size()
|
||||
@@ -94,16 +90,16 @@ pub fn run<E: Example>(title: &str) {
|
||||
(window, instance, hidpi_factor, size, surface)
|
||||
};
|
||||
|
||||
let adapter = instance.get_adapter(Some(&wgpu::RequestAdapterOptions {
|
||||
let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
power_preference: wgpu::PowerPreference::LowPower,
|
||||
}));
|
||||
});
|
||||
|
||||
let mut device = adapter.request_device(Some(&wgpu::DeviceDescriptor {
|
||||
let mut device = adapter.request_device(&wgpu::DeviceDescriptor {
|
||||
extensions: wgpu::Extensions {
|
||||
anisotropic_filtering: false,
|
||||
},
|
||||
limits: wgpu::Limits::default(),
|
||||
}));
|
||||
});
|
||||
|
||||
let mut sc_desc = wgpu::SwapChainDescriptor {
|
||||
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||
@@ -118,10 +114,14 @@ pub fn run<E: Example>(title: &str) {
|
||||
let mut example = E::init(&sc_desc, &mut device);
|
||||
|
||||
info!("Entering render loop...");
|
||||
let mut running = true;
|
||||
while running {
|
||||
events_loop.poll_events(|event| match event {
|
||||
Event::WindowEvent {
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
*control_flow = if cfg!(feature = "metal-auto-capture") {
|
||||
ControlFlow::Exit
|
||||
} else {
|
||||
ControlFlow::Poll
|
||||
};
|
||||
match event {
|
||||
event::Event::WindowEvent {
|
||||
event: WindowEvent::Resized(size),
|
||||
..
|
||||
} => {
|
||||
@@ -132,30 +132,30 @@ pub fn run<E: Example>(title: &str) {
|
||||
swap_chain = device.create_swap_chain(&surface, &sc_desc);
|
||||
example.resize(&sc_desc, &mut device);
|
||||
}
|
||||
Event::WindowEvent { event, .. } => match event {
|
||||
event::Event::WindowEvent { event, .. } => match event {
|
||||
WindowEvent::KeyboardInput {
|
||||
input:
|
||||
KeyboardInput {
|
||||
virtual_keycode: Some(VirtualKeyCode::Escape),
|
||||
state: ElementState::Pressed,
|
||||
event::KeyboardInput {
|
||||
virtual_keycode: Some(event::VirtualKeyCode::Escape),
|
||||
state: event::ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
..
|
||||
}
|
||||
| WindowEvent::CloseRequested => {
|
||||
running = false;
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
_ => {
|
||||
example.update(event);
|
||||
}
|
||||
},
|
||||
event::Event::EventsCleared => {
|
||||
let frame = swap_chain.get_next_texture();
|
||||
example.render(&frame, &mut device);
|
||||
}
|
||||
_ => (),
|
||||
});
|
||||
|
||||
let frame = swap_chain.get_next_texture();
|
||||
example.render(&frame, &mut device);
|
||||
running &= !cfg!(feature = "metal-auto-capture");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// This allows treating the framework as a standalone example,
|
||||
|
||||
@@ -15,16 +15,16 @@ fn main() {
|
||||
let size = (numbers.len() * std::mem::size_of::<u32>()) as wgpu::BufferAddress;
|
||||
|
||||
let instance = wgpu::Instance::new();
|
||||
let adapter = instance.get_adapter(Some(&wgpu::RequestAdapterOptions {
|
||||
let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
power_preference: wgpu::PowerPreference::Default,
|
||||
}));
|
||||
});
|
||||
|
||||
let mut device = adapter.request_device(Some(&wgpu::DeviceDescriptor {
|
||||
let mut device = adapter.request_device(&wgpu::DeviceDescriptor {
|
||||
extensions: wgpu::Extensions {
|
||||
anisotropic_filtering: false,
|
||||
},
|
||||
limits: wgpu::Limits::default(),
|
||||
}));
|
||||
});
|
||||
|
||||
let cs = include_bytes!("shader.comp.spv");
|
||||
let cs_module = device.create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(&cs[..])).unwrap());
|
||||
@@ -46,14 +46,13 @@ fn main() {
|
||||
});
|
||||
|
||||
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
bindings: &[wgpu::BindGroupLayoutBinding {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::COMPUTE,
|
||||
ty: wgpu::BindingType::StorageBuffer,
|
||||
dynamic: false,
|
||||
multisampled: false,
|
||||
texture_dimension: wgpu::TextureViewDimension::D2,
|
||||
}],
|
||||
bindings: &[
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::COMPUTE,
|
||||
ty: wgpu::BindingType::StorageBuffer { dynamic: false, readonly: false },
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
@@ -89,7 +88,7 @@ fn main() {
|
||||
}
|
||||
encoder.copy_buffer_to_buffer(&storage_buffer, 0, &staging_buffer, 0, size);
|
||||
|
||||
device.get_queue().submit(&[encoder.finish(None)]);
|
||||
device.get_queue().submit(&[encoder.finish()]);
|
||||
|
||||
staging_buffer.map_read_async(0, size, |result: wgpu::BufferMapAsyncResult<&[u32]>| {
|
||||
if let Ok(mapping) = result {
|
||||
|
||||
@@ -1,39 +1,32 @@
|
||||
fn main() {
|
||||
use wgpu::winit::{
|
||||
ElementState,
|
||||
Event,
|
||||
EventsLoop,
|
||||
KeyboardInput,
|
||||
VirtualKeyCode,
|
||||
WindowEvent,
|
||||
use winit::{
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
event,
|
||||
};
|
||||
|
||||
env_logger::init();
|
||||
|
||||
let mut events_loop = EventsLoop::new();
|
||||
let event_loop = EventLoop::new();
|
||||
|
||||
#[cfg(not(feature = "gl"))]
|
||||
let (_window, instance, size, surface) = {
|
||||
use wgpu::winit::Window;
|
||||
use raw_window_handle::HasRawWindowHandle as _;
|
||||
|
||||
let window = winit::window::Window::new(&event_loop).unwrap();
|
||||
let size = window
|
||||
.inner_size()
|
||||
.to_physical(window.hidpi_factor());
|
||||
|
||||
let instance = wgpu::Instance::new();
|
||||
|
||||
let window = Window::new(&events_loop).unwrap();
|
||||
let size = window
|
||||
.get_inner_size()
|
||||
.unwrap()
|
||||
.to_physical(window.get_hidpi_factor());
|
||||
|
||||
let surface = instance.create_surface(&window);
|
||||
let surface = instance.create_surface(window.raw_window_handle());
|
||||
|
||||
(window, instance, size, surface)
|
||||
};
|
||||
|
||||
#[cfg(feature = "gl")]
|
||||
let (_window, instance, size, surface) = {
|
||||
let wb = wgpu::winit::WindowBuilder::new();
|
||||
let wb = winit::WindowBuilder::new();
|
||||
let cb = wgpu::glutin::ContextBuilder::new().with_vsync(true);
|
||||
let context = cb.build_windowed(wb, &events_loop).unwrap();
|
||||
let context = cb.build_windowed(wb, &event_loop).unwrap();
|
||||
|
||||
let size = context
|
||||
.window()
|
||||
@@ -49,16 +42,16 @@ fn main() {
|
||||
(window, instance, size, surface)
|
||||
};
|
||||
|
||||
let adapter = instance.get_adapter(Some(&wgpu::RequestAdapterOptions {
|
||||
let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
power_preference: wgpu::PowerPreference::LowPower,
|
||||
}));
|
||||
});
|
||||
|
||||
let mut device = adapter.request_device(Some(&wgpu::DeviceDescriptor {
|
||||
let mut device = adapter.request_device(&wgpu::DeviceDescriptor {
|
||||
extensions: wgpu::Extensions {
|
||||
anisotropic_filtering: false,
|
||||
},
|
||||
limits: wgpu::Limits::default(),
|
||||
}));
|
||||
});
|
||||
|
||||
let vs = include_bytes!("shader.vert.spv");
|
||||
let vs_module = device.create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(&vs[..])).unwrap());
|
||||
@@ -66,8 +59,9 @@ fn main() {
|
||||
let fs = include_bytes!("shader.frag.spv");
|
||||
let fs_module = device.create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(&fs[..])).unwrap());
|
||||
|
||||
let bind_group_layout =
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { bindings: &[] });
|
||||
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
bindings: &[],
|
||||
});
|
||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
layout: &bind_group_layout,
|
||||
bindings: &[],
|
||||
@@ -118,47 +112,52 @@ fn main() {
|
||||
present_mode: wgpu::PresentMode::Vsync,
|
||||
},
|
||||
);
|
||||
let mut running = true;
|
||||
while running {
|
||||
events_loop.poll_events(|event| match event {
|
||||
Event::WindowEvent { event, .. } => match event {
|
||||
WindowEvent::KeyboardInput {
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
*control_flow = if cfg!(feature = "metal-auto-capture") {
|
||||
ControlFlow::Exit
|
||||
} else {
|
||||
ControlFlow::Poll
|
||||
};
|
||||
match event {
|
||||
event::Event::WindowEvent { event, .. } => match event {
|
||||
event::WindowEvent::KeyboardInput {
|
||||
input:
|
||||
KeyboardInput {
|
||||
virtual_keycode: Some(code),
|
||||
state: ElementState::Pressed,
|
||||
event::KeyboardInput {
|
||||
virtual_keycode: Some(event::VirtualKeyCode::Escape),
|
||||
state: event::ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => match code {
|
||||
VirtualKeyCode::Escape => running = false,
|
||||
_ => {}
|
||||
},
|
||||
WindowEvent::CloseRequested => running = false,
|
||||
}
|
||||
| event::WindowEvent::CloseRequested => {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
});
|
||||
event::Event::EventsCleared => {
|
||||
let frame = swap_chain.get_next_texture();
|
||||
let mut encoder =
|
||||
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
|
||||
{
|
||||
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
||||
attachment: &frame.view,
|
||||
resolve_target: None,
|
||||
load_op: wgpu::LoadOp::Clear,
|
||||
store_op: wgpu::StoreOp::Store,
|
||||
clear_color: wgpu::Color::GREEN,
|
||||
}],
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
rpass.set_pipeline(&render_pipeline);
|
||||
rpass.set_bind_group(0, &bind_group, &[]);
|
||||
rpass.draw(0 .. 3, 0 .. 1);
|
||||
}
|
||||
|
||||
let frame = swap_chain.get_next_texture();
|
||||
let mut encoder =
|
||||
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
|
||||
{
|
||||
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
||||
attachment: &frame.view,
|
||||
resolve_target: None,
|
||||
load_op: wgpu::LoadOp::Clear,
|
||||
store_op: wgpu::StoreOp::Store,
|
||||
clear_color: wgpu::Color::GREEN,
|
||||
}],
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
rpass.set_pipeline(&render_pipeline);
|
||||
rpass.set_bind_group(0, &bind_group, &[]);
|
||||
rpass.draw(0 .. 3, 0 .. 1);
|
||||
device.get_queue().submit(&[encoder.finish()]);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
device.get_queue().submit(&[encoder.finish(None)]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -76,18 +76,15 @@ impl Example {
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture,
|
||||
dynamic: false,
|
||||
multisampled: false,
|
||||
texture_dimension: wgpu::TextureViewDimension::D2,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
multisampled: false,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
},
|
||||
},
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler,
|
||||
dynamic: false,
|
||||
multisampled: false,
|
||||
texture_dimension: wgpu::TextureViewDimension::D2,
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -151,7 +148,7 @@ impl Example {
|
||||
});
|
||||
|
||||
let views = (0 .. mip_count)
|
||||
.map(|mip| texture.create_view(Some(&wgpu::TextureViewDescriptor {
|
||||
.map(|mip| texture.create_view(&wgpu::TextureViewDescriptor {
|
||||
format: TEXTURE_FORMAT,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
aspect: wgpu::TextureAspect::All,
|
||||
@@ -159,7 +156,7 @@ impl Example {
|
||||
level_count: 1,
|
||||
base_array_layer: 0,
|
||||
array_layer_count: 1,
|
||||
})))
|
||||
}))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut encoder = device.create_command_encoder(
|
||||
@@ -196,7 +193,7 @@ impl Example {
|
||||
rpass.draw(0 .. 4, 0 .. 1);
|
||||
}
|
||||
|
||||
encoder.finish(None)
|
||||
encoder.finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,26 +217,22 @@ impl framework::Example for Example {
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX,
|
||||
ty: wgpu::BindingType::UniformBuffer,
|
||||
dynamic: false,
|
||||
multisampled: false,
|
||||
texture_dimension: wgpu::TextureViewDimension::D2,
|
||||
ty: wgpu::BindingType::UniformBuffer {
|
||||
dynamic: false,
|
||||
},
|
||||
},
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture,
|
||||
dynamic: false,
|
||||
multisampled: false,
|
||||
texture_dimension: wgpu::TextureViewDimension::D2,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
multisampled: false,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
},
|
||||
},
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 2,
|
||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler,
|
||||
dynamic: false,
|
||||
multisampled: false,
|
||||
texture_dimension: wgpu::TextureViewDimension::D2,
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -265,7 +258,7 @@ impl framework::Example for Example {
|
||||
format: TEXTURE_FORMAT,
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::OUTPUT_ATTACHMENT | wgpu::TextureUsage::COPY_DST,
|
||||
});
|
||||
let texture_view = texture.create_view(None);
|
||||
let texture_view = texture.create_default_view();
|
||||
let temp_buf = device
|
||||
.create_buffer_mapped(texels.len(), wgpu::BufferUsage::COPY_SRC)
|
||||
.fill_from_slice(&texels);
|
||||
@@ -387,7 +380,7 @@ impl framework::Example for Example {
|
||||
});
|
||||
|
||||
// Done
|
||||
let init_command_buf = init_encoder.finish(None);
|
||||
let init_command_buf = init_encoder.finish();
|
||||
let mipmap_command_buf = Self::generate_mipmaps(&device, &texture, mip_level_count);
|
||||
device.get_queue().submit(&[init_command_buf, mipmap_command_buf]);
|
||||
Example {
|
||||
@@ -398,7 +391,7 @@ impl framework::Example for Example {
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, _event: wgpu::winit::WindowEvent) {
|
||||
fn update(&mut self, _event: winit::event::WindowEvent) {
|
||||
//empty
|
||||
}
|
||||
|
||||
@@ -413,7 +406,7 @@ impl framework::Example for Example {
|
||||
let mut encoder =
|
||||
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
|
||||
encoder.copy_buffer_to_buffer(&temp_buf, 0, &self.uniform_buf, 0, 64);
|
||||
device.get_queue().submit(&[encoder.finish(None)]);
|
||||
device.get_queue().submit(&[encoder.finish()]);
|
||||
}
|
||||
|
||||
fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) {
|
||||
@@ -441,7 +434,7 @@ impl framework::Example for Example {
|
||||
rpass.draw(0 .. 4, 0 .. 1);
|
||||
}
|
||||
|
||||
device.get_queue().submit(&[encoder.finish(None)]);
|
||||
device.get_queue().submit(&[encoder.finish()]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ impl Example {
|
||||
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||
};
|
||||
|
||||
device.create_texture(multisampled_frame_descriptor).create_view(None)
|
||||
device.create_texture(multisampled_frame_descriptor).create_default_view()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,18 +152,18 @@ impl framework::Example for Example {
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, event: wgpu::winit::WindowEvent) {
|
||||
fn update(&mut self, event: winit::event::WindowEvent) {
|
||||
match event {
|
||||
wgpu::winit::WindowEvent::KeyboardInput { input, .. } => {
|
||||
if let wgpu::winit::ElementState::Pressed = input.state {
|
||||
winit::event::WindowEvent::KeyboardInput { input, .. } => {
|
||||
if let winit::event::ElementState::Pressed = input.state {
|
||||
match input.virtual_keycode {
|
||||
Some(wgpu::winit::VirtualKeyCode::Left) => {
|
||||
Some(winit::event::VirtualKeyCode::Left) => {
|
||||
if self.sample_count >= 2 {
|
||||
self.sample_count = self.sample_count >> 1;
|
||||
self.rebuild_pipeline = true;
|
||||
}
|
||||
}
|
||||
Some(wgpu::winit::VirtualKeyCode::Right) => {
|
||||
Some(winit::event::VirtualKeyCode::Right) => {
|
||||
if self.sample_count <= 16 {
|
||||
self.sample_count = self.sample_count << 1;
|
||||
self.rebuild_pipeline = true;
|
||||
@@ -218,7 +218,7 @@ impl framework::Example for Example {
|
||||
rpass.draw(0..self.vertex_count, 0..1);
|
||||
}
|
||||
|
||||
device.get_queue().submit(&[encoder.finish(None)]);
|
||||
device.get_queue().submit(&[encoder.finish()]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -212,17 +212,15 @@ impl framework::Example for Example {
|
||||
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
|
||||
});
|
||||
|
||||
let local_bind_group_layout =
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
bindings: &[wgpu::BindGroupLayoutBinding {
|
||||
let local_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
bindings: &[
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::UniformBuffer,
|
||||
dynamic: false,
|
||||
multisampled: false,
|
||||
texture_dimension: wgpu::TextureViewDimension::D2,
|
||||
}],
|
||||
});
|
||||
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let mut entities = vec![{
|
||||
use cgmath::SquareMatrix;
|
||||
@@ -260,25 +258,25 @@ impl framework::Example for Example {
|
||||
offset: cgmath::vec3(-2.0, -2.0, 2.0),
|
||||
angle: 10.0,
|
||||
scale: 0.7,
|
||||
rotation: 1.0,
|
||||
rotation: 0.1,
|
||||
},
|
||||
CubeDesc {
|
||||
offset: cgmath::vec3(2.0, -2.0, 2.0),
|
||||
angle: 50.0,
|
||||
scale: 1.3,
|
||||
rotation: 2.0,
|
||||
rotation: 0.2,
|
||||
},
|
||||
CubeDesc {
|
||||
offset: cgmath::vec3(-2.0, 2.0, 2.0),
|
||||
angle: 140.0,
|
||||
scale: 1.1,
|
||||
rotation: 3.0,
|
||||
rotation: 0.3,
|
||||
},
|
||||
CubeDesc {
|
||||
offset: cgmath::vec3(2.0, 2.0, 2.0),
|
||||
angle: 210.0,
|
||||
scale: 0.9,
|
||||
rotation: 4.0,
|
||||
rotation: 0.4,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -337,19 +335,19 @@ impl framework::Example for Example {
|
||||
format: Self::SHADOW_FORMAT,
|
||||
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT | wgpu::TextureUsage::SAMPLED,
|
||||
});
|
||||
let shadow_view = shadow_texture.create_view(None);
|
||||
let shadow_view = shadow_texture.create_default_view();
|
||||
|
||||
let mut shadow_target_views = (0 .. 2)
|
||||
.map(|i| {
|
||||
Some(shadow_texture.create_view(Some(&wgpu::TextureViewDescriptor {
|
||||
Some(shadow_texture.create_view(&wgpu::TextureViewDescriptor {
|
||||
format: Self::SHADOW_FORMAT,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
aspect: wgpu::TextureAspect::DepthOnly,
|
||||
aspect: wgpu::TextureAspect::All,
|
||||
base_mip_level: 0,
|
||||
level_count: 1,
|
||||
base_array_layer: i as u32,
|
||||
array_layer_count: 1,
|
||||
})))
|
||||
}))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let lights = vec![
|
||||
@@ -406,17 +404,15 @@ impl framework::Example for Example {
|
||||
|
||||
let shadow_pass = {
|
||||
// Create pipeline layout
|
||||
let bind_group_layout =
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
bindings: &[wgpu::BindGroupLayoutBinding {
|
||||
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
bindings: &[
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 0, // global
|
||||
visibility: wgpu::ShaderStage::VERTEX,
|
||||
ty: wgpu::BindingType::UniformBuffer,
|
||||
dynamic: false,
|
||||
multisampled: false,
|
||||
texture_dimension: wgpu::TextureViewDimension::D2,
|
||||
}],
|
||||
});
|
||||
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
|
||||
},
|
||||
],
|
||||
});
|
||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
bind_group_layouts: &[&bind_group_layout, &local_bind_group_layout],
|
||||
});
|
||||
@@ -497,34 +493,29 @@ impl framework::Example for Example {
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 0, // global
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::UniformBuffer,
|
||||
dynamic: false,
|
||||
multisampled: false,
|
||||
texture_dimension: wgpu::TextureViewDimension::D2,
|
||||
ty: wgpu::BindingType::UniformBuffer {
|
||||
dynamic: false,
|
||||
},
|
||||
},
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 1, // lights
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::UniformBuffer,
|
||||
dynamic: false,
|
||||
multisampled: false,
|
||||
texture_dimension: wgpu::TextureViewDimension::D2,
|
||||
ty: wgpu::BindingType::UniformBuffer {
|
||||
dynamic: false,
|
||||
},
|
||||
},
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 2,
|
||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture,
|
||||
dynamic: false,
|
||||
multisampled: false,
|
||||
texture_dimension: wgpu::TextureViewDimension::D2,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
multisampled: false,
|
||||
dimension: wgpu::TextureViewDimension::D2Array,
|
||||
},
|
||||
},
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 3,
|
||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler,
|
||||
dynamic: false,
|
||||
multisampled: false,
|
||||
texture_dimension: wgpu::TextureViewDimension::D2,
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -651,12 +642,12 @@ impl framework::Example for Example {
|
||||
lights_are_dirty: true,
|
||||
shadow_pass,
|
||||
forward_pass,
|
||||
forward_depth: depth_texture.create_view(None),
|
||||
forward_depth: depth_texture.create_default_view(),
|
||||
light_uniform_buf,
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, _event: wgpu::winit::WindowEvent) {
|
||||
fn update(&mut self, _event: winit::event::WindowEvent) {
|
||||
//empty
|
||||
}
|
||||
|
||||
@@ -671,7 +662,7 @@ impl framework::Example for Example {
|
||||
let mut encoder =
|
||||
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
|
||||
encoder.copy_buffer_to_buffer(&temp_buf, 0, &self.forward_pass.uniform_buf, 0, 64);
|
||||
device.get_queue().submit(&[encoder.finish(None)]);
|
||||
device.get_queue().submit(&[encoder.finish()]);
|
||||
}
|
||||
|
||||
let depth_texture = device.create_texture(&wgpu::TextureDescriptor {
|
||||
@@ -687,7 +678,7 @@ impl framework::Example for Example {
|
||||
format: Self::DEPTH_FORMAT,
|
||||
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||
});
|
||||
self.forward_depth = depth_texture.create_view(None);
|
||||
self.forward_depth = depth_texture.create_default_view();
|
||||
}
|
||||
|
||||
fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) {
|
||||
@@ -816,7 +807,7 @@ impl framework::Example for Example {
|
||||
}
|
||||
}
|
||||
|
||||
device.get_queue().submit(&[encoder.finish(None)]);
|
||||
device.get_queue().submit(&[encoder.finish()]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
196
src/lib.rs
196
src/lib.rs
@@ -10,12 +10,8 @@ use std::ptr;
|
||||
use std::slice;
|
||||
use std::thread;
|
||||
|
||||
pub use wgn::winit;
|
||||
pub use wgn::{
|
||||
RequestAdapterOptions,
|
||||
AddressMode,
|
||||
BindGroupLayoutBinding,
|
||||
BindingType,
|
||||
BlendDescriptor,
|
||||
BlendFactor,
|
||||
BlendOperation,
|
||||
@@ -46,6 +42,7 @@ pub use wgn::{
|
||||
PrimitiveTopology,
|
||||
RasterizationStateDescriptor,
|
||||
RenderPassDepthStencilAttachmentDescriptor,
|
||||
RequestAdapterOptions,
|
||||
SamplerDescriptor,
|
||||
ShaderLocation,
|
||||
ShaderModuleDescriptor,
|
||||
@@ -71,6 +68,7 @@ pub use wgn::glutin;
|
||||
|
||||
//TODO: avoid heap allocating vectors during resource creation.
|
||||
#[derive(Default)]
|
||||
#[derive(Debug)]
|
||||
struct Temp {
|
||||
//bind_group_descriptors: Vec<wgn::BindGroupDescriptor>,
|
||||
//vertex_buffers: Vec<wgn::VertexBufferDescriptor>,
|
||||
@@ -81,6 +79,7 @@ struct Temp {
|
||||
///
|
||||
/// An `Instance` represents the entire context of a running `wgpu` instance. The `Instance`
|
||||
/// allows the querying of [`Adapter`] objects and the creation of [`Surface`] objects.
|
||||
#[derive(Debug)]
|
||||
pub struct Instance {
|
||||
id: wgn::InstanceId,
|
||||
}
|
||||
@@ -89,6 +88,7 @@ pub struct Instance {
|
||||
///
|
||||
/// An `Adapter` can be used to open a connection to the corresponding device on the host system,
|
||||
/// yielding a [`Device`] object.
|
||||
#[derive(Debug)]
|
||||
pub struct Adapter {
|
||||
id: wgn::AdapterId,
|
||||
}
|
||||
@@ -97,17 +97,20 @@ pub struct Adapter {
|
||||
///
|
||||
/// The `Device` is the responsible for the creation of most rendering and compute resources, as
|
||||
/// well as exposing [`Queue`] objects.
|
||||
#[derive(Debug)]
|
||||
pub struct Device {
|
||||
id: wgn::DeviceId,
|
||||
temp: Temp,
|
||||
}
|
||||
|
||||
/// A handle to a GPU-accessible buffer.
|
||||
#[derive(Debug)]
|
||||
pub struct Buffer {
|
||||
id: wgn::BufferId,
|
||||
}
|
||||
|
||||
/// A handle to a texture on the GPU.
|
||||
#[derive(Debug)]
|
||||
pub struct Texture {
|
||||
id: wgn::TextureId,
|
||||
owned: bool,
|
||||
@@ -117,6 +120,7 @@ pub struct Texture {
|
||||
///
|
||||
/// A `TextureView` object describes a texture and associated metadata needed by a
|
||||
/// [`RenderPipeline`] or [`BindGroup`].
|
||||
#[derive(Debug)]
|
||||
pub struct TextureView {
|
||||
id: wgn::TextureViewId,
|
||||
owned: bool,
|
||||
@@ -127,6 +131,7 @@ pub struct TextureView {
|
||||
/// A `Sampler` object defines how a pipeline will sample from a [`TextureView`]. Samplers define
|
||||
/// image filters (including anisotropy) and address (wrapping) modes, among other things. See
|
||||
/// the documentation for [`SamplerDescriptor`] for more information.
|
||||
#[derive(Debug)]
|
||||
pub struct Sampler {
|
||||
id: wgn::SamplerId,
|
||||
}
|
||||
@@ -135,6 +140,7 @@ pub struct Sampler {
|
||||
///
|
||||
/// A `Surface` represents a platform-specific surface (e.g. a window) to which rendered images may
|
||||
/// be presented. A `Surface` may be created with [`Instance::create_surface`].
|
||||
#[derive(Debug)]
|
||||
pub struct Surface {
|
||||
id: wgn::SurfaceId,
|
||||
}
|
||||
@@ -143,6 +149,7 @@ pub struct Surface {
|
||||
///
|
||||
/// A `SwapChain` represents the image or series of images that will be presented to a [`Surface`].
|
||||
/// A `SwapChain` may be created with [`Device::create_swap_chain`].
|
||||
#[derive(Debug)]
|
||||
pub struct SwapChain {
|
||||
id: wgn::SwapChainId,
|
||||
}
|
||||
@@ -153,6 +160,7 @@ pub struct SwapChain {
|
||||
/// create a [`BindGroupDescriptor`] object, which in turn can be used to create a [`BindGroup`]
|
||||
/// object with [`Device::create_bind_group`]. A series of `BindGroupLayout`s can also be used to
|
||||
/// create a [`PipelineLayoutDescriptor`], which can be used to create a [`PipelineLayout`].
|
||||
#[derive(Debug)]
|
||||
pub struct BindGroupLayout {
|
||||
id: wgn::BindGroupLayoutId,
|
||||
}
|
||||
@@ -163,6 +171,7 @@ pub struct BindGroupLayout {
|
||||
/// [`BindGroupLayout`]. It can be created with [`Device::create_bind_group`]. A `BindGroup` can
|
||||
/// be bound to a particular [`RenderPass`] with [`RenderPass::set_bind_group`], or to a
|
||||
/// [`ComputePass`] with [`ComputePass::set_bind_group`].
|
||||
#[derive(Debug)]
|
||||
pub struct BindGroup {
|
||||
id: wgn::BindGroupId,
|
||||
}
|
||||
@@ -178,6 +187,7 @@ impl Drop for BindGroup {
|
||||
/// A `ShaderModule` represents a compiled shader module on the GPU. It can be created by passing
|
||||
/// valid SPIR-V source code to [`Device::create_shader_module`]. Shader modules are used to define
|
||||
/// programmable stages of a pipeline.
|
||||
#[derive(Debug)]
|
||||
pub struct ShaderModule {
|
||||
id: wgn::ShaderModuleId,
|
||||
}
|
||||
@@ -185,6 +195,7 @@ pub struct ShaderModule {
|
||||
/// An opaque handle to a pipeline layout.
|
||||
///
|
||||
/// A `PipelineLayout` object describes the available binding groups of a pipeline.
|
||||
#[derive(Debug)]
|
||||
pub struct PipelineLayout {
|
||||
id: wgn::PipelineLayoutId,
|
||||
}
|
||||
@@ -193,11 +204,13 @@ pub struct PipelineLayout {
|
||||
///
|
||||
/// A `RenderPipeline` object represents a graphics pipeline and its stages, bindings, vertex
|
||||
/// buffers and targets. A `RenderPipeline` may be created with [`Device::create_render_pipeline`].
|
||||
#[derive(Debug)]
|
||||
pub struct RenderPipeline {
|
||||
id: wgn::RenderPipelineId,
|
||||
}
|
||||
|
||||
/// A handle to a compute pipeline.
|
||||
#[derive(Debug)]
|
||||
pub struct ComputePipeline {
|
||||
id: wgn::ComputePipelineId,
|
||||
}
|
||||
@@ -207,6 +220,7 @@ pub struct ComputePipeline {
|
||||
/// A `CommandBuffer` represents a complete sequence of commands that may be submitted to a command
|
||||
/// queue with [`Queue::submit`]. A `CommandBuffer` is obtained by recording a series of commands to
|
||||
/// a [`CommandEncoder`] and then calling [`CommandEncoder::finish`].
|
||||
#[derive(Debug)]
|
||||
pub struct CommandBuffer {
|
||||
id: wgn::CommandBufferId,
|
||||
}
|
||||
@@ -218,17 +232,20 @@ pub struct CommandBuffer {
|
||||
///
|
||||
/// When finished recording, call [`CommandEncoder::finish`] to obtain a [`CommandBuffer`] which may
|
||||
/// be submitted for execution.
|
||||
#[derive(Debug)]
|
||||
pub struct CommandEncoder {
|
||||
id: wgn::CommandEncoderId,
|
||||
}
|
||||
|
||||
/// An in-progress recording of a render pass.
|
||||
#[derive(Debug)]
|
||||
pub struct RenderPass<'a> {
|
||||
id: wgn::RenderPassId,
|
||||
_parent: &'a mut CommandEncoder,
|
||||
}
|
||||
|
||||
/// An in-progress recording of a compute pass.
|
||||
#[derive(Debug)]
|
||||
pub struct ComputePass<'a> {
|
||||
id: wgn::ComputePassId,
|
||||
_parent: &'a mut CommandEncoder,
|
||||
@@ -237,12 +254,14 @@ pub struct ComputePass<'a> {
|
||||
/// A handle to a command queue on a device.
|
||||
///
|
||||
/// A `Queue` executes finished [`CommandBuffer`] objects.
|
||||
#[derive(Debug)]
|
||||
pub struct Queue<'a> {
|
||||
id: wgn::QueueId,
|
||||
temp: &'a mut Temp,
|
||||
}
|
||||
|
||||
/// A resource that can be bound to a pipeline.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum BindingResource<'a> {
|
||||
Buffer {
|
||||
buffer: &'a Buffer,
|
||||
@@ -253,20 +272,47 @@ pub enum BindingResource<'a> {
|
||||
}
|
||||
|
||||
/// A bindable resource and the slot to bind it to.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Binding<'a> {
|
||||
pub binding: u32,
|
||||
pub resource: BindingResource<'a>,
|
||||
}
|
||||
|
||||
/// A description of a bind group layout.
|
||||
///
|
||||
/// A `BindGroupLayoutDescriptor` can be passed to [`Device::create_bind_group_layout`] to obtain a
|
||||
/// [`BindGroupLayout`].
|
||||
/// Specific type of a binding..
|
||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||
pub enum BindingType {
|
||||
UniformBuffer {
|
||||
dynamic: bool,
|
||||
},
|
||||
StorageBuffer {
|
||||
dynamic: bool,
|
||||
readonly: bool,
|
||||
},
|
||||
Sampler,
|
||||
SampledTexture {
|
||||
multisampled: bool,
|
||||
dimension: TextureViewDimension,
|
||||
},
|
||||
StorageTexture {
|
||||
dimension: TextureViewDimension,
|
||||
},
|
||||
}
|
||||
|
||||
/// A description of a single binding inside a bind group.
|
||||
#[derive(Clone, Debug, Hash)]
|
||||
pub struct BindGroupLayoutBinding {
|
||||
pub binding: u32,
|
||||
pub visibility: ShaderStage,
|
||||
pub ty: BindingType,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BindGroupLayoutDescriptor<'a> {
|
||||
pub bindings: &'a [BindGroupLayoutBinding],
|
||||
}
|
||||
|
||||
/// A description of a group of bindings and the resources to be bound.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BindGroupDescriptor<'a> {
|
||||
/// The layout for this bind group.
|
||||
pub layout: &'a BindGroupLayout,
|
||||
@@ -279,11 +325,13 @@ pub struct BindGroupDescriptor<'a> {
|
||||
///
|
||||
/// A `PipelineLayoutDescriptor` can be passed to [`Device::create_pipeline_layout`] to obtain a
|
||||
/// [`PipelineLayout`].
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PipelineLayoutDescriptor<'a> {
|
||||
pub bind_group_layouts: &'a [&'a BindGroupLayout],
|
||||
}
|
||||
|
||||
/// A description of a programmable pipeline stage.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ProgrammableStageDescriptor<'a> {
|
||||
/// The compiled shader module for this stage.
|
||||
pub module: &'a ShaderModule,
|
||||
@@ -305,6 +353,7 @@ pub struct VertexBufferDescriptor<'a> {
|
||||
}
|
||||
|
||||
/// A complete description of a render (graphics) pipeline.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RenderPipelineDescriptor<'a> {
|
||||
/// The layout of bind groups for this pipeline.
|
||||
pub layout: &'a PipelineLayout,
|
||||
@@ -348,6 +397,7 @@ pub struct RenderPipelineDescriptor<'a> {
|
||||
}
|
||||
|
||||
/// A complete description of a compute pipeline.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ComputePipelineDescriptor<'a> {
|
||||
/// The layout of bind groups for this pipeline.
|
||||
pub layout: &'a PipelineLayout,
|
||||
@@ -357,6 +407,7 @@ pub struct ComputePipelineDescriptor<'a> {
|
||||
}
|
||||
|
||||
/// A description of all the attachments of a render pass.
|
||||
#[derive(Debug)]
|
||||
pub struct RenderPassDescriptor<'a> {
|
||||
/// The color attachments of the render pass.
|
||||
pub color_attachments: &'a [RenderPassColorAttachmentDescriptor<'a>],
|
||||
@@ -367,6 +418,7 @@ pub struct RenderPassDescriptor<'a> {
|
||||
}
|
||||
|
||||
/// A description of a color attachment.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RenderPassColorAttachmentDescriptor<'a> {
|
||||
/// The actual color attachment.
|
||||
pub attachment: &'a TextureView,
|
||||
@@ -385,6 +437,7 @@ pub struct RenderPassColorAttachmentDescriptor<'a> {
|
||||
}
|
||||
|
||||
/// A swap chain image that can be rendered to.
|
||||
#[derive(Debug)]
|
||||
pub struct SwapChainOutput<'a> {
|
||||
pub texture: Texture,
|
||||
pub view: TextureView,
|
||||
@@ -392,6 +445,7 @@ pub struct SwapChainOutput<'a> {
|
||||
}
|
||||
|
||||
/// A view of a buffer which can be used to copy to or from a texture.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BufferCopyView<'a> {
|
||||
/// The buffer to be copied to or from.
|
||||
pub buffer: &'a Buffer,
|
||||
@@ -418,6 +472,7 @@ impl<'a> BufferCopyView<'a> {
|
||||
}
|
||||
|
||||
/// A view of a texture which can be used to copy to or from a buffer or another texture.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TextureCopyView<'a> {
|
||||
/// The texture to be copied to or from.
|
||||
pub texture: &'a Texture,
|
||||
@@ -490,24 +545,31 @@ impl Instance {
|
||||
|
||||
/// Retrieves an [`Adapter`] which matches the given descriptor.
|
||||
///
|
||||
/// If there are no available adapters matching `desc`, this function will return another
|
||||
/// If there are no available adapters matching `options`, this function will return another
|
||||
/// adapter.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if there are no available adapters. This will occur if none of the graphics backends
|
||||
/// are enabled.
|
||||
pub fn get_adapter(&self, options: Option<&RequestAdapterOptions>) -> Adapter {
|
||||
pub fn request_adapter(&self, options: &RequestAdapterOptions) -> Adapter {
|
||||
Adapter {
|
||||
id: wgn::wgpu_instance_request_adapter(self.id, options),
|
||||
id: wgn::wgpu_instance_request_adapter(self.id, Some(options)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a surface from a window.
|
||||
/// Creates a surface from a raw window handle.
|
||||
#[cfg(not(feature = "gl"))]
|
||||
pub fn create_surface(&self, window: &winit::Window) -> Surface {
|
||||
pub fn create_surface(&self, raw_handle: raw_window_handle::RawWindowHandle) -> Surface {
|
||||
Surface {
|
||||
id: wgn::wgpu_instance_create_surface_from_winit(self.id, window),
|
||||
id: wgn::wgpu_instance_create_surface(self.id, raw_handle),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "gl"))]
|
||||
pub fn create_surface_from_core_animation_layer(&self, layer: *mut std::ffi::c_void) -> Surface {
|
||||
Surface {
|
||||
id: wgn::wgpu_instance_create_surface_from_macos_layer(self.id, layer),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,35 +579,6 @@ impl Instance {
|
||||
id: wgn::wgpu_instance_get_gl_surface(self.id),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "gl"))]
|
||||
pub fn create_surface_from_xlib(
|
||||
&self,
|
||||
display: *mut *const std::ffi::c_void,
|
||||
window: u64,
|
||||
) -> Surface {
|
||||
Surface {
|
||||
id: wgn::wgpu_instance_create_surface_from_xlib(self.id, display, window),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "gl"))]
|
||||
pub fn create_surface_from_macos_layer(&self, layer: *mut std::ffi::c_void) -> Surface {
|
||||
Surface {
|
||||
id: wgn::wgpu_instance_create_surface_from_macos_layer(self.id, layer),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "gl"))]
|
||||
pub fn create_surface_from_windows_hwnd(
|
||||
&self,
|
||||
hinstance: *mut std::ffi::c_void,
|
||||
hwnd: *mut std::ffi::c_void,
|
||||
) -> Surface {
|
||||
Surface {
|
||||
id: wgn::wgpu_instance_create_surface_from_windows_hwnd(self.id, hinstance, hwnd),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Adapter {
|
||||
@@ -554,9 +587,9 @@ impl Adapter {
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the extensions specified by `desc` are not supported by this adapter.
|
||||
pub fn request_device(&self, desc: Option<&DeviceDescriptor>) -> Device {
|
||||
pub fn request_device(&self, desc: &DeviceDescriptor) -> Device {
|
||||
Device {
|
||||
id: wgn::wgpu_adapter_request_device(self.id, desc),
|
||||
id: wgn::wgpu_adapter_request_device(self.id, Some(desc)),
|
||||
temp: Temp::default(),
|
||||
}
|
||||
}
|
||||
@@ -635,12 +668,41 @@ impl Device {
|
||||
|
||||
/// Creates a bind group layout.
|
||||
pub fn create_bind_group_layout(&self, desc: &BindGroupLayoutDescriptor) -> BindGroupLayout {
|
||||
let temp_layouts = desc.bindings
|
||||
.iter()
|
||||
.map(|bind| wgn::BindGroupLayoutBinding {
|
||||
binding: bind.binding,
|
||||
visibility: bind.visibility,
|
||||
ty: match bind.ty {
|
||||
BindingType::UniformBuffer { .. } => wgn::BindingType::UniformBuffer,
|
||||
BindingType::StorageBuffer { readonly: false, .. } => wgn::BindingType::StorageBuffer,
|
||||
BindingType::StorageBuffer { readonly: true, .. } => wgn::BindingType::ReadonlyStorageBuffer,
|
||||
BindingType::Sampler => wgn::BindingType::Sampler,
|
||||
BindingType::SampledTexture { .. } => wgn::BindingType::SampledTexture,
|
||||
BindingType::StorageTexture { .. } => wgn::BindingType::StorageTexture,
|
||||
},
|
||||
dynamic: match bind.ty {
|
||||
BindingType::UniformBuffer { dynamic } |
|
||||
BindingType::StorageBuffer { dynamic, .. } => dynamic,
|
||||
_ => false,
|
||||
},
|
||||
multisampled: match bind.ty {
|
||||
BindingType::SampledTexture { multisampled, .. } => multisampled,
|
||||
_ => false,
|
||||
},
|
||||
texture_dimension: match bind.ty {
|
||||
BindingType::SampledTexture { dimension, .. } |
|
||||
BindingType::StorageTexture { dimension } => dimension,
|
||||
_ => TextureViewDimension::D2,
|
||||
},
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
BindGroupLayout {
|
||||
id: wgn::wgpu_device_create_bind_group_layout(
|
||||
self.id,
|
||||
&wgn::BindGroupLayoutDescriptor {
|
||||
bindings: desc.bindings.as_ptr(),
|
||||
bindings_length: desc.bindings.len(),
|
||||
bindings: temp_layouts.as_ptr(),
|
||||
bindings_length: temp_layouts.len(),
|
||||
},
|
||||
),
|
||||
}
|
||||
@@ -707,7 +769,7 @@ impl Device {
|
||||
.map_or(ptr::null(), |fs| fs as *const _),
|
||||
rasterization_state: desc.rasterization_state
|
||||
.as_ref()
|
||||
.map_or(ptr::null(), |fs| fs as *const _),
|
||||
.map_or(ptr::null(), |p| p as *const _),
|
||||
primitive_topology: desc.primitive_topology,
|
||||
color_states: temp_color_states.as_ptr(),
|
||||
color_states_length: temp_color_states.len(),
|
||||
@@ -959,9 +1021,17 @@ impl Drop for Buffer {
|
||||
|
||||
impl Texture {
|
||||
/// Creates a view of this texture.
|
||||
pub fn create_view(&self, desc: Option<&TextureViewDescriptor>) -> TextureView {
|
||||
pub fn create_view(&self, desc: &TextureViewDescriptor) -> TextureView {
|
||||
TextureView {
|
||||
id: wgn::wgpu_texture_create_view(self.id, desc),
|
||||
id: wgn::wgpu_texture_create_view(self.id, Some(desc)),
|
||||
owned: true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a default view of this whole texture.
|
||||
pub fn create_default_view(&self) -> TextureView {
|
||||
TextureView {
|
||||
id: wgn::wgpu_texture_create_view(self.id, None),
|
||||
owned: true,
|
||||
}
|
||||
}
|
||||
@@ -985,9 +1055,9 @@ impl Drop for TextureView {
|
||||
|
||||
impl CommandEncoder {
|
||||
/// Finishes recording and returns a [`CommandBuffer`] that can be submitted for execution.
|
||||
pub fn finish(self, desc: Option<&CommandBufferDescriptor>) -> CommandBuffer {
|
||||
pub fn finish(self) -> CommandBuffer {
|
||||
CommandBuffer {
|
||||
id: wgn::wgpu_command_encoder_finish(self.id, desc),
|
||||
id: wgn::wgpu_command_encoder_finish(self.id, None),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1054,7 +1124,7 @@ impl CommandEncoder {
|
||||
destination_offset: BufferAddress,
|
||||
copy_size: BufferAddress,
|
||||
) {
|
||||
wgn::wgpu_command_buffer_copy_buffer_to_buffer(
|
||||
wgn::wgpu_command_encoder_copy_buffer_to_buffer(
|
||||
self.id,
|
||||
source.id,
|
||||
source_offset,
|
||||
@@ -1071,7 +1141,7 @@ impl CommandEncoder {
|
||||
destination: TextureCopyView,
|
||||
copy_size: Extent3d,
|
||||
) {
|
||||
wgn::wgpu_command_buffer_copy_buffer_to_texture(
|
||||
wgn::wgpu_command_encoder_copy_buffer_to_texture(
|
||||
self.id,
|
||||
&source.into_native(),
|
||||
&destination.into_native(),
|
||||
@@ -1086,7 +1156,7 @@ impl CommandEncoder {
|
||||
destination: BufferCopyView,
|
||||
copy_size: Extent3d,
|
||||
) {
|
||||
wgn::wgpu_command_buffer_copy_texture_to_buffer(
|
||||
wgn::wgpu_command_encoder_copy_texture_to_buffer(
|
||||
self.id,
|
||||
&source.into_native(),
|
||||
&destination.into_native(),
|
||||
@@ -1101,7 +1171,7 @@ impl CommandEncoder {
|
||||
destination: TextureCopyView,
|
||||
copy_size: Extent3d,
|
||||
) {
|
||||
wgn::wgpu_command_buffer_copy_texture_to_texture(
|
||||
wgn::wgpu_command_encoder_copy_texture_to_texture(
|
||||
self.id,
|
||||
&source.into_native(),
|
||||
&destination.into_native(),
|
||||
@@ -1146,11 +1216,15 @@ impl<'a> RenderPass<'a> {
|
||||
wgn::wgpu_render_pass_set_index_buffer(self.id, buffer.id, offset);
|
||||
}
|
||||
|
||||
/// Sets the active vertex buffers.
|
||||
/// Sets the active vertex buffers, starting from `start_slot`.
|
||||
///
|
||||
/// Each element of `buffer_pairs` describes a vertex buffer and an offset in bytes into that
|
||||
/// buffer. The offset must be aligned to a multiple of 4 bytes.
|
||||
pub fn set_vertex_buffers(&mut self, start_slot: u32, buffer_pairs: &[(&Buffer, BufferAddress)]) {
|
||||
pub fn set_vertex_buffers(
|
||||
&mut self,
|
||||
start_slot: u32,
|
||||
buffer_pairs: &[(&Buffer, BufferAddress)],
|
||||
) {
|
||||
let mut buffers = Vec::new();
|
||||
let mut offsets = Vec::new();
|
||||
for &(buffer, offset) in buffer_pairs {
|
||||
@@ -1172,16 +1246,16 @@ impl<'a> RenderPass<'a> {
|
||||
pub fn set_scissor_rect(&mut self, x: u32, y: u32, w: u32, h: u32) {
|
||||
wgn::wgpu_render_pass_set_scissor_rect(self.id, x, y, w, h)
|
||||
}
|
||||
|
||||
|
||||
/// Sets the viewport region.
|
||||
///
|
||||
/// Subsequent draw calls will draw any fragments in this region.
|
||||
pub fn set_viewport(&mut self, x: f32, y: f32, w: f32, h: f32, min_depth: f32, max_depth: f32) {
|
||||
wgn::wgpu_render_pass_set_viewport(self.id, x, y, w, h, min_depth, max_depth)
|
||||
wgn::wgpu_render_pass_set_viewport(self.id, x, y, w, h, min_depth, max_depth)
|
||||
}
|
||||
|
||||
/// Sets the stencil reference.
|
||||
///
|
||||
///
|
||||
/// Subsequent stencil tests will test against this value.
|
||||
pub fn set_stencil_reference(&mut self, reference: u32) {
|
||||
wgn::wgpu_render_pass_set_stencil_reference(self.id, reference)
|
||||
|
||||
@@ -16,16 +16,16 @@ fn multithreaded_compute() {
|
||||
let size = (numbers.len() * std::mem::size_of::<u32>()) as wgpu::BufferAddress;
|
||||
|
||||
let instance = wgpu::Instance::new();
|
||||
let adapter = instance.get_adapter(Some(&wgpu::RequestAdapterOptions {
|
||||
let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
power_preference: wgpu::PowerPreference::Default,
|
||||
}));
|
||||
});
|
||||
|
||||
let mut device = adapter.request_device(Some(&wgpu::DeviceDescriptor {
|
||||
let mut device = adapter.request_device(&wgpu::DeviceDescriptor {
|
||||
extensions: wgpu::Extensions {
|
||||
anisotropic_filtering: false,
|
||||
},
|
||||
limits: wgpu::Limits::default(),
|
||||
}));
|
||||
});
|
||||
|
||||
let cs = include_bytes!("../examples/hello-compute/shader.comp.spv");
|
||||
let cs_module = device.create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(&cs[..])).unwrap());
|
||||
@@ -48,14 +48,16 @@ fn multithreaded_compute() {
|
||||
|
||||
let bind_group_layout =
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
bindings: &[wgpu::BindGroupLayoutBinding {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::COMPUTE,
|
||||
ty: wgpu::BindingType::StorageBuffer,
|
||||
dynamic: false,
|
||||
multisampled: false,
|
||||
texture_dimension: wgpu::TextureViewDimension::D2,
|
||||
}],
|
||||
bindings: &[
|
||||
wgpu::BindGroupLayoutBinding {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::COMPUTE,
|
||||
ty: wgpu::BindingType::StorageBuffer {
|
||||
dynamic: false,
|
||||
readonly: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
@@ -93,7 +95,7 @@ fn multithreaded_compute() {
|
||||
}
|
||||
encoder.copy_buffer_to_buffer(&storage_buffer, 0, &staging_buffer, 0, size);
|
||||
|
||||
device.get_queue().submit(&[encoder.finish(None)]);
|
||||
device.get_queue().submit(&[encoder.finish()]);
|
||||
|
||||
staging_buffer.map_read_async(0, size, |result: wgpu::BufferMapAsyncResult<&[u32]>| {
|
||||
assert_eq!(result.unwrap().data, [25, 25, 25]);
|
||||
|
||||
Reference in New Issue
Block a user