mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-21 22:33:49 +00:00
Bump raw window handle to 0.6.0 (#4202)
Co-authored-by: junglie85 <junglie85@gmail.com> Co-authored-by: Connor Fitzgerald <connorwadefitzgerald@gmail.com>
This commit is contained in:
parent
2a9fdf9aa1
commit
4c5a817071
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
@ -441,7 +441,9 @@ jobs:
|
||||
**/*-difference.png
|
||||
|
||||
- name: generate coverage report
|
||||
id: coverage
|
||||
shell: bash
|
||||
continue-on-error: true
|
||||
run: |
|
||||
set -e
|
||||
|
||||
@ -449,6 +451,7 @@ jobs:
|
||||
|
||||
- name: upload coverage report to codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
if: steps.coverage.outcome == 'success'
|
||||
with:
|
||||
files: lcov.info
|
||||
|
||||
|
654
Cargo.lock
generated
654
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -109,7 +109,7 @@ pico-args = { version = "0.5.0", features = [
|
||||
png = "0.17.10"
|
||||
pollster = "0.3"
|
||||
profiling = { version = "1", default-features = false }
|
||||
raw-window-handle = "0.5"
|
||||
raw-window-handle = "0.6"
|
||||
renderdoc-sys = "1.0.0"
|
||||
ron = "0.8"
|
||||
serde = "1"
|
||||
@ -123,7 +123,7 @@ wgpu-example = { version = "0.18.0", path = "./examples/common" }
|
||||
wgpu-macros = { version = "0.18.0", path = "./wgpu-macros" }
|
||||
wgpu-test = { version = "0.18.0", path = "./tests" }
|
||||
wgpu-types = { version = "0.18.0", path = "./wgpu-types" }
|
||||
winit = { version = "0.28.7", features = ["android-native-activity"] }
|
||||
winit = { version = "0.29.2", features = [ "android-native-activity" ] }
|
||||
|
||||
# Metal dependencies
|
||||
block = "0.1"
|
||||
|
@ -2,6 +2,10 @@ use bytemuck::{Pod, Zeroable};
|
||||
use nanorand::{Rng, WyRand};
|
||||
use std::{borrow::Cow, mem};
|
||||
use wgpu::util::DeviceExt;
|
||||
use winit::{
|
||||
event::{ElementState, KeyEvent},
|
||||
keyboard::{Key, NamedKey},
|
||||
};
|
||||
|
||||
const MAX_BUNNIES: usize = 1 << 20;
|
||||
const BUNNY_SIZE: f32 = 0.15 * 256.0;
|
||||
@ -18,24 +22,115 @@ struct Globals {
|
||||
|
||||
#[repr(C, align(256))]
|
||||
#[derive(Clone, Copy, Zeroable)]
|
||||
struct Locals {
|
||||
struct Bunny {
|
||||
position: [f32; 2],
|
||||
velocity: [f32; 2],
|
||||
color: u32,
|
||||
_pad: u32,
|
||||
}
|
||||
|
||||
impl Bunny {
|
||||
fn update_data(&mut self, delta: f32, extent: &[u32; 2]) {
|
||||
self.position[0] += self.velocity[0] * delta;
|
||||
self.position[1] += self.velocity[1] * delta;
|
||||
self.velocity[1] += GRAVITY * delta;
|
||||
if (self.velocity[0] > 0.0 && self.position[0] + 0.5 * BUNNY_SIZE > extent[0] as f32)
|
||||
|| (self.velocity[0] < 0.0 && self.position[0] - 0.5 * BUNNY_SIZE < 0.0)
|
||||
{
|
||||
self.velocity[0] *= -1.0;
|
||||
}
|
||||
if self.velocity[1] < 0.0 && self.position[1] < 0.5 * BUNNY_SIZE {
|
||||
self.velocity[1] *= -1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Example struct holds references to wgpu resources and frame persistent data
|
||||
struct Example {
|
||||
global_group: wgpu::BindGroup,
|
||||
local_group: wgpu::BindGroup,
|
||||
pipeline: wgpu::RenderPipeline,
|
||||
bunnies: Vec<Locals>,
|
||||
bunnies: Vec<Bunny>,
|
||||
local_buffer: wgpu::Buffer,
|
||||
extent: [u32; 2],
|
||||
rng: WyRand,
|
||||
}
|
||||
|
||||
impl Example {
|
||||
fn spawn_bunnies(&mut self) {
|
||||
let spawn_count = 64 + self.bunnies.len() / 2;
|
||||
let color = self.rng.generate::<u32>();
|
||||
println!(
|
||||
"Spawning {} bunnies, total at {}",
|
||||
spawn_count,
|
||||
self.bunnies.len() + spawn_count
|
||||
);
|
||||
for _ in 0..spawn_count {
|
||||
let speed = self.rng.generate::<f32>() * MAX_VELOCITY - (MAX_VELOCITY * 0.5);
|
||||
self.bunnies.push(Bunny {
|
||||
position: [0.0, 0.5 * (self.extent[1] as f32)],
|
||||
velocity: [speed, 0.0],
|
||||
color,
|
||||
_pad: 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn render_inner(
|
||||
&mut self,
|
||||
view: &wgpu::TextureView,
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
) {
|
||||
let delta = 0.01;
|
||||
for bunny in self.bunnies.iter_mut() {
|
||||
bunny.update_data(delta, &self.extent);
|
||||
}
|
||||
|
||||
let uniform_alignment = device.limits().min_uniform_buffer_offset_alignment;
|
||||
queue.write_buffer(&self.local_buffer, 0, unsafe {
|
||||
std::slice::from_raw_parts(
|
||||
self.bunnies.as_ptr() as *const u8,
|
||||
self.bunnies.len() * uniform_alignment as usize,
|
||||
)
|
||||
});
|
||||
|
||||
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor::default());
|
||||
{
|
||||
let clear_color = wgpu::Color {
|
||||
r: 0.1,
|
||||
g: 0.2,
|
||||
b: 0.3,
|
||||
a: 1.0,
|
||||
};
|
||||
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: None,
|
||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||
view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Clear(clear_color),
|
||||
store: wgpu::StoreOp::Store,
|
||||
},
|
||||
})],
|
||||
depth_stencil_attachment: None,
|
||||
timestamp_writes: None,
|
||||
occlusion_query_set: None,
|
||||
});
|
||||
rpass.set_pipeline(&self.pipeline);
|
||||
rpass.set_bind_group(0, &self.global_group, &[]);
|
||||
for i in 0..self.bunnies.len() {
|
||||
let offset =
|
||||
(i as wgpu::DynamicOffset) * (uniform_alignment as wgpu::DynamicOffset);
|
||||
rpass.set_bind_group(1, &self.local_group, &[offset]);
|
||||
rpass.draw(0..4, 0..1);
|
||||
}
|
||||
}
|
||||
|
||||
queue.submit(Some(encoder.finish()));
|
||||
}
|
||||
}
|
||||
|
||||
impl wgpu_example::framework::Example for Example {
|
||||
fn init(
|
||||
config: &wgpu::SurfaceConfiguration,
|
||||
@ -90,7 +185,7 @@ impl wgpu_example::framework::Example for Example {
|
||||
ty: wgpu::BindingType::Buffer {
|
||||
ty: wgpu::BufferBindingType::Uniform,
|
||||
has_dynamic_offset: true,
|
||||
min_binding_size: wgpu::BufferSize::new(mem::size_of::<Locals>() as _),
|
||||
min_binding_size: wgpu::BufferSize::new(mem::size_of::<Bunny>() as _),
|
||||
},
|
||||
count: None,
|
||||
}],
|
||||
@ -228,7 +323,7 @@ impl wgpu_example::framework::Example for Example {
|
||||
resource: wgpu::BindingResource::Buffer(wgpu::BufferBinding {
|
||||
buffer: &local_buffer,
|
||||
offset: 0,
|
||||
size: wgpu::BufferSize::new(mem::size_of::<Locals>() as _),
|
||||
size: wgpu::BufferSize::new(mem::size_of::<Bunny>() as _),
|
||||
}),
|
||||
}],
|
||||
label: None,
|
||||
@ -249,31 +344,16 @@ impl wgpu_example::framework::Example for Example {
|
||||
|
||||
fn update(&mut self, event: winit::event::WindowEvent) {
|
||||
if let winit::event::WindowEvent::KeyboardInput {
|
||||
input:
|
||||
winit::event::KeyboardInput {
|
||||
virtual_keycode: Some(winit::event::VirtualKeyCode::Space),
|
||||
state: winit::event::ElementState::Pressed,
|
||||
event:
|
||||
KeyEvent {
|
||||
logical_key: Key::Named(NamedKey::Space),
|
||||
state: ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
..
|
||||
} = event
|
||||
{
|
||||
let spawn_count = 64 + self.bunnies.len() / 2;
|
||||
let color = self.rng.generate::<u32>();
|
||||
println!(
|
||||
"Spawning {} bunnies, total at {}",
|
||||
spawn_count,
|
||||
self.bunnies.len() + spawn_count
|
||||
);
|
||||
for _ in 0..spawn_count {
|
||||
let speed = self.rng.generate::<f32>() * MAX_VELOCITY - (MAX_VELOCITY * 0.5);
|
||||
self.bunnies.push(Locals {
|
||||
position: [0.0, 0.5 * (self.extent[1] as f32)],
|
||||
velocity: [speed, 0.0],
|
||||
color,
|
||||
_pad: 0,
|
||||
});
|
||||
}
|
||||
self.spawn_bunnies();
|
||||
}
|
||||
}
|
||||
|
||||
@ -287,63 +367,11 @@ impl wgpu_example::framework::Example for Example {
|
||||
}
|
||||
|
||||
fn render(&mut self, view: &wgpu::TextureView, device: &wgpu::Device, queue: &wgpu::Queue) {
|
||||
let delta = 0.01;
|
||||
for bunny in self.bunnies.iter_mut() {
|
||||
bunny.position[0] += bunny.velocity[0] * delta;
|
||||
bunny.position[1] += bunny.velocity[1] * delta;
|
||||
bunny.velocity[1] += GRAVITY * delta;
|
||||
if (bunny.velocity[0] > 0.0
|
||||
&& bunny.position[0] + 0.5 * BUNNY_SIZE > self.extent[0] as f32)
|
||||
|| (bunny.velocity[0] < 0.0 && bunny.position[0] - 0.5 * BUNNY_SIZE < 0.0)
|
||||
{
|
||||
bunny.velocity[0] *= -1.0;
|
||||
}
|
||||
if bunny.velocity[1] < 0.0 && bunny.position[1] < 0.5 * BUNNY_SIZE {
|
||||
bunny.velocity[1] *= -1.0;
|
||||
}
|
||||
self.spawn_bunnies();
|
||||
|
||||
for _frame_number in 0..3 {
|
||||
self.render_inner(view, device, queue);
|
||||
}
|
||||
|
||||
let uniform_alignment = device.limits().min_uniform_buffer_offset_alignment;
|
||||
queue.write_buffer(&self.local_buffer, 0, unsafe {
|
||||
std::slice::from_raw_parts(
|
||||
self.bunnies.as_ptr() as *const u8,
|
||||
self.bunnies.len() * uniform_alignment as usize,
|
||||
)
|
||||
});
|
||||
|
||||
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor::default());
|
||||
{
|
||||
let clear_color = wgpu::Color {
|
||||
r: 0.1,
|
||||
g: 0.2,
|
||||
b: 0.3,
|
||||
a: 1.0,
|
||||
};
|
||||
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: None,
|
||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||
view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Clear(clear_color),
|
||||
store: wgpu::StoreOp::Store,
|
||||
},
|
||||
})],
|
||||
depth_stencil_attachment: None,
|
||||
timestamp_writes: None,
|
||||
occlusion_query_set: None,
|
||||
});
|
||||
rpass.set_pipeline(&self.pipeline);
|
||||
rpass.set_bind_group(0, &self.global_group, &[]);
|
||||
for i in 0..self.bunnies.len() {
|
||||
let offset =
|
||||
(i as wgpu::DynamicOffset) * (uniform_alignment as wgpu::DynamicOffset);
|
||||
rpass.set_bind_group(1, &self.local_group, &[offset]);
|
||||
rpass.draw(0..4, 0..1);
|
||||
}
|
||||
}
|
||||
|
||||
queue.submit(Some(encoder.finish()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,9 @@ use web_sys::{ImageBitmapRenderingContext, OffscreenCanvas};
|
||||
use wgpu::{WasmNotSend, WasmNotSync};
|
||||
use wgpu_test::GpuTestConfiguration;
|
||||
use winit::{
|
||||
event::{self, WindowEvent},
|
||||
event::{self, KeyEvent, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
keyboard::{Key, NamedKey},
|
||||
};
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -31,9 +32,11 @@ pub trait Example: 'static + Sized {
|
||||
fn optional_features() -> wgpu::Features {
|
||||
wgpu::Features::empty()
|
||||
}
|
||||
|
||||
fn required_features() -> wgpu::Features {
|
||||
wgpu::Features::empty()
|
||||
}
|
||||
|
||||
fn required_downlevel_capabilities() -> wgpu::DownlevelCapabilities {
|
||||
wgpu::DownlevelCapabilities {
|
||||
flags: wgpu::DownlevelFlags::empty(),
|
||||
@ -41,27 +44,31 @@ pub trait Example: 'static + Sized {
|
||||
..wgpu::DownlevelCapabilities::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn required_limits() -> wgpu::Limits {
|
||||
wgpu::Limits::downlevel_webgl2_defaults() // These downlevel limits will allow the code to run on all possible hardware
|
||||
}
|
||||
|
||||
fn init(
|
||||
config: &wgpu::SurfaceConfiguration,
|
||||
adapter: &wgpu::Adapter,
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
) -> Self;
|
||||
|
||||
fn resize(
|
||||
&mut self,
|
||||
config: &wgpu::SurfaceConfiguration,
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
);
|
||||
|
||||
fn update(&mut self, event: WindowEvent);
|
||||
|
||||
fn render(&mut self, view: &wgpu::TextureView, device: &wgpu::Device, queue: &wgpu::Queue);
|
||||
}
|
||||
|
||||
struct Setup {
|
||||
window: winit::window::Window,
|
||||
event_loop: EventLoop<()>,
|
||||
instance: wgpu::Instance,
|
||||
size: winit::dpi::PhysicalSize<u32>,
|
||||
@ -85,7 +92,7 @@ async fn setup<E: Example>(title: &str) -> Setup {
|
||||
env_logger::init();
|
||||
};
|
||||
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
let mut builder = winit::window::WindowBuilder::new();
|
||||
builder = builder.with_title(title);
|
||||
#[cfg(windows_OFF)] // TODO
|
||||
@ -109,8 +116,10 @@ async fn setup<E: Example>(title: &str) -> Setup {
|
||||
.and_then(|win| win.document())
|
||||
.and_then(|doc| doc.body())
|
||||
.and_then(|body| {
|
||||
body.append_child(&web_sys::Element::from(window.canvas()))
|
||||
.ok()
|
||||
body.append_child(&web_sys::Element::from(
|
||||
window.canvas().expect("Couldn't get canvas"),
|
||||
))
|
||||
.ok()
|
||||
})
|
||||
.expect("couldn't append canvas to document body");
|
||||
}
|
||||
@ -133,6 +142,7 @@ async fn setup<E: Example>(title: &str) -> Setup {
|
||||
|
||||
let bitmap_renderer = window
|
||||
.canvas()
|
||||
.expect("Couldn't get html canvas")
|
||||
.get_context("bitmaprenderer")
|
||||
.expect("couldn't create ImageBitmapRenderingContext (Result)")
|
||||
.expect("couldn't create ImageBitmapRenderingContext (Option)")
|
||||
@ -230,7 +240,6 @@ async fn setup<E: Example>(title: &str) -> Setup {
|
||||
.expect("Unable to find a suitable GPU adapter!");
|
||||
|
||||
Setup {
|
||||
window,
|
||||
event_loop,
|
||||
instance,
|
||||
size,
|
||||
@ -245,7 +254,6 @@ async fn setup<E: Example>(title: &str) -> Setup {
|
||||
|
||||
fn start<E: Example>(
|
||||
#[cfg(not(target_arch = "wasm32"))] Setup {
|
||||
window,
|
||||
event_loop,
|
||||
instance,
|
||||
size,
|
||||
@ -255,7 +263,6 @@ fn start<E: Example>(
|
||||
queue,
|
||||
}: Setup,
|
||||
#[cfg(target_arch = "wasm32")] Setup {
|
||||
window,
|
||||
event_loop,
|
||||
instance,
|
||||
size,
|
||||
@ -282,113 +289,103 @@ fn start<E: Example>(
|
||||
let (mut frame_count, mut accum_time) = (0, 0.0);
|
||||
|
||||
log::info!("Entering render loop...");
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
let _ = (&instance, &adapter); // force ownership by the closure
|
||||
*control_flow = if cfg!(feature = "metal-auto-capture") {
|
||||
ControlFlow::Exit
|
||||
} else {
|
||||
ControlFlow::Poll
|
||||
};
|
||||
match event {
|
||||
event::Event::RedrawEventsCleared => {
|
||||
window.request_redraw();
|
||||
}
|
||||
event::Event::WindowEvent {
|
||||
event:
|
||||
WindowEvent::Resized(size)
|
||||
| WindowEvent::ScaleFactorChanged {
|
||||
new_inner_size: &mut size,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
log::info!("Resizing to {:?}", size);
|
||||
config.width = size.width.max(1);
|
||||
config.height = size.height.max(1);
|
||||
example.resize(&config, &device, &queue);
|
||||
surface.configure(&device, &config);
|
||||
}
|
||||
event::Event::WindowEvent { event, .. } => match event {
|
||||
WindowEvent::KeyboardInput {
|
||||
input:
|
||||
event::KeyboardInput {
|
||||
virtual_keycode: Some(event::VirtualKeyCode::Escape),
|
||||
state: event::ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
..
|
||||
}
|
||||
| WindowEvent::CloseRequested => {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
WindowEvent::KeyboardInput {
|
||||
input:
|
||||
event::KeyboardInput {
|
||||
virtual_keycode: Some(event::VirtualKeyCode::R),
|
||||
state: event::ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
event_loop
|
||||
.run(move |event, target| {
|
||||
let _ = (&instance, &adapter); // force ownership by the closure
|
||||
target.set_control_flow(ControlFlow::Poll);
|
||||
|
||||
if cfg!(feature = "metal-auto-capture") {
|
||||
target.exit();
|
||||
};
|
||||
|
||||
match event {
|
||||
event::Event::WindowEvent {
|
||||
event: WindowEvent::Resized(size),
|
||||
..
|
||||
} => {
|
||||
println!("{:#?}", instance.generate_report());
|
||||
config.width = size.width.max(1);
|
||||
config.height = size.height.max(1);
|
||||
example.resize(&config, &device, &queue);
|
||||
surface.configure(&device, &config);
|
||||
}
|
||||
_ => {
|
||||
example.update(event);
|
||||
}
|
||||
},
|
||||
event::Event::RedrawRequested(_) => {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
accum_time += last_frame_inst.elapsed().as_secs_f32();
|
||||
last_frame_inst = Instant::now();
|
||||
frame_count += 1;
|
||||
if frame_count == 100 {
|
||||
println!(
|
||||
"Avg frame time {}ms",
|
||||
accum_time * 1000.0 / frame_count as f32
|
||||
);
|
||||
accum_time = 0.0;
|
||||
frame_count = 0;
|
||||
event::Event::WindowEvent { event, .. } => match event {
|
||||
WindowEvent::KeyboardInput {
|
||||
event:
|
||||
KeyEvent {
|
||||
logical_key: Key::Named(NamedKey::Escape),
|
||||
..
|
||||
},
|
||||
..
|
||||
}
|
||||
}
|
||||
|
||||
let frame = match surface.get_current_texture() {
|
||||
Ok(frame) => frame,
|
||||
Err(_) => {
|
||||
surface.configure(&device, &config);
|
||||
surface
|
||||
.get_current_texture()
|
||||
.expect("Failed to acquire next surface texture!")
|
||||
| WindowEvent::CloseRequested => {
|
||||
target.exit();
|
||||
}
|
||||
};
|
||||
let view = frame.texture.create_view(&wgpu::TextureViewDescriptor {
|
||||
format: Some(surface_view_format),
|
||||
..wgpu::TextureViewDescriptor::default()
|
||||
});
|
||||
|
||||
example.render(&view, &device, &queue);
|
||||
|
||||
frame.present();
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
if let Some(offscreen_canvas_setup) = &offscreen_canvas_setup {
|
||||
let image_bitmap = offscreen_canvas_setup
|
||||
.offscreen_canvas
|
||||
.transfer_to_image_bitmap()
|
||||
.expect("couldn't transfer offscreen canvas to image bitmap.");
|
||||
offscreen_canvas_setup
|
||||
.bitmap_renderer
|
||||
.transfer_from_image_bitmap(&image_bitmap);
|
||||
|
||||
log::info!("Transferring OffscreenCanvas to ImageBitmapRenderer");
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
WindowEvent::KeyboardInput {
|
||||
event:
|
||||
KeyEvent {
|
||||
logical_key: Key::Character(s),
|
||||
..
|
||||
},
|
||||
..
|
||||
} if s == "r" => {
|
||||
println!("{:#?}", instance.generate_report());
|
||||
}
|
||||
}
|
||||
event::WindowEvent::RedrawRequested => {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
accum_time += last_frame_inst.elapsed().as_secs_f32();
|
||||
last_frame_inst = Instant::now();
|
||||
frame_count += 1;
|
||||
if frame_count == 100 {
|
||||
println!(
|
||||
"Avg frame time {}ms",
|
||||
accum_time * 1000.0 / frame_count as f32
|
||||
);
|
||||
accum_time = 0.0;
|
||||
frame_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
let frame = match surface.get_current_texture() {
|
||||
Ok(frame) => frame,
|
||||
Err(_) => {
|
||||
surface.configure(&device, &config);
|
||||
surface
|
||||
.get_current_texture()
|
||||
.expect("Failed to acquire next surface texture!")
|
||||
}
|
||||
};
|
||||
let view = frame.texture.create_view(&wgpu::TextureViewDescriptor {
|
||||
format: Some(surface_view_format),
|
||||
..wgpu::TextureViewDescriptor::default()
|
||||
});
|
||||
|
||||
example.render(&view, &device, &queue);
|
||||
|
||||
frame.present();
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
if let Some(offscreen_canvas_setup) = &offscreen_canvas_setup {
|
||||
let image_bitmap = offscreen_canvas_setup
|
||||
.offscreen_canvas
|
||||
.transfer_to_image_bitmap()
|
||||
.expect("couldn't transfer offscreen canvas to image bitmap.");
|
||||
offscreen_canvas_setup
|
||||
.bitmap_renderer
|
||||
.transfer_from_image_bitmap(&image_bitmap);
|
||||
|
||||
log::info!("Transferring OffscreenCanvas to ImageBitmapRenderer");
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => example.update(event),
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
@ -511,30 +508,7 @@ impl<E: Example + WasmNotSend + WasmNotSync> From<ExampleTestParams<E>> for GpuT
|
||||
&ctx.queue,
|
||||
);
|
||||
|
||||
{
|
||||
example.render(&dst_view, &ctx.device, &ctx.queue);
|
||||
|
||||
// Handle specific case for bunnymark
|
||||
#[allow(deprecated)]
|
||||
if params.image_path == "/examples/bunnymark/screenshot.png" {
|
||||
// Press spacebar to spawn bunnies
|
||||
example.update(winit::event::WindowEvent::KeyboardInput {
|
||||
input: winit::event::KeyboardInput {
|
||||
scancode: 0,
|
||||
state: winit::event::ElementState::Pressed,
|
||||
virtual_keycode: Some(winit::event::VirtualKeyCode::Space),
|
||||
modifiers: winit::event::ModifiersState::empty(),
|
||||
},
|
||||
device_id: unsafe { winit::event::DeviceId::dummy() },
|
||||
is_synthetic: false,
|
||||
});
|
||||
|
||||
// Step 3 extra frames
|
||||
for _ in 0..3 {
|
||||
example.render(&dst_view, &ctx.device, &ctx.queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
example.render(&dst_view, &ctx.device, &ctx.queue);
|
||||
|
||||
let mut cmd_buf = ctx
|
||||
.device
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::borrow::Cow;
|
||||
use winit::{
|
||||
event::{Event, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
event_loop::EventLoop,
|
||||
window::Window,
|
||||
};
|
||||
|
||||
@ -82,67 +82,71 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
|
||||
|
||||
surface.configure(&device, &config);
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
// Have the closure take ownership of the resources.
|
||||
// `event_loop.run` never returns, therefore we must do this to ensure
|
||||
// the resources are properly cleaned up.
|
||||
let _ = (&instance, &adapter, &shader, &pipeline_layout);
|
||||
event_loop
|
||||
.run(move |event, target| {
|
||||
// Have the closure take ownership of the resources.
|
||||
// `event_loop.run` never returns, therefore we must do this to ensure
|
||||
// the resources are properly cleaned up.
|
||||
let _ = (&instance, &adapter, &shader, &pipeline_layout);
|
||||
|
||||
*control_flow = ControlFlow::Wait;
|
||||
match event {
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::Resized(size),
|
||||
..
|
||||
} => {
|
||||
// Reconfigure the surface with the new size
|
||||
config.width = size.width;
|
||||
config.height = size.height;
|
||||
surface.configure(&device, &config);
|
||||
// On macos the window needs to be redrawn manually after resizing
|
||||
window.request_redraw();
|
||||
}
|
||||
Event::RedrawRequested(_) => {
|
||||
let frame = surface
|
||||
.get_current_texture()
|
||||
.expect("Failed to acquire next swap chain texture");
|
||||
let view = frame
|
||||
.texture
|
||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
let mut encoder =
|
||||
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
||||
{
|
||||
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: None,
|
||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||
view: &view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
|
||||
store: wgpu::StoreOp::Store,
|
||||
},
|
||||
})],
|
||||
depth_stencil_attachment: None,
|
||||
timestamp_writes: None,
|
||||
occlusion_query_set: None,
|
||||
});
|
||||
rpass.set_pipeline(&render_pipeline);
|
||||
rpass.draw(0..3, 0..1);
|
||||
}
|
||||
if let Event::WindowEvent {
|
||||
window_id: _,
|
||||
event,
|
||||
} = event
|
||||
{
|
||||
match event {
|
||||
WindowEvent::Resized(new_size) => {
|
||||
// Reconfigure the surface with the new size
|
||||
config.width = new_size.width;
|
||||
config.height = new_size.height;
|
||||
surface.configure(&device, &config);
|
||||
// On macos the window needs to be redrawn manually after resizing
|
||||
window.request_redraw();
|
||||
}
|
||||
WindowEvent::RedrawRequested => {
|
||||
let frame = surface
|
||||
.get_current_texture()
|
||||
.expect("Failed to acquire next swap chain texture");
|
||||
let view = frame
|
||||
.texture
|
||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
let mut encoder =
|
||||
device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||
label: None,
|
||||
});
|
||||
{
|
||||
let mut rpass =
|
||||
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: None,
|
||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||
view: &view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
|
||||
store: wgpu::StoreOp::Store,
|
||||
},
|
||||
})],
|
||||
depth_stencil_attachment: None,
|
||||
timestamp_writes: None,
|
||||
occlusion_query_set: None,
|
||||
});
|
||||
rpass.set_pipeline(&render_pipeline);
|
||||
rpass.draw(0..3, 0..1);
|
||||
}
|
||||
|
||||
queue.submit(Some(encoder.finish()));
|
||||
frame.present();
|
||||
queue.submit(Some(encoder.finish()));
|
||||
frame.present();
|
||||
}
|
||||
WindowEvent::CloseRequested => target.exit(),
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::CloseRequested,
|
||||
..
|
||||
} => *control_flow = ControlFlow::Exit,
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
let window = winit::window::Window::new(&event_loop).unwrap();
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
@ -159,7 +163,7 @@ fn main() {
|
||||
.and_then(|win| win.document())
|
||||
.and_then(|doc| doc.body())
|
||||
.and_then(|body| {
|
||||
body.append_child(&web_sys::Element::from(window.canvas()))
|
||||
body.append_child(&web_sys::Element::from(window.canvas().unwrap()))
|
||||
.ok()
|
||||
})
|
||||
.expect("couldn't append canvas to document body");
|
||||
|
@ -3,7 +3,7 @@
|
||||
use std::collections::HashMap;
|
||||
use winit::{
|
||||
event::{Event, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
event_loop::EventLoop,
|
||||
window::{Window, WindowId},
|
||||
};
|
||||
|
||||
@ -95,68 +95,70 @@ async fn run(event_loop: EventLoop<()>, viewports: Vec<(Window, wgpu::Color)>) {
|
||||
.map(|desc| (desc.window.id(), desc.build(&adapter, &device)))
|
||||
.collect();
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
// Have the closure take ownership of the resources.
|
||||
// `event_loop.run` never returns, therefore we must do this to ensure
|
||||
// the resources are properly cleaned up.
|
||||
let _ = (&instance, &adapter);
|
||||
event_loop
|
||||
.run(move |event, target| {
|
||||
// Have the closure take ownership of the resources.
|
||||
// `event_loop.run` never returns, therefore we must do this to ensure
|
||||
// the resources are properly cleaned up.
|
||||
let _ = (&instance, &adapter);
|
||||
|
||||
*control_flow = ControlFlow::Wait;
|
||||
match event {
|
||||
Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::Resized(size),
|
||||
..
|
||||
} => {
|
||||
// Recreate the swap chain with the new size
|
||||
if let Some(viewport) = viewports.get_mut(&window_id) {
|
||||
viewport.resize(&device, size);
|
||||
// On macos the window needs to be redrawn manually after resizing
|
||||
viewport.desc.window.request_redraw();
|
||||
}
|
||||
}
|
||||
Event::RedrawRequested(window_id) => {
|
||||
if let Some(viewport) = viewports.get_mut(&window_id) {
|
||||
let frame = viewport.get_current_texture();
|
||||
let view = frame
|
||||
.texture
|
||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
let mut encoder = device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
||||
{
|
||||
let _rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: None,
|
||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||
view: &view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Clear(viewport.desc.background),
|
||||
store: wgpu::StoreOp::Store,
|
||||
},
|
||||
})],
|
||||
depth_stencil_attachment: None,
|
||||
timestamp_writes: None,
|
||||
occlusion_query_set: None,
|
||||
});
|
||||
if let Event::WindowEvent { window_id, event } = event {
|
||||
match event {
|
||||
WindowEvent::Resized(new_size) => {
|
||||
// Recreate the swap chain with the new size
|
||||
if let Some(viewport) = viewports.get_mut(&window_id) {
|
||||
viewport.resize(&device, new_size);
|
||||
// On macos the window needs to be redrawn manually after resizing
|
||||
viewport.desc.window.request_redraw();
|
||||
}
|
||||
}
|
||||
WindowEvent::RedrawRequested => {
|
||||
if let Some(viewport) = viewports.get_mut(&window_id) {
|
||||
let frame = viewport.get_current_texture();
|
||||
let view = frame
|
||||
.texture
|
||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
let mut encoder =
|
||||
device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||
label: None,
|
||||
});
|
||||
{
|
||||
let _rpass =
|
||||
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: None,
|
||||
color_attachments: &[Some(
|
||||
wgpu::RenderPassColorAttachment {
|
||||
view: &view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Clear(
|
||||
viewport.desc.background,
|
||||
),
|
||||
store: wgpu::StoreOp::Store,
|
||||
},
|
||||
},
|
||||
)],
|
||||
depth_stencil_attachment: None,
|
||||
timestamp_writes: None,
|
||||
occlusion_query_set: None,
|
||||
});
|
||||
}
|
||||
|
||||
queue.submit(Some(encoder.finish()));
|
||||
frame.present();
|
||||
queue.submit(Some(encoder.finish()));
|
||||
frame.present();
|
||||
}
|
||||
}
|
||||
WindowEvent::CloseRequested => {
|
||||
viewports.remove(&window_id);
|
||||
if viewports.is_empty() {
|
||||
target.exit();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::CloseRequested,
|
||||
..
|
||||
} => {
|
||||
viewports.remove(&window_id);
|
||||
if viewports.is_empty() {
|
||||
*control_flow = ControlFlow::Exit
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
@ -169,7 +171,7 @@ fn main() {
|
||||
const ROWS: u32 = 4;
|
||||
const COLUMNS: u32 = 4;
|
||||
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
let mut viewports = Vec::with_capacity((ROWS * COLUMNS) as usize);
|
||||
for row in 0..ROWS {
|
||||
for column in 0..COLUMNS {
|
||||
|
@ -14,6 +14,10 @@ use wgpu::util::DeviceExt;
|
||||
|
||||
#[cfg(test)]
|
||||
use wgpu_test::FailureCase;
|
||||
use winit::{
|
||||
event::{ElementState, KeyEvent, WindowEvent},
|
||||
keyboard::{Key, NamedKey},
|
||||
};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||
@ -215,27 +219,31 @@ impl wgpu_example::framework::Example for Example {
|
||||
#[allow(clippy::single_match)]
|
||||
fn update(&mut self, event: winit::event::WindowEvent) {
|
||||
match event {
|
||||
winit::event::WindowEvent::KeyboardInput { input, .. } => {
|
||||
if let winit::event::ElementState::Pressed = input.state {
|
||||
match input.virtual_keycode {
|
||||
// TODO: Switch back to full scans of possible options when we expose
|
||||
// supported sample counts to the user.
|
||||
Some(winit::event::VirtualKeyCode::Left) => {
|
||||
if self.sample_count == self.max_sample_count {
|
||||
self.sample_count = 1;
|
||||
self.rebuild_bundle = true;
|
||||
}
|
||||
}
|
||||
Some(winit::event::VirtualKeyCode::Right) => {
|
||||
if self.sample_count == 1 {
|
||||
self.sample_count = self.max_sample_count;
|
||||
self.rebuild_bundle = true;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
WindowEvent::KeyboardInput {
|
||||
event:
|
||||
KeyEvent {
|
||||
logical_key,
|
||||
state: ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => match logical_key {
|
||||
// TODO: Switch back to full scans of possible options when we expose
|
||||
// supported sample counts to the user.
|
||||
Key::Named(NamedKey::ArrowLeft) => {
|
||||
if self.sample_count == self.max_sample_count {
|
||||
self.sample_count = 1;
|
||||
self.rebuild_bundle = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Key::Named(NamedKey::ArrowRight) => {
|
||||
if self.sample_count == 1 {
|
||||
self.sample_count = self.max_sample_count;
|
||||
self.rebuild_bundle = true;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,9 @@
|
||||
// with actual GPU-allocated WGPU storage buffers.
|
||||
use encase::ShaderType;
|
||||
use winit::{
|
||||
event::{Event, VirtualKeyCode, WindowEvent},
|
||||
event::{Event, KeyEvent, WindowEvent},
|
||||
event_loop::EventLoop,
|
||||
keyboard::{Key, NamedKey},
|
||||
window::Window,
|
||||
};
|
||||
|
||||
@ -227,103 +228,124 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
|
||||
// (6)
|
||||
let mut state = Some(AppState::default());
|
||||
let main_window_id = wgpu_context.as_ref().unwrap().window.id();
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
control_flow.set_wait();
|
||||
match event {
|
||||
Event::LoopDestroyed => {
|
||||
wgpu_context = None;
|
||||
state = None;
|
||||
}
|
||||
Event::WindowEvent { window_id, event } if window_id == main_window_id => match event {
|
||||
WindowEvent::CloseRequested => {
|
||||
control_flow.set_exit();
|
||||
event_loop
|
||||
.run(move |event, target| {
|
||||
match event {
|
||||
Event::LoopExiting => {
|
||||
wgpu_context = None;
|
||||
state = None;
|
||||
}
|
||||
WindowEvent::KeyboardInput { input, .. } => {
|
||||
let state_mut = state.as_mut().unwrap();
|
||||
let wgpu_context_ref = wgpu_context.as_ref().unwrap();
|
||||
if let Some(virtual_keycode) = input.virtual_keycode {
|
||||
// (7a)
|
||||
match virtual_keycode {
|
||||
VirtualKeyCode::Escape => control_flow.set_exit(),
|
||||
VirtualKeyCode::Up => state_mut.translate_view(1, 1),
|
||||
VirtualKeyCode::Down => state_mut.translate_view(-1, 1),
|
||||
VirtualKeyCode::Left => state_mut.translate_view(-1, 0),
|
||||
VirtualKeyCode::Right => state_mut.translate_view(1, 0),
|
||||
VirtualKeyCode::U => state_mut.max_iterations += 3,
|
||||
VirtualKeyCode::D => state_mut.max_iterations -= 3,
|
||||
_ => {}
|
||||
Event::WindowEvent { window_id, event } if window_id == main_window_id => {
|
||||
match event {
|
||||
WindowEvent::CloseRequested => {
|
||||
target.exit();
|
||||
}
|
||||
wgpu_context_ref.window.request_redraw();
|
||||
WindowEvent::KeyboardInput {
|
||||
event:
|
||||
KeyEvent {
|
||||
logical_key, text, ..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
let state_mut = state.as_mut().unwrap();
|
||||
let wgpu_context_ref = wgpu_context.as_ref().unwrap();
|
||||
|
||||
if let Key::Named(key) = logical_key {
|
||||
match key {
|
||||
NamedKey::Escape => target.exit(),
|
||||
NamedKey::ArrowUp => state_mut.translate_view(1, 1),
|
||||
NamedKey::ArrowDown => state_mut.translate_view(-1, 1),
|
||||
NamedKey::ArrowLeft => state_mut.translate_view(-1, 0),
|
||||
NamedKey::ArrowRight => state_mut.translate_view(1, 0),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(text) = text {
|
||||
if text == "u" {
|
||||
state_mut.max_iterations += 3;
|
||||
} else if text == "d" {
|
||||
state_mut.max_iterations -= 3;
|
||||
}
|
||||
};
|
||||
|
||||
wgpu_context_ref.window.request_redraw();
|
||||
}
|
||||
WindowEvent::MouseWheel { delta, .. } => {
|
||||
let change = match delta {
|
||||
winit::event::MouseScrollDelta::LineDelta(_, vertical) => vertical,
|
||||
winit::event::MouseScrollDelta::PixelDelta(pos) => {
|
||||
pos.y as f32 / 20.0
|
||||
}
|
||||
};
|
||||
let state_mut = state.as_mut().unwrap();
|
||||
let wgpu_context_ref = wgpu_context.as_ref().unwrap();
|
||||
// (7b)
|
||||
state_mut.zoom(change);
|
||||
wgpu_context_ref.window.request_redraw();
|
||||
}
|
||||
WindowEvent::Resized(new_size) => {
|
||||
let wgpu_context_mut = wgpu_context.as_mut().unwrap();
|
||||
wgpu_context_mut.resize(new_size);
|
||||
wgpu_context_mut.window.request_redraw();
|
||||
}
|
||||
WindowEvent::RedrawRequested => {
|
||||
let wgpu_context_ref = wgpu_context.as_ref().unwrap();
|
||||
let state_ref = state.as_ref().unwrap();
|
||||
let frame = wgpu_context_ref.surface.get_current_texture().unwrap();
|
||||
let view = frame
|
||||
.texture
|
||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
|
||||
// (8)
|
||||
wgpu_context_ref.queue.write_buffer(
|
||||
&wgpu_context_ref.uniform_buffer,
|
||||
0,
|
||||
&state_ref.as_wgsl_bytes().expect(
|
||||
"Error in encase translating AppState \
|
||||
struct to WGSL bytes.",
|
||||
),
|
||||
);
|
||||
let mut encoder = wgpu_context_ref.device.create_command_encoder(
|
||||
&wgpu::CommandEncoderDescriptor { label: None },
|
||||
);
|
||||
{
|
||||
let mut render_pass =
|
||||
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: None,
|
||||
color_attachments: &[Some(
|
||||
wgpu::RenderPassColorAttachment {
|
||||
view: &view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
|
||||
store: wgpu::StoreOp::Store,
|
||||
},
|
||||
},
|
||||
)],
|
||||
depth_stencil_attachment: None,
|
||||
occlusion_query_set: None,
|
||||
timestamp_writes: None,
|
||||
});
|
||||
render_pass.set_pipeline(&wgpu_context_ref.pipeline);
|
||||
// (9)
|
||||
render_pass.set_bind_group(0, &wgpu_context_ref.bind_group, &[]);
|
||||
render_pass.draw(0..3, 0..1);
|
||||
}
|
||||
wgpu_context_ref.queue.submit(Some(encoder.finish()));
|
||||
frame.present();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
WindowEvent::MouseWheel { delta, .. } => {
|
||||
let change = match delta {
|
||||
winit::event::MouseScrollDelta::LineDelta(_, vertical) => vertical,
|
||||
winit::event::MouseScrollDelta::PixelDelta(pos) => pos.y as f32 / 20.0,
|
||||
};
|
||||
let state_mut = state.as_mut().unwrap();
|
||||
let wgpu_context_ref = wgpu_context.as_ref().unwrap();
|
||||
// (7b)
|
||||
state_mut.zoom(change);
|
||||
wgpu_context_ref.window.request_redraw();
|
||||
}
|
||||
WindowEvent::Resized(new_size) => {
|
||||
let wgpu_context_mut = wgpu_context.as_mut().unwrap();
|
||||
wgpu_context_mut.resize(new_size);
|
||||
wgpu_context_mut.window.request_redraw();
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
Event::RedrawRequested(id) if id == main_window_id => {
|
||||
let wgpu_context_ref = wgpu_context.as_ref().unwrap();
|
||||
let state_ref = state.as_ref().unwrap();
|
||||
let frame = wgpu_context_ref.surface.get_current_texture().unwrap();
|
||||
let view = frame
|
||||
.texture
|
||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
|
||||
// (8)
|
||||
wgpu_context_ref.queue.write_buffer(
|
||||
&wgpu_context_ref.uniform_buffer,
|
||||
0,
|
||||
&state_ref.as_wgsl_bytes().expect(
|
||||
"Error in encase translating AppState \
|
||||
struct to WGSL bytes.",
|
||||
),
|
||||
);
|
||||
let mut encoder = wgpu_context_ref
|
||||
.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
||||
{
|
||||
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: None,
|
||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||
view: &view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
|
||||
store: wgpu::StoreOp::Store,
|
||||
},
|
||||
})],
|
||||
depth_stencil_attachment: None,
|
||||
occlusion_query_set: None,
|
||||
timestamp_writes: None,
|
||||
});
|
||||
render_pass.set_pipeline(&wgpu_context_ref.pipeline);
|
||||
// (9)
|
||||
render_pass.set_bind_group(0, &wgpu_context_ref.bind_group, &[]);
|
||||
render_pass.draw(0..3, 0..1);
|
||||
}
|
||||
wgpu_context_ref.queue.submit(Some(encoder.finish()));
|
||||
frame.present();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
let window = winit::window::WindowBuilder::new()
|
||||
.with_title("Remember: Use U/D to change sample count!")
|
||||
.with_inner_size(winit::dpi::LogicalSize::new(900, 900))
|
||||
@ -344,8 +366,10 @@ fn main() {
|
||||
.and_then(|win| win.document())
|
||||
.expect("Failed to get document.");
|
||||
let body = document.body().unwrap();
|
||||
body.append_child(&web_sys::Element::from(window.canvas()))
|
||||
.unwrap();
|
||||
body.append_child(&web_sys::Element::from(
|
||||
window.canvas().expect("Couldn't get canvas"),
|
||||
))
|
||||
.unwrap();
|
||||
let controls_text = document
|
||||
.create_element("p")
|
||||
.expect("Failed to create controls text as element.");
|
||||
|
@ -12,9 +12,14 @@ fn main() {
|
||||
};
|
||||
|
||||
#[cfg(feature = "winit")]
|
||||
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
|
||||
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
|
||||
#[cfg(feature = "winit")]
|
||||
use winit::{event_loop::EventLoop, window::WindowBuilder};
|
||||
use winit::{
|
||||
event::KeyEvent,
|
||||
event_loop::EventLoop,
|
||||
keyboard::{Key, NamedKey},
|
||||
window::WindowBuilder,
|
||||
};
|
||||
|
||||
env_logger::init();
|
||||
|
||||
@ -35,7 +40,7 @@ fn main() {
|
||||
#[cfg(feature = "winit")]
|
||||
let event_loop = {
|
||||
log::info!("Creating a window");
|
||||
EventLoop::new()
|
||||
EventLoop::new().unwrap()
|
||||
};
|
||||
#[cfg(feature = "winit")]
|
||||
let window = WindowBuilder::new()
|
||||
@ -53,8 +58,8 @@ fn main() {
|
||||
|
||||
#[cfg(feature = "winit")]
|
||||
let surface = global.instance_create_surface(
|
||||
window.raw_display_handle(),
|
||||
window.raw_window_handle(),
|
||||
window.display_handle().unwrap().into(),
|
||||
window.window_handle().unwrap().into(),
|
||||
wgc::id::TypedId::zip(0, 1, wgt::Backend::Empty),
|
||||
);
|
||||
|
||||
@ -110,32 +115,32 @@ fn main() {
|
||||
#[cfg(feature = "winit")]
|
||||
{
|
||||
use winit::{
|
||||
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
|
||||
event::{ElementState, Event, WindowEvent},
|
||||
event_loop::ControlFlow,
|
||||
};
|
||||
|
||||
let mut resize_config = None;
|
||||
let mut frame_count = 0;
|
||||
let mut done = false;
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
*control_flow = ControlFlow::Poll;
|
||||
event_loop.run(move |event, target| {
|
||||
target.set_control_flow(ControlFlow::Poll);
|
||||
|
||||
match event {
|
||||
Event::MainEventsCleared => {
|
||||
window.request_redraw();
|
||||
}
|
||||
Event::RedrawRequested(_) if resize_config.is_none() => loop {
|
||||
Event::WindowEvent { event, .. } => match event {
|
||||
WindowEvent::RedrawRequested if resize_config.is_none() => {
|
||||
|
||||
match actions.pop() {
|
||||
Some(trace::Action::ConfigureSurface(_device_id, config)) => {
|
||||
log::info!("Configuring the surface");
|
||||
let current_size: (u32, u32) = window.inner_size().into();
|
||||
let size = (config.width, config.height);
|
||||
if current_size != size {
|
||||
window.set_inner_size(winit::dpi::PhysicalSize::new(
|
||||
let _ = window.request_inner_size(winit::dpi::PhysicalSize::new(
|
||||
config.width,
|
||||
config.height,
|
||||
));
|
||||
resize_config = Some(config);
|
||||
break;
|
||||
target.exit();
|
||||
} else {
|
||||
let error = gfx_select!(device => global.surface_configure(surface, device, &config));
|
||||
if let Some(e) = error {
|
||||
@ -147,12 +152,12 @@ fn main() {
|
||||
frame_count += 1;
|
||||
log::debug!("Presenting frame {}", frame_count);
|
||||
gfx_select!(device => global.surface_present(id)).unwrap();
|
||||
break;
|
||||
target.exit();
|
||||
}
|
||||
Some(trace::Action::DiscardSurfaceTexture(id)) => {
|
||||
log::debug!("Discarding frame {}", frame_count);
|
||||
gfx_select!(device => global.surface_texture_discard(id)).unwrap();
|
||||
break;
|
||||
target.exit();
|
||||
}
|
||||
Some(action) => {
|
||||
gfx_select!(device => global.process(device, action, &dir, &mut command_buffer_id_manager));
|
||||
@ -162,11 +167,10 @@ fn main() {
|
||||
println!("Finished the end at frame {}", frame_count);
|
||||
done = true;
|
||||
}
|
||||
break;
|
||||
target.exit();
|
||||
}
|
||||
}
|
||||
},
|
||||
Event::WindowEvent { event, .. } => match event {
|
||||
},
|
||||
WindowEvent::Resized(_) => {
|
||||
if let Some(config) = resize_config.take() {
|
||||
let error = gfx_select!(device => global.surface_configure(surface, device, &config));
|
||||
@ -176,26 +180,23 @@ fn main() {
|
||||
}
|
||||
}
|
||||
WindowEvent::KeyboardInput {
|
||||
input:
|
||||
KeyboardInput {
|
||||
virtual_keycode: Some(VirtualKeyCode::Escape),
|
||||
state: ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
event: KeyEvent {
|
||||
logical_key: Key::Named(NamedKey::Escape),
|
||||
state: ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
..
|
||||
}
|
||||
| WindowEvent::CloseRequested => {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
| WindowEvent::CloseRequested => target.exit(),
|
||||
_ => {}
|
||||
},
|
||||
Event::LoopDestroyed => {
|
||||
Event::LoopExiting => {
|
||||
log::info!("Closing");
|
||||
gfx_select!(device => global.device_poll(device, wgt::Maintain::Wait)).unwrap();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
}).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ log = "0.4"
|
||||
# parking_lot 0.12 switches from `winapi` to `windows`; permit either
|
||||
parking_lot = ">=0.11,<0.13"
|
||||
profiling = { version = "1", default-features = false }
|
||||
raw-window-handle = { version = "0.5", optional = true }
|
||||
raw-window-handle = { version = "0.6", optional = true }
|
||||
ron = { version = "0.8", optional = true }
|
||||
serde = { version = "1", features = ["serde_derive"], optional = true }
|
||||
smallvec = "1"
|
||||
|
@ -86,7 +86,7 @@ required-features = ["gles"]
|
||||
bitflags = "2"
|
||||
parking_lot = ">=0.11,<0.13"
|
||||
profiling = { version = "1", default-features = false }
|
||||
raw-window-handle = "0.5"
|
||||
raw-window-handle = "0.6"
|
||||
thiserror = "1"
|
||||
once_cell = "1.18.0"
|
||||
|
||||
@ -180,9 +180,7 @@ features = ["wgsl-in"]
|
||||
[dev-dependencies]
|
||||
cfg-if = "1"
|
||||
env_logger = "0.10"
|
||||
winit = { version = "0.28.7", features = [
|
||||
"android-native-activity",
|
||||
] } # for "halmark" example
|
||||
winit = { version = "0.29.2", features = [ "android-native-activity" ] } # for "halmark" example
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
|
||||
glutin = "0.29.1" # for "gles" example
|
||||
|
@ -5,7 +5,12 @@ extern crate wgpu_hal as hal;
|
||||
use hal::{
|
||||
Adapter as _, CommandEncoder as _, Device as _, Instance as _, Queue as _, Surface as _,
|
||||
};
|
||||
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
|
||||
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
|
||||
use winit::{
|
||||
event::{ElementState, Event, KeyEvent, WindowEvent},
|
||||
event_loop::ControlFlow,
|
||||
keyboard::{Key, NamedKey},
|
||||
};
|
||||
|
||||
use std::{
|
||||
borrow::{Borrow, Cow},
|
||||
@ -95,10 +100,15 @@ impl<A: hal::Api> Example<A> {
|
||||
gles_minor_version: wgt::Gles3MinorVersion::default(),
|
||||
};
|
||||
let instance = unsafe { A::Instance::init(&instance_desc)? };
|
||||
let mut surface = unsafe {
|
||||
instance
|
||||
.create_surface(window.raw_display_handle(), window.raw_window_handle())
|
||||
.unwrap()
|
||||
let mut surface = {
|
||||
let raw_window_handle = window.window_handle()?.as_raw();
|
||||
let raw_display_handle = window.display_handle()?.as_raw();
|
||||
|
||||
unsafe {
|
||||
instance
|
||||
.create_surface(raw_display_handle, raw_window_handle)
|
||||
.unwrap()
|
||||
}
|
||||
};
|
||||
|
||||
let (adapter, capabilities) = unsafe {
|
||||
@ -261,7 +271,7 @@ impl<A: hal::Api> Example<A> {
|
||||
};
|
||||
let pipeline = unsafe { device.create_render_pipeline(&pipeline_desc).unwrap() };
|
||||
|
||||
let texture_data = vec![0xFFu8; 4];
|
||||
let texture_data = [0xFFu8; 4];
|
||||
|
||||
let staging_buffer_desc = hal::BufferDescriptor {
|
||||
label: Some("stage"),
|
||||
@ -563,10 +573,10 @@ impl<A: hal::Api> Example<A> {
|
||||
|
||||
fn update(&mut self, event: winit::event::WindowEvent) {
|
||||
if let winit::event::WindowEvent::KeyboardInput {
|
||||
input:
|
||||
winit::event::KeyboardInput {
|
||||
virtual_keycode: Some(winit::event::VirtualKeyCode::Space),
|
||||
state: winit::event::ElementState::Pressed,
|
||||
event:
|
||||
KeyEvent {
|
||||
logical_key: Key::Named(NamedKey::Space),
|
||||
state: ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
..
|
||||
@ -777,7 +787,7 @@ cfg_if::cfg_if! {
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let event_loop = winit::event_loop::EventLoop::new();
|
||||
let event_loop = winit::event_loop::EventLoop::new().unwrap();
|
||||
let window = winit::window::WindowBuilder::new()
|
||||
.with_title("hal-bunnymark")
|
||||
.build(&event_loop)
|
||||
@ -789,51 +799,49 @@ fn main() {
|
||||
let mut last_frame_inst = Instant::now();
|
||||
let (mut frame_count, mut accum_time) = (0, 0.0);
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
let _ = &window; // force ownership by the closure
|
||||
*control_flow = winit::event_loop::ControlFlow::Poll;
|
||||
match event {
|
||||
winit::event::Event::RedrawEventsCleared => {
|
||||
window.request_redraw();
|
||||
}
|
||||
winit::event::Event::WindowEvent { event, .. } => match event {
|
||||
winit::event::WindowEvent::KeyboardInput {
|
||||
input:
|
||||
winit::event::KeyboardInput {
|
||||
virtual_keycode: Some(winit::event::VirtualKeyCode::Escape),
|
||||
state: winit::event::ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
..
|
||||
event_loop
|
||||
.run(move |event, target| {
|
||||
let _ = &window; // force ownership by the closure
|
||||
target.set_control_flow(ControlFlow::Poll);
|
||||
|
||||
match event {
|
||||
Event::LoopExiting => {
|
||||
example.take().unwrap().exit();
|
||||
}
|
||||
| winit::event::WindowEvent::CloseRequested => {
|
||||
*control_flow = winit::event_loop::ControlFlow::Exit;
|
||||
}
|
||||
_ => {
|
||||
example.as_mut().unwrap().update(event);
|
||||
}
|
||||
},
|
||||
winit::event::Event::RedrawRequested(_) => {
|
||||
let ex = example.as_mut().unwrap();
|
||||
{
|
||||
accum_time += last_frame_inst.elapsed().as_secs_f32();
|
||||
last_frame_inst = Instant::now();
|
||||
frame_count += 1;
|
||||
if frame_count == 100 && !ex.is_empty() {
|
||||
println!(
|
||||
"Avg frame time {}ms",
|
||||
accum_time * 1000.0 / frame_count as f32
|
||||
);
|
||||
accum_time = 0.0;
|
||||
frame_count = 0;
|
||||
Event::WindowEvent { event, .. } => match event {
|
||||
WindowEvent::KeyboardInput {
|
||||
event:
|
||||
KeyEvent {
|
||||
logical_key: Key::Named(NamedKey::Escape),
|
||||
state: ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
..
|
||||
}
|
||||
}
|
||||
ex.render();
|
||||
| WindowEvent::CloseRequested => target.exit(),
|
||||
WindowEvent::RedrawRequested => {
|
||||
let ex = example.as_mut().unwrap();
|
||||
{
|
||||
accum_time += last_frame_inst.elapsed().as_secs_f32();
|
||||
last_frame_inst = Instant::now();
|
||||
frame_count += 1;
|
||||
if frame_count == 100 && !ex.is_empty() {
|
||||
println!(
|
||||
"Avg frame time {}ms",
|
||||
accum_time * 1000.0 / frame_count as f32
|
||||
);
|
||||
accum_time = 0.0;
|
||||
frame_count = 0;
|
||||
}
|
||||
}
|
||||
ex.render();
|
||||
}
|
||||
_ => {
|
||||
example.as_mut().unwrap().update(event);
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
winit::event::Event::LoopDestroyed => {
|
||||
example.take().unwrap().exit();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ impl crate::Instance<super::Api> for super::Instance {
|
||||
raw_window_handle::RawWindowHandle::Win32(handle) => Ok(super::Surface {
|
||||
factory: self.factory.clone(),
|
||||
factory_media: self.factory_media.clone(),
|
||||
target: SurfaceTarget::WndHandle(handle.hwnd as *mut _),
|
||||
target: SurfaceTarget::WndHandle(handle.hwnd.get() as *mut _),
|
||||
supports_allow_tearing: self.supports_allow_tearing,
|
||||
swap_chain: None,
|
||||
}),
|
||||
|
@ -865,7 +865,7 @@ impl crate::Instance<super::Api> for Instance {
|
||||
.unwrap();
|
||||
|
||||
let ret = unsafe {
|
||||
ANativeWindow_setBuffersGeometry(handle.a_native_window, 0, 0, format)
|
||||
ANativeWindow_setBuffersGeometry(handle.a_native_window.as_ptr(), 0, 0, format)
|
||||
};
|
||||
|
||||
if ret != 0 {
|
||||
@ -878,7 +878,7 @@ impl crate::Instance<super::Api> for Instance {
|
||||
(Rwh::Wayland(_), raw_window_handle::RawDisplayHandle::Wayland(display_handle)) => {
|
||||
if inner
|
||||
.wl_display
|
||||
.map(|ptr| ptr != display_handle.display)
|
||||
.map(|ptr| ptr != display_handle.display.as_ptr())
|
||||
.unwrap_or(true)
|
||||
{
|
||||
/* Wayland displays are not sharable between surfaces so if the
|
||||
@ -900,7 +900,7 @@ impl crate::Instance<super::Api> for Instance {
|
||||
.unwrap()
|
||||
.get_platform_display(
|
||||
EGL_PLATFORM_WAYLAND_KHR,
|
||||
display_handle.display,
|
||||
display_handle.display.as_ptr(),
|
||||
&display_attributes,
|
||||
)
|
||||
}
|
||||
@ -914,7 +914,7 @@ impl crate::Instance<super::Api> for Instance {
|
||||
)?;
|
||||
|
||||
let old_inner = std::mem::replace(inner.deref_mut(), new_inner);
|
||||
inner.wl_display = Some(display_handle.display);
|
||||
inner.wl_display = Some(display_handle.display.as_ptr());
|
||||
|
||||
drop(old_inner);
|
||||
}
|
||||
@ -1155,29 +1155,35 @@ impl crate::Surface<super::Api> for Surface {
|
||||
&mut temp_xcb_handle as *mut _ as *mut std::ffi::c_void
|
||||
}
|
||||
(WindowKind::AngleX11, Rwh::Xcb(handle)) => {
|
||||
handle.window as *mut std::ffi::c_void
|
||||
handle.window.get() as *mut std::ffi::c_void
|
||||
}
|
||||
(WindowKind::Unknown, Rwh::AndroidNdk(handle)) => {
|
||||
handle.a_native_window.as_ptr()
|
||||
}
|
||||
(WindowKind::Unknown, Rwh::AndroidNdk(handle)) => handle.a_native_window,
|
||||
(WindowKind::Wayland, Rwh::Wayland(handle)) => {
|
||||
let library = &self.wsi.display_owner.as_ref().unwrap().library;
|
||||
let wl_egl_window_create: libloading::Symbol<WlEglWindowCreateFun> =
|
||||
unsafe { library.get(b"wl_egl_window_create") }.unwrap();
|
||||
let window = unsafe { wl_egl_window_create(handle.surface, 640, 480) };
|
||||
let window =
|
||||
unsafe { wl_egl_window_create(handle.surface.as_ptr(), 640, 480) }
|
||||
as *mut _;
|
||||
wl_window = Some(window);
|
||||
window
|
||||
}
|
||||
#[cfg(target_os = "emscripten")]
|
||||
(WindowKind::Unknown, Rwh::Web(handle)) => handle.id as *mut std::ffi::c_void,
|
||||
(WindowKind::Unknown, Rwh::Win32(handle)) => handle.hwnd,
|
||||
(WindowKind::Unknown, Rwh::Win32(handle)) => {
|
||||
handle.hwnd.get() as *mut std::ffi::c_void
|
||||
}
|
||||
(WindowKind::Unknown, Rwh::AppKit(handle)) => {
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
let window_ptr = handle.ns_view;
|
||||
let window_ptr = handle.ns_view.as_ptr();
|
||||
#[cfg(target_os = "macos")]
|
||||
let window_ptr = {
|
||||
use objc::{msg_send, runtime::Object, sel, sel_impl};
|
||||
// ns_view always have a layer and don't need to verify that it exists.
|
||||
let layer: *mut Object =
|
||||
msg_send![handle.ns_view as *mut Object, layer];
|
||||
msg_send![handle.ns_view.as_ptr() as *mut Object, layer];
|
||||
layer as *mut ffi::c_void
|
||||
};
|
||||
window_ptr
|
||||
|
@ -441,7 +441,7 @@ impl crate::Instance<super::Api> for Instance {
|
||||
)));
|
||||
};
|
||||
Ok(Surface {
|
||||
window: window.hwnd as *mut _,
|
||||
window: window.hwnd.get() as *mut _,
|
||||
presentable: true,
|
||||
swapchain: None,
|
||||
srgb_capable: self.srgb_capable,
|
||||
|
@ -96,11 +96,14 @@ impl crate::Instance<Api> for Instance {
|
||||
#[cfg(target_os = "ios")]
|
||||
raw_window_handle::RawWindowHandle::UiKit(handle) => {
|
||||
let _ = &self.managed_metal_layer_delegate;
|
||||
Ok(unsafe { Surface::from_view(handle.ui_view, None) })
|
||||
Ok(unsafe { Surface::from_view(handle.ui_view.as_ptr(), None) })
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
raw_window_handle::RawWindowHandle::AppKit(handle) => Ok(unsafe {
|
||||
Surface::from_view(handle.ns_view, Some(&self.managed_metal_layer_delegate))
|
||||
Surface::from_view(
|
||||
handle.ns_view.as_ptr(),
|
||||
Some(&self.managed_metal_layer_delegate),
|
||||
)
|
||||
}),
|
||||
_ => Err(crate::InstanceError::new(format!(
|
||||
"window handle {window_handle:?} is not a Metal-compatible handle"
|
||||
|
@ -740,33 +740,37 @@ impl crate::Instance<super::Api> for super::Instance {
|
||||
|
||||
match (window_handle, display_handle) {
|
||||
(Rwh::Wayland(handle), Rdh::Wayland(display)) => {
|
||||
self.create_surface_from_wayland(display.display, handle.surface)
|
||||
self.create_surface_from_wayland(display.display.as_ptr(), handle.surface.as_ptr())
|
||||
}
|
||||
(Rwh::Xlib(handle), Rdh::Xlib(display)) => {
|
||||
self.create_surface_from_xlib(display.display as *mut _, handle.window)
|
||||
let display = display.display.expect("Display pointer is not set.");
|
||||
self.create_surface_from_xlib(display.as_ptr() as *mut *const c_void, handle.window)
|
||||
}
|
||||
(Rwh::Xcb(handle), Rdh::Xcb(display)) => {
|
||||
self.create_surface_from_xcb(display.connection, handle.window)
|
||||
let connection = display.connection.expect("Pointer to X-Server is not set.");
|
||||
self.create_surface_from_xcb(connection.as_ptr(), handle.window.get())
|
||||
}
|
||||
(Rwh::AndroidNdk(handle), _) => {
|
||||
self.create_surface_android(handle.a_native_window.as_ptr())
|
||||
}
|
||||
(Rwh::AndroidNdk(handle), _) => self.create_surface_android(handle.a_native_window),
|
||||
#[cfg(windows)]
|
||||
(Rwh::Win32(handle), _) => {
|
||||
use winapi::um::libloaderapi::GetModuleHandleW;
|
||||
|
||||
let hinstance = unsafe { GetModuleHandleW(std::ptr::null()) };
|
||||
self.create_surface_from_hwnd(hinstance as *mut _, handle.hwnd)
|
||||
self.create_surface_from_hwnd(hinstance as *mut _, handle.hwnd.get() as *mut _)
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
(Rwh::AppKit(handle), _)
|
||||
if self.shared.extensions.contains(&ext::MetalSurface::name()) =>
|
||||
{
|
||||
self.create_surface_from_view(handle.ns_view)
|
||||
self.create_surface_from_view(handle.ns_view.as_ptr())
|
||||
}
|
||||
#[cfg(target_os = "ios")]
|
||||
(Rwh::UiKit(handle), _)
|
||||
if self.shared.extensions.contains(&ext::MetalSurface::name()) =>
|
||||
{
|
||||
self.create_surface_from_view(handle.ui_view)
|
||||
self.create_surface_from_view(handle.ui_view.as_ptr())
|
||||
}
|
||||
(_, _) => Err(crate::InstanceError::new(format!(
|
||||
"window handle {window_handle:?} is not a Vulkan-compatible handle"
|
||||
|
@ -107,7 +107,7 @@ flume.workspace = true
|
||||
log.workspace = true
|
||||
parking_lot.workspace = true
|
||||
profiling.workspace = true
|
||||
raw-window-handle.workspace = true
|
||||
raw-window-handle = { workspace = true, features = ["std"] }
|
||||
serde = { workspace = true, features = ["derive"], optional = true }
|
||||
smallvec.workspace = true
|
||||
static_assertions.workspace = true
|
||||
|
@ -1937,15 +1937,27 @@ impl Instance {
|
||||
/// - On web: will panic if the `raw_window_handle` does not properly refer to a
|
||||
/// canvas element.
|
||||
pub unsafe fn create_surface<
|
||||
W: raw_window_handle::HasRawWindowHandle + raw_window_handle::HasRawDisplayHandle,
|
||||
W: raw_window_handle::HasWindowHandle + raw_window_handle::HasDisplayHandle,
|
||||
>(
|
||||
&self,
|
||||
window: &W,
|
||||
) -> Result<Surface, CreateSurfaceError> {
|
||||
let raw_display_handle = window
|
||||
.display_handle()
|
||||
.map_err(|e| CreateSurfaceError {
|
||||
inner: CreateSurfaceErrorKind::RawHandle(e),
|
||||
})?
|
||||
.as_raw();
|
||||
let raw_window_handle = window
|
||||
.window_handle()
|
||||
.map_err(|e| CreateSurfaceError {
|
||||
inner: CreateSurfaceErrorKind::RawHandle(e),
|
||||
})?
|
||||
.as_raw();
|
||||
let (id, data) = DynContext::instance_create_surface(
|
||||
&*self.context,
|
||||
raw_window_handle::HasRawDisplayHandle::raw_display_handle(window),
|
||||
raw_window_handle::HasRawWindowHandle::raw_window_handle(window),
|
||||
raw_display_handle,
|
||||
raw_window_handle,
|
||||
)?;
|
||||
Ok(Surface {
|
||||
context: Arc::clone(&self.context),
|
||||
@ -2925,6 +2937,10 @@ enum CreateSurfaceErrorKind {
|
||||
/// Error from WebGPU surface creation.
|
||||
#[allow(dead_code)] // may be unused depending on target and features
|
||||
Web(String),
|
||||
|
||||
/// Error when trying to get a [`DisplayHandle`] or a [`WindowHandle`] from
|
||||
/// `raw_window_handle`.
|
||||
RawHandle(raw_window_handle::HandleError),
|
||||
}
|
||||
static_assertions::assert_impl_all!(CreateSurfaceError: Send, Sync);
|
||||
|
||||
@ -2938,6 +2954,7 @@ impl fmt::Display for CreateSurfaceError {
|
||||
))]
|
||||
CreateSurfaceErrorKind::Hal(e) => e.fmt(f),
|
||||
CreateSurfaceErrorKind::Web(e) => e.fmt(f),
|
||||
CreateSurfaceErrorKind::RawHandle(e) => e.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2952,6 +2969,7 @@ impl error::Error for CreateSurfaceError {
|
||||
))]
|
||||
CreateSurfaceErrorKind::Hal(e) => e.source(),
|
||||
CreateSurfaceErrorKind::Web(_) => None,
|
||||
CreateSurfaceErrorKind::RawHandle(e) => e.source(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user