diff --git a/CHANGELOG.md b/CHANGELOG.md index 16d7bb93cd..7ff1f78924 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -146,6 +146,7 @@ By @cwfitzgerald in [#3610](https://github.com/gfx-rs/wgpu/pull/3610). - Reset all queue state between command buffers in a submit. By @jleibs [#3589](https://github.com/gfx-rs/wgpu/pull/3589) - Reset the state of `SAMPLE_ALPHA_TO_COVERAGE` on queue reset. By @jleibs [#3589](https://github.com/gfx-rs/wgpu/pull/3589) - Fix `Vertex buffer is not big enough for the draw call.` for ANGLE/Web when rendering with instance attributes on a single instance. By @wumpf in [#3597](https://github.com/gfx-rs/wgpu/pull/3597) +- Fix `copy_external_image_to_texture`, `copy_texture_to_texture` and `copy_buffer_to_texture` not taking the specified index into account if the target texture is a cube map, 2D texture array or cube map array. By @daxpedda [#3641](https://github.com/gfx-rs/wgpu/pull/3641) #### General diff --git a/wgpu-hal/src/gles/queue.rs b/wgpu-hal/src/gles/queue.rs index 5dd8b1f554..87a82524fc 100644 --- a/wgpu-hal/src/gles/queue.rs +++ b/wgpu-hal/src/gles/queue.rs @@ -393,6 +393,13 @@ impl super::Queue { unsafe { gl.bind_texture(dst_target, Some(dst)) }; let format_desc = self.shared.describe_texture_format(dst_format); if is_layered_target(dst_target) { + let z_offset = + if let glow::TEXTURE_2D_ARRAY | glow::TEXTURE_CUBE_MAP_ARRAY = dst_target { + copy.dst_base.array_layer as i32 + } else { + copy.dst_base.origin.z as i32 + }; + match src.source { wgt::ExternalImageSource::ImageBitmap(ref b) => unsafe { gl.tex_sub_image_3d_with_image_bitmap( @@ -400,7 +407,7 @@ impl super::Queue { copy.dst_base.mip_level as i32, copy.dst_base.origin.x as i32, copy.dst_base.origin.y as i32, - copy.dst_base.origin.z as i32, + z_offset, copy.size.width as i32, copy.size.height as i32, copy.size.depth as i32, @@ -415,7 +422,7 @@ impl super::Queue { copy.dst_base.mip_level as i32, copy.dst_base.origin.x as i32, copy.dst_base.origin.y as i32, - copy.dst_base.origin.z as i32, + z_offset, copy.size.width as i32, copy.size.height as i32, copy.size.depth as i32, @@ -430,7 +437,7 @@ impl super::Queue { copy.dst_base.mip_level as i32, copy.dst_base.origin.x as i32, copy.dst_base.origin.y as i32, - copy.dst_base.origin.z as i32, + z_offset, copy.size.width as i32, copy.size.height as i32, copy.size.depth as i32, @@ -442,6 +449,12 @@ impl super::Queue { wgt::ExternalImageSource::OffscreenCanvas(_) => unreachable!(), } } else { + let dst_target = if let glow::TEXTURE_CUBE_MAP = dst_target { + CUBEMAP_FACES[copy.dst_base.array_layer as usize] + } else { + dst_target + }; + match src.source { wgt::ExternalImageSource::ImageBitmap(ref b) => unsafe { gl.tex_sub_image_2d_with_image_bitmap_and_width_and_height( @@ -549,7 +562,13 @@ impl super::Queue { copy.dst_base.mip_level as i32, copy.dst_base.origin.x as i32, copy.dst_base.origin.y as i32, - copy.dst_base.origin.z as i32, + if let glow::TEXTURE_2D_ARRAY | glow::TEXTURE_CUBE_MAP_ARRAY = + dst_target + { + copy.dst_base.array_layer as i32 + } else { + copy.dst_base.origin.z as i32 + }, copy.src_base.origin.x as i32, copy.src_base.origin.y as i32, copy.size.width as i32, @@ -610,90 +629,46 @@ impl super::Queue { glow::PixelUnpackData::Slice(src_data) } }; - match dst_target { - glow::TEXTURE_3D => { - unsafe { - gl.tex_sub_image_3d( - dst_target, - copy.texture_base.mip_level as i32, - copy.texture_base.origin.x as i32, - copy.texture_base.origin.y as i32, - copy.texture_base.origin.z as i32, - copy.size.width as i32, - copy.size.height as i32, - copy.size.depth as i32, - format_desc.external, - format_desc.data_type, - unpack_data, - ) - }; - } - glow::TEXTURE_2D_ARRAY => { - unsafe { - gl.tex_sub_image_3d( - dst_target, - copy.texture_base.mip_level as i32, - copy.texture_base.origin.x as i32, - copy.texture_base.origin.y as i32, - copy.texture_base.array_layer as i32, - copy.size.width as i32, - copy.size.height as i32, - copy.size.depth as i32, - format_desc.external, - format_desc.data_type, - unpack_data, - ) - }; - } - glow::TEXTURE_2D => { - unsafe { - gl.tex_sub_image_2d( - dst_target, - copy.texture_base.mip_level as i32, - copy.texture_base.origin.x as i32, - copy.texture_base.origin.y as i32, - copy.size.width as i32, - copy.size.height as i32, - format_desc.external, - format_desc.data_type, - unpack_data, - ) - }; - } - glow::TEXTURE_CUBE_MAP => { - unsafe { - gl.tex_sub_image_2d( - CUBEMAP_FACES[copy.texture_base.array_layer as usize], - copy.texture_base.mip_level as i32, - copy.texture_base.origin.x as i32, - copy.texture_base.origin.y as i32, - copy.size.width as i32, - copy.size.height as i32, - format_desc.external, - format_desc.data_type, - unpack_data, - ) - }; - } - glow::TEXTURE_CUBE_MAP_ARRAY => { - //Note: not sure if this is correct! - unsafe { - gl.tex_sub_image_3d( - dst_target, - copy.texture_base.mip_level as i32, - copy.texture_base.origin.x as i32, - copy.texture_base.origin.y as i32, - copy.texture_base.origin.z as i32, - copy.size.width as i32, - copy.size.height as i32, - copy.size.depth as i32, - format_desc.external, - format_desc.data_type, - unpack_data, - ) - }; - } - _ => unreachable!(), + if is_layered_target(dst_target) { + unsafe { + gl.tex_sub_image_3d( + dst_target, + copy.texture_base.mip_level as i32, + copy.texture_base.origin.x as i32, + copy.texture_base.origin.y as i32, + if let glow::TEXTURE_2D_ARRAY | glow::TEXTURE_CUBE_MAP_ARRAY = + dst_target + { + copy.texture_base.array_layer as i32 + } else { + copy.texture_base.origin.z as i32 + }, + copy.size.width as i32, + copy.size.height as i32, + copy.size.depth as i32, + format_desc.external, + format_desc.data_type, + unpack_data, + ) + }; + } else { + unsafe { + gl.tex_sub_image_2d( + if let glow::TEXTURE_CUBE_MAP = dst_target { + CUBEMAP_FACES[copy.texture_base.array_layer as usize] + } else { + dst_target + }, + copy.texture_base.mip_level as i32, + copy.texture_base.origin.x as i32, + copy.texture_base.origin.y as i32, + copy.size.width as i32, + copy.size.height as i32, + format_desc.external, + format_desc.data_type, + unpack_data, + ) + }; } } else { let bytes_per_row = copy @@ -730,54 +705,44 @@ impl super::Queue { } }; - match dst_target { - glow::TEXTURE_3D - | glow::TEXTURE_CUBE_MAP_ARRAY - | glow::TEXTURE_2D_ARRAY => { - unsafe { - gl.compressed_tex_sub_image_3d( - dst_target, - copy.texture_base.mip_level as i32, - copy.texture_base.origin.x as i32, - copy.texture_base.origin.y as i32, - copy.texture_base.origin.z as i32, - copy.size.width as i32, - copy.size.height as i32, - copy.size.depth as i32, - format_desc.internal, - unpack_data, - ) - }; - } - glow::TEXTURE_2D => { - unsafe { - gl.compressed_tex_sub_image_2d( - dst_target, - copy.texture_base.mip_level as i32, - copy.texture_base.origin.x as i32, - copy.texture_base.origin.y as i32, - copy.size.width as i32, - copy.size.height as i32, - format_desc.internal, - unpack_data, - ) - }; - } - glow::TEXTURE_CUBE_MAP => { - unsafe { - gl.compressed_tex_sub_image_2d( - CUBEMAP_FACES[copy.texture_base.array_layer as usize], - copy.texture_base.mip_level as i32, - copy.texture_base.origin.x as i32, - copy.texture_base.origin.y as i32, - copy.size.width as i32, - copy.size.height as i32, - format_desc.internal, - unpack_data, - ) - }; - } - _ => unreachable!(), + if is_layered_target(dst_target) { + unsafe { + gl.compressed_tex_sub_image_3d( + dst_target, + copy.texture_base.mip_level as i32, + copy.texture_base.origin.x as i32, + copy.texture_base.origin.y as i32, + if let glow::TEXTURE_2D_ARRAY | glow::TEXTURE_CUBE_MAP_ARRAY = + dst_target + { + copy.texture_base.array_layer as i32 + } else { + copy.texture_base.origin.z as i32 + }, + copy.size.width as i32, + copy.size.height as i32, + copy.size.depth as i32, + format_desc.internal, + unpack_data, + ) + }; + } else { + unsafe { + gl.compressed_tex_sub_image_2d( + if let glow::TEXTURE_CUBE_MAP = dst_target { + CUBEMAP_FACES[copy.texture_base.array_layer as usize] + } else { + dst_target + }, + copy.texture_base.mip_level as i32, + copy.texture_base.origin.x as i32, + copy.texture_base.origin.y as i32, + copy.size.width as i32, + copy.size.height as i32, + format_desc.internal, + unpack_data, + ) + }; } } if unbind_unpack_buffer { diff --git a/wgpu/tests/external_texture.rs b/wgpu/tests/external_texture.rs index b40dc337e4..973110901c 100644 --- a/wgpu/tests/external_texture.rs +++ b/wgpu/tests/external_texture.rs @@ -162,8 +162,6 @@ async fn image_bitmap_import() { // If the test is suppoed to be valid call to copyExternal. let mut valid = true; - // If the result is incorrect - let mut correct = true; match case { TestCase::Normal => {} TestCase::FlipY => { @@ -244,7 +242,6 @@ async fn image_bitmap_import() { dest_layers = 2; } TestCase::SecondSliceCopy => { - correct = false; // TODO: what? dest_origin.z = 1; dest_data_layer = 1; dest_layers = 2; @@ -336,7 +333,7 @@ async fn image_bitmap_import() { let gpu_image_cropped = image::imageops::crop_imm(&gpu_image, 0, 0, 3, 3).to_image(); - if valid && correct { + if valid { assert_eq!( raw_image, gpu_image_cropped, "Failed on test case {case:?} {source:?}"