From 6ad2de0272a72ddb4da2b089e800e7a22e72c4a4 Mon Sep 17 00:00:00 2001 From: "zed-zippy[bot]" <234243425+zed-zippy[bot]@users.noreply.github.com> Date: Fri, 27 Feb 2026 21:11:13 +0000 Subject: [PATCH] Clamp window size on wgpu (#50329) (cherry-pick to preview) (#50346) Cherry-pick of #50329 to preview ---- Fixes ZED-59P Release Notes: - Linux: Fix panic when requested window size was larger than supported by your GPU Co-authored-by: Conrad Irwin (cherry picked from commit 496e115fd3a7ec42a19bb2ff3588ffe5e8e6df7f) --- .../gpui/src/platform/linux/wayland/window.rs | 6 +++ .../gpui/src/platform/wgpu/wgpu_renderer.rs | 42 ++++++++++++++++--- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/crates/gpui/src/platform/linux/wayland/window.rs b/crates/gpui/src/platform/linux/wayland/window.rs index 4bc9172b94c4fa96ccd48977d33b1bcc576223c9..c3cbcb9ddd99017696b98181b92e6ea60a4a9fee 100644 --- a/crates/gpui/src/platform/linux/wayland/window.rs +++ b/crates/gpui/src/platform/linux/wayland/window.rs @@ -347,6 +347,12 @@ impl WaylandWindowState { if let Some(title) = options.titlebar.and_then(|titlebar| titlebar.title) { xdg_state.toplevel.set_title(title.to_string()); } + // Set max window size based on the GPU's maximum texture dimension. + // This prevents the window from being resized larger than what the GPU can render. + let max_texture_size = renderer.max_texture_size() as i32; + xdg_state + .toplevel + .set_max_size(max_texture_size, max_texture_size); } Ok(Self { diff --git a/crates/gpui/src/platform/wgpu/wgpu_renderer.rs b/crates/gpui/src/platform/wgpu/wgpu_renderer.rs index 8d69383df5083373ab41b64be43cdf166b73d69b..6b00fa5f5b22c8175237b90d68608351e3fbe74b 100644 --- a/crates/gpui/src/platform/wgpu/wgpu_renderer.rs +++ b/crates/gpui/src/platform/wgpu/wgpu_renderer.rs @@ -116,6 +116,7 @@ pub struct WgpuRenderer { adapter_info: wgpu::AdapterInfo, transparent_alpha_mode: wgpu::CompositeAlphaMode, opaque_alpha_mode: wgpu::CompositeAlphaMode, + max_texture_size: u32, } impl WgpuRenderer { @@ -215,11 +216,27 @@ impl WgpuRenderer { opaque_alpha_mode }; + let device = Arc::clone(&context.device); + let max_texture_size = device.limits().max_texture_dimension_2d; + + let requested_width = config.size.width.0 as u32; + let requested_height = config.size.height.0 as u32; + let clamped_width = requested_width.min(max_texture_size); + let clamped_height = requested_height.min(max_texture_size); + + if clamped_width != requested_width || clamped_height != requested_height { + warn!( + "Requested surface size ({}, {}) exceeds maximum texture dimension {}. \ + Clamping to ({}, {}). Window content may not fill the entire window.", + requested_width, requested_height, max_texture_size, clamped_width, clamped_height + ); + } + let surface_config = wgpu::SurfaceConfiguration { usage: wgpu::TextureUsages::RENDER_ATTACHMENT, format: surface_format, - width: config.size.width.0 as u32, - height: config.size.height.0 as u32, + width: clamped_width.max(1), + height: clamped_height.max(1), present_mode: wgpu::PresentMode::Fifo, desired_maximum_frame_latency: 2, alpha_mode, @@ -227,7 +244,6 @@ impl WgpuRenderer { }; surface.configure(&context.device, &surface_config); - let device = Arc::clone(&context.device); let queue = Arc::clone(&context.queue); let dual_source_blending = context.supports_dual_source_blending(); @@ -348,6 +364,7 @@ impl WgpuRenderer { adapter_info, transparent_alpha_mode, opaque_alpha_mode, + max_texture_size, }) } @@ -762,6 +779,17 @@ impl WgpuRenderer { let height = size.height.0 as u32; if width != self.surface_config.width || height != self.surface_config.height { + let clamped_width = width.min(self.max_texture_size); + let clamped_height = height.min(self.max_texture_size); + + if clamped_width != width || clamped_height != height { + warn!( + "Requested surface size ({}, {}) exceeds maximum texture dimension {}. \ + Clamping to ({}, {}). Window content may not fill the entire window.", + width, height, self.max_texture_size, clamped_width, clamped_height + ); + } + // Wait for any in-flight GPU work to complete before destroying textures if let Err(e) = self.device.poll(wgpu::PollType::Wait { submission_index: None, @@ -778,8 +806,8 @@ impl WgpuRenderer { texture.destroy(); } - self.surface_config.width = width.max(1); - self.surface_config.height = height.max(1); + self.surface_config.width = clamped_width.max(1); + self.surface_config.height = clamped_height.max(1); self.surface.configure(&self.device, &self.surface_config); // Invalidate intermediate textures - they will be lazily recreated @@ -864,6 +892,10 @@ impl WgpuRenderer { } } + pub fn max_texture_size(&self) -> u32 { + self.max_texture_size + } + pub fn draw(&mut self, scene: &Scene) { self.atlas.before_frame();