From 59554041c7911dedb1c4cf8ff2ec5619f8ed8f8b Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Tue, 24 Feb 2026 14:53:43 -0700 Subject: [PATCH] Clamp textures on Linux too Port of #10314 to the wgpu renderer --- crates/gpui/src/platform/wgpu/wgpu_atlas.rs | 28 +++++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/crates/gpui/src/platform/wgpu/wgpu_atlas.rs b/crates/gpui/src/platform/wgpu/wgpu_atlas.rs index f9e4aecc370434cc659afc75e2abd64d7202c98b..bdd6d096b4c5c1577a0334fe44ccfa528da09a2f 100644 --- a/crates/gpui/src/platform/wgpu/wgpu_atlas.rs +++ b/crates/gpui/src/platform/wgpu/wgpu_atlas.rs @@ -2,7 +2,7 @@ use crate::{ AtlasKey, AtlasTextureId, AtlasTextureKind, AtlasTile, Bounds, DevicePixels, PlatformAtlas, Point, Size, platform::AtlasTextureList, }; -use anyhow::Result; +use anyhow::{Context as _, Result}; use collections::FxHashMap; use etagere::{BucketedAtlasAllocator, size2}; use parking_lot::Mutex; @@ -30,6 +30,7 @@ struct PendingUpload { struct WgpuAtlasState { device: Arc, queue: Arc, + max_texture_size: u32, storage: WgpuAtlasStorage, tiles_by_key: FxHashMap, pending_uploads: Vec, @@ -41,9 +42,11 @@ pub struct WgpuTextureInfo { impl WgpuAtlas { pub(crate) fn new(device: Arc, queue: Arc) -> Self { + let max_texture_size = device.limits().max_texture_dimension_2d; WgpuAtlas(Mutex::new(WgpuAtlasState { device, queue, + max_texture_size, storage: WgpuAtlasStorage::default(), tiles_by_key: Default::default(), pending_uploads: Vec::new(), @@ -78,7 +81,9 @@ impl PlatformAtlas for WgpuAtlas { let Some((size, bytes)) = build()? else { return Ok(None); }; - let tile = lock.allocate(size, key.texture_kind()); + let tile = lock + .allocate(size, key.texture_kind()) + .context("failed to allocate")?; lock.upload_texture(tile.texture_id, tile.bounds, &bytes); lock.tiles_by_key.insert(key.clone(), tile.clone()); Ok(Some(tile)) @@ -110,7 +115,11 @@ impl PlatformAtlas for WgpuAtlas { } impl WgpuAtlasState { - fn allocate(&mut self, size: Size, texture_kind: AtlasTextureKind) -> AtlasTile { + fn allocate( + &mut self, + size: Size, + texture_kind: AtlasTextureKind, + ) -> Option { { let textures = &mut self.storage[texture_kind]; @@ -119,14 +128,12 @@ impl WgpuAtlasState { .rev() .find_map(|texture| texture.allocate(size)) { - return tile; + return Some(tile); } } let texture = self.push_texture(size, texture_kind); - texture - .allocate(size) - .expect("Failed to allocate from newly created texture") + texture.allocate(size) } fn push_texture( @@ -138,8 +145,13 @@ impl WgpuAtlasState { width: DevicePixels(1024), height: DevicePixels(1024), }; + let max_texture_size = self.max_texture_size as i32; + let max_atlas_size = Size { + width: DevicePixels(max_texture_size), + height: DevicePixels(max_texture_size), + }; - let size = min_size.max(&DEFAULT_ATLAS_SIZE); + let size = min_size.min(&max_atlas_size).max(&DEFAULT_ATLAS_SIZE); let format = match kind { AtlasTextureKind::Monochrome => wgpu::TextureFormat::R8Unorm, AtlasTextureKind::Subpixel => wgpu::TextureFormat::Bgra8Unorm,