diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs index 3cede8b6..b78ca8d1 100644 --- a/wgpu/src/image/atlas.rs +++ b/wgpu/src/image/atlas.rs @@ -98,6 +98,7 @@ impl Atlas { pub fn upload( &mut self, device: &wgpu::Device, + backend: wgpu::Backend, encoder: &mut wgpu::CommandEncoder, width: u32, height: u32, @@ -109,7 +110,7 @@ impl Atlas { // We grow the internal texture after allocating if necessary let new_layers = self.layers.len() - current_size; - self.grow(new_layers, device, encoder); + self.grow(new_layers, device, backend, encoder); entry }; @@ -370,18 +371,29 @@ impl Atlas { &mut self, amount: usize, device: &wgpu::Device, + backend: wgpu::Backend, encoder: &mut wgpu::CommandEncoder, ) { if amount == 0 { return; } + // On the GL backend if layers.len() == 6 we need to help wgpu figure out that this texture + // is still a `GL_TEXTURE_2D_ARRAY` rather than `GL_TEXTURE_CUBE_MAP`. This will over-allocate + // some unused memory on GL, but it's better than not being able to grow the atlas past a depth + // of 6! + // https://github.com/gfx-rs/wgpu/blob/004e3efe84a320d9331371ed31fa50baa2414911/wgpu-hal/src/gles/mod.rs#L371 + let depth_or_array_layers = match backend { + wgpu::Backend::Gl if self.layers.len() == 6 => 7, + _ => self.layers.len() as u32, + }; + let new_texture = device.create_texture(&wgpu::TextureDescriptor { label: Some("iced_wgpu::image texture atlas"), size: wgpu::Extent3d { width: SIZE, height: SIZE, - depth_or_array_layers: self.layers.len() as u32, + depth_or_array_layers, }, mip_level_count: 1, sample_count: 1, diff --git a/wgpu/src/image/cache.rs b/wgpu/src/image/cache.rs index 94f7071d..c53af11f 100644 --- a/wgpu/src/image/cache.rs +++ b/wgpu/src/image/cache.rs @@ -49,16 +49,19 @@ impl Cache { pub fn upload_raster( &mut self, device: &wgpu::Device, + backend: wgpu::Backend, encoder: &mut wgpu::CommandEncoder, handle: &core::image::Handle, ) -> Option<&atlas::Entry> { - self.raster.upload(device, encoder, handle, &mut self.atlas) + self.raster + .upload(device, backend, encoder, handle, &mut self.atlas) } #[cfg(feature = "svg")] pub fn upload_vector( &mut self, device: &wgpu::Device, + backend: wgpu::Backend, encoder: &mut wgpu::CommandEncoder, handle: &core::svg::Handle, color: Option, @@ -67,6 +70,7 @@ impl Cache { ) -> Option<&atlas::Entry> { self.vector.upload( device, + backend, encoder, handle, color, diff --git a/wgpu/src/image/mod.rs b/wgpu/src/image/mod.rs index 51d2acef..b089ef53 100644 --- a/wgpu/src/image/mod.rs +++ b/wgpu/src/image/mod.rs @@ -235,9 +235,12 @@ impl State { match &image { #[cfg(feature = "image")] Image::Raster(image, bounds) => { - if let Some(atlas_entry) = - cache.upload_raster(device, encoder, &image.handle) - { + if let Some(atlas_entry) = cache.upload_raster( + device, + pipeline.backend, + encoder, + &image.handle, + ) { add_instances( [bounds.x, bounds.y], [bounds.width, bounds.height], @@ -265,6 +268,7 @@ impl State { if let Some(atlas_entry) = cache.upload_vector( device, + pipeline.backend, encoder, &svg.handle, svg.color, diff --git a/wgpu/src/image/raster.rs b/wgpu/src/image/raster.rs index 83777807..e2ccc0cd 100644 --- a/wgpu/src/image/raster.rs +++ b/wgpu/src/image/raster.rs @@ -66,6 +66,7 @@ impl Cache { pub fn upload( &mut self, device: &wgpu::Device, + backend: wgpu::Backend, encoder: &mut wgpu::CommandEncoder, handle: &image::Handle, atlas: &mut Atlas, @@ -75,7 +76,8 @@ impl Cache { if let Memory::Host(image) = memory { let (width, height) = image.dimensions(); - let entry = atlas.upload(device, encoder, width, height, image)?; + let entry = + atlas.upload(device, backend, encoder, width, height, image)?; *memory = Memory::Device(entry); } diff --git a/wgpu/src/image/vector.rs b/wgpu/src/image/vector.rs index e55ade38..076e4491 100644 --- a/wgpu/src/image/vector.rs +++ b/wgpu/src/image/vector.rs @@ -93,6 +93,7 @@ impl Cache { pub fn upload( &mut self, device: &wgpu::Device, + backend: wgpu::Backend, encoder: &mut wgpu::CommandEncoder, handle: &svg::Handle, color: Option, @@ -167,8 +168,8 @@ impl Cache { }); } - let allocation = - atlas.upload(device, encoder, width, height, &rgba)?; + let allocation = atlas + .upload(device, backend, encoder, width, height, &rgba)?; log::debug!("allocating {id} {width}x{height}");