Adds a `BindingResource` variant for external textures. In core's
create_bind_group() implementation, allow binding either external
textures or texture views to `BindingType::ExternalTexture` layout
entries.
In either case, provide HAL with a `hal::ExternalTextureBinding`,
consisting of 3 `hal::TextureBinding`s and a `hal::BufferBinding`. In
the texture view case we use the device's default params buffer for
the buffer. When there are fewer than 3 planes we can simply repeat an
existing plane multiple times - the contents of the params buffer will
ensure the shader only accesses the correct number of planes anyway.
Track the view or external texture in `BindGroupStates` to ensure they
remain alive whilst required.
And finally, add the corresponding API to wgpu, with an implementation
for the wgpu-core backend.
In upcoming patches, wgpu will allowing the creation of bind groups
with either `TextureView`s or `ExternalTexture`s bound to a
`BindingType::ExternalTexture` bind group layout entry.
Wgpu-hal and the Naga-generated shaders must be able to handle both of
these cases. For external textures they will be provided a uniform
buffer containing the external texture's `ExternalTextureParams`. For
the texture view case, we must therefore provide the same.
To do this, we create a single buffer per device which can be shared
between all texture views. We initialize it with the required values
in Device::late_init_resources_with_queue(). We know that texture
views must have a single RGBA plane, with no rotation or
crop-rect. The only thing that can vary between them is their size. We
will therefore use the value of [0, 0] in the params buffer to
indicate to the shader that it should query the actual texture's size
rather than using the value provided in the buffer.
`ExternalTexture` will form the basis of wgpu's implementation of
WebGPU's `GPUExternalTexture`. [1]
The application will be responsible for creating `Texture`(s) and
`TextureView`(s) from the external texture source and managing their
lifecycle. It may have a single RGBA texture, or it may have multiple
textures for separate Y and Cb/Cr planes. It can then create an external
texture by calling `create_external_texture()`, providing the texture
views and a descriptor. The descriptor provides the following required
information:
* Whether the texture data is RGBA, or multiplanar or interleaved
YCbCr.
* The purpoted size of the external texture, which may not match the
actual size of the underlying textures.
* A matrix for converting from YCbCr to RGBA, if required.
* A transform to apply to texture sample coordinates, allowing for
rotation and crop rects.
The external texture stores a reference to the provided texture views,
and additionally owns a `Buffer`. This buffer holds data of the type
`ExternalTextureParams`, and will be provided as a uniform buffer to
shaders containing external textures. This contains information that
will be required by the shaders to handle external textures correctly.
Note that attempting to create an external texture will fail unless the
`Feature::EXTERNAL_TEXTURE` feature is enabled, which as of yet is not
supported by any HAL backends.
Additionally add the relevant API to wgpu, implemented for the
wgpu-core backend. The web and custom backends are unimplemented.
[1] https://www.w3.org/TR/webgpu/#gpuexternaltexture
* [naga wgsl-in wgsl-out] WGSL support for texture_external texture type
Make wgsl-in correctly parse `texture_external` texture declarations,
and allow such textures to be used in `textureDimensions()`,
`textureSampleBaseClampToEdge()`, and `textureLoad()` function
calls. In IR these are represented by the `ImageClass::External` image
class, which is a 2D, non-multisampled, non-mipmapped, float-sampled
image.
Adds a new Capability `TEXTURE_EXTERNAL` and ensure validation rejects
shaders containing external textures if this capability flag is not
set. This capability is enabled for validation by wgpu devices which
support the `TEXTURE_EXTERNAL` feature (currently only when using the
noop backend), and by the Naga CLI when validating-only or when
outputting WGSL.
The WGSL backend can of course emit `ImageClass::External` images
directly as `texture_external` textures. Other backends are, for now,
unimplemented.
Lastly, we add a snapshot test covering all the valid uses of a
texture_external texture. These are:
- As a global variable declaration
- As an argument to the built-in functions `textureDimensions()`,
`textureSampleBaseClampToEdge()`, and `textureLoad()`
- As an argument to user-defined function declarations and calls.
We keep these in their own test so that we can control which targets
to run them against (currently WGSL and IR). When external textures
are supported by all Naga backends we can, if so inclined, integrate
these with existing texture tests.
* fixup! [naga wgsl-in wgsl-out] WGSL support for texture_external texture type
* fixup! [naga wgsl-in wgsl-out] WGSL support for texture_external texture type
---------
Co-authored-by: Jim Blandy <jimb@red-bean.com>
* Additional validation of texture copies
* Copies must not overlap.
* Copies of multisampled or depth/stencil formats must span
the entire texture.
* Move no-op for zero-size copies after parameter validation.
Closes#2951Fixes#7844
* Fix issue with combined depth+stencil copy on dx12
* PR feedback