From 83e037829c67d010afa1f3318252f2e40535352e Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 27 Aug 2020 13:41:00 +0200 Subject: Update `image` pipeline in `iced_wgpu` --- wgpu/src/image/atlas.rs | 76 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 16 deletions(-) (limited to 'wgpu/src/image') diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs index 3ce3ce8b..99e9995f 100644 --- a/wgpu/src/image/atlas.rs +++ b/wgpu/src/image/atlas.rs @@ -30,7 +30,6 @@ impl Atlas { let texture = device.create_texture(&wgpu::TextureDescriptor { label: None, size: extent, - array_layer_count: 2, mip_level_count: 1, sample_count: 1, dimension: wgpu::TextureDimension::D2, @@ -40,7 +39,10 @@ impl Atlas { | wgpu::TextureUsage::SAMPLED, }); - let texture_view = texture.create_default_view(); + let texture_view = texture.create_view(&wgpu::TextureViewDescriptor { + dimension: Some(wgpu::TextureViewDimension::D2Array), + ..Default::default() + }); Atlas { texture, @@ -65,6 +67,8 @@ impl Atlas { device: &wgpu::Device, encoder: &mut wgpu::CommandEncoder, ) -> Option { + use wgpu::util::DeviceExt; + let entry = { let current_size = self.layers.len(); let entry = self.allocate(width, height)?; @@ -78,8 +82,31 @@ impl Atlas { log::info!("Allocated atlas entry: {:?}", entry); + // It is a webgpu requirement that: + // BufferCopyView.layout.bytes_per_row % wgpu::COPY_BYTES_PER_ROW_ALIGNMENT == 0 + // So we calculate padded_width by rounding width up to the next + // multiple of wgpu::COPY_BYTES_PER_ROW_ALIGNMENT. + let align = wgpu::COPY_BYTES_PER_ROW_ALIGNMENT; + let padding = (align - (4 * width) % align) % align; + let padded_width = (4 * width + padding) as usize; + let padded_data_size = padded_width * height as usize; + + let mut padded_data = vec![0; padded_data_size]; + + for row in 0..height as usize { + let offset = row * padded_width; + + padded_data[offset..offset + 4 * width as usize].copy_from_slice( + &data[row * 4 * width as usize..(row + 1) * 4 * width as usize], + ) + } + let buffer = - device.create_buffer_with_data(data, wgpu::BufferUsage::COPY_SRC); + device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + contents: &padded_data, + usage: wgpu::BufferUsage::COPY_SRC, + }); match &entry { Entry::Contiguous(allocation) => { @@ -87,6 +114,7 @@ impl Atlas { &buffer, width, height, + padding, 0, &allocation, encoder, @@ -95,12 +123,13 @@ impl Atlas { Entry::Fragmented { fragments, .. } => { for fragment in fragments { let (x, y) = fragment.position; - let offset = (y * width + x) as usize * 4; + let offset = (y * padded_width as u32 + x) as usize * 4; self.upload_allocation( &buffer, width, height, + padding, offset, &fragment.allocation, encoder, @@ -253,6 +282,7 @@ impl Atlas { buffer: &wgpu::Buffer, image_width: u32, image_height: u32, + padding: u32, offset: usize, allocation: &Allocation, encoder: &mut wgpu::CommandEncoder, @@ -270,15 +300,20 @@ impl Atlas { encoder.copy_buffer_to_texture( wgpu::BufferCopyView { buffer, - offset: offset as u64, - bytes_per_row: 4 * image_width, - rows_per_image: image_height, + layout: wgpu::TextureDataLayout { + offset: offset as u64, + bytes_per_row: 4 * image_width + padding, + rows_per_image: image_height, + }, }, wgpu::TextureCopyView { texture: &self.texture, - array_layer: layer as u32, mip_level: 0, - origin: wgpu::Origin3d { x, y, z: 0 }, + origin: wgpu::Origin3d { + x, + y, + z: layer as u32, + }, }, extent, ); @@ -299,9 +334,8 @@ impl Atlas { size: wgpu::Extent3d { width: SIZE, height: SIZE, - depth: 1, + depth: self.layers.len() as u32, }, - array_layer_count: self.layers.len() as u32, mip_level_count: 1, sample_count: 1, dimension: wgpu::TextureDimension::D2, @@ -323,15 +357,21 @@ impl Atlas { encoder.copy_texture_to_texture( wgpu::TextureCopyView { texture: &self.texture, - array_layer: i as u32, mip_level: 0, - origin: wgpu::Origin3d { x: 0, y: 0, z: 0 }, + origin: wgpu::Origin3d { + x: 0, + y: 0, + z: i as u32, + }, }, wgpu::TextureCopyView { texture: &new_texture, - array_layer: i as u32, mip_level: 0, - origin: wgpu::Origin3d { x: 0, y: 0, z: 0 }, + origin: wgpu::Origin3d { + x: 0, + y: 0, + z: i as u32, + }, }, wgpu::Extent3d { width: SIZE, @@ -342,6 +382,10 @@ impl Atlas { } self.texture = new_texture; - self.texture_view = self.texture.create_default_view(); + self.texture_view = + self.texture.create_view(&wgpu::TextureViewDescriptor { + dimension: Some(wgpu::TextureViewDimension::D2Array), + ..Default::default() + }); } } -- cgit From ecbee66bd652228204568c17dd5e8a97b0a59ee0 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 27 Aug 2020 14:44:51 +0200 Subject: Fix `layers` initialization in `image::Atlas` --- wgpu/src/image/atlas.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wgpu/src/image') diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs index 99e9995f..8d110fc4 100644 --- a/wgpu/src/image/atlas.rs +++ b/wgpu/src/image/atlas.rs @@ -47,7 +47,7 @@ impl Atlas { Atlas { texture, texture_view, - layers: vec![Layer::Empty, Layer::Empty], + layers: vec![Layer::Empty], } } -- cgit From bb5f034e08c46e5ce46ed0e38a684c5ca710cb11 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 27 Aug 2020 14:45:08 +0200 Subject: Fix `offset` calculation in `image::Atlas` --- wgpu/src/image/atlas.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wgpu/src/image') diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs index 8d110fc4..69f872e8 100644 --- a/wgpu/src/image/atlas.rs +++ b/wgpu/src/image/atlas.rs @@ -123,7 +123,7 @@ impl Atlas { Entry::Fragmented { fragments, .. } => { for fragment in fragments { let (x, y) = fragment.position; - let offset = (y * padded_width as u32 + x) as usize * 4; + let offset = (y * padded_width as u32 + 4 * x) as usize; self.upload_allocation( &buffer, -- cgit From 44118263b5de7bc32f6280ee3d1dc170a9b034d3 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 31 Aug 2020 14:41:41 +0200 Subject: Add labels to `iced_wgpu` internals --- wgpu/src/image/atlas.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'wgpu/src/image') diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs index 69f872e8..660ebe44 100644 --- a/wgpu/src/image/atlas.rs +++ b/wgpu/src/image/atlas.rs @@ -28,7 +28,7 @@ impl Atlas { }; let texture = device.create_texture(&wgpu::TextureDescriptor { - label: None, + label: Some("iced_wgpu::image texture atlas"), size: extent, mip_level_count: 1, sample_count: 1, @@ -103,7 +103,7 @@ impl Atlas { let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: None, + label: Some("iced_wgpu::image staging buffer"), contents: &padded_data, usage: wgpu::BufferUsage::COPY_SRC, }); @@ -330,7 +330,7 @@ impl Atlas { } let new_texture = device.create_texture(&wgpu::TextureDescriptor { - label: None, + label: Some("iced_wgpu::image texture atlas"), size: wgpu::Extent3d { width: SIZE, height: SIZE, -- cgit