2018-11-30 19:52:05 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2018-06-13 17:43:48 +00:00
|
|
|
/* 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/. */
|
|
|
|
|
2019-12-10 17:07:18 +00:00
|
|
|
#include "js/ArrayBuffer.h"
|
|
|
|
#include "js/Value.h"
|
2023-04-22 04:23:57 +00:00
|
|
|
#include "mozilla/Attributes.h"
|
2020-11-23 16:21:38 +00:00
|
|
|
#include "mozilla/ErrorResult.h"
|
2020-02-24 22:54:54 +00:00
|
|
|
#include "mozilla/Logging.h"
|
2021-07-08 20:24:12 +00:00
|
|
|
#include "mozilla/dom/Promise.h"
|
2020-02-24 20:12:16 +00:00
|
|
|
#include "mozilla/dom/WebGPUBinding.h"
|
2018-06-13 17:43:48 +00:00
|
|
|
#include "Device.h"
|
2020-11-16 19:57:04 +00:00
|
|
|
#include "CommandEncoder.h"
|
|
|
|
#include "BindGroup.h"
|
2018-06-13 17:43:48 +00:00
|
|
|
|
|
|
|
#include "Adapter.h"
|
2020-02-24 20:12:16 +00:00
|
|
|
#include "Buffer.h"
|
2020-03-03 16:37:02 +00:00
|
|
|
#include "ComputePipeline.h"
|
2022-04-27 21:13:21 +00:00
|
|
|
#include "DeviceLostInfo.h"
|
2023-06-16 18:16:28 +00:00
|
|
|
#include "OutOfMemoryError.h"
|
2023-04-12 17:53:50 +00:00
|
|
|
#include "PipelineLayout.h"
|
2020-03-03 16:37:02 +00:00
|
|
|
#include "Queue.h"
|
2021-05-26 20:30:45 +00:00
|
|
|
#include "RenderBundleEncoder.h"
|
2020-03-03 16:37:02 +00:00
|
|
|
#include "RenderPipeline.h"
|
2020-02-24 20:12:16 +00:00
|
|
|
#include "Sampler.h"
|
2021-12-10 01:09:04 +00:00
|
|
|
#include "SupportedFeatures.h"
|
|
|
|
#include "SupportedLimits.h"
|
2020-02-24 20:12:16 +00:00
|
|
|
#include "Texture.h"
|
|
|
|
#include "TextureView.h"
|
2021-07-08 20:24:12 +00:00
|
|
|
#include "ValidationError.h"
|
2019-11-14 04:59:56 +00:00
|
|
|
#include "ipc/WebGPUChild.h"
|
2018-06-13 17:43:48 +00:00
|
|
|
|
2022-05-09 20:41:19 +00:00
|
|
|
namespace mozilla::webgpu {
|
2018-06-13 17:43:48 +00:00
|
|
|
|
2019-12-10 17:07:18 +00:00
|
|
|
mozilla::LazyLogModule gWebGPULog("WebGPU");
|
|
|
|
|
2022-01-25 05:41:40 +00:00
|
|
|
GPU_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_INHERITED(Device, DOMEventTargetHelper,
|
|
|
|
mBridge, mQueue, mFeatures,
|
2022-04-27 21:13:21 +00:00
|
|
|
mLimits, mLostPromise);
|
2019-10-02 16:46:03 +00:00
|
|
|
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(Device, DOMEventTargetHelper)
|
|
|
|
GPU_IMPL_JS_WRAP(Device)
|
2019-10-02 03:04:25 +00:00
|
|
|
|
2020-04-06 22:29:18 +00:00
|
|
|
RefPtr<WebGPUChild> Device::GetBridge() { return mBridge; }
|
|
|
|
|
2021-12-10 01:09:04 +00:00
|
|
|
Device::Device(Adapter* const aParent, RawId aId,
|
2023-06-12 21:10:11 +00:00
|
|
|
const ffi::WGPULimits& aRawLimits)
|
2019-11-14 04:59:56 +00:00
|
|
|
: DOMEventTargetHelper(aParent->GetParentObject()),
|
2020-01-22 07:31:51 +00:00
|
|
|
mId(aId),
|
2021-12-10 01:09:04 +00:00
|
|
|
// features are filled in Adapter::RequestDevice
|
|
|
|
mFeatures(new SupportedFeatures(aParent)),
|
2023-06-12 21:10:11 +00:00
|
|
|
mLimits(new SupportedLimits(aParent, aRawLimits)),
|
2021-12-15 20:31:34 +00:00
|
|
|
mBridge(aParent->mBridge),
|
|
|
|
mQueue(new class Queue(this, aParent->mBridge, aId)) {
|
2022-01-28 00:08:53 +00:00
|
|
|
mBridge->RegisterDevice(this);
|
2020-12-18 20:07:47 +00:00
|
|
|
}
|
2019-11-14 04:59:56 +00:00
|
|
|
|
2020-01-22 07:31:51 +00:00
|
|
|
Device::~Device() { Cleanup(); }
|
|
|
|
|
|
|
|
void Device::Cleanup() {
|
2022-04-27 21:13:21 +00:00
|
|
|
if (!mValid) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mValid = false;
|
|
|
|
|
|
|
|
if (mBridge) {
|
2020-12-18 20:07:47 +00:00
|
|
|
mBridge->UnregisterDevice(mId);
|
2019-11-14 04:59:56 +00:00
|
|
|
}
|
2022-04-27 21:13:21 +00:00
|
|
|
|
2022-07-05 18:03:36 +00:00
|
|
|
// Cycle collection may have disconnected the promise object.
|
|
|
|
if (mLostPromise && mLostPromise->PromiseObj() != nullptr) {
|
2022-04-27 21:13:21 +00:00
|
|
|
auto info = MakeRefPtr<DeviceLostInfo>(GetParentObject(),
|
|
|
|
dom::GPUDeviceLostReason::Destroyed,
|
|
|
|
u"Device destroyed"_ns);
|
|
|
|
mLostPromise->MaybeResolve(info);
|
|
|
|
}
|
2019-11-14 04:59:56 +00:00
|
|
|
}
|
2018-06-13 17:43:48 +00:00
|
|
|
|
2022-01-28 00:08:53 +00:00
|
|
|
void Device::CleanupUnregisteredInParent() {
|
|
|
|
if (mBridge) {
|
|
|
|
mBridge->FreeUnregisteredInParentDevice(mId);
|
|
|
|
}
|
|
|
|
mValid = false;
|
|
|
|
}
|
|
|
|
|
2022-08-10 15:55:05 +00:00
|
|
|
bool Device::IsLost() const { return !mBridge || !mBridge->CanSend(); }
|
|
|
|
|
2022-06-06 06:33:13 +00:00
|
|
|
// Generate an error on the Device timeline for this device.
|
|
|
|
//
|
|
|
|
// aMessage is interpreted as UTF-8.
|
2023-06-14 05:51:00 +00:00
|
|
|
void Device::GenerateValidationError(const nsCString& aMessage) {
|
|
|
|
if (IsLost()) {
|
|
|
|
return; // Just drop it?
|
2022-05-17 00:25:35 +00:00
|
|
|
}
|
2023-06-14 05:51:00 +00:00
|
|
|
mBridge->SendGenerateError(Some(mId), dom::GPUErrorFilter::Validation,
|
|
|
|
aMessage);
|
2022-05-17 00:25:35 +00:00
|
|
|
}
|
|
|
|
|
2019-10-02 16:46:03 +00:00
|
|
|
void Device::GetLabel(nsAString& aValue) const { aValue = mLabel; }
|
|
|
|
void Device::SetLabel(const nsAString& aLabel) { mLabel = aLabel; }
|
2018-06-13 17:43:48 +00:00
|
|
|
|
2022-04-27 21:13:21 +00:00
|
|
|
dom::Promise* Device::GetLost(ErrorResult& aRv) {
|
|
|
|
if (!mLostPromise) {
|
|
|
|
mLostPromise = dom::Promise::Create(GetParentObject(), aRv);
|
|
|
|
if (mLostPromise && !mBridge->CanSend()) {
|
|
|
|
auto info = MakeRefPtr<DeviceLostInfo>(GetParentObject(),
|
|
|
|
u"WebGPUChild destroyed"_ns);
|
|
|
|
mLostPromise->MaybeResolve(info);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return mLostPromise;
|
|
|
|
}
|
|
|
|
|
2019-12-10 17:07:18 +00:00
|
|
|
already_AddRefed<Buffer> Device::CreateBuffer(
|
2020-10-19 17:19:12 +00:00
|
|
|
const dom::GPUBufferDescriptor& aDesc, ErrorResult& aRv) {
|
2022-08-10 15:55:05 +00:00
|
|
|
return Buffer::Create(this, mId, aDesc, aRv);
|
2022-08-10 12:04:12 +00:00
|
|
|
}
|
|
|
|
|
2020-02-24 20:12:16 +00:00
|
|
|
already_AddRefed<Texture> Device::CreateTexture(
|
|
|
|
const dom::GPUTextureDescriptor& aDesc) {
|
2022-04-27 21:13:21 +00:00
|
|
|
RawId id = 0;
|
|
|
|
if (mBridge->CanSend()) {
|
|
|
|
id = mBridge->DeviceCreateTexture(mId, aDesc);
|
|
|
|
}
|
2020-02-24 20:12:16 +00:00
|
|
|
RefPtr<Texture> texture = new Texture(this, id, aDesc);
|
|
|
|
return texture.forget();
|
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<Sampler> Device::CreateSampler(
|
|
|
|
const dom::GPUSamplerDescriptor& aDesc) {
|
2022-04-27 21:13:21 +00:00
|
|
|
RawId id = 0;
|
|
|
|
if (mBridge->CanSend()) {
|
|
|
|
id = mBridge->DeviceCreateSampler(mId, aDesc);
|
|
|
|
}
|
2020-02-24 20:12:16 +00:00
|
|
|
RefPtr<Sampler> sampler = new Sampler(this, id);
|
|
|
|
return sampler.forget();
|
|
|
|
}
|
|
|
|
|
2020-01-22 07:31:51 +00:00
|
|
|
already_AddRefed<CommandEncoder> Device::CreateCommandEncoder(
|
|
|
|
const dom::GPUCommandEncoderDescriptor& aDesc) {
|
2022-04-27 21:13:21 +00:00
|
|
|
RawId id = 0;
|
|
|
|
if (mBridge->CanSend()) {
|
|
|
|
id = mBridge->DeviceCreateCommandEncoder(mId, aDesc);
|
|
|
|
}
|
2020-01-22 07:31:51 +00:00
|
|
|
RefPtr<CommandEncoder> encoder = new CommandEncoder(this, mBridge, id);
|
|
|
|
return encoder.forget();
|
|
|
|
}
|
|
|
|
|
2021-05-26 20:30:45 +00:00
|
|
|
already_AddRefed<RenderBundleEncoder> Device::CreateRenderBundleEncoder(
|
|
|
|
const dom::GPURenderBundleEncoderDescriptor& aDesc) {
|
|
|
|
RefPtr<RenderBundleEncoder> encoder =
|
|
|
|
new RenderBundleEncoder(this, mBridge, aDesc);
|
|
|
|
return encoder.forget();
|
|
|
|
}
|
|
|
|
|
2020-01-24 16:27:09 +00:00
|
|
|
already_AddRefed<BindGroupLayout> Device::CreateBindGroupLayout(
|
|
|
|
const dom::GPUBindGroupLayoutDescriptor& aDesc) {
|
2022-04-27 21:13:21 +00:00
|
|
|
RawId id = 0;
|
|
|
|
if (mBridge->CanSend()) {
|
|
|
|
id = mBridge->DeviceCreateBindGroupLayout(mId, aDesc);
|
|
|
|
}
|
2021-05-18 16:26:27 +00:00
|
|
|
RefPtr<BindGroupLayout> object = new BindGroupLayout(this, id, true);
|
2020-01-24 16:27:09 +00:00
|
|
|
return object.forget();
|
|
|
|
}
|
|
|
|
already_AddRefed<PipelineLayout> Device::CreatePipelineLayout(
|
|
|
|
const dom::GPUPipelineLayoutDescriptor& aDesc) {
|
2022-04-27 21:13:21 +00:00
|
|
|
RawId id = 0;
|
|
|
|
if (mBridge->CanSend()) {
|
|
|
|
id = mBridge->DeviceCreatePipelineLayout(mId, aDesc);
|
|
|
|
}
|
2020-01-24 16:27:09 +00:00
|
|
|
RefPtr<PipelineLayout> object = new PipelineLayout(this, id);
|
|
|
|
return object.forget();
|
|
|
|
}
|
|
|
|
already_AddRefed<BindGroup> Device::CreateBindGroup(
|
|
|
|
const dom::GPUBindGroupDescriptor& aDesc) {
|
2022-04-27 21:13:21 +00:00
|
|
|
RawId id = 0;
|
|
|
|
if (mBridge->CanSend()) {
|
|
|
|
id = mBridge->DeviceCreateBindGroup(mId, aDesc);
|
|
|
|
}
|
2020-01-24 16:27:09 +00:00
|
|
|
RefPtr<BindGroup> object = new BindGroup(this, id);
|
|
|
|
return object.forget();
|
2020-01-24 05:05:34 +00:00
|
|
|
}
|
|
|
|
|
2023-04-22 04:23:57 +00:00
|
|
|
MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION already_AddRefed<ShaderModule>
|
|
|
|
Device::CreateShaderModule(JSContext* aCx,
|
|
|
|
const dom::GPUShaderModuleDescriptor& aDesc) {
|
2021-03-04 21:25:46 +00:00
|
|
|
Unused << aCx;
|
2022-07-08 08:11:39 +00:00
|
|
|
|
|
|
|
if (!mBridge->CanSend()) {
|
|
|
|
return nullptr;
|
2022-07-07 14:35:28 +00:00
|
|
|
}
|
2022-07-08 08:11:39 +00:00
|
|
|
|
|
|
|
ErrorResult err;
|
|
|
|
RefPtr<dom::Promise> promise = dom::Promise::Create(GetParentObject(), err);
|
|
|
|
if (NS_WARN_IF(err.Failed())) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2023-06-05 16:47:54 +00:00
|
|
|
return MOZ_KnownLive(mBridge)->DeviceCreateShaderModule(this, aDesc, promise);
|
2020-01-24 16:27:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<ComputePipeline> Device::CreateComputePipeline(
|
|
|
|
const dom::GPUComputePipelineDescriptor& aDesc) {
|
2022-01-22 15:53:47 +00:00
|
|
|
PipelineCreationContext context = {mId};
|
2022-04-27 21:13:21 +00:00
|
|
|
RawId id = 0;
|
|
|
|
if (mBridge->CanSend()) {
|
|
|
|
id = mBridge->DeviceCreateComputePipeline(&context, aDesc);
|
|
|
|
}
|
2020-11-13 14:15:49 +00:00
|
|
|
RefPtr<ComputePipeline> object =
|
2022-01-22 15:53:47 +00:00
|
|
|
new ComputePipeline(this, id, context.mImplicitPipelineLayoutId,
|
|
|
|
std::move(context.mImplicitBindGroupLayoutIds));
|
2020-01-24 16:27:09 +00:00
|
|
|
return object.forget();
|
2019-12-10 17:07:18 +00:00
|
|
|
}
|
|
|
|
|
2020-03-03 16:37:02 +00:00
|
|
|
already_AddRefed<RenderPipeline> Device::CreateRenderPipeline(
|
|
|
|
const dom::GPURenderPipelineDescriptor& aDesc) {
|
2022-01-22 15:53:47 +00:00
|
|
|
PipelineCreationContext context = {mId};
|
2022-04-27 21:13:21 +00:00
|
|
|
RawId id = 0;
|
|
|
|
if (mBridge->CanSend()) {
|
|
|
|
id = mBridge->DeviceCreateRenderPipeline(&context, aDesc);
|
|
|
|
}
|
2020-11-13 14:15:49 +00:00
|
|
|
RefPtr<RenderPipeline> object =
|
2022-01-22 15:53:47 +00:00
|
|
|
new RenderPipeline(this, id, context.mImplicitPipelineLayoutId,
|
|
|
|
std::move(context.mImplicitBindGroupLayoutIds));
|
2020-03-03 16:37:02 +00:00
|
|
|
return object.forget();
|
|
|
|
}
|
|
|
|
|
2022-01-22 15:53:47 +00:00
|
|
|
already_AddRefed<dom::Promise> Device::CreateComputePipelineAsync(
|
|
|
|
const dom::GPUComputePipelineDescriptor& aDesc, ErrorResult& aRv) {
|
|
|
|
RefPtr<dom::Promise> promise = dom::Promise::Create(GetParentObject(), aRv);
|
|
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2022-04-27 21:13:21 +00:00
|
|
|
if (!mBridge->CanSend()) {
|
|
|
|
promise->MaybeRejectWithOperationError("Internal communication error");
|
|
|
|
return promise.forget();
|
|
|
|
}
|
|
|
|
|
2022-01-22 15:53:47 +00:00
|
|
|
std::shared_ptr<PipelineCreationContext> context(
|
|
|
|
new PipelineCreationContext());
|
|
|
|
context->mParentId = mId;
|
|
|
|
mBridge->DeviceCreateComputePipelineAsync(context.get(), aDesc)
|
|
|
|
->Then(
|
2022-02-09 22:01:48 +00:00
|
|
|
GetCurrentSerialEventTarget(), __func__,
|
2022-01-22 15:53:47 +00:00
|
|
|
[self = RefPtr{this}, context, promise](RawId aId) {
|
|
|
|
RefPtr<ComputePipeline> object = new ComputePipeline(
|
|
|
|
self, aId, context->mImplicitPipelineLayoutId,
|
|
|
|
std::move(context->mImplicitBindGroupLayoutIds));
|
|
|
|
promise->MaybeResolve(object);
|
|
|
|
},
|
|
|
|
[promise](const ipc::ResponseRejectReason&) {
|
|
|
|
promise->MaybeRejectWithOperationError(
|
|
|
|
"Internal communication error");
|
|
|
|
});
|
|
|
|
|
|
|
|
return promise.forget();
|
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<dom::Promise> Device::CreateRenderPipelineAsync(
|
|
|
|
const dom::GPURenderPipelineDescriptor& aDesc, ErrorResult& aRv) {
|
|
|
|
RefPtr<dom::Promise> promise = dom::Promise::Create(GetParentObject(), aRv);
|
|
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2022-04-27 21:13:21 +00:00
|
|
|
if (!mBridge->CanSend()) {
|
|
|
|
promise->MaybeRejectWithOperationError("Internal communication error");
|
|
|
|
return promise.forget();
|
|
|
|
}
|
|
|
|
|
2022-01-22 15:53:47 +00:00
|
|
|
std::shared_ptr<PipelineCreationContext> context(
|
|
|
|
new PipelineCreationContext());
|
|
|
|
context->mParentId = mId;
|
|
|
|
mBridge->DeviceCreateRenderPipelineAsync(context.get(), aDesc)
|
|
|
|
->Then(
|
2022-02-09 22:01:48 +00:00
|
|
|
GetCurrentSerialEventTarget(), __func__,
|
2022-01-22 15:53:47 +00:00
|
|
|
[self = RefPtr{this}, context, promise](RawId aId) {
|
|
|
|
RefPtr<RenderPipeline> object = new RenderPipeline(
|
|
|
|
self, aId, context->mImplicitPipelineLayoutId,
|
|
|
|
std::move(context->mImplicitBindGroupLayoutIds));
|
|
|
|
promise->MaybeResolve(object);
|
|
|
|
},
|
|
|
|
[promise](const ipc::ResponseRejectReason&) {
|
|
|
|
promise->MaybeRejectWithOperationError(
|
|
|
|
"Internal communication error");
|
|
|
|
});
|
|
|
|
|
|
|
|
return promise.forget();
|
|
|
|
}
|
|
|
|
|
2020-04-06 22:29:18 +00:00
|
|
|
already_AddRefed<Texture> Device::InitSwapChain(
|
2021-08-18 14:11:21 +00:00
|
|
|
const dom::GPUCanvasConfiguration& aDesc,
|
2022-12-23 20:41:02 +00:00
|
|
|
const layers::RemoteTextureOwnerId aOwnerId, gfx::SurfaceFormat aFormat,
|
2023-02-01 18:32:31 +00:00
|
|
|
gfx::IntSize aCanvasSize) {
|
2022-04-27 21:13:21 +00:00
|
|
|
if (!mBridge->CanSend()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2023-02-01 18:32:31 +00:00
|
|
|
const layers::RGBDescriptor rgbDesc(aCanvasSize, aFormat);
|
2020-04-06 22:29:18 +00:00
|
|
|
// buffer count doesn't matter much, will be created on demand
|
|
|
|
const size_t maxBufferCount = 10;
|
2022-12-23 20:41:02 +00:00
|
|
|
mBridge->DeviceCreateSwapChain(mId, rgbDesc, maxBufferCount, aOwnerId);
|
2020-04-06 22:29:18 +00:00
|
|
|
|
|
|
|
dom::GPUTextureDescriptor desc;
|
|
|
|
desc.mDimension = dom::GPUTextureDimension::_2d;
|
2021-08-18 14:11:21 +00:00
|
|
|
auto& sizeDict = desc.mSize.SetAsGPUExtent3DDict();
|
2023-02-01 18:32:31 +00:00
|
|
|
sizeDict.mWidth = aCanvasSize.width;
|
|
|
|
sizeDict.mHeight = aCanvasSize.height;
|
2021-08-18 14:11:21 +00:00
|
|
|
sizeDict.mDepthOrArrayLayers = 1;
|
2020-04-06 22:29:18 +00:00
|
|
|
desc.mFormat = aDesc.mFormat;
|
|
|
|
desc.mMipLevelCount = 1;
|
|
|
|
desc.mSampleCount = 1;
|
|
|
|
desc.mUsage = aDesc.mUsage | dom::GPUTextureUsage_Binding::COPY_SRC;
|
2023-06-15 21:22:53 +00:00
|
|
|
desc.mViewFormats = aDesc.mViewFormats;
|
2020-04-06 22:29:18 +00:00
|
|
|
return CreateTexture(desc);
|
|
|
|
}
|
|
|
|
|
2021-11-29 21:57:04 +00:00
|
|
|
bool Device::CheckNewWarning(const nsACString& aMessage) {
|
|
|
|
return mKnownWarnings.EnsureInserted(aMessage);
|
|
|
|
}
|
|
|
|
|
2021-03-04 21:25:46 +00:00
|
|
|
void Device::Destroy() {
|
|
|
|
// TODO
|
|
|
|
}
|
|
|
|
|
2021-07-08 20:24:12 +00:00
|
|
|
void Device::PushErrorScope(const dom::GPUErrorFilter& aFilter) {
|
2023-06-14 05:51:00 +00:00
|
|
|
if (IsLost()) {
|
|
|
|
return;
|
2022-04-27 21:13:21 +00:00
|
|
|
}
|
2023-06-14 05:51:00 +00:00
|
|
|
mBridge->SendDevicePushErrorScope(mId, aFilter);
|
2021-07-08 20:24:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<dom::Promise> Device::PopErrorScope(ErrorResult& aRv) {
|
2023-06-14 05:51:00 +00:00
|
|
|
/*
|
|
|
|
https://www.w3.org/TR/webgpu/#errors-and-debugging:
|
|
|
|
> After a device is lost (described below), errors are no longer surfaced.
|
|
|
|
> At this point, implementations do not need to run validation or error
|
|
|
|
tracking: > popErrorScope() and uncapturederror stop reporting errors, > and
|
|
|
|
the validity of objects on the device becomes unobservable.
|
|
|
|
*/
|
2021-07-08 20:24:12 +00:00
|
|
|
RefPtr<dom::Promise> promise = dom::Promise::Create(GetParentObject(), aRv);
|
|
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2023-06-14 05:51:00 +00:00
|
|
|
if (IsLost()) {
|
|
|
|
WebGPUChild::JsWarning(
|
|
|
|
GetOwnerGlobal(),
|
|
|
|
"popErrorScope resolving to null because device is already lost."_ns);
|
|
|
|
promise->MaybeResolve(JS::NullHandleValue);
|
2022-04-27 21:13:21 +00:00
|
|
|
return promise.forget();
|
|
|
|
}
|
|
|
|
|
2021-07-08 20:24:12 +00:00
|
|
|
auto errorPromise = mBridge->SendDevicePopErrorScope(mId);
|
|
|
|
|
|
|
|
errorPromise->Then(
|
2022-02-09 22:01:48 +00:00
|
|
|
GetCurrentSerialEventTarget(), __func__,
|
2023-06-14 05:51:00 +00:00
|
|
|
[self = RefPtr{this}, promise](const PopErrorScopeResult& aResult) {
|
|
|
|
dom::OwningGPUOutOfMemoryErrorOrGPUValidationError error;
|
|
|
|
|
|
|
|
switch (aResult.resultType) {
|
|
|
|
case PopErrorScopeResultType::NoError:
|
|
|
|
promise->MaybeResolve(JS::NullHandleValue);
|
|
|
|
return;
|
|
|
|
|
|
|
|
case PopErrorScopeResultType::DeviceLost:
|
|
|
|
WebGPUChild::JsWarning(
|
|
|
|
self->GetOwnerGlobal(),
|
|
|
|
"popErrorScope resolving to null because device was lost."_ns);
|
|
|
|
promise->MaybeResolve(JS::NullHandleValue);
|
|
|
|
return;
|
|
|
|
|
|
|
|
case PopErrorScopeResultType::ThrowOperationError:
|
|
|
|
promise->MaybeRejectWithOperationError(aResult.message);
|
|
|
|
return;
|
|
|
|
|
|
|
|
case PopErrorScopeResultType::OutOfMemory:
|
2023-06-16 18:16:28 +00:00
|
|
|
error.SetAsGPUOutOfMemoryError() = new OutOfMemoryError(self);
|
2023-06-14 05:51:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PopErrorScopeResultType::ValidationError:
|
|
|
|
error.SetAsGPUValidationError() =
|
|
|
|
new ValidationError(self->GetParentObject(), aResult.message);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PopErrorScopeResultType::InternalError:
|
|
|
|
MOZ_CRASH("TODO");
|
|
|
|
/*
|
|
|
|
error.SetAsGPUInternalError() = new InternalError(
|
|
|
|
self->GetParentObject(), aResult.message);
|
|
|
|
break;
|
|
|
|
*/
|
2021-07-08 20:24:12 +00:00
|
|
|
}
|
2023-06-14 05:51:00 +00:00
|
|
|
promise->MaybeResolve(std::move(error));
|
2021-07-08 20:24:12 +00:00
|
|
|
},
|
2023-06-14 05:51:00 +00:00
|
|
|
[self = RefPtr{this}, promise](const ipc::ResponseRejectReason&) {
|
|
|
|
// Device was lost.
|
|
|
|
WebGPUChild::JsWarning(
|
|
|
|
self->GetOwnerGlobal(),
|
|
|
|
"popErrorScope resolving to null because device was just lost."_ns);
|
|
|
|
promise->MaybeResolve(JS::NullHandleValue);
|
2021-07-08 20:24:12 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
return promise.forget();
|
|
|
|
}
|
|
|
|
|
2022-05-09 20:41:19 +00:00
|
|
|
} // namespace mozilla::webgpu
|