From 80175a52676473ba73b80ad52bf4ebff7c2447b5 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Sat, 22 May 2021 19:14:15 -0700 Subject: [PATCH 1/8] fix webgl init by initializing windows before wgpu --- crates/bevy_internal/src/default_plugins.rs | 5 +- crates/bevy_winit/src/lib.rs | 53 ++++++++++++++++----- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/crates/bevy_internal/src/default_plugins.rs b/crates/bevy_internal/src/default_plugins.rs index 27e206d657af8..c3b53bb0d5e28 100644 --- a/crates/bevy_internal/src/default_plugins.rs +++ b/crates/bevy_internal/src/default_plugins.rs @@ -119,6 +119,9 @@ impl PluginGroup for PipelinedDefaultPlugins { group.add(bevy_asset::AssetPlugin::default()); group.add(bevy_scene::ScenePlugin::default()); + #[cfg(feature = "bevy_winit")] + group.add(bevy_winit::WinitPlugin::default()); + #[cfg(feature = "bevy_render2")] { group.add(bevy_render2::RenderPlugin::default()); @@ -138,7 +141,5 @@ impl PluginGroup for PipelinedDefaultPlugins { group.add(bevy_gltf2::GltfPlugin::default()); } - #[cfg(feature = "bevy_winit")] - group.add(bevy_winit::WinitPlugin::default()); } } diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index af072b7a60f9f..3c357840d7f88 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -43,6 +43,9 @@ impl Plugin for WinitPlugin { app.init_resource::() .set_runner(winit_runner) .add_system_to_stage(CoreStage::PostUpdate, change_window.exclusive_system()); + let mut event_loop = EventLoop::new(); + handle_initial_window_events(&mut app.world, &mut event_loop); + app.insert_non_send_resource(event_loop); } } @@ -206,22 +209,24 @@ where panic!("Run return is not supported on this platform!") } -pub fn winit_runner(app: App) { - winit_runner_with(app, EventLoop::new()); -} -#[cfg(any( - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" -))] -pub fn winit_runner_any_thread(app: App) { - winit_runner_with(app, EventLoop::new_any_thread()); +pub fn winit_runner(app: App) { + winit_runner_with(app); } -pub fn winit_runner_with(mut app: App, mut event_loop: EventLoop<()>) { +// #[cfg(any( +// target_os = "linux", +// target_os = "dragonfly", +// target_os = "freebsd", +// target_os = "netbsd", +// target_os = "openbsd" +// ))] +// pub fn winit_runner_any_thread(app: App) { +// winit_runner_with(app, EventLoop::new_any_thread()); +// } + +pub fn winit_runner_with(mut app: App) { + let mut event_loop = app.world.remove_non_send::>().unwrap(); let mut create_window_event_reader = ManualEventReader::::default(); let mut app_exit_event_reader = ManualEventReader::::default(); app.world.insert_non_send(event_loop.create_proxy()); @@ -525,3 +530,25 @@ fn handle_create_window_events( }); } } + +fn handle_initial_window_events( + world: &mut World, + event_loop: &EventLoop<()>, +) { + let world = world.cell(); + let mut winit_windows = world.get_resource_mut::().unwrap(); + let mut windows = world.get_resource_mut::().unwrap(); + let mut create_window_events = world.get_resource_mut::>().unwrap(); + let mut window_created_events = world.get_resource_mut::>().unwrap(); + for create_window_event in create_window_events.drain() { + let window = winit_windows.create_window( + event_loop, + create_window_event.id, + &create_window_event.descriptor, + ); + windows.add(window); + window_created_events.send(WindowCreated { + id: create_window_event.id, + }); + } +} From d852db31d70add12c72a60c280e80373af587963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Kry=C5=84ski?= Date: Fri, 8 Oct 2021 01:48:57 +0200 Subject: [PATCH 2/8] fix wgpu initialization --- pipelined/bevy_render2/src/lib.rs | 34 ++++++++++++++++++++-- pipelined/bevy_render2/src/renderer/mod.rs | 7 ++--- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/pipelined/bevy_render2/src/lib.rs b/pipelined/bevy_render2/src/lib.rs index ce28144d00714..09823813b42f9 100644 --- a/pipelined/bevy_render2/src/lib.rs +++ b/pipelined/bevy_render2/src/lib.rs @@ -84,14 +84,42 @@ struct ScratchRenderWorld(World); impl Plugin for RenderPlugin { fn build(&self, app: &mut App) { - let (instance, device, queue) = + let default_backend = if cfg!(not(target_arch = "wasm32")) { + Backends::PRIMARY + } else { + Backends::GL + }; + let backends = wgpu::util::backend_bits_from_env().unwrap_or(default_backend); + let instance = wgpu::Instance::new(backends); + let surface = { + let world = app.world.cell(); + let windows = world.get_resource_mut::().unwrap(); + let raw_handle = windows.get_primary().map(|window| { + unsafe { + let handle = window.raw_window_handle().get_handle(); + instance.create_surface(&handle) + } + }); + raw_handle + }; + let (device, queue) = futures_lite::future::block_on(renderer::initialize_renderer( - wgpu::util::backend_bits_from_env().unwrap_or(Backends::PRIMARY), + &instance, &wgpu::RequestAdapterOptions { power_preference: wgpu::PowerPreference::HighPerformance, + compatible_surface: surface.as_ref(), + ..Default::default() + }, + &wgpu::DeviceDescriptor { + features: wgpu::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES, + #[cfg(not(target_arch = "wasm32"))] + limits: wgpu::Limits::default(), + #[cfg(target_arch = "wasm32")] + limits: wgpu::Limits { + ..wgpu::Limits::downlevel_webgl2_defaults() + }, ..Default::default() }, - &wgpu::DeviceDescriptor::default(), )); app.insert_resource(device.clone()) .insert_resource(queue.clone()) diff --git a/pipelined/bevy_render2/src/renderer/mod.rs b/pipelined/bevy_render2/src/renderer/mod.rs index 840faed624036..c4edce21145b6 100644 --- a/pipelined/bevy_render2/src/renderer/mod.rs +++ b/pipelined/bevy_render2/src/renderer/mod.rs @@ -42,11 +42,10 @@ pub type RenderQueue = Arc; pub type RenderInstance = Instance; pub async fn initialize_renderer( - backends: Backends, + instance: &Instance, request_adapter_options: &RequestAdapterOptions<'_>, device_descriptor: &DeviceDescriptor<'_>, -) -> (RenderInstance, RenderDevice, RenderQueue) { - let instance = wgpu::Instance::new(backends); +) -> (RenderDevice, RenderQueue) { let adapter = instance .request_adapter(request_adapter_options) @@ -72,7 +71,7 @@ pub async fn initialize_renderer( .unwrap(); let device = Arc::new(device); let queue = Arc::new(queue); - (instance, RenderDevice::from(device), queue) + (RenderDevice::from(device), queue) } pub struct RenderContext { From 9e6eccd174f88f3242418da4e76353831b88236b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Kry=C5=84ski?= Date: Fri, 8 Oct 2021 09:03:29 +0200 Subject: [PATCH 3/8] add webgl to wgpu features --- pipelined/bevy_render2/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipelined/bevy_render2/Cargo.toml b/pipelined/bevy_render2/Cargo.toml index 694b500e3d439..9d2aa768f2883 100644 --- a/pipelined/bevy_render2/Cargo.toml +++ b/pipelined/bevy_render2/Cargo.toml @@ -29,7 +29,7 @@ bevy_utils = { path = "../../crates/bevy_utils", version = "0.5.0" } image = { version = "0.23.12", default-features = false } # misc -wgpu = { version = "0.11.0", features = ["spirv"] } +wgpu = { version = "0.11.0", features = ["spirv", "webgl"] } naga = { version = "0.7.0", features = ["glsl-in", "spv-in", "spv-out", "wgsl-in", "wgsl-out"] } serde = { version = "1", features = ["derive"] } bitflags = "1.2.1" From c2b89d3864eb7a0fc79b5f1ee3ffde57ef4485aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Kry=C5=84ski?= Date: Fri, 8 Oct 2021 01:49:54 +0200 Subject: [PATCH 4/8] use Rgba8UnormSrgb by default on wasm32 --- pipelined/bevy_render2/src/texture/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipelined/bevy_render2/src/texture/mod.rs b/pipelined/bevy_render2/src/texture/mod.rs index cd25dd57387ae..59eb1f5dc11d0 100644 --- a/pipelined/bevy_render2/src/texture/mod.rs +++ b/pipelined/bevy_render2/src/texture/mod.rs @@ -42,7 +42,7 @@ pub trait BevyDefault { impl BevyDefault for wgpu::TextureFormat { fn bevy_default() -> Self { - if cfg!(target_os = "android") { + if cfg!(target_os = "android") || cfg!(target_arch = "wasm32") { // Bgra8UnormSrgb texture missing on some Android devices wgpu::TextureFormat::Rgba8UnormSrgb } else { From 52f9f4a91753c06032a3df2d52dd60d0dca9fe1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Kry=C5=84ski?= Date: Wed, 27 Oct 2021 23:55:34 +0200 Subject: [PATCH 5/8] cargo fmt --- crates/bevy_internal/src/default_plugins.rs | 1 - crates/bevy_winit/src/lib.rs | 8 +--- pipelined/bevy_render2/src/lib.rs | 43 ++++++++++----------- pipelined/bevy_render2/src/renderer/mod.rs | 1 - 4 files changed, 22 insertions(+), 31 deletions(-) diff --git a/crates/bevy_internal/src/default_plugins.rs b/crates/bevy_internal/src/default_plugins.rs index c3b53bb0d5e28..0a97da009ac62 100644 --- a/crates/bevy_internal/src/default_plugins.rs +++ b/crates/bevy_internal/src/default_plugins.rs @@ -140,6 +140,5 @@ impl PluginGroup for PipelinedDefaultPlugins { #[cfg(feature = "bevy_gltf2")] group.add(bevy_gltf2::GltfPlugin::default()); } - } } diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 3c357840d7f88..298f9fb0f6a40 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -43,7 +43,7 @@ impl Plugin for WinitPlugin { app.init_resource::() .set_runner(winit_runner) .add_system_to_stage(CoreStage::PostUpdate, change_window.exclusive_system()); - let mut event_loop = EventLoop::new(); + let mut event_loop = EventLoop::new(); handle_initial_window_events(&mut app.world, &mut event_loop); app.insert_non_send_resource(event_loop); } @@ -209,7 +209,6 @@ where panic!("Run return is not supported on this platform!") } - pub fn winit_runner(app: App) { winit_runner_with(app); } @@ -531,10 +530,7 @@ fn handle_create_window_events( } } -fn handle_initial_window_events( - world: &mut World, - event_loop: &EventLoop<()>, -) { +fn handle_initial_window_events(world: &mut World, event_loop: &EventLoop<()>) { let world = world.cell(); let mut winit_windows = world.get_resource_mut::().unwrap(); let mut windows = world.get_resource_mut::().unwrap(); diff --git a/pipelined/bevy_render2/src/lib.rs b/pipelined/bevy_render2/src/lib.rs index 09823813b42f9..c10e5baa5a25d 100644 --- a/pipelined/bevy_render2/src/lib.rs +++ b/pipelined/bevy_render2/src/lib.rs @@ -94,33 +94,30 @@ impl Plugin for RenderPlugin { let surface = { let world = app.world.cell(); let windows = world.get_resource_mut::().unwrap(); - let raw_handle = windows.get_primary().map(|window| { - unsafe { - let handle = window.raw_window_handle().get_handle(); - instance.create_surface(&handle) - } + let raw_handle = windows.get_primary().map(|window| unsafe { + let handle = window.raw_window_handle().get_handle(); + instance.create_surface(&handle) }); raw_handle }; - let (device, queue) = - futures_lite::future::block_on(renderer::initialize_renderer( - &instance, - &wgpu::RequestAdapterOptions { - power_preference: wgpu::PowerPreference::HighPerformance, - compatible_surface: surface.as_ref(), - ..Default::default() + let (device, queue) = futures_lite::future::block_on(renderer::initialize_renderer( + &instance, + &wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::HighPerformance, + compatible_surface: surface.as_ref(), + ..Default::default() + }, + &wgpu::DeviceDescriptor { + features: wgpu::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES, + #[cfg(not(target_arch = "wasm32"))] + limits: wgpu::Limits::default(), + #[cfg(target_arch = "wasm32")] + limits: wgpu::Limits { + ..wgpu::Limits::downlevel_webgl2_defaults() }, - &wgpu::DeviceDescriptor { - features: wgpu::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES, - #[cfg(not(target_arch = "wasm32"))] - limits: wgpu::Limits::default(), - #[cfg(target_arch = "wasm32")] - limits: wgpu::Limits { - ..wgpu::Limits::downlevel_webgl2_defaults() - }, - ..Default::default() - }, - )); + ..Default::default() + }, + )); app.insert_resource(device.clone()) .insert_resource(queue.clone()) .init_resource::(); diff --git a/pipelined/bevy_render2/src/renderer/mod.rs b/pipelined/bevy_render2/src/renderer/mod.rs index c4edce21145b6..e3ef3635c3214 100644 --- a/pipelined/bevy_render2/src/renderer/mod.rs +++ b/pipelined/bevy_render2/src/renderer/mod.rs @@ -46,7 +46,6 @@ pub async fn initialize_renderer( request_adapter_options: &RequestAdapterOptions<'_>, device_descriptor: &DeviceDescriptor<'_>, ) -> (RenderDevice, RenderQueue) { - let adapter = instance .request_adapter(request_adapter_options) .await From 6716a28483fc99145b829b29b4db21543d5df1dd Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Thu, 28 Oct 2021 17:15:46 -0700 Subject: [PATCH 6/8] only enable webgl feature on wasm targets --- pipelined/bevy_render2/Cargo.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pipelined/bevy_render2/Cargo.toml b/pipelined/bevy_render2/Cargo.toml index 9d2aa768f2883..cfeca598b9aac 100644 --- a/pipelined/bevy_render2/Cargo.toml +++ b/pipelined/bevy_render2/Cargo.toml @@ -29,7 +29,7 @@ bevy_utils = { path = "../../crates/bevy_utils", version = "0.5.0" } image = { version = "0.23.12", default-features = false } # misc -wgpu = { version = "0.11.0", features = ["spirv", "webgl"] } +wgpu = { version = "0.11.0", features = ["spirv"] } naga = { version = "0.7.0", features = ["glsl-in", "spv-in", "spv-out", "wgsl-in", "wgsl-out"] } serde = { version = "1", features = ["derive"] } bitflags = "1.2.1" @@ -44,6 +44,9 @@ hexasphere = "4.0" parking_lot = "0.11.0" crevice = { path = "../../crates/crevice", version = "0.6.0" } +[target.'cfg(target_arch = "wasm32")'.dependencies] +wgpu = { version = "0.11.0", features = ["spirv", "webgl"] } + [features] png = ["image/png"] hdr = ["image/hdr"] From 20a761c188c66bea8401880c381f3dd735b84b84 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Thu, 28 Oct 2021 17:28:32 -0700 Subject: [PATCH 7/8] clippy --- crates/bevy_winit/src/lib.rs | 6 ++---- pipelined/bevy_render2/src/renderer/mod.rs | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 298f9fb0f6a40..33d4571c46633 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -33,8 +33,6 @@ use winit::dpi::LogicalSize; target_os = "netbsd", target_os = "openbsd" ))] -use winit::platform::unix::EventLoopExtUnix; - #[derive(Default)] pub struct WinitPlugin; @@ -43,8 +41,8 @@ impl Plugin for WinitPlugin { app.init_resource::() .set_runner(winit_runner) .add_system_to_stage(CoreStage::PostUpdate, change_window.exclusive_system()); - let mut event_loop = EventLoop::new(); - handle_initial_window_events(&mut app.world, &mut event_loop); + let event_loop = EventLoop::new(); + handle_initial_window_events(&mut app.world, &event_loop); app.insert_non_send_resource(event_loop); } } diff --git a/pipelined/bevy_render2/src/renderer/mod.rs b/pipelined/bevy_render2/src/renderer/mod.rs index e3ef3635c3214..461df246308ce 100644 --- a/pipelined/bevy_render2/src/renderer/mod.rs +++ b/pipelined/bevy_render2/src/renderer/mod.rs @@ -8,7 +8,7 @@ pub use render_device::*; use crate::{render_graph::RenderGraph, view::ExtractedWindows}; use bevy_ecs::prelude::*; use std::sync::Arc; -use wgpu::{Backends, CommandEncoder, DeviceDescriptor, Instance, Queue, RequestAdapterOptions}; +use wgpu::{CommandEncoder, DeviceDescriptor, Instance, Queue, RequestAdapterOptions}; pub fn render_system(world: &mut World) { world.resource_scope(|world, mut graph: Mut| { From dbe09fa51395138f92bacfb86b0434f227e8c0ff Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Thu, 28 Oct 2021 17:45:00 -0700 Subject: [PATCH 8/8] come on cart get it together! --- crates/bevy_winit/src/lib.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 33d4571c46633..8e84bd2480340 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -26,13 +26,7 @@ use winit::{ }; use winit::dpi::LogicalSize; -#[cfg(any( - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" -))] + #[derive(Default)] pub struct WinitPlugin;