mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-21 22:34:34 +00:00
Merged wgpu runners (#241)
* Added clap to switch between shaders * Merged wgpu runners * tested something related to async which i forgot to udno * clippy * xamprocky suggestion
This commit is contained in:
parent
28e71d9932
commit
2d75e0473f
25
Cargo.lock
generated
25
Cargo.lock
generated
@ -649,17 +649,6 @@ dependencies = [
|
||||
"winit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "example-runner-wgpu-compute"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"rspirv 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"spirv-builder",
|
||||
"wasm-bindgen-futures",
|
||||
"wgpu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.13"
|
||||
@ -1960,18 +1949,6 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rspirv"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31b11de7481ced3d22182a2be7670323028b38a7cc3457e470f91d144947fba4"
|
||||
dependencies = [
|
||||
"derive_more",
|
||||
"fxhash",
|
||||
"num-traits",
|
||||
"spirv_headers 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rspirv"
|
||||
version = "0.7.0"
|
||||
@ -1990,7 +1967,7 @@ dependencies = [
|
||||
"bimap",
|
||||
"pipe",
|
||||
"pretty_assertions",
|
||||
"rspirv 0.7.0 (git+https://github.com/gfx-rs/rspirv.git?rev=f11f8797bd4df2d1d22cf10767b39a5119c57551)",
|
||||
"rspirv",
|
||||
"spirv-tools",
|
||||
"tar",
|
||||
"tempfile",
|
||||
|
@ -3,7 +3,6 @@ members = [
|
||||
"examples/runners/cpu",
|
||||
"examples/runners/ash",
|
||||
"examples/runners/wgpu",
|
||||
"examples/runners/wgpu-compute",
|
||||
"examples/shaders/sky-shader",
|
||||
"examples/shaders/simplest-shader",
|
||||
"examples/shaders/compute-shader",
|
||||
|
@ -1,23 +0,0 @@
|
||||
[package]
|
||||
name = "example-runner-wgpu-compute"
|
||||
version = "0.1.0"
|
||||
authors = ["Embark <opensource@embark-studios.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
# See rustc_codegen_spirv/Cargo.toml for details on these features
|
||||
[features]
|
||||
default = ["use-compiled-tools"]
|
||||
use-installed-tools = ["spirv-builder/use-installed-tools"]
|
||||
use-compiled-tools = ["spirv-builder/use-compiled-tools"]
|
||||
|
||||
[dependencies]
|
||||
wgpu = "0.6.0"
|
||||
futures = { version = "0.3", default-features = false, features = ["std", "executor"] }
|
||||
rspirv = "0.7.0"
|
||||
|
||||
[build-dependencies]
|
||||
spirv-builder = { path = "../../../crates/spirv-builder" }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
wasm-bindgen-futures = "0.4.18"
|
@ -1,8 +0,0 @@
|
||||
use spirv_builder::SpirvBuilder;
|
||||
use std::error::Error;
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
// This will set the env var `compute_shader.spv` to a spir-v file that can be include!()'d
|
||||
SpirvBuilder::new("../../shaders/compute-shader").build()?;
|
||||
Ok(())
|
||||
}
|
@ -11,5 +11,6 @@ fn build_shader(path_to_create: &str) -> Result<(), Box<dyn Error>> {
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
build_shader("../../shaders/sky-shader")?;
|
||||
build_shader("../../shaders/simplest-shader")?;
|
||||
build_shader("../../shaders/compute-shader")?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
fn shader_module() -> wgpu::ShaderModuleSource<'static> {
|
||||
wgpu::include_spirv!(env!("compute_shader.spv"))
|
||||
}
|
||||
use super::{shader_module, Options};
|
||||
|
||||
fn create_device_queue() -> (wgpu::Device, wgpu::Queue) {
|
||||
async fn create_device_queue_async() -> (wgpu::Device, wgpu::Queue) {
|
||||
@ -25,21 +23,20 @@ fn create_device_queue() -> (wgpu::Device, wgpu::Queue) {
|
||||
.await
|
||||
.expect("Failed to create device")
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
return futures::executor::block_on(create_device_queue_async());
|
||||
};
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
return wasm_bindgen_futures::spawn_local(create_device_queue_async());
|
||||
};
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_arch = "wasm32")] {
|
||||
wasm_bindgen_futures::spawn_local(create_device_queue_async())
|
||||
} else {
|
||||
futures::executor::block_on(create_device_queue_async())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
pub fn start(options: &Options) {
|
||||
let (device, queue) = create_device_queue();
|
||||
|
||||
// Load the shaders from disk
|
||||
let module = device.create_shader_module(shader_module());
|
||||
let module = device.create_shader_module(shader_module(options.shader));
|
||||
|
||||
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: None,
|
211
examples/runners/wgpu/src/graphics.rs
Normal file
211
examples/runners/wgpu/src/graphics.rs
Normal file
@ -0,0 +1,211 @@
|
||||
use super::{shader_module, Options};
|
||||
use winit::{
|
||||
event::{Event, KeyboardInput, VirtualKeyCode, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
window::Window,
|
||||
};
|
||||
|
||||
async fn run(
|
||||
options: &Options,
|
||||
event_loop: EventLoop<()>,
|
||||
window: Window,
|
||||
swapchain_format: wgpu::TextureFormat,
|
||||
) {
|
||||
let size = window.inner_size();
|
||||
let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY);
|
||||
|
||||
// Wait for Resumed event on Android; the surface is only needed early to
|
||||
// find an adapter that can render to this surface.
|
||||
let mut surface = if cfg!(target_os = "android") {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { instance.create_surface(&window) })
|
||||
};
|
||||
|
||||
let adapter = instance
|
||||
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
power_preference: wgpu::PowerPreference::default(),
|
||||
// Request an adapter which can render to our surface
|
||||
compatible_surface: surface.as_ref(),
|
||||
})
|
||||
.await
|
||||
.expect("Failed to find an appropriate adapter");
|
||||
|
||||
// Create the logical device and command queue
|
||||
let (device, queue) = adapter
|
||||
.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
features: wgpu::Features::empty(),
|
||||
limits: wgpu::Limits::default(),
|
||||
shader_validation: true,
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.expect("Failed to create device");
|
||||
|
||||
// Load the shaders from disk
|
||||
let module = device.create_shader_module(shader_module(options.shader));
|
||||
|
||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: None,
|
||||
bind_group_layouts: &[],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: None,
|
||||
layout: Some(&pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: &module,
|
||||
entry_point: "main_vs",
|
||||
},
|
||||
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
||||
module: &module,
|
||||
entry_point: "main_fs",
|
||||
}),
|
||||
// Use the default rasterizer state: no culling, no depth bias
|
||||
rasterization_state: None,
|
||||
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
color_states: &[swapchain_format.into()],
|
||||
depth_stencil_state: None,
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: wgpu::IndexFormat::Uint16,
|
||||
vertex_buffers: &[],
|
||||
},
|
||||
sample_count: 1,
|
||||
sample_mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
});
|
||||
|
||||
let mut sc_desc = wgpu::SwapChainDescriptor {
|
||||
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||
format: swapchain_format,
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
present_mode: wgpu::PresentMode::Mailbox,
|
||||
};
|
||||
|
||||
let mut swap_chain = surface
|
||||
.as_ref()
|
||||
.map(|surface| device.create_swap_chain(&surface, &sc_desc));
|
||||
|
||||
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, &module, &pipeline_layout);
|
||||
|
||||
*control_flow = ControlFlow::Wait;
|
||||
match event {
|
||||
Event::Resumed => {
|
||||
let s = unsafe { instance.create_surface(&window) };
|
||||
swap_chain = Some(device.create_swap_chain(&s, &sc_desc));
|
||||
surface = Some(s);
|
||||
}
|
||||
Event::Suspended => {
|
||||
surface = None;
|
||||
swap_chain = None;
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::Resized(size),
|
||||
..
|
||||
} => {
|
||||
// Recreate the swap chain with the new size
|
||||
sc_desc.width = size.width;
|
||||
sc_desc.height = size.height;
|
||||
if let Some(surface) = &surface {
|
||||
swap_chain = Some(device.create_swap_chain(surface, &sc_desc));
|
||||
}
|
||||
}
|
||||
Event::RedrawRequested(_) => {
|
||||
if let Some(swap_chain) = &mut swap_chain {
|
||||
let frame = swap_chain
|
||||
.get_current_frame()
|
||||
.expect("Failed to acquire next swap chain texture")
|
||||
.output;
|
||||
let mut encoder = device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
||||
{
|
||||
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
||||
attachment: &frame.view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
|
||||
store: true,
|
||||
},
|
||||
}],
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
rpass.set_pipeline(&render_pipeline);
|
||||
rpass.draw(0..3, 0..1);
|
||||
}
|
||||
|
||||
queue.submit(Some(encoder.finish()));
|
||||
}
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::CloseRequested,
|
||||
..
|
||||
} => *control_flow = ControlFlow::Exit,
|
||||
Event::WindowEvent {
|
||||
event:
|
||||
WindowEvent::KeyboardInput {
|
||||
input:
|
||||
KeyboardInput {
|
||||
virtual_keycode: Some(VirtualKeyCode::Escape),
|
||||
..
|
||||
},
|
||||
..
|
||||
},
|
||||
..
|
||||
} => *control_flow = ControlFlow::Exit,
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn start(options: &Options) {
|
||||
let event_loop = EventLoop::new();
|
||||
let window = winit::window::WindowBuilder::new()
|
||||
.with_title("Rust GPU - wgpu")
|
||||
.with_inner_size(winit::dpi::LogicalSize::new(1280.0, 720.0))
|
||||
.build(&event_loop)
|
||||
.unwrap();
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_arch = "wasm32")] {
|
||||
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
|
||||
console_log::init().expect("could not initialize logger");
|
||||
use winit::platform::web::WindowExtWebSys;
|
||||
// On wasm, append the canvas to the document body
|
||||
web_sys::window()
|
||||
.and_then(|win| win.document())
|
||||
.and_then(|doc| doc.body())
|
||||
.and_then(|body| {
|
||||
body.append_child(&web_sys::Element::from(window.canvas()))
|
||||
.ok()
|
||||
})
|
||||
.expect("couldn't append canvas to document body");
|
||||
// Temporarily avoid srgb formats for the swapchain on the web
|
||||
wasm_bindgen_futures::spawn_local(run(
|
||||
event_loop,
|
||||
window,
|
||||
wgpu::TextureFormat::Bgra8Unorm,
|
||||
));
|
||||
} else {
|
||||
wgpu_subscriber::initialize_default_subscriber(None);
|
||||
futures::executor::block_on(run(
|
||||
options,
|
||||
event_loop,
|
||||
window,
|
||||
if cfg!(target_os = "android") {
|
||||
wgpu::TextureFormat::Rgba8UnormSrgb
|
||||
} else {
|
||||
wgpu::TextureFormat::Bgra8UnormSrgb
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,234 +1,41 @@
|
||||
use clap::Clap;
|
||||
use strum::{Display, EnumString};
|
||||
use winit::{
|
||||
event::{Event, KeyboardInput, VirtualKeyCode, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
window::Window,
|
||||
};
|
||||
|
||||
#[derive(EnumString, Display)]
|
||||
enum RustGPUShader {
|
||||
mod compute;
|
||||
mod graphics;
|
||||
|
||||
#[derive(EnumString, Display, PartialEq, Copy, Clone)]
|
||||
pub enum RustGPUShader {
|
||||
Simplest,
|
||||
Sky,
|
||||
Compute,
|
||||
}
|
||||
|
||||
fn shader_module(shader: RustGPUShader) -> wgpu::ShaderModuleSource<'static> {
|
||||
match shader {
|
||||
RustGPUShader::Simplest => wgpu::include_spirv!(env!("simplest_shader.spv")),
|
||||
RustGPUShader::Sky => wgpu::include_spirv!(env!("sky_shader.spv")),
|
||||
RustGPUShader::Compute => wgpu::include_spirv!(env!("compute_shader.spv")),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_compute_shader(shader: RustGPUShader) -> bool {
|
||||
shader == RustGPUShader::Compute
|
||||
}
|
||||
|
||||
#[derive(Clap)]
|
||||
struct Options {
|
||||
pub struct Options {
|
||||
#[clap(short, long, default_value = "Sky")]
|
||||
shader: RustGPUShader,
|
||||
}
|
||||
|
||||
async fn run(
|
||||
options: Options,
|
||||
event_loop: EventLoop<()>,
|
||||
window: Window,
|
||||
swapchain_format: wgpu::TextureFormat,
|
||||
) {
|
||||
let size = window.inner_size();
|
||||
let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY);
|
||||
|
||||
// Wait for Resumed event on Android; the surface is only needed early to
|
||||
// find an adapter that can render to this surface.
|
||||
let mut surface = if cfg!(target_os = "android") {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { instance.create_surface(&window) })
|
||||
};
|
||||
|
||||
let adapter = instance
|
||||
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
power_preference: wgpu::PowerPreference::default(),
|
||||
// Request an adapter which can render to our surface
|
||||
compatible_surface: surface.as_ref(),
|
||||
})
|
||||
.await
|
||||
.expect("Failed to find an appropriate adapter");
|
||||
|
||||
// Create the logical device and command queue
|
||||
let (device, queue) = adapter
|
||||
.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
features: wgpu::Features::empty(),
|
||||
limits: wgpu::Limits::default(),
|
||||
shader_validation: true,
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.expect("Failed to create device");
|
||||
|
||||
// Load the shaders from disk
|
||||
let module = device.create_shader_module(shader_module(options.shader));
|
||||
|
||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: None,
|
||||
bind_group_layouts: &[],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: None,
|
||||
layout: Some(&pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: &module,
|
||||
entry_point: "main_vs",
|
||||
},
|
||||
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
||||
module: &module,
|
||||
entry_point: "main_fs",
|
||||
}),
|
||||
// Use the default rasterizer state: no culling, no depth bias
|
||||
rasterization_state: None,
|
||||
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
color_states: &[swapchain_format.into()],
|
||||
depth_stencil_state: None,
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: wgpu::IndexFormat::Uint16,
|
||||
vertex_buffers: &[],
|
||||
},
|
||||
sample_count: 1,
|
||||
sample_mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
});
|
||||
|
||||
let mut sc_desc = wgpu::SwapChainDescriptor {
|
||||
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||
format: swapchain_format,
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
present_mode: wgpu::PresentMode::Mailbox,
|
||||
};
|
||||
|
||||
let mut swap_chain = surface
|
||||
.as_ref()
|
||||
.map(|surface| device.create_swap_chain(&surface, &sc_desc));
|
||||
|
||||
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, &module, &pipeline_layout);
|
||||
|
||||
*control_flow = ControlFlow::Wait;
|
||||
match event {
|
||||
Event::Resumed => {
|
||||
let s = unsafe { instance.create_surface(&window) };
|
||||
swap_chain = Some(device.create_swap_chain(&s, &sc_desc));
|
||||
surface = Some(s);
|
||||
}
|
||||
Event::Suspended => {
|
||||
surface = None;
|
||||
swap_chain = None;
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::Resized(size),
|
||||
..
|
||||
} => {
|
||||
// Recreate the swap chain with the new size
|
||||
sc_desc.width = size.width;
|
||||
sc_desc.height = size.height;
|
||||
if let Some(surface) = &surface {
|
||||
swap_chain = Some(device.create_swap_chain(surface, &sc_desc));
|
||||
}
|
||||
}
|
||||
Event::RedrawRequested(_) => {
|
||||
if let Some(swap_chain) = &mut swap_chain {
|
||||
let frame = swap_chain
|
||||
.get_current_frame()
|
||||
.expect("Failed to acquire next swap chain texture")
|
||||
.output;
|
||||
let mut encoder = device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
||||
{
|
||||
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
||||
attachment: &frame.view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
|
||||
store: true,
|
||||
},
|
||||
}],
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
rpass.set_pipeline(&render_pipeline);
|
||||
rpass.draw(0..3, 0..1);
|
||||
}
|
||||
|
||||
queue.submit(Some(encoder.finish()));
|
||||
}
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::CloseRequested,
|
||||
..
|
||||
} => *control_flow = ControlFlow::Exit,
|
||||
Event::WindowEvent {
|
||||
event:
|
||||
WindowEvent::KeyboardInput {
|
||||
input:
|
||||
KeyboardInput {
|
||||
virtual_keycode: Some(VirtualKeyCode::Escape),
|
||||
..
|
||||
},
|
||||
..
|
||||
},
|
||||
..
|
||||
} => *control_flow = ControlFlow::Exit,
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg_attr(target_os = "android", ndk_glue::main(backtrace = "on"))]
|
||||
pub fn main() {
|
||||
let options: Options = Options::parse();
|
||||
|
||||
let event_loop = EventLoop::new();
|
||||
let window = winit::window::WindowBuilder::new()
|
||||
.with_title("Rust GPU - wgpu")
|
||||
.with_inner_size(winit::dpi::LogicalSize::new(1280.0, 720.0))
|
||||
.build(&event_loop)
|
||||
.unwrap();
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_arch = "wasm32")] {
|
||||
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
|
||||
console_log::init().expect("could not initialize logger");
|
||||
use winit::platform::web::WindowExtWebSys;
|
||||
// On wasm, append the canvas to the document body
|
||||
web_sys::window()
|
||||
.and_then(|win| win.document())
|
||||
.and_then(|doc| doc.body())
|
||||
.and_then(|body| {
|
||||
body.append_child(&web_sys::Element::from(window.canvas()))
|
||||
.ok()
|
||||
})
|
||||
.expect("couldn't append canvas to document body");
|
||||
// Temporarily avoid srgb formats for the swapchain on the web
|
||||
wasm_bindgen_futures::spawn_local(run(
|
||||
event_loop,
|
||||
window,
|
||||
wgpu::TextureFormat::Bgra8Unorm,
|
||||
));
|
||||
if is_compute_shader(options.shader) {
|
||||
compute::start(&options)
|
||||
} else {
|
||||
wgpu_subscriber::initialize_default_subscriber(None);
|
||||
futures::executor::block_on(run(
|
||||
options,
|
||||
event_loop,
|
||||
window,
|
||||
if cfg!(target_os = "android") {
|
||||
wgpu::TextureFormat::Rgba8UnormSrgb
|
||||
} else {
|
||||
wgpu::TextureFormat::Bgra8UnormSrgb
|
||||
},
|
||||
));
|
||||
}
|
||||
graphics::start(&options);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user