From ea4ecab422cff7a741a2cef272d6a267b364f255 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 30 Oct 2024 18:17:08 +0100 Subject: [PATCH] replace webgpu detection workaround for linux chrome with `wgpu::util::new_instance_with_webgpu_detection` --- crates/eframe/src/web/web_painter_wgpu.rs | 61 +++-------------------- scripts/build_demo_web.sh | 2 +- 2 files changed, 7 insertions(+), 56 deletions(-) diff --git a/crates/eframe/src/web/web_painter_wgpu.rs b/crates/eframe/src/web/web_painter_wgpu.rs index 6cf0e8ff039..2d5f5a4c3f0 100644 --- a/crates/eframe/src/web/web_painter_wgpu.rs +++ b/crates/eframe/src/web/web_painter_wgpu.rs @@ -114,62 +114,13 @@ impl WebPainterWgpu { } log::debug!("Creating wgpu instance with backends {:?}", backends); - let mut instance = wgpu::Instance::new(wgpu::InstanceDescriptor { - backends, - ..Default::default() - }); - // It can happen that a browser advertises WebGPU support, but then fails to create a - // suitable adapter. As of writing this happens for example on Linux with Chrome 121. - // - // Since WebGPU is handled in a special way in wgpu, we have to recreate the instance - // if we instead want to try with WebGL. - // - // To make matters worse, once a canvas has been used with either WebGL or WebGPU, - // we can't go back and change that without replacing the canvas (which is hard to do from here). - // Therefore, we have to create the surface *after* requesting the adapter. - // However, wgpu offers to pass in a surface on adapter creation to ensure it is actually compatible with the chosen backend. - // This in turn isn't all that important on the web, but it still makes sense for the design of - // `egui::RenderState`! - // Therefore, we have to first check if it's possible to create a WebGPU adapter, - // and if it is not, start over with a WebGL instance. - // - // Note that we also might needlessly try this here if wgpu already determined that there's no - // WebGPU support in the first place. This is not a huge problem since it fails very fast, but - // it would be nice to avoid this. See https://github.com/gfx-rs/wgpu/issues/5142 - if backends.contains(wgpu::Backends::BROWSER_WEBGPU) { - log::debug!("Attempting to create WebGPU adapter to check for support."); - if let Some(adapter) = instance - .request_adapter(&wgpu::RequestAdapterOptions { - power_preference: *power_preference, - compatible_surface: None, - force_fallback_adapter: false, - }) - .await - { - // WebGPU doesn't spec yet a destroy on the adapter, only on the device. - //adapter.destroy(); - log::debug!( - "Successfully created WebGPU adapter, WebGPU confirmed to be supported!" - ); - } else { - log::debug!("Failed to create WebGPU adapter."); - - if backends.contains(wgpu::Backends::GL) { - log::debug!("Recreating wgpu instance with WebGL backend only."); - backends = wgpu::Backends::GL; - instance = wgpu::Instance::new(wgpu::InstanceDescriptor { - backends, - ..Default::default() - }); - } else { - return Err( - "Failed to create WebGPU adapter and WebGL was not enabled." - .to_owned(), - ); - } - } - } + let instance = + wgpu::util::new_instance_with_webgpu_detection(wgpu::InstanceDescriptor { + backends, + ..Default::default() + }) + .await; // On wasm, depending on feature flags, wgpu objects may or may not implement sync. // It doesn't make sense to switch to Rc for that special usecase, so simply disable the lint. diff --git a/scripts/build_demo_web.sh b/scripts/build_demo_web.sh index 282d493e6bc..b6eb7197a73 100755 --- a/scripts/build_demo_web.sh +++ b/scripts/build_demo_web.sh @@ -19,7 +19,7 @@ WASM_OPT_FLAGS="-O2 --fast-math" while test $# -gt 0; do case "$1" in -h|--help) - echo "build_demo_web.sh [--release] [--webgpu] [--open]" + echo "build_demo_web.sh [--release] [--wgpu] [--open]" echo "" echo " -g: Keep debug symbols even with --release." echo " These are useful profiling and size trimming."