P010 is a 4:2:0 chroma subsampled planar format, similar to NV12. Each
component uses 16 bits of storage, of which only the high 10 bits are
used. On DX12 this maps to DXGI_FORMAT_P010, and on Vulkan this maps to
G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16.
The existing "nv12" gpu test module has been renamed to
"planar_texture", and a new test P010_TEXTURE_CREATION_SAMPLING has
been added similar to the existing NV12_TEXTURE_CREATION_SAMPLING. The
remaining tests in this module have been converted to validation tests,
and now test both NV12 and P010 formats.
These tests cover the external texture binding resource. They ensure
the WGSL functions `textureDimensions()`, `textureLoad()`, and
`textureSampleBaseClampToEdge()` work as expected for both
`TextureView`s and `ExternalTexture`s bound to external texture
resource bindings.
For external textures, they ensure multiplanar YUV formats work as
expected including handling color space transformation. And that the
provided sample and load transforms correctly handle cropping,
flipping, and rotation.
These existing tests cover `Queue::copy_external_image_to_texture()`
which, despite the similar name, is unrelated to the external texture
binding resource.
The following patch is going to add some tests for the latter, so we
are taking this opportunity to rename the former to help avoid
confusion.
This adds several fields to `ExternalTextureDescriptor`, specifying
how to handle color space conversion for an external texture. These
fields consist of transfer functions for the source and destination
color spaces, and a matrix for converting between gamuts. This allows
`ImageSample` and `ImageLoad` operations on external textures to
return values in a desired destination color space rather than the
source color space of the underlying planes.
These fields are plumbed through to the `ExternalTextureParams`
uniform buffer from which they are exposed to the shader. Following
conversion from YUV to RGB after sampling/loading from the external
texture planes, the shader uses them to gamma decode to linear RGB in
the source color space, convert from source to destination gamut, then
finally gamma encode to non-linear RGB in the destination color space.
Vulkan's `VK_EXT_memory_budget` extension doesn't cover query sets, so
`wgpu_hal::vulkan::Device::error_if_would_oom_on_resource_allocation`'s
tactic doesn't work to anticipate OOM errors from the Vulkan driver
when creating query sets.
Without these checks, `wgpu_gpu::oom::query_set_oom_test` actually
consumes a significant amount of memory and attracts the attention of
the system's OOM killer. While it does get killed, the situation tends
to adversely affect the stability of the rest of the system, and thus
is not a friendly thing for a test run to do (#7817).
This change can be reverted once a suitable accounting method for
query sets has been implemented on Vulkan.
Adds a new feature flag, `EXTERNAL_TEXTURE`, indicating device support
for our implementation of WebGPU's `GPUExternalTexture` [1] which will
land in upcoming patches. Conceptually this would make more sense as a
downlevel flag, as it is a core part of the WebGPU spec which we do not
yet support. We do not want, however, to cause applications to reject
adapters because we have not finished implementing this, so for now we
are making it an opt-in feature.
As an initial step towards supporting this feature, this patch adds a
new `BindingType` corresponding to WebGPU's
`GPUExternalTextureBindingLayout` [2]. This binding type dictates that
when creating a bind group the corresponding entry must be either an
external texture or a texture view with certain additional requirements
[3].
As of yet wgpu has no concept of an external texture (that will follow
in later patches) but for now this patch ensures that texture views
corresponding to an external texture binding type are validated
correctly. Note that as the feature flag is not yet supported on any
real backends, bind group layout creation will fail before getting the
chance to attempt to create a bind group. But in the added tests using
the noop backend we can see this validation taking place.
[1] https://www.w3.org/TR/webgpu/#gpuexternaltexture
[1] https://www.w3.org/TR/webgpu/#dictdef-gpuexternaltexturebindinglayout
[2] https://gpuweb.github.io/gpuweb/#bind-group-creation