From a7c9c24f40d7e916999824bc4728bdd38daa4ae0 Mon Sep 17 00:00:00 2001 From: John Tur Date: Thu, 19 Mar 2026 02:57:57 -0400 Subject: [PATCH] Update to wgpu v29 (#51889) This release includes the OpenGL fixes which were sent upstream. Release Notes: - N/A --- Cargo.lock | 199 ++++++++++-------- Cargo.toml | 6 +- crates/client/src/telemetry.rs | 2 +- crates/gpui_linux/src/linux/wayland/window.rs | 21 +- crates/gpui_linux/src/linux/x11/window.rs | 21 +- crates/gpui_wgpu/src/wgpu_context.rs | 17 +- crates/gpui_wgpu/src/wgpu_renderer.rs | 62 +++--- 7 files changed, 175 insertions(+), 153 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b90e82d0078560a9989e53923042989c7795c51..fd8c847109e113f0e31fc59b39051d853e099ac6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2073,7 +2073,16 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ - "bit-vec", + "bit-vec 0.8.0", +] + +[[package]] +name = "bit-set" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ddef2995421ab6a5c779542c81ee77c115206f4ad9d5a8e05f4ff49716a3dd" +dependencies = [ + "bit-vec 0.9.1", ] [[package]] @@ -2082,6 +2091,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +[[package]] +name = "bit-vec" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51" + [[package]] name = "bit_field" version = "0.10.3" @@ -3163,17 +3178,6 @@ dependencies = [ "objc", ] -[[package]] -name = "codespan-reporting" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" -dependencies = [ - "serde", - "termcolor", - "unicode-width", -] - [[package]] name = "codespan-reporting" version = "0.13.0" @@ -4398,7 +4402,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d74b6bcf49ebbd91f1b1875b706ea46545032a14003b5557b7dfa4bbeba6766e" dependencies = [ "cc", - "codespan-reporting 0.13.0", + "codespan-reporting", "indexmap", "proc-macro2", "quote", @@ -4413,7 +4417,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94ca2ad69673c4b35585edfa379617ac364bccd0ba0adf319811ba3a74ffa48a" dependencies = [ "clap", - "codespan-reporting 0.13.0", + "codespan-reporting", "indexmap", "proc-macro2", "quote", @@ -6181,7 +6185,7 @@ version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "998b056554fbe42e03ae0e152895cd1a7e1002aec800fdc6635d20270260c46f" dependencies = [ - "bit-set", + "bit-set 0.8.0", "regex-automata", "regex-syntax", ] @@ -6192,7 +6196,7 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72cf461f865c862bb7dc573f643dd6a2b6842f7c30b07882b56bd148cc2761b8" dependencies = [ - "bit-set", + "bit-set 0.8.0", "regex-automata", "regex-syntax", ] @@ -7507,9 +7511,9 @@ dependencies = [ [[package]] name = "glow" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" +checksum = "29038e1c483364cc6bb3cf78feee1816002e127c331a1eec55a4d202b9e1adb5" dependencies = [ "js-sys", "slotmap", @@ -7662,7 +7666,7 @@ dependencies = [ "mach2 0.5.0", "media", "metal", - "naga 28.0.0", + "naga", "num_cpus", "objc", "objc2", @@ -10762,40 +10766,16 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "naga" -version = "28.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "618f667225063219ddfc61251087db8a9aec3c3f0950c916b614e403486f1135" +checksum = "85b4372fed0bd362d646d01b6926df0e837859ccc522fed720c395e0460f29c8" dependencies = [ "arrayvec", - "bit-set", + "bit-set 0.9.1", "bitflags 2.10.0", "cfg-if", "cfg_aliases 0.2.1", - "codespan-reporting 0.12.0", - "half", - "hashbrown 0.16.1", - "hexf-parse", - "indexmap", - "libm", - "log", - "num-traits", - "once_cell", - "rustc-hash 1.1.0", - "thiserror 2.0.17", - "unicode-ident", -] - -[[package]] -name = "naga" -version = "28.0.1" -source = "git+https://github.com/zed-industries/wgpu?rev=465557eccfe77c840a9b4936f1408da9503372c4#465557eccfe77c840a9b4936f1408da9503372c4" -dependencies = [ - "arrayvec", - "bit-set", - "bitflags 2.10.0", - "cfg-if", - "cfg_aliases 0.2.1", - "codespan-reporting 0.12.0", + "codespan-reporting", "half", "hashbrown 0.16.1", "hexf-parse", @@ -11325,9 +11305,9 @@ dependencies = [ [[package]] name = "objc2-audio-toolbox" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cbe18d879e20a4aea544f8befe38bcf52255eb63d3f23eca2842f3319e4c07" +checksum = "6948501a91121d6399b79abaa33a8aa4ea7857fe019f341b8c23ad6e81b79b08" dependencies = [ "bitflags 2.10.0", "libc", @@ -11340,9 +11320,9 @@ dependencies = [ [[package]] name = "objc2-avf-audio" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfc1d11521c211a7ebe17739fc806719da41f56c6b3f949d9861b459188ce910" +checksum = "13a380031deed8e99db00065c45937da434ca987c034e13b87e4441f9e4090be" dependencies = [ "objc2", "objc2-foundation", @@ -11350,9 +11330,9 @@ dependencies = [ [[package]] name = "objc2-core-audio" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca44961e888e19313b808f23497073e3f6b3c22bb485056674c8b49f3b025c82" +checksum = "e1eebcea8b0dbff5f7c8504f3107c68fc061a3eb44932051c8cf8a68d969c3b2" dependencies = [ "dispatch2", "objc2", @@ -11392,9 +11372,9 @@ checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" [[package]] name = "objc2-foundation" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ "bitflags 2.10.0", "block2", @@ -11415,9 +11395,9 @@ dependencies = [ [[package]] name = "objc2-metal" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f246c183239540aab1782457b35ab2040d4259175bd1d0c58e46ada7b47a874" +checksum = "a0125f776a10d00af4152d74616409f0d4a2053a6f57fa5b7d6aa2854ac04794" dependencies = [ "bitflags 2.10.0", "block2", @@ -11427,6 +11407,19 @@ dependencies = [ "objc2-foundation", ] +[[package]] +name = "objc2-quartz-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" +dependencies = [ + "bitflags 2.10.0", + "objc2", + "objc2-core-foundation", + "objc2-foundation", + "objc2-metal", +] + [[package]] name = "objc_exception" version = "0.1.2" @@ -13348,8 +13341,8 @@ name = "proptest" version = "1.10.0" source = "git+https://github.com/proptest-rs/proptest?rev=3dca198a8fef1b32e3a66f1e1897c955b4dc5b5b#3dca198a8fef1b32e3a66f1e1897c955b4dc5b5b" dependencies = [ - "bit-set", - "bit-vec", + "bit-set 0.8.0", + "bit-vec 0.8.0", "bitflags 2.10.0", "num-traits", "proptest-macro", @@ -13978,6 +13971,18 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" +[[package]] +name = "raw-window-metal" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40d213455a5f1dc59214213c7330e074ddf8114c9a42411eb890c767357ce135" +dependencies = [ + "objc2", + "objc2-core-foundation", + "objc2-foundation", + "objc2-quartz-core", +] + [[package]] name = "rayon" version = "1.11.0" @@ -16210,9 +16215,9 @@ dependencies = [ [[package]] name = "spirv" -version = "0.3.0+sdk-1.3.268.0" +version = "0.4.0+sdk-1.4.341.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +checksum = "d9571ea910ebd84c86af4b3ed27f9dbdc6ad06f17c5f96146b2b671e2976744f" dependencies = [ "bitflags 2.10.0", ] @@ -20063,8 +20068,9 @@ checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" [[package]] name = "wgpu" -version = "28.0.1" -source = "git+https://github.com/zed-industries/wgpu?rev=465557eccfe77c840a9b4936f1408da9503372c4#465557eccfe77c840a9b4936f1408da9503372c4" +version = "29.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78f9f386699b1fb8b8a05bfe82169b24d151f05702d2905a0bf93bc454fcc825" dependencies = [ "arrayvec", "bitflags 2.10.0", @@ -20075,7 +20081,7 @@ dependencies = [ "hashbrown 0.16.1", "js-sys", "log", - "naga 28.0.1", + "naga", "parking_lot", "portable-atomic", "profiling", @@ -20092,12 +20098,13 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "28.0.1" -source = "git+https://github.com/zed-industries/wgpu?rev=465557eccfe77c840a9b4936f1408da9503372c4#465557eccfe77c840a9b4936f1408da9503372c4" +version = "29.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c34181b0acb8f98168f78f8e57ec66f57df5522b39143dbe5f2f45d7ca927c" dependencies = [ "arrayvec", - "bit-set", - "bit-vec", + "bit-set 0.9.1", + "bit-vec 0.9.1", "bitflags 2.10.0", "bytemuck", "cfg_aliases 0.2.1", @@ -20105,7 +20112,7 @@ dependencies = [ "hashbrown 0.16.1", "indexmap", "log", - "naga 28.0.1", + "naga", "once_cell", "parking_lot", "portable-atomic", @@ -20118,48 +20125,52 @@ dependencies = [ "wgpu-core-deps-emscripten", "wgpu-core-deps-windows-linux-android", "wgpu-hal", + "wgpu-naga-bridge", "wgpu-types", ] [[package]] name = "wgpu-core-deps-apple" -version = "28.0.1" -source = "git+https://github.com/zed-industries/wgpu?rev=465557eccfe77c840a9b4936f1408da9503372c4#465557eccfe77c840a9b4936f1408da9503372c4" +version = "29.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43acd053312501689cd92a01a9638d37f3e41a5fd9534875efa8917ee2d11ac0" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-emscripten" -version = "28.0.1" -source = "git+https://github.com/zed-industries/wgpu?rev=465557eccfe77c840a9b4936f1408da9503372c4#465557eccfe77c840a9b4936f1408da9503372c4" +version = "29.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef043bf135cc68b6f667c55ff4e345ce2b5924d75bad36a47921b0287ca4b24a" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-windows-linux-android" -version = "28.0.1" -source = "git+https://github.com/zed-industries/wgpu?rev=465557eccfe77c840a9b4936f1408da9503372c4#465557eccfe77c840a9b4936f1408da9503372c4" +version = "29.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "725d5c006a8c02967b6d93ef04f6537ec4593313e330cfe86d9d3f946eb90f28" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-hal" -version = "28.0.1" -source = "git+https://github.com/zed-industries/wgpu?rev=465557eccfe77c840a9b4936f1408da9503372c4#465557eccfe77c840a9b4936f1408da9503372c4" +version = "29.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "058b6047337cf323a4f092486443a9337f3d81325347e5d77deed7e563aeaedc" dependencies = [ "android_system_properties", "arrayvec", "ash", - "bit-set", + "bit-set 0.9.1", "bitflags 2.10.0", - "block", + "block2", "bytemuck", "cfg-if", "cfg_aliases 0.2.1", - "core-graphics-types 0.2.0", "glow", "glutin_wgl_sys", "gpu-allocator", @@ -20170,10 +20181,13 @@ dependencies = [ "libc", "libloading", "log", - "metal", - "naga 28.0.1", + "naga", "ndk-sys", - "objc", + "objc2", + "objc2-core-foundation", + "objc2-foundation", + "objc2-metal", + "objc2-quartz-core", "once_cell", "ordered-float 4.6.0", "parking_lot", @@ -20182,25 +20196,40 @@ dependencies = [ "profiling", "range-alloc", "raw-window-handle", + "raw-window-metal", "renderdoc-sys", "smallvec", "thiserror 2.0.17", "wasm-bindgen", + "wayland-sys", "web-sys", + "wgpu-naga-bridge", "wgpu-types", "windows 0.62.2", "windows-core 0.62.2", ] +[[package]] +name = "wgpu-naga-bridge" +version = "29.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0b8e1e505095f24cb4a578f04b1421d456257dca7fac114d9d9dd3d978c34b8" +dependencies = [ + "naga", + "wgpu-types", +] + [[package]] name = "wgpu-types" -version = "28.0.1" -source = "git+https://github.com/zed-industries/wgpu?rev=465557eccfe77c840a9b4936f1408da9503372c4#465557eccfe77c840a9b4936f1408da9503372c4" +version = "29.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d15ece45db77dd5451f11c0ce898334317ce8502d304a20454b531fdc0652fae" dependencies = [ "bitflags 2.10.0", "bytemuck", "js-sys", "log", + "raw-window-handle", "web-sys", ] diff --git a/Cargo.toml b/Cargo.toml index 3b8ddd6404bcfd115e5ead25601e944197053bd6..a91fbed94ce2d1d5fd680bb04b1c0ec43f16634f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -596,13 +596,13 @@ markup5ever_rcdom = "0.3.0" metal = "0.33" minidumper = "0.9" moka = { version = "0.12.10", features = ["sync"] } -naga = { version = "28.0", features = ["wgsl-in"] } +naga = { version = "29.0", features = ["wgsl-in"] } nanoid = "0.4" nbformat = "1.2.0" nix = "0.29" num-format = "0.4.4" objc = "0.2" -objc2-foundation = { version = "=0.3.1", default-features = false, features = [ +objc2-foundation = { version = "=0.3.2", default-features = false, features = [ "NSArray", "NSAttributedString", "NSBundle", @@ -779,7 +779,7 @@ wax = "0.7" which = "6.0.0" wasm-bindgen = "0.2.113" web-time = "1.1.0" -wgpu = { git = "https://github.com/zed-industries/wgpu", rev = "465557eccfe77c840a9b4936f1408da9503372c4" } +wgpu = "29" windows-core = "0.61" yawc = "0.2.5" zeroize = "1.8" diff --git a/crates/client/src/telemetry.rs b/crates/client/src/telemetry.rs index 70056f19653b097173f6af9c80dc74f67b3d49f9..58681d2e14bb8bd8e8109958d8c5706df5bfb6e2 100644 --- a/crates/client/src/telemetry.rs +++ b/crates/client/src/telemetry.rs @@ -129,7 +129,7 @@ pub fn os_version() -> String { { use objc2_foundation::NSProcessInfo; let process_info = NSProcessInfo::processInfo(); - let version_nsstring = unsafe { process_info.operatingSystemVersionString() }; + let version_nsstring = process_info.operatingSystemVersionString(); // "Version 15.6.1 (Build 24G90)" -> "15.6.1 (Build 24G90)" let version_string = version_nsstring.to_string().replace("Version ", ""); // "15.6.1 (Build 24G90)" -> "15.6.1" diff --git a/crates/gpui_linux/src/linux/wayland/window.rs b/crates/gpui_linux/src/linux/wayland/window.rs index 001571d7f44767db19924eb2e58f7723bbe7a755..189ef91e6005b73801fa4be3b1f152ffe3952ff9 100644 --- a/crates/gpui_linux/src/linux/wayland/window.rs +++ b/crates/gpui_linux/src/linux/wayland/window.rs @@ -52,6 +52,7 @@ pub(crate) struct Callbacks { appearance_changed: Option>, } +#[derive(Debug, Clone, Copy)] struct RawWindow { window: *mut c_void, display: *mut c_void, @@ -1348,23 +1349,13 @@ impl PlatformWindow for WaylandWindow { .display_ptr() .cast::(), }; - let display_handle = rwh::HasDisplayHandle::display_handle(&raw_window) - .unwrap() - .as_raw(); - let window_handle = rwh::HasWindowHandle::window_handle(&raw_window) - .unwrap() - .as_raw(); - - state - .renderer - .recover(display_handle, window_handle) - .unwrap_or_else(|err| { - panic!( - "GPU device lost and recovery failed. \ + state.renderer.recover(&raw_window).unwrap_or_else(|err| { + panic!( + "GPU device lost and recovery failed. \ This may happen after system suspend/resume. \ Please restart the application.\n\nError: {err}" - ) - }); + ) + }); // The current scene references atlas textures that were cleared during recovery. // Skip this frame and let the next frame rebuild the scene with fresh textures. diff --git a/crates/gpui_linux/src/linux/x11/window.rs b/crates/gpui_linux/src/linux/x11/window.rs index 5c7c0e8e02231b5b14d8820401d5e5c6409158af..689a652b918e7bc1e793d19b66d954eaa6277a6e 100644 --- a/crates/gpui_linux/src/linux/x11/window.rs +++ b/crates/gpui_linux/src/linux/x11/window.rs @@ -225,6 +225,7 @@ fn find_visuals(xcb: &XCBConnection, screen_index: usize) -> VisualSet { set } +#[derive(Debug, Clone, Copy)] struct RawWindow { connection: *mut c_void, screen_id: usize, @@ -1613,23 +1614,13 @@ impl PlatformWindow for X11Window { window_id: self.0.x_window, visual_id: inner.visual_id, }; - let display_handle = rwh::HasDisplayHandle::display_handle(&raw_window) - .unwrap() - .as_raw(); - let window_handle = rwh::HasWindowHandle::window_handle(&raw_window) - .unwrap() - .as_raw(); - - inner - .renderer - .recover(display_handle, window_handle) - .unwrap_or_else(|err| { - panic!( - "GPU device lost and recovery failed. \ + inner.renderer.recover(&raw_window).unwrap_or_else(|err| { + panic!( + "GPU device lost and recovery failed. \ This may happen after system suspend/resume. \ Please restart the application.\n\nError: {err}" - ) - }); + ) + }); // The current scene references atlas textures that were cleared during recovery. // Skip this frame and let the next frame rebuild the scene with fresh textures. diff --git a/crates/gpui_wgpu/src/wgpu_context.rs b/crates/gpui_wgpu/src/wgpu_context.rs index 6df2e6fa8aa9d7f529b500e4691c649c21c1fdb1..7c03c4752ebf2e76b04c384722f4a9c17054487a 100644 --- a/crates/gpui_wgpu/src/wgpu_context.rs +++ b/crates/gpui_wgpu/src/wgpu_context.rs @@ -78,11 +78,12 @@ impl WgpuContext { #[cfg(target_family = "wasm")] pub async fn new_web() -> anyhow::Result { - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { backends: wgpu::Backends::BROWSER_WEBGPU | wgpu::Backends::GL, flags: wgpu::InstanceFlags::default(), backend_options: wgpu::BackendOptions::default(), memory_budget_thresholds: wgpu::MemoryBudgetThresholds::default(), + display: None, }); let adapter = instance @@ -148,12 +149,13 @@ impl WgpuContext { } #[cfg(not(target_family = "wasm"))] - pub fn instance() -> wgpu::Instance { - wgpu::Instance::new(&wgpu::InstanceDescriptor { + pub fn instance(display: Box) -> wgpu::Instance { + wgpu::Instance::new(wgpu::InstanceDescriptor { backends: wgpu::Backends::VULKAN | wgpu::Backends::GL, flags: wgpu::InstanceFlags::default(), backend_options: wgpu::BackendOptions::default(), memory_budget_thresholds: wgpu::MemoryBudgetThresholds::default(), + display: Some(display), }) } @@ -198,9 +200,8 @@ impl WgpuContext { // // 1. ZED_DEVICE_ID match — explicit user override // 2. Compositor GPU match — the GPU the display server is rendering on - // 3. Device type — WGPU HighPerformance order (Discrete > Integrated > - // Other > Virtual > Cpu). "Other" ranks above "Virtual" because - // backends like OpenGL may report real hardware as "Other". + // 3. Device type (Discrete > Integrated > Other > Virtual > Cpu). + // "Other" ranks above "Virtual" because OpenGL seems to count as "Other". // 4. Backend — prefer Vulkan/Metal/Dx12 over GL/etc. adapters.sort_by_key(|adapter| { let info = adapter.get_info(); @@ -305,10 +306,7 @@ impl WgpuContext { anyhow::bail!("no compatible alpha modes"); } - // Create the real device with full features let (device, queue, dual_source_blending) = Self::create_device(adapter).await?; - - // Use an error scope to capture any validation errors during configure let error_scope = device.push_error_scope(wgpu::ErrorFilter::Validation); let test_config = wgpu::SurfaceConfiguration { @@ -324,7 +322,6 @@ impl WgpuContext { surface.configure(&device, &test_config); - // Check if there was a validation error let error = error_scope.pop().await; if let Some(e) = error { anyhow::bail!("surface configuration failed: {e}"); diff --git a/crates/gpui_wgpu/src/wgpu_renderer.rs b/crates/gpui_wgpu/src/wgpu_renderer.rs index da94747f3b4debcc65723c8a0ca031d59d9ae03c..2197f6914e4a1f0486a1a96af726ea7215807718 100644 --- a/crates/gpui_wgpu/src/wgpu_renderer.rs +++ b/crates/gpui_wgpu/src/wgpu_renderer.rs @@ -163,21 +163,22 @@ impl WgpuRenderer { /// The caller must ensure that the window handle remains valid for the lifetime /// of the returned renderer. #[cfg(not(target_family = "wasm"))] - pub fn new( + pub fn new( gpu_context: GpuContext, window: &W, config: WgpuSurfaceConfig, compositor_gpu: Option, - ) -> anyhow::Result { + ) -> anyhow::Result + where + W: HasWindowHandle + HasDisplayHandle + std::fmt::Debug + Send + Sync + Clone + 'static, + { let window_handle = window .window_handle() .map_err(|e| anyhow::anyhow!("Failed to get window handle: {e}"))?; - let display_handle = window - .display_handle() - .map_err(|e| anyhow::anyhow!("Failed to get display handle: {e}"))?; let target = wgpu::SurfaceTargetUnsafe::RawHandle { - raw_display_handle: display_handle.as_raw(), + // Fall back to the display handle already provided via InstanceDescriptor::display. + raw_display_handle: None, raw_window_handle: window_handle.as_raw(), }; @@ -188,7 +189,7 @@ impl WgpuRenderer { .borrow() .as_ref() .map(|ctx| ctx.instance.clone()) - .unwrap_or_else(WgpuContext::instance); + .unwrap_or_else(|| WgpuContext::instance(Box::new(window.clone()))); // Safety: The caller guarantees that the window handle is valid for the // lifetime of this renderer. In practice, the RawWindow struct is created @@ -645,7 +646,7 @@ impl WgpuRenderer { module: &wgpu::ShaderModule| { let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some(&format!("{name}_layout")), - bind_group_layouts: &[globals_layout, data_layout], + bind_group_layouts: &[Some(globals_layout), Some(data_layout)], immediate_size: 0, }); @@ -1052,10 +1053,17 @@ impl WgpuRenderer { self.atlas.before_frame(); - let texture_result = self.resources().surface.get_current_texture(); - let frame = match texture_result { - Ok(frame) => frame, - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { + let frame = match self.resources().surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(frame) => frame, + wgpu::CurrentSurfaceTexture::Suboptimal(frame) => { + let surface_config = self.surface_config.clone(); + let resources = self.resources_mut(); + resources + .surface + .configure(&resources.device, &surface_config); + frame + } + wgpu::CurrentSurfaceTexture::Lost | wgpu::CurrentSurfaceTexture::Outdated => { let surface_config = self.surface_config.clone(); let resources = self.resources_mut(); resources @@ -1063,9 +1071,12 @@ impl WgpuRenderer { .configure(&resources.device, &surface_config); return; } - Err(e) => { + wgpu::CurrentSurfaceTexture::Timeout | wgpu::CurrentSurfaceTexture::Occluded => { + return; + } + wgpu::CurrentSurfaceTexture::Validation => { *self.last_error.lock().unwrap() = - Some(format!("Failed to acquire surface texture: {e}")); + Some("Surface texture validation error".to_string()); return; } }; @@ -1625,11 +1636,10 @@ impl WgpuRenderer { /// - The first window to call this will recreate the shared context /// - Subsequent windows will adopt the already-recovered context #[cfg(not(target_family = "wasm"))] - pub fn recover( - &mut self, - raw_display_handle: raw_window_handle::RawDisplayHandle, - raw_window_handle: raw_window_handle::RawWindowHandle, - ) -> anyhow::Result<()> { + pub fn recover(&mut self, window: &W) -> anyhow::Result<()> + where + W: HasWindowHandle + HasDisplayHandle + std::fmt::Debug + Send + Sync + Clone + 'static, + { let gpu_context = self.context.as_ref().expect("recover requires gpu_context"); // Check if another window already recovered the context @@ -1638,6 +1648,10 @@ impl WgpuRenderer { .as_ref() .is_none_or(|ctx| ctx.device_lost()); + let window_handle = window + .window_handle() + .map_err(|e| anyhow::anyhow!("Failed to get window handle: {e}"))?; + let surface = if needs_new_context { log::warn!("GPU device lost, recreating context..."); @@ -1648,15 +1662,15 @@ impl WgpuRenderer { // Wait for GPU driver to stabilize (350ms copied from windows :shrug:) std::thread::sleep(std::time::Duration::from_millis(350)); - let instance = WgpuContext::instance(); - let surface = create_surface(&instance, raw_display_handle, raw_window_handle)?; + let instance = WgpuContext::instance(Box::new(window.clone())); + let surface = create_surface(&instance, window_handle.as_raw())?; let new_context = WgpuContext::new(instance, &surface, self.compositor_gpu)?; *gpu_context.borrow_mut() = Some(new_context); surface } else { let ctx_ref = gpu_context.borrow(); let instance = &ctx_ref.as_ref().unwrap().instance; - create_surface(instance, raw_display_handle, raw_window_handle)? + create_surface(instance, window_handle.as_raw())? }; let config = WgpuSurfaceConfig { @@ -1691,13 +1705,13 @@ impl WgpuRenderer { #[cfg(not(target_family = "wasm"))] fn create_surface( instance: &wgpu::Instance, - raw_display_handle: raw_window_handle::RawDisplayHandle, raw_window_handle: raw_window_handle::RawWindowHandle, ) -> anyhow::Result> { unsafe { instance .create_surface_unsafe(wgpu::SurfaceTargetUnsafe::RawHandle { - raw_display_handle, + // Fall back to the display handle already provided via InstanceDescriptor::display. + raw_display_handle: None, raw_window_handle, }) .map_err(|e| anyhow::anyhow!("{e}"))