fune/dom/webgpu/CommandEncoder.h
Jim Blandy 2b4ba22045 Bug 1752538: Properly report GPURenderPassDescriptors with too many color attachments. r=jgilbert
The WebGPU spec says that `beginRenderPass` should generate a
validation error if the valid usage rules for
`GPURenderPassDescriptor` are not satisfied. In particular, a
`GPURenderPassDescriptor` may not contain more than eight color
attachments.

The `wgpu-core` crate will panic if a
`wgpu_core::command::RenderPassDescriptor` contains too many color
attachments.  This is safe, but panics are not acceptable in Firefox,
so it falls to our WebGPU implementation to perform the error checks
described by the spec.

Since WebGPU error handling records the first error to occur within
each error scope, the API is sensitive to the order in which errors
are generated. To ensure that the error is properly ordered with
respect to other messages sent to the device, we must send the error
to compositor process. The WebGPUParent will then handle it
interleaved appropriately with other Device timeline activity.

Differential Revision: https://phabricator.services.mozilla.com/D146391
2022-05-17 00:25:35 +00:00

109 lines
3.6 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GPU_CommandEncoder_H_
#define GPU_CommandEncoder_H_
#include "mozilla/dom/TypedArray.h"
#include "mozilla/WeakPtr.h"
#include "mozilla/webgpu/WebGPUTypes.h"
#include "nsWrapperCache.h"
#include "ObjectModel.h"
namespace mozilla {
class ErrorResult;
namespace dom {
struct GPUComputePassDescriptor;
template <typename T>
class Sequence;
struct GPUCommandBufferDescriptor;
class GPUComputePipelineOrGPURenderPipeline;
class RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict;
struct GPUImageCopyBuffer;
struct GPUImageCopyTexture;
struct GPUImageBitmapCopyView;
struct GPUImageDataLayout;
struct GPURenderPassDescriptor;
using GPUExtent3D = RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict;
} // namespace dom
namespace webgpu {
namespace ffi {
struct WGPUComputePass;
struct WGPURenderPass;
struct WGPUImageDataLayout;
struct WGPUImageCopyTexture_TextureId;
struct WGPUExtent3d;
} // namespace ffi
class BindGroup;
class Buffer;
class CanvasContext;
class CommandBuffer;
class ComputePassEncoder;
class Device;
class RenderPassEncoder;
class CommandEncoder final : public ObjectBase, public ChildOf<Device> {
public:
GPU_DECL_CYCLE_COLLECTION(CommandEncoder)
GPU_DECL_JS_WRAP(CommandEncoder)
CommandEncoder(Device* const aParent, WebGPUChild* const aBridge, RawId aId);
const RawId mId;
static void ConvertTextureDataLayoutToFFI(
const dom::GPUImageDataLayout& aLayout,
ffi::WGPUImageDataLayout* aLayoutFFI);
static void ConvertTextureCopyViewToFFI(
const dom::GPUImageCopyTexture& aCopy,
ffi::WGPUImageCopyTexture_TextureId* aViewFFI);
static void ConvertExtent3DToFFI(const dom::GPUExtent3D& aExtent,
ffi::WGPUExtent3d* aExtentFFI);
private:
~CommandEncoder();
void Cleanup();
RefPtr<WebGPUChild> mBridge;
nsTArray<WeakPtr<CanvasContext>> mTargetContexts;
public:
const auto& GetDevice() const { return mParent; };
void EndComputePass(ffi::WGPUComputePass& aPass, ErrorResult& aRv);
void EndRenderPass(ffi::WGPURenderPass& aPass, ErrorResult& aRv);
void CopyBufferToBuffer(const Buffer& aSource, BufferAddress aSourceOffset,
const Buffer& aDestination,
BufferAddress aDestinationOffset,
BufferAddress aSize);
void CopyBufferToTexture(const dom::GPUImageCopyBuffer& aSource,
const dom::GPUImageCopyTexture& aDestination,
const dom::GPUExtent3D& aCopySize);
void CopyTextureToBuffer(const dom::GPUImageCopyTexture& aSource,
const dom::GPUImageCopyBuffer& aDestination,
const dom::GPUExtent3D& aCopySize);
void CopyTextureToTexture(const dom::GPUImageCopyTexture& aSource,
const dom::GPUImageCopyTexture& aDestination,
const dom::GPUExtent3D& aCopySize);
void PushDebugGroup(const nsAString& aString);
void PopDebugGroup();
void InsertDebugMarker(const nsAString& aString);
already_AddRefed<ComputePassEncoder> BeginComputePass(
const dom::GPUComputePassDescriptor& aDesc);
already_AddRefed<RenderPassEncoder> BeginRenderPass(
const dom::GPURenderPassDescriptor& aDesc);
already_AddRefed<CommandBuffer> Finish(
const dom::GPUCommandBufferDescriptor& aDesc);
};
} // namespace webgpu
} // namespace mozilla
#endif // GPU_CommandEncoder_H_