It is replaced by a standard-conforming cast to (void) which is
understood the same by the compiler.
In some cases this could be replaced by `[[maybe_unused]]` but for
expression whose value is ignored, this requires storing to a temporary
variable first, so not going that way.
One notable change is that marking an object of type already_AddRefed as
unused used to implicitly leak memory. This is now made explicit.
Most of the heavy lifting was done through:
$ git grep -l '\<Unused\> <<' | xargs sed -i -e 's/Unused << /(void)/g'
$ git grep -l mozilla/Unused.h | xargs sed -i -e '/mozilla\/Unused.h/ d'
Differential Revision: https://phabricator.services.mozilla.com/D268706
It is replaced by a standard-conforming cast to (void) which is
understood the same by the compiler.
In some cases this could be replaced by `[[maybe_unused]]` but for
expression whose value is ignored, this requires storing to a temporary
variable first, so not going that way.
One notable change is that marking an object of type already_AddRefed as
unused used to implicitly leak memory. This is now made explicit.
Most of the heavy lifting was done through:
$ git grep -l '\<Unused\> <<' | xargs sed -i -e 's/Unused << /(void)/g'
$ git grep -l mozilla/Unused.h | xargs sed -i -e '/mozilla\/Unused.h/ d'
Differential Revision: https://phabricator.services.mozilla.com/D268706
It is replaced by a standard-conforming cast to (void) which is
understood the same by the compiler.
In some cases this could be replaced by `[[maybe_unused]]` but for
expression whose value is ignored, this requires storing to a temporary
variable first, so not going that way.
One notable change is that marking an object of type already_AddRefed as
unused used to implicitly leak memory. This is now made explicit.
Most of the heavy lifting was done through:
$ git grep -l '\<Unused\> <<' | xargs sed -i -e 's/Unused << /(void)/g'
$ git grep -l mozilla/Unused.h | xargs sed -i -e '/mozilla\/Unused.h/ d'
Differential Revision: https://phabricator.services.mozilla.com/D268706
It is replaced by a standard-conforming cast to (void) which is
understood the same by the compiler.
In some cases this could be replaced by `[[maybe_unused]]` but for
expression whose value is ignored, this requires storing to a temporary
variable first, so not going that way.
One notable change is that marking an object of type already_AddRefed as
unused used to implicitly leak memory. This is now made explicit.
Most of the heavy lifting was done through:
$ git grep -l '\<Unused\> <<' | xargs sed -i -e 's/Unused << /(void)/g'
$ git grep -l mozilla/Unused.h | xargs sed -i -e '/mozilla\/Unused.h/ d'
Differential Revision: https://phabricator.services.mozilla.com/D268706
In `mozilla::webgpu::ExternalTextureSourceHost::Create`, when the data
is received as a `SurfaceDescriptorBuffer`, simply fetch the address
directly from the `Shmem`; don't call `GetAddressFromDescriptor`.
Differential Revision: https://phabricator.services.mozilla.com/D268286
When importing an external texture in the content process, call
BuildSurfaceDescriptorGPUVideoOrBuffer() instead of
BuildSurfaceDescriptorBuffer(), in order to avoid a readback of GPUVideo
images into a shmem.
In the GPU process, handle GPUVideo surface descriptors. For Tnull_t, if
the remote texture host is a BufferTextureHost we can use the existing
CreateFromBufferDesc() path to create the required wgpu textures. For
TSurfaceDescriptorD3D10 and TSurfaceDescriptorDXGIYCbCr we add new paths
to import the textures directly into wgpu via their shared
handles. SurfaceDescriptorDXGIYCbCr always requires 3 textures and
views: for Y, Cb, and Cr planes respectively. SurfaceDescriptorD3D10 can
come in a variety of formats, which we attempt to handle.
If a CompositeProcessFencesHolderId is provided we must ensure we wait
on the appropriate write fence prior to reading from the texture. To
ensure this occurs, we make the ExternalTextureSourceHost hold on to its
fences holder ID. When submitting command buffers, we pass the list of
used external texture sources to the host side, then on the host side
for each source we call OnBeforeQueueSubmit(). This obtains the write
fence's shared handle and the value which must be waited for from the
CompositeProcessD3D11FencesHolderMap, then imports the fence from the
shared handle and inserts a wait for the specified value into the
command queue.
If available, we request wgpu's TEXTURE_FORMAT_NV12,
TEXTURE_FORMAT_P010, and TEXTURE_FORMAT_16BIT_NORM features. The first
is required for NV12 format textures, and the latter 2 are required for
P010. If unavailable, we will gracefully fail to create these textures
but other content will continue to work. It would be surprising,
however, if the decoder were to provide us with textures in these
formats when they are not supported.
Differential Revision: https://phabricator.services.mozilla.com/D261424
When importing an external texture in the content process, call
BuildSurfaceDescriptorGPUVideoOrBuffer() instead of
BuildSurfaceDescriptorBuffer(), in order to avoid a readback of GPUVideo
images into a shmem.
In the GPU process, handle GPUVideo surface descriptors. For Tnull_t, if
the remote texture host is a BufferTextureHost we can use the existing
CreateFromBufferDesc() path to create the required wgpu textures. For
TSurfaceDescriptorD3D10 and TSurfaceDescriptorDXGIYCbCr we add new paths
to import the textures directly into wgpu via their shared
handles. SurfaceDescriptorDXGIYCbCr always requires 3 textures and
views: for Y, Cb, and Cr planes respectively. SurfaceDescriptorD3D10 can
come in a variety of formats, which we attempt to handle.
If a CompositeProcessFencesHolderId is provided we must ensure we wait
on the appropriate write fence prior to reading from the texture. To
ensure this occurs, we make the ExternalTextureSourceHost hold on to its
fences holder ID. When submitting command buffers, we pass the list of
used external texture sources to the host side, then on the host side
for each source we call OnBeforeQueueSubmit(). This obtains the write
fence's shared handle and the value which must be waited for from the
CompositeProcessD3D11FencesHolderMap, then imports the fence from the
shared handle and inserts a wait for the specified value into the
command queue.
If available, we request wgpu's TEXTURE_FORMAT_NV12,
TEXTURE_FORMAT_P010, and TEXTURE_FORMAT_16BIT_NORM features. The first
is required for NV12 format textures, and the latter 2 are required for
P010. If unavailable, we will gracefully fail to create these textures
but other content will continue to work. It would be surprising,
however, if the decoder were to provide us with textures in these
formats when they are not supported.
Differential Revision: https://phabricator.services.mozilla.com/D261424
The WebGPU spec allows us to return a previously imported external
texture from `importExternalTexture()` when provided with the same
descriptor (ignoring the label), as long as the current image contents
of the source is the same. For applications that import a large number
of external textures from the same source, this can be a significant
performance improvement.
This implementation maintains a cache of imported external texture
sources, keyed by the "serial" of the layers::Image they were imported
from. Additionally, each source maintains a cache of external textures
that have been created from it. This is keyed by the contents of their
descriptor, ignoring the label (as per the spec) and the "source" (as
the cache is owned by the source) leaving just the color space.
Using these two separate levels of cache means that we not only create
a single single external texture for multiple imports with the same
descriptor, but when importing from the same source with an otherwise
different descriptor we are still able to share the underlying plane
textures.
Differential Revision: https://phabricator.services.mozilla.com/D260827
And then eagerly destroy external textures and external texture sources
when possible.
We must retain a reference to the layers::Image from which an external
texture source was imported as long as any work involving external
textures created from that source is outstanding. This prevents the
decoder from attempting to recycle the underlying resource too early,
e.g. decoding a future video frame into the texture while wgpu is still
to render the previous frame.
On the other hand, we don't want to hold on to resources longer than
required in order to prevent excess memory usage.
For each external texture, keep track of submission index at which work
involving the external texture was last submitted, and the index of the
last such submission whose work has since completed. When all submitted
work for an external texture has completed, and the external texture
has been expired, eagerly destroy the external texture.
Additionally, when the external texture is destroyed also release its
reference to the external texture source. This means the source will
itself be destroyed as soon as there are no more live external textures
that were created from it. When the source is destroyed the last
reference to the layes::Image will be dropped, indicating to the
decoder that it can reuse the underlying resources.
Differential Revision: https://phabricator.services.mozilla.com/D260826
ExternalTextures imported from HTMLVideoElements get "expired" in the
"automatic expiry task source", which is implemented by scheduling a
stable state task. ExternalTextures imported from VideoFrames get
expired when the VideoFrame is closed.
Keep track of each external texture used by any used bind group when
encoding compute and render passes. When submitting, if any passes
contain expired external textures then raise a validation error.
Currently we always create a new ExternalTexture when
importExternalTexture() is called. When support for reusing previously
imported textures is added, we must ensure they are correctly
"unexpired".
Differential Revision: https://phabricator.services.mozilla.com/D260295
First we create an ExternalTextureSource using the infrastructure added
in the previous patch, and from that we create an ExternalTexture.
In order to create the external texture the client side passes an
`ExternalTextureDescriptor` to the host side, which encodes the
source as a optional ID. On the host side additional information is
queried from the ExternalTextureSourceHost, which is combined with the
`ExternalTextureDescriptor` provided by the client in order to call
wgpu's create_external_texture().
If there was an error importing the source on the client side the
source ID will be `None`. If there was an error importing the source
on the host side, it will return an empty slice of texture views as its
planes. In either case this indicates we should propagate the error
state to the external texture.
Subsequent patches will allow for creating multiple external textures
from the same source, and returning previously imported external
textures rather than always creating a new one.
Note that for now we have not requested Features::EXTERNAL_TEXTURE when
creating the wgpu device, meaning that any attempts to actually create
an external texture will result in an error.
Differential Revision: https://phabricator.services.mozilla.com/D259820
In order to support webgpu's GPUExternalTexture we must first be able
to import video frames into wgpu. To do so we introduce the concept of
an external texture "source". This consists of between 1 and 3
textures and texture views, in order to support single-plane RGBA or
multiplanar YCbCr data. The source is implemented as a distinct
concept from the external texture itself so that multiple external
textures can be created from the same source.
An external texture source has both a client-side and host-side
representation. The client side is responsible for managing the
lifecycle of the host side. It obtains a SurfaceDescriptor from the
current layers::Image of the video element or frame it was imported
from, and sends this to the host side. The host side is responsible
for creating the wgpu Textures and TextureViews it needs from the
SurfaceDescriptor. It also holds various pieces of information derived
from the imported frames that will be required to construct the
wgpu::ExternalTextureDescriptor required to create a
wgpu::ExternalTexture.
For now, we always call Image::BuildSurfaceDescriptorBuffer to obtain
the surface descriptor, and therefore only have to handle
SurfaceDescriptorBuffers. In subsequent patches we will handle
GPUVideo surface descriptors to directly import hardware decoded video
frames without requiring a readback.
Differential Revision: https://phabricator.services.mozilla.com/D259819
First we create an ExternalTextureSource using the infrastructure added
in the previous patch, and from that we create an ExternalTexture.
In order to create the external texture the client side passes an
`ExternalTextureDescriptor` to the host side, which encodes the
source as a optional ID. On the host side additional information is
queried from the ExternalTextureSourceHost, which is combined with the
`ExternalTextureDescriptor` provided by the client in order to call
wgpu's create_external_texture().
If there was an error importing the source on the client side the
source ID will be `None`. If there was an error importing the source
on the host side, it will return an empty slice of texture views as its
planes. In either case this indicates we should propagate the error
state to the external texture.
Subsequent patches will allow for creating multiple external textures
from the same source, and returning previously imported external
textures rather than always creating a new one.
Note that for now we have not requested Features::EXTERNAL_TEXTURE when
creating the wgpu device, meaning that any attempts to actually create
an external texture will result in an error.
Differential Revision: https://phabricator.services.mozilla.com/D259820
In order to support webgpu's GPUExternalTexture we must first be able
to import video frames into wgpu. To do so we introduce the concept of
an external texture "source". This consists of between 1 and 3
textures and texture views, in order to support single-plane RGBA or
multiplanar YCbCr data. The source is implemented as a distinct
concept from the external texture itself so that multiple external
textures can be created from the same source.
An external texture source has both a client-side and host-side
representation. The client side is responsible for managing the
lifecycle of the host side. It obtains a SurfaceDescriptor from the
current layers::Image of the video element or frame it was imported
from, and sends this to the host side. The host side is responsible
for creating the wgpu Textures and TextureViews it needs from the
SurfaceDescriptor. It also holds various pieces of information derived
from the imported frames that will be required to construct the
wgpu::ExternalTextureDescriptor required to create a
wgpu::ExternalTexture.
For now, we always call Image::BuildSurfaceDescriptorBuffer to obtain
the surface descriptor, and therefore only have to handle
SurfaceDescriptorBuffers. In subsequent patches we will handle
GPUVideo surface descriptors to directly import hardware decoded video
frames without requiring a readback.
Differential Revision: https://phabricator.services.mozilla.com/D259819
Now that the previous patch has renamed ExternalTexture to
SharedTexture, we can rename our (currently just a stub)
implementation of webgpu's GPUExternalTexture to ExternalTexture.
Differential Revision: https://phabricator.services.mozilla.com/D255977
An ExternalTexture is a texture that is created and owned by gecko,
but shared with the webgpu implementation. It is used for webgpu
presentation. While this name describes the class well, it is
confusing due to webgpu having an entirely unrelated concept of
GPUExternalTexture.
This patch renames ExternalTexture, and all of its subclasses and
uses, to SharedTexture. This still describes the purpose accurately,
and has similarities to gl::SharedSurface which serves a similar
purpose for our webgl implementation.
Differential Revision: https://phabricator.services.mozilla.com/D255976
Now that the previous patch has renamed ExternalTexture to
SharedTexture, we can rename our (currently just a stub)
implementation of webgpu's GPUExternalTexture to ExternalTexture.
Differential Revision: https://phabricator.services.mozilla.com/D255977
An ExternalTexture is a texture that is created and owned by gecko,
but shared with the webgpu implementation. It is used for webgpu
presentation. While this name describes the class well, it is
confusing due to webgpu having an entirely unrelated concept of
GPUExternalTexture.
This patch renames ExternalTexture, and all of its subclasses and
uses, to SharedTexture. This still describes the purpose accurately,
and has similarities to gl::SharedSurface which serves a similar
purpose for our webgl implementation.
Differential Revision: https://phabricator.services.mozilla.com/D255976
Remove FenceInfo. Instead use GpuProcessFencesHolderId and GpuProcessD3D11FencesHolderMap.
GpuProcessD3D11FencesHolderMap is changed to instantiate also in Parent process when GPU process does not exist. Then it seems better to change its name. The name change is going to be handled in Bug 1958752.
Differential Revision: https://phabricator.services.mozilla.com/D244539
Do this by populating a trivial `ExtTex` type in `ExternalTexture.h`. Do not use `ExternalTexture`, since that's currently used by the internals that actually implement interesting operations for external texture usage with WGPU; punt on figuring out the perfect name for later.
This allows many CTS tests, which use `x instanceof GPUExternalTexture` without actually consuming the external texture API, to make interesting forward progress.
This should be strictly safe to do, since we do not permit the user to actually construct or use a `GPUExternalTexture`.
Analysis of CTS outcome changes:
- New `PASS`es resulting in promotion to tier 2:
- `webgpu:shader,execution,expression,call,builtin,textureDimensions:depth:*`
- `webgpu:shader,execution,expression,call,builtin,textureDimensions:sampled_and_multisampled:*` on Linux and macOS
- `webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_1d:*` on Windows and Linux
- `webgpu:shader,execution,expression,call,builtin,textureLoad:sampled_3d:*` on Windows and Linux
- `webgpu:shader,execution,expression,call,builtin,textureNumLayers:arrayed:*` on Linux and macOS
- `webgpu:shader,execution,expression,call,builtin,textureNumLayers:sampled:*` on Linux and macOS
- `webgpu:shader,execution,expression,call,builtin,textureNumLevels:depth:*`
- `webgpu:shader,execution,expression,call,builtin,textureNumLevels:sampled:*` on Linux and macOS
- `webgpu:shader,execution,expression,call,builtin,textureNumSamples:depth:*`
- `webgpu:shader,execution,expression,call,builtin,textureNumSamples:sampled:*`
- `webgpu:shader,execution,expression,call,builtin,textureSample:sampled_1d_coords:*` on Windows and Linux
Otherwise are _many_ new `PASS`es in test variants that don't quite make entire test(s) pass, so this is definitely a good change. 🙂
- Some tests' variants have been deleted, since they are no longer reported due to _all_ runs of them `CRASH`ing due to timeout (rather than a stack crash). This will be dealt with in follow-up work. Since these tests are in tier 3, I don't see a hard problem with letting these be deleted for now.
Differential Revision: https://phabricator.services.mozilla.com/D240673