Skip to content

fix(dx12): Handle multi-planar formats in texture copy operations#9551

Open
AdrianEddy wants to merge 6 commits into
gfx-rs:trunkfrom
AdrianEddy:multiplanar-copy
Open

fix(dx12): Handle multi-planar formats in texture copy operations#9551
AdrianEddy wants to merge 6 commits into
gfx-rs:trunkfrom
AdrianEddy:multiplanar-copy

Conversation

@AdrianEddy
Copy link
Copy Markdown
Contributor

Description
Adds support for copying a single plane of a multi-planar texture (NV12, P010) into a single-plane destination of the matching format, and adds the DX12-side plumbing for cross-API importers that wrap one plane of a multi-plane DXGI resource (e.g. DXGI_FORMAT_NV12) as a single-plane wgpu texture.

  • copy_texture_to_texture: extends copy-compatibility so that, when the source is multi-planar and source.aspect selects a single plane, the destination may be a single-plane texture whose format matches that plane (e.g. NV12 Plane0 -> R8Unorm, NV12 Plane1 -> Rg8Unorm).
  • dx12::Texture::with_plane_slice(plane_slice: u32): a builder on the HAL Texture that pins PlaneSlice for every view and copy derived from that texture, overriding the default aspect-based derivation. Intended use is to call texture_from_raw twice with two clones of the same ID3D12Resource. One wrapper per plane - each declaring the matching single-plane TextureFormat.
  • DX12 bug fixes uncovered while wiring this up:
    • map_texture_format_for_copy previously panicked on (planar_format, single_plane_aspect) combinations during CopyTextureRegion; it now maps to the plane-specific single-plane DXGI format.
    • TextureView::subresource_index was hard-coded to plane 0 regardless of the view's aspect, so SRVs/UAVs/RTVs targeting plane 1 of a planar resource were referring to the wrong subresource. Views now go through the same plane-slice resolution as descriptor creation.

Caveats

  • with_plane_slice wrappers alias the same underlying ID3D12Resource. wgpu's state tracker treats them as independent textures and has no way to know about the aliasing, so the safety contract on with_plane_slice requires the caller to keep accesses to the two wrappers from racing or invalidating each other's tracked state (documented on the method).

Testing

  • New GPU test NV12_PLANE_TO_SINGLE_PLANE_COPY: writes distinct byte patterns into NV12 Plane0 / Plane1, copies each plane into an R8Unorm / Rg8Unorm destination via copy_texture_to_texture, reads back via copy_texture_to_buffer, and asserts byte-for-byte equality per plane (so a plane swap or plane-0 fallback would fail).
  • Existing NV12_TEXTURE_COPYING / P010_TEXTURE_COPYING still pass (no regression on the existing planar->planar copy path).

Squash or Rebase?

Squash

Checklist

  • I self-reviewed and fully understand this PR.
  • WebGPU implementations built with wgpu may be affected behaviorally.
  • Validation and feature gates are in place to confine behavioral changes.
  • Tests demonstrate the validation and altered logic works.
  • CHANGELOG.md entries for the user-facing effects of this change are present.
  • The PR is minimal, and doesn't make sense to land as multiple PRs.
  • Commits are logically scoped and individually reviewable.
  • The PR description has enough context to understand the motivation and solution implemented.

@jimblandy
Copy link
Copy Markdown
Member

I'm really ignorant about this, but: Isn't this user-visible behavior? Why doesn't it need a feature flag?

@AdrianEddy
Copy link
Copy Markdown
Contributor Author

AdrianEddy commented May 21, 2026

Current wgpu (without this PR) simply returns TextureFormatsNotCopyCompatible in this case, so this PR doesn't change any useful existing behavior

Copy link
Copy Markdown
Member

@ErichDonGubler ErichDonGubler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some commentary, but I'm going to specifically not promise doing further review on this.

@jamienicol, does this sound like something that might be reusable for Firefox?

Comment thread wgpu-hal/src/dx12/mod.rs Outdated
Comment thread CHANGELOG.md Outdated
@jamienicol
Copy link
Copy Markdown
Contributor

@jamienicol, does this sound like something that might be reusable for Firefox?

@ErichDonGubler No, I don't think this is useful to firefox (specifically the external texture implementation).

We do make use of multiplanar formats, but only when importing directly from hardware decoded video, so we have no need to perform a copy.

When handling software-decoded video I opted never to use multiplanar textures, as we need to work on platforms that don't support them anyway. We could in the future as an optimisation make use of them when supported. But we'd still have no need for texture to texture copies. (Buffer to texture copies would be helpful in that case though, if that could be supported)

@teoxoy teoxoy self-assigned this May 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants