зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1751718 - Reject WebGPU device promise on wrong features and limits r=jimb
Differential Revision: https://phabricator.services.mozilla.com/D136770
This commit is contained in:
Родитель
377caf35ba
Коммит
e7c5d38a9a
|
@ -86,10 +86,10 @@ already_AddRefed<dom::Promise> Adapter::RequestDevice(
|
||||||
}
|
}
|
||||||
|
|
||||||
ffi::WGPULimits limits = {};
|
ffi::WGPULimits limits = {};
|
||||||
Maybe<RawId> id = mBridge->AdapterRequestDevice(mId, aDesc, &limits);
|
auto request = mBridge->AdapterRequestDevice(mId, aDesc, &limits);
|
||||||
if (id.isSome()) {
|
if (request) {
|
||||||
RefPtr<Device> device =
|
RefPtr<Device> device =
|
||||||
new Device(this, id.value(), MakeUnique<ffi::WGPULimits>(limits));
|
new Device(this, request->mId, MakeUnique<ffi::WGPULimits>(limits));
|
||||||
// copy over the features
|
// copy over the features
|
||||||
for (const auto& feature : aDesc.mRequiredFeatures) {
|
for (const auto& feature : aDesc.mRequiredFeatures) {
|
||||||
NS_ConvertASCIItoUTF16 string(
|
NS_ConvertASCIItoUTF16 string(
|
||||||
|
@ -97,9 +97,30 @@ already_AddRefed<dom::Promise> Adapter::RequestDevice(
|
||||||
dom::GPUSupportedFeatures_Binding::SetlikeHelpers::Add(device->mFeatures,
|
dom::GPUSupportedFeatures_Binding::SetlikeHelpers::Add(device->mFeatures,
|
||||||
string, aRv);
|
string, aRv);
|
||||||
}
|
}
|
||||||
promise->MaybeResolve(device);
|
|
||||||
|
request->mPromise->Then(
|
||||||
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[promise, device](bool aSuccess) {
|
||||||
|
if (aSuccess) {
|
||||||
|
promise->MaybeResolve(device);
|
||||||
|
} else {
|
||||||
|
// In this path, request->mId has an error entry in the wgpu
|
||||||
|
// registry, so let Device::~Device clean things up on both the
|
||||||
|
// child and parent side.
|
||||||
|
promise->MaybeRejectWithInvalidStateError(
|
||||||
|
"Unable to fulfill requested features and limits");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[promise, device](const ipc::ResponseRejectReason& aReason) {
|
||||||
|
// We can't be sure how far along the WebGPUParent got in handling
|
||||||
|
// our AdapterRequestDevice message, but we can't communicate with it,
|
||||||
|
// so clear up our client state for this Device without trying to
|
||||||
|
// communicate with the parent about it.
|
||||||
|
device->CleanupUnregisteredInParent();
|
||||||
|
promise->MaybeRejectWithNotSupportedError("IPC error");
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
promise->MaybeRejectWithNotSupportedError("Unable to instanciate a Device");
|
promise->MaybeRejectWithNotSupportedError("Unable to instantiate a Device");
|
||||||
}
|
}
|
||||||
|
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
|
|
|
@ -63,7 +63,7 @@ Device::Device(Adapter* const aParent, RawId aId,
|
||||||
mLimits(new SupportedLimits(aParent, std::move(aRawLimits))),
|
mLimits(new SupportedLimits(aParent, std::move(aRawLimits))),
|
||||||
mBridge(aParent->mBridge),
|
mBridge(aParent->mBridge),
|
||||||
mQueue(new class Queue(this, aParent->mBridge, aId)) {
|
mQueue(new class Queue(this, aParent->mBridge, aId)) {
|
||||||
mBridge->RegisterDevice(mId, this);
|
mBridge->RegisterDevice(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::~Device() { Cleanup(); }
|
Device::~Device() { Cleanup(); }
|
||||||
|
@ -75,6 +75,13 @@ void Device::Cleanup() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Device::CleanupUnregisteredInParent() {
|
||||||
|
if (mBridge) {
|
||||||
|
mBridge->FreeUnregisteredInParentDevice(mId);
|
||||||
|
}
|
||||||
|
mValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
void Device::GetLabel(nsAString& aValue) const { aValue = mLabel; }
|
void Device::GetLabel(nsAString& aValue) const { aValue = mLabel; }
|
||||||
void Device::SetLabel(const nsAString& aLabel) { mLabel = aLabel; }
|
void Device::SetLabel(const nsAString& aLabel) { mLabel = aLabel; }
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,8 @@ class Device final : public DOMEventTargetHelper, public SupportsWeakPtr {
|
||||||
gfx::IntSize* aDefaultSize);
|
gfx::IntSize* aDefaultSize);
|
||||||
bool CheckNewWarning(const nsACString& aMessage);
|
bool CheckNewWarning(const nsACString& aMessage);
|
||||||
|
|
||||||
|
void CleanupUnregisteredInParent();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~Device();
|
~Device();
|
||||||
void Cleanup();
|
void Cleanup();
|
||||||
|
|
|
@ -38,7 +38,7 @@ parent:
|
||||||
async BumpImplicitBindGroupLayout(RawId pipelineId, bool isCompute, uint32_t index, RawId assignId);
|
async BumpImplicitBindGroupLayout(RawId pipelineId, bool isCompute, uint32_t index, RawId assignId);
|
||||||
|
|
||||||
async InstanceRequestAdapter(GPURequestAdapterOptions options, RawId[] ids) returns (ByteBuf byteBuf);
|
async InstanceRequestAdapter(GPURequestAdapterOptions options, RawId[] ids) returns (ByteBuf byteBuf);
|
||||||
async AdapterRequestDevice(RawId selfId, ByteBuf buf, RawId newId);
|
async AdapterRequestDevice(RawId selfId, ByteBuf buf, RawId newId) returns (bool success);
|
||||||
async AdapterDestroy(RawId selfId);
|
async AdapterDestroy(RawId selfId);
|
||||||
async BufferReturnShmem(RawId selfId, Shmem shmem);
|
async BufferReturnShmem(RawId selfId, Shmem shmem);
|
||||||
async BufferMap(RawId selfId, WGPUHostMap hostMap, uint64_t offset, uint64_t size) returns (Shmem sm);
|
async BufferMap(RawId selfId, WGPUHostMap hostMap, uint64_t offset, uint64_t size) returns (Shmem sm);
|
||||||
|
|
|
@ -202,17 +202,15 @@ RefPtr<AdapterPromise> WebGPUChild::InstanceRequestAdapter(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe<RawId> WebGPUChild::AdapterRequestDevice(
|
Maybe<DeviceRequest> WebGPUChild::AdapterRequestDevice(
|
||||||
RawId aSelfId, const dom::GPUDeviceDescriptor& aDesc,
|
RawId aSelfId, const dom::GPUDeviceDescriptor& aDesc,
|
||||||
ffi::WGPULimits* aLimits) {
|
ffi::WGPULimits* aLimits) {
|
||||||
RawId id = ffi::wgpu_client_make_device_id(mClient, aSelfId);
|
|
||||||
|
|
||||||
ffi::WGPUDeviceDescriptor desc = {};
|
ffi::WGPUDeviceDescriptor desc = {};
|
||||||
ffi::wgpu_client_fill_default_limits(&desc.limits);
|
ffi::wgpu_client_fill_default_limits(&desc.limits);
|
||||||
|
|
||||||
const auto featureBits = Adapter::MakeFeatureBits(aDesc.mRequiredFeatures);
|
const auto featureBits = Adapter::MakeFeatureBits(aDesc.mRequiredFeatures);
|
||||||
if (!featureBits) {
|
if (!featureBits) {
|
||||||
return {};
|
return Nothing();
|
||||||
}
|
}
|
||||||
desc.features = *featureBits;
|
desc.features = *featureBits;
|
||||||
|
|
||||||
|
@ -283,14 +281,17 @@ Maybe<RawId> WebGPUChild::AdapterRequestDevice(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RawId id = ffi::wgpu_client_make_device_id(mClient, aSelfId);
|
||||||
|
|
||||||
ByteBuf bb;
|
ByteBuf bb;
|
||||||
ffi::wgpu_client_serialize_device_descriptor(&desc, ToFFI(&bb));
|
ffi::wgpu_client_serialize_device_descriptor(&desc, ToFFI(&bb));
|
||||||
if (SendAdapterRequestDevice(aSelfId, std::move(bb), id)) {
|
|
||||||
*aLimits = desc.limits;
|
DeviceRequest request;
|
||||||
return Some(id);
|
request.mId = id;
|
||||||
}
|
request.mPromise = SendAdapterRequestDevice(aSelfId, std::move(bb), id);
|
||||||
ffi::wgpu_client_kill_device_id(mClient, id);
|
*aLimits = desc.limits;
|
||||||
return Nothing();
|
|
||||||
|
return Some(std::move(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
RawId WebGPUChild::DeviceCreateBuffer(RawId aSelfId,
|
RawId WebGPUChild::DeviceCreateBuffer(RawId aSelfId,
|
||||||
|
@ -979,8 +980,8 @@ void WebGPUChild::SwapChainPresent(wr::ExternalImageId aExternalImageId,
|
||||||
SendSwapChainPresent(aExternalImageId, aTextureId, encoderId);
|
SendSwapChainPresent(aExternalImageId, aTextureId, encoderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGPUChild::RegisterDevice(RawId aId, Device* aDevice) {
|
void WebGPUChild::RegisterDevice(Device* const aDevice) {
|
||||||
mDeviceMap.insert({aId, aDevice});
|
mDeviceMap.insert({aDevice->mId, aDevice});
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGPUChild::UnregisterDevice(RawId aId) {
|
void WebGPUChild::UnregisterDevice(RawId aId) {
|
||||||
|
@ -990,5 +991,10 @@ void WebGPUChild::UnregisterDevice(RawId aId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebGPUChild::FreeUnregisteredInParentDevice(RawId aId) {
|
||||||
|
ffi::wgpu_client_kill_device_id(mClient, aId);
|
||||||
|
mDeviceMap.erase(aId);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webgpu
|
} // namespace webgpu
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -27,6 +27,7 @@ struct WGPUTextureViewDescriptor;
|
||||||
using AdapterPromise =
|
using AdapterPromise =
|
||||||
MozPromise<ipc::ByteBuf, Maybe<ipc::ResponseRejectReason>, true>;
|
MozPromise<ipc::ByteBuf, Maybe<ipc::ResponseRejectReason>, true>;
|
||||||
using PipelinePromise = MozPromise<RawId, ipc::ResponseRejectReason, true>;
|
using PipelinePromise = MozPromise<RawId, ipc::ResponseRejectReason, true>;
|
||||||
|
using DevicePromise = MozPromise<bool, ipc::ResponseRejectReason, true>;
|
||||||
|
|
||||||
struct PipelineCreationContext {
|
struct PipelineCreationContext {
|
||||||
RawId mParentId = 0;
|
RawId mParentId = 0;
|
||||||
|
@ -34,6 +35,13 @@ struct PipelineCreationContext {
|
||||||
nsTArray<RawId> mImplicitBindGroupLayoutIds;
|
nsTArray<RawId> mImplicitBindGroupLayoutIds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DeviceRequest {
|
||||||
|
RawId mId = 0;
|
||||||
|
RefPtr<DevicePromise> mPromise;
|
||||||
|
// Note: we could put `ffi::WGPULimits` in here as well,
|
||||||
|
// but we don't want to #include ffi stuff in this header
|
||||||
|
};
|
||||||
|
|
||||||
ffi::WGPUByteBuf* ToFFI(ipc::ByteBuf* x);
|
ffi::WGPUByteBuf* ToFFI(ipc::ByteBuf* x);
|
||||||
|
|
||||||
class WebGPUChild final : public PWebGPUChild, public SupportsWeakPtr {
|
class WebGPUChild final : public PWebGPUChild, public SupportsWeakPtr {
|
||||||
|
@ -50,9 +58,9 @@ class WebGPUChild final : public PWebGPUChild, public SupportsWeakPtr {
|
||||||
|
|
||||||
RefPtr<AdapterPromise> InstanceRequestAdapter(
|
RefPtr<AdapterPromise> InstanceRequestAdapter(
|
||||||
const dom::GPURequestAdapterOptions& aOptions);
|
const dom::GPURequestAdapterOptions& aOptions);
|
||||||
Maybe<RawId> AdapterRequestDevice(RawId aSelfId,
|
Maybe<DeviceRequest> AdapterRequestDevice(
|
||||||
const dom::GPUDeviceDescriptor& aDesc,
|
RawId aSelfId, const dom::GPUDeviceDescriptor& aDesc,
|
||||||
ffi::WGPULimits* aLimtis);
|
ffi::WGPULimits* aLimits);
|
||||||
RawId DeviceCreateBuffer(RawId aSelfId,
|
RawId DeviceCreateBuffer(RawId aSelfId,
|
||||||
const dom::GPUBufferDescriptor& aDesc);
|
const dom::GPUBufferDescriptor& aDesc);
|
||||||
RawId DeviceCreateTexture(RawId aSelfId,
|
RawId DeviceCreateTexture(RawId aSelfId,
|
||||||
|
@ -95,8 +103,9 @@ class WebGPUChild final : public PWebGPUChild, public SupportsWeakPtr {
|
||||||
wr::ExternalImageId aExternalImageId);
|
wr::ExternalImageId aExternalImageId);
|
||||||
void SwapChainPresent(wr::ExternalImageId aExternalImageId, RawId aTextureId);
|
void SwapChainPresent(wr::ExternalImageId aExternalImageId, RawId aTextureId);
|
||||||
|
|
||||||
void RegisterDevice(RawId aId, Device* aDevice);
|
void RegisterDevice(Device* const aDevice);
|
||||||
void UnregisterDevice(RawId aId);
|
void UnregisterDevice(RawId aId);
|
||||||
|
void FreeUnregisteredInParentDevice(RawId aId);
|
||||||
|
|
||||||
static void ConvertTextureFormatRef(const dom::GPUTextureFormat& aInput,
|
static void ConvertTextureFormatRef(const dom::GPUTextureFormat& aInput,
|
||||||
ffi::WGPUTextureFormat& aOutput);
|
ffi::WGPUTextureFormat& aOutput);
|
||||||
|
|
|
@ -281,12 +281,17 @@ ipc::IPCResult WebGPUParent::RecvInstanceRequestAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
ipc::IPCResult WebGPUParent::RecvAdapterRequestDevice(
|
ipc::IPCResult WebGPUParent::RecvAdapterRequestDevice(
|
||||||
RawId aSelfId, const ipc::ByteBuf& aByteBuf, RawId aNewId) {
|
RawId aSelfId, const ipc::ByteBuf& aByteBuf, RawId aNewId,
|
||||||
|
AdapterRequestDeviceResolver&& resolver) {
|
||||||
ErrorBuffer error;
|
ErrorBuffer error;
|
||||||
ffi::wgpu_server_adapter_request_device(mContext, aSelfId, ToFFI(&aByteBuf),
|
ffi::wgpu_server_adapter_request_device(mContext, aSelfId, ToFFI(&aByteBuf),
|
||||||
aNewId, error.ToFFI());
|
aNewId, error.ToFFI());
|
||||||
mErrorScopeMap.insert({aSelfId, ErrorScopeStack()});
|
if (ForwardError(0, error)) {
|
||||||
ForwardError(0, error);
|
resolver(false);
|
||||||
|
} else {
|
||||||
|
mErrorScopeMap.insert({aSelfId, ErrorScopeStack()});
|
||||||
|
resolver(true);
|
||||||
|
}
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,9 @@ class WebGPUParent final : public PWebGPUParent {
|
||||||
const dom::GPURequestAdapterOptions& aOptions,
|
const dom::GPURequestAdapterOptions& aOptions,
|
||||||
const nsTArray<RawId>& aTargetIds,
|
const nsTArray<RawId>& aTargetIds,
|
||||||
InstanceRequestAdapterResolver&& resolver);
|
InstanceRequestAdapterResolver&& resolver);
|
||||||
ipc::IPCResult RecvAdapterRequestDevice(RawId aSelfId,
|
ipc::IPCResult RecvAdapterRequestDevice(
|
||||||
const ipc::ByteBuf& aByteBuf,
|
RawId aSelfId, const ipc::ByteBuf& aByteBuf, RawId aNewId,
|
||||||
RawId aNewId);
|
AdapterRequestDeviceResolver&& resolver);
|
||||||
ipc::IPCResult RecvAdapterDestroy(RawId aSelfId);
|
ipc::IPCResult RecvAdapterDestroy(RawId aSelfId);
|
||||||
ipc::IPCResult RecvDeviceDestroy(RawId aSelfId);
|
ipc::IPCResult RecvDeviceDestroy(RawId aSelfId);
|
||||||
ipc::IPCResult RecvBufferReturnShmem(RawId aSelfId, Shmem&& aShmem);
|
ipc::IPCResult RecvBufferReturnShmem(RawId aSelfId, Shmem&& aShmem);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче