fix(hal/gles): copy every depth slice in copy_texture_to_texture - #10004
Open
AlexEgger2Build wants to merge 1 commit into
Open
fix(hal/gles): copy every depth slice in copy_texture_to_texture#10004AlexEgger2Build wants to merge 1 commit into
AlexEgger2Build wants to merge 1 commit into
Conversation
The `C::CopyTextureToTexture` arm never read `copy.size.depth`. It attached one slice to the read framebuffer and issued a single `copy_tex_sub_image_*`, so a copy between 3D textures transferred only z slice 0. Nothing errored and no validation tripped; the remaining slices were silently left untouched. GL has no call that copies a volume between textures, because the read framebuffer holds one 2D slice at a time, so loop over the depth extent and copy one slice per iteration. The source slice index was also taken from `copy.src_base.array_layer` while the destination used `get_z_offset()`. For `TEXTURE_3D` the z coordinate lives in `origin.z` rather than `array_layer`, so a copy with a nonzero source z read the wrong slice; both sides now use `get_z_offset()`. Non-layered sources go through `get_2d_target()` as the destination already did, so a cube map source selects the right face rather than passing `TEXTURE_CUBE_MAP` to `glFramebufferTexture2D`. Add a test copying a four-slice 3D texture with a distinct value per slice. The existing `copy_texture_to_texture` coverage only ever copies a single slice, which is how this went unnoticed.
AlexEgger2Build
force-pushed
the
fix-gles-3d-texture-copy
branch
from
August 4, 2026 00:32
7421d24 to
0ea7294
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #9992.
On the GLES backend (including WebGL2),
copy_texture_to_texture()between two 3D textures only copied z slice 0. TheC::CopyTextureToTexturearm never readcopy.size.depth— it attached a single slice to the read framebuffer and issued onecopy_tex_sub_image_*. Nothing errored and no validation tripped, so the remaining slices were silently left untouched. The arm carried a//TODO: handle 3D copies.GL has no call that copies a volume between textures, since the read framebuffer holds one 2D slice at a time, so this loops over the depth extent and copies one slice per iteration.
Two related things in the same arm, fixed alongside because the loop needs them to be right:
copy.src_base.array_layerwhile the destination usedget_z_offset(). ForTEXTURE_3Dthe z coordinate lives inorigin.zrather thanarray_layer, so a copy with a nonzero source z read the wrong slice. Both sides useget_z_offset()now.get_2d_target(), as the destination already did. Previously a cube map source passedTEXTURE_CUBE_MAPstraight toglFramebufferTexture2D, which isn't a validtextarget.Testing
New test in
tests/tests/wgpu-gpu/transfer.rscopies a four-slice 3D texture with a distinct value per slice and checks each slice separately, so a dropped or misplaced slice is caught rather than just a wrong copy length. The existingcopy_texture_to_texturecoverage only ever copies a single slice — thezero_init.rs3D cases usedepth_or_array_layers: 1— which is how this survived. #3315 tracks that gap.Being clear about what I ran and what I didn't:
cargo xtask testgives the same 10 failures with and without this change (naga snapshots, Metal passthrough shaders, timestamp resolve), so those are pre-existing in my environment.wasm-bindgen-testin headless Firefox and failed 3 of 4 slices, which is what prompted this. I'm counting on CI to actually exercise the GL path.Downstream this is the bug behind kpreid/all-is-cubes#391, where a 3D block-texture atlas loses most of its contents when reallocated and has carried a CPU-side re-upload workaround since 2023.