From 401b2e77f3d4e8fe39f21ef51961d2a5bbedf9b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Tue, 19 Sep 2023 07:57:54 +0200 Subject: [PATCH] renderer init: create a detached task only on wasm, block otherwise (#9830) # Objective - When initializing the renderer, Bevy currently create a detached task - This is needed on wasm but not on native ## Solution - Don't create a detached task on native but block on the future --- crates/bevy_render/src/lib.rs | 68 ++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index 2f36d3a1cf8a6..cc62f3fcead84 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -251,41 +251,43 @@ impl Plugin for RenderPlugin { let primary_window = system_state.get(&app.world).get_single().ok().cloned(); let settings = self.wgpu_settings.clone(); - bevy_tasks::IoTaskPool::get() - .spawn_local(async move { - let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { - backends, - dx12_shader_compiler: settings.dx12_shader_compiler.clone(), - }); - let surface = primary_window.map(|wrapper| unsafe { - // SAFETY: Plugins should be set up on the main thread. - let handle = wrapper.get_handle(); - instance - .create_surface(&handle) - .expect("Failed to create wgpu surface") - }); - - let request_adapter_options = wgpu::RequestAdapterOptions { - power_preference: settings.power_preference, - compatible_surface: surface.as_ref(), - ..Default::default() - }; - - let (device, queue, adapter_info, render_adapter) = - renderer::initialize_renderer( - &instance, - &settings, - &request_adapter_options, - ) + let async_renderer = async move { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { + backends, + dx12_shader_compiler: settings.dx12_shader_compiler.clone(), + }); + let surface = primary_window.map(|wrapper| unsafe { + // SAFETY: Plugins should be set up on the main thread. + let handle = wrapper.get_handle(); + instance + .create_surface(&handle) + .expect("Failed to create wgpu surface") + }); + + let request_adapter_options = wgpu::RequestAdapterOptions { + power_preference: settings.power_preference, + compatible_surface: surface.as_ref(), + ..Default::default() + }; + + let (device, queue, adapter_info, render_adapter) = + renderer::initialize_renderer(&instance, &settings, &request_adapter_options) .await; - debug!("Configured wgpu adapter Limits: {:#?}", device.limits()); - debug!("Configured wgpu adapter Features: {:#?}", device.features()); - let mut future_renderer_resources_inner = - future_renderer_resources_wrapper.lock().unwrap(); - *future_renderer_resources_inner = - Some((device, queue, adapter_info, render_adapter, instance)); - }) + debug!("Configured wgpu adapter Limits: {:#?}", device.limits()); + debug!("Configured wgpu adapter Features: {:#?}", device.features()); + let mut future_renderer_resources_inner = + future_renderer_resources_wrapper.lock().unwrap(); + *future_renderer_resources_inner = + Some((device, queue, adapter_info, render_adapter, instance)); + }; + // In wasm, spawn a task and detach it for execution + #[cfg(target_arch = "wasm32")] + bevy_tasks::IoTaskPool::get() + .spawn_local(async_renderer) .detach(); + // Otherwise, just block for it to complete + #[cfg(not(target_arch = "wasm32"))] + futures_lite::future::block_on(async_renderer); app.init_resource::();