fix(dx12): Handle multi-planar formats in texture copy operations#9551
fix(dx12): Handle multi-planar formats in texture copy operations#9551AdrianEddy wants to merge 6 commits into
Conversation
|
I'm really ignorant about this, but: Isn't this user-visible behavior? Why doesn't it need a feature flag? |
|
Current wgpu (without this PR) simply returns |
ErichDonGubler
left a comment
There was a problem hiding this comment.
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?
Co-authored-by: Erich Gubler <erichdongubler@gmail.com>
@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) |
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 andsource.aspectselects a single plane, the destination may be a single-plane texture whose format matches that plane (e.g. NV12Plane0->R8Unorm, NV12Plane1->Rg8Unorm).dx12::Texture::with_plane_slice(plane_slice: u32): a builder on the HALTexturethat pinsPlaneSlicefor every view and copy derived from that texture, overriding the default aspect-based derivation. Intended use is to calltexture_from_rawtwice with two clones of the sameID3D12Resource. One wrapper per plane - each declaring the matching single-planeTextureFormat.map_texture_format_for_copypreviously panicked on(planar_format, single_plane_aspect)combinations duringCopyTextureRegion; it now maps to the plane-specific single-plane DXGI format.TextureView::subresource_indexwas 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_slicewrappers alias the same underlyingID3D12Resource. wgpu's state tracker treats them as independent textures and has no way to know about the aliasing, so the safety contract onwith_plane_slicerequires the caller to keep accesses to the two wrappers from racing or invalidating each other's tracked state (documented on the method).Testing
NV12_PLANE_TO_SINGLE_PLANE_COPY: writes distinct byte patterns into NV12Plane0/Plane1, copies each plane into anR8Unorm/Rg8Unormdestination viacopy_texture_to_texture, reads back viacopy_texture_to_buffer, and asserts byte-for-byte equality per plane (so a plane swap or plane-0 fallback would fail).NV12_TEXTURE_COPYING/P010_TEXTURE_COPYINGstill pass (no regression on the existing planar->planar copy path).Squash or Rebase?
Squash
Checklist
wgpumay be affected behaviorally.CHANGELOG.mdentries for the user-facing effects of this change are present.