mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1752188: Move GPUBufferDescriptor validation to server. r=jgilbert
Depends on [`wgpu#2673`]. WebGPU requires `GPUBufferDescriptor` validation failure to: 1) generate an error on the Device timeline, and 2) mark the new buffer as invalid. Satisfy 1) by moving most validation to the compositor process. Requirement 2) is harder. `wgpu_core::Global::device_create_buffer` already takes care of some validation for us, and marks the provided buffer id invalid when there's a problem. However, there are certain errors the spec requires us to detect which `device_create_buffer` cannot even see, because they are caught by standard Rust validation steps in the process of creating the `wgpu_types::BufferDescriptor` that one would *pass to* that function. For example, if there are bogus bits set in the `usage` property, we can't even construct a Rust `BufferUsages` value from that to include in the `BufferDescriptor` that we must pass to `device_create_buffer`. This means that we need to do some validation ourselves, in the process of constructing that `BufferDescriptor`, and use the `Global::create_buffer_error` method added in [`wgpu#2673`] to mark the new buffer as invalid. [`wgpu#2673`]: https://github.com/gfx-rs/wgpu/pull/2673 Differential Revision: https://phabricator.services.mozilla.com/D146768
This commit is contained in:
parent
b3f36731c3
commit
cee3303a59
@ -10,6 +10,7 @@ using layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
|
|||||||
using RawId from "mozilla/webgpu/WebGPUTypes.h";
|
using RawId from "mozilla/webgpu/WebGPUTypes.h";
|
||||||
using dom::GPURequestAdapterOptions from "mozilla/dom/WebGPUBinding.h";
|
using dom::GPURequestAdapterOptions from "mozilla/dom/WebGPUBinding.h";
|
||||||
using dom::GPUCommandBufferDescriptor from "mozilla/dom/WebGPUBinding.h";
|
using dom::GPUCommandBufferDescriptor from "mozilla/dom/WebGPUBinding.h";
|
||||||
|
using dom::GPUBufferDescriptor from "mozilla/dom/WebGPUBinding.h";
|
||||||
using webgpu::ffi::WGPUHostMap from "mozilla/webgpu/ffi/wgpu.h";
|
using webgpu::ffi::WGPUHostMap from "mozilla/webgpu/ffi/wgpu.h";
|
||||||
using MaybeScopedError from "mozilla/webgpu/WebGPUTypes.h";
|
using MaybeScopedError from "mozilla/webgpu/WebGPUTypes.h";
|
||||||
|
|
||||||
@ -38,6 +39,8 @@ parent:
|
|||||||
async CommandEncoderAction(RawId selfId, RawId aDeviceId, ByteBuf buf);
|
async CommandEncoderAction(RawId selfId, RawId aDeviceId, ByteBuf buf);
|
||||||
async BumpImplicitBindGroupLayout(RawId pipelineId, bool isCompute, uint32_t index, RawId assignId);
|
async BumpImplicitBindGroupLayout(RawId pipelineId, bool isCompute, uint32_t index, RawId assignId);
|
||||||
|
|
||||||
|
async CreateBuffer(RawId deviceId, RawId bufferId, GPUBufferDescriptor desc);
|
||||||
|
|
||||||
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) returns (bool success);
|
async AdapterRequestDevice(RawId selfId, ByteBuf buf, RawId newId) returns (bool success);
|
||||||
async AdapterDestroy(RawId selfId);
|
async AdapterDestroy(RawId selfId);
|
||||||
|
@ -352,23 +352,11 @@ Maybe<DeviceRequest> WebGPUChild::AdapterRequestDevice(
|
|||||||
|
|
||||||
RawId WebGPUChild::DeviceCreateBuffer(RawId aSelfId,
|
RawId WebGPUChild::DeviceCreateBuffer(RawId aSelfId,
|
||||||
const dom::GPUBufferDescriptor& aDesc) {
|
const dom::GPUBufferDescriptor& aDesc) {
|
||||||
ffi::WGPUBufferDescriptor desc = {};
|
RawId bufferId = ffi::wgpu_client_make_buffer_id(mClient.get(), aSelfId);
|
||||||
nsCString label;
|
if (!SendCreateBuffer(aSelfId, bufferId, aDesc)) {
|
||||||
if (aDesc.mLabel.WasPassed()) {
|
|
||||||
LossyCopyUTF16toASCII(aDesc.mLabel.Value(), label);
|
|
||||||
desc.label = label.get();
|
|
||||||
}
|
|
||||||
desc.size = aDesc.mSize;
|
|
||||||
desc.usage = aDesc.mUsage;
|
|
||||||
desc.mapped_at_creation = aDesc.mMappedAtCreation;
|
|
||||||
|
|
||||||
ByteBuf bb;
|
|
||||||
RawId id =
|
|
||||||
ffi::wgpu_client_create_buffer(mClient.get(), aSelfId, &desc, ToFFI(&bb));
|
|
||||||
if (!SendDeviceAction(aSelfId, std::move(bb))) {
|
|
||||||
MOZ_CRASH("IPC failure");
|
MOZ_CRASH("IPC failure");
|
||||||
}
|
}
|
||||||
return id;
|
return bufferId;
|
||||||
}
|
}
|
||||||
|
|
||||||
RawId WebGPUChild::DeviceCreateTexture(RawId aSelfId,
|
RawId WebGPUChild::DeviceCreateTexture(RawId aSelfId,
|
||||||
|
@ -334,6 +334,22 @@ ipc::IPCResult WebGPUParent::RecvDeviceDestroy(RawId aSelfId) {
|
|||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ipc::IPCResult WebGPUParent::RecvCreateBuffer(
|
||||||
|
RawId aSelfId, RawId aBufferId, dom::GPUBufferDescriptor&& aDesc) {
|
||||||
|
nsCString label;
|
||||||
|
const char* labelOrNull = nullptr;
|
||||||
|
if (aDesc.mLabel.WasPassed()) {
|
||||||
|
LossyCopyUTF16toASCII(aDesc.mLabel.Value(), label);
|
||||||
|
labelOrNull = label.get();
|
||||||
|
}
|
||||||
|
ErrorBuffer error;
|
||||||
|
ffi::wgpu_server_device_create_buffer(mContext.get(), aSelfId, aBufferId,
|
||||||
|
labelOrNull, aDesc.mSize, aDesc.mUsage,
|
||||||
|
aDesc.mMappedAtCreation, error.ToFFI());
|
||||||
|
ForwardError(aSelfId, error);
|
||||||
|
return IPC_OK();
|
||||||
|
}
|
||||||
|
|
||||||
ipc::IPCResult WebGPUParent::RecvBufferReturnShmem(RawId aSelfId,
|
ipc::IPCResult WebGPUParent::RecvBufferReturnShmem(RawId aSelfId,
|
||||||
Shmem&& aShmem) {
|
Shmem&& aShmem) {
|
||||||
MOZ_LOG(sLogger, LogLevel::Info,
|
MOZ_LOG(sLogger, LogLevel::Info,
|
||||||
@ -744,13 +760,11 @@ ipc::IPCResult WebGPUParent::RecvSwapChainPresent(
|
|||||||
|
|
||||||
ffi::WGPUBufferUsages usage =
|
ffi::WGPUBufferUsages usage =
|
||||||
WGPUBufferUsages_COPY_DST | WGPUBufferUsages_MAP_READ;
|
WGPUBufferUsages_COPY_DST | WGPUBufferUsages_MAP_READ;
|
||||||
ffi::WGPUBufferDescriptor desc = {};
|
|
||||||
desc.size = bufferSize;
|
|
||||||
desc.usage = usage;
|
|
||||||
|
|
||||||
ErrorBuffer error;
|
ErrorBuffer error;
|
||||||
ffi::wgpu_server_device_create_buffer(mContext.get(), data->mDeviceId,
|
ffi::wgpu_server_device_create_buffer(mContext.get(), data->mDeviceId,
|
||||||
&desc, bufferId, error.ToFFI());
|
bufferId, nullptr, bufferSize,
|
||||||
|
usage, false, error.ToFFI());
|
||||||
if (ForwardError(data->mDeviceId, error)) {
|
if (ForwardError(data->mDeviceId, error)) {
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,8 @@ class WebGPUParent final : public PWebGPUParent {
|
|||||||
AdapterRequestDeviceResolver&& resolver);
|
AdapterRequestDeviceResolver&& resolver);
|
||||||
ipc::IPCResult RecvAdapterDestroy(RawId aSelfId);
|
ipc::IPCResult RecvAdapterDestroy(RawId aSelfId);
|
||||||
ipc::IPCResult RecvDeviceDestroy(RawId aSelfId);
|
ipc::IPCResult RecvDeviceDestroy(RawId aSelfId);
|
||||||
|
ipc::IPCResult RecvCreateBuffer(RawId aSelfId, RawId aBufferId,
|
||||||
|
dom::GPUBufferDescriptor&& aDesc);
|
||||||
ipc::IPCResult RecvBufferReturnShmem(RawId aSelfId, Shmem&& aShmem);
|
ipc::IPCResult RecvBufferReturnShmem(RawId aSelfId, Shmem&& aShmem);
|
||||||
ipc::IPCResult RecvBufferMap(RawId aSelfId, ffi::WGPUHostMap aHostMap,
|
ipc::IPCResult RecvBufferMap(RawId aSelfId, ffi::WGPUHostMap aHostMap,
|
||||||
uint64_t aOffset, uint64_t size,
|
uint64_t aOffset, uint64_t size,
|
||||||
|
@ -33,6 +33,9 @@ DEFINE_IPC_SERIALIZER_WITHOUT_FIELDS(mozilla::dom::GPUCommandBufferDescriptor);
|
|||||||
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::GPURequestAdapterOptions,
|
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::GPURequestAdapterOptions,
|
||||||
mPowerPreference, mForceFallbackAdapter);
|
mPowerPreference, mForceFallbackAdapter);
|
||||||
|
|
||||||
|
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::GPUBufferDescriptor, mSize,
|
||||||
|
mUsage, mMappedAtCreation);
|
||||||
|
|
||||||
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ScopedError, operationError,
|
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ScopedError, operationError,
|
||||||
validationMessage);
|
validationMessage);
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ exclude = [
|
|||||||
"Option_BufferSize", "Option_NonZeroU32", "Option_NonZeroU8",
|
"Option_BufferSize", "Option_NonZeroU32", "Option_NonZeroU8",
|
||||||
"ANativeWindow_setBuffersGeometry",
|
"ANativeWindow_setBuffersGeometry",
|
||||||
]
|
]
|
||||||
|
include = ["BufferUsages"]
|
||||||
|
|
||||||
[export.rename]
|
[export.rename]
|
||||||
"BufferDescriptor_RawString" = "BufferDescriptor"
|
"BufferDescriptor_RawString" = "BufferDescriptor"
|
||||||
|
@ -475,26 +475,6 @@ pub extern "C" fn wgpu_client_make_buffer_id(
|
|||||||
.alloc(backend)
|
.alloc(backend)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wgpu_client_create_buffer(
|
|
||||||
client: &Client,
|
|
||||||
device_id: id::DeviceId,
|
|
||||||
desc: &wgt::BufferDescriptor<RawString>,
|
|
||||||
bb: &mut ByteBuf,
|
|
||||||
) -> id::BufferId {
|
|
||||||
let backend = device_id.backend();
|
|
||||||
let id = client
|
|
||||||
.identities
|
|
||||||
.lock()
|
|
||||||
.select(backend)
|
|
||||||
.buffers
|
|
||||||
.alloc(backend);
|
|
||||||
|
|
||||||
let action = DeviceAction::CreateBuffer(id, desc.map_label(cow_label));
|
|
||||||
*bb = make_byte_buf(&action);
|
|
||||||
id
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wgpu_client_create_texture(
|
pub extern "C" fn wgpu_client_create_texture(
|
||||||
client: &Client,
|
client: &Client,
|
||||||
|
@ -75,7 +75,6 @@ struct ImplicitLayout<'a> {
|
|||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
enum DeviceAction<'a> {
|
enum DeviceAction<'a> {
|
||||||
CreateBuffer(id::BufferId, wgc::resource::BufferDescriptor<'a>),
|
|
||||||
CreateTexture(id::TextureId, wgc::resource::TextureDescriptor<'a>),
|
CreateTexture(id::TextureId, wgc::resource::TextureDescriptor<'a>),
|
||||||
CreateSampler(id::SamplerId, wgc::resource::SamplerDescriptor<'a>),
|
CreateSampler(id::SamplerId, wgc::resource::SamplerDescriptor<'a>),
|
||||||
CreateBindGroupLayout(
|
CreateBindGroupLayout(
|
||||||
|
@ -211,12 +211,30 @@ pub extern "C" fn wgpu_server_device_drop(global: &Global, self_id: id::DeviceId
|
|||||||
pub extern "C" fn wgpu_server_device_create_buffer(
|
pub extern "C" fn wgpu_server_device_create_buffer(
|
||||||
global: &Global,
|
global: &Global,
|
||||||
self_id: id::DeviceId,
|
self_id: id::DeviceId,
|
||||||
desc: &wgt::BufferDescriptor<RawString>,
|
buffer_id: id::BufferId,
|
||||||
new_id: id::BufferId,
|
label_or_null: RawString,
|
||||||
|
size: wgt::BufferAddress,
|
||||||
|
usage: u32,
|
||||||
|
mapped_at_creation: bool,
|
||||||
mut error_buf: ErrorBuffer,
|
mut error_buf: ErrorBuffer,
|
||||||
) {
|
) {
|
||||||
let desc = desc.map_label(cow_label);
|
let label = cow_label(&label_or_null);
|
||||||
let (_, error) = gfx_select!(self_id => global.device_create_buffer(self_id, &desc, new_id));
|
let usage = match wgt::BufferUsages::from_bits(usage) {
|
||||||
|
Some(usage) => usage,
|
||||||
|
None => {
|
||||||
|
error_buf.init_str("GPUBufferDescriptor's 'usage' includes invalid unimplemented bits \
|
||||||
|
or unimplemented usages");
|
||||||
|
gfx_select!(self_id => global.create_buffer_error(buffer_id, label));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let desc = wgc::resource::BufferDescriptor {
|
||||||
|
label,
|
||||||
|
size,
|
||||||
|
usage,
|
||||||
|
mapped_at_creation,
|
||||||
|
};
|
||||||
|
let (_, error) = gfx_select!(self_id => global.device_create_buffer(self_id, &desc, buffer_id));
|
||||||
if let Some(err) = error {
|
if let Some(err) = error {
|
||||||
error_buf.init(err);
|
error_buf.init(err);
|
||||||
}
|
}
|
||||||
@ -285,12 +303,6 @@ impl Global {
|
|||||||
mut error_buf: ErrorBuffer,
|
mut error_buf: ErrorBuffer,
|
||||||
) {
|
) {
|
||||||
match action {
|
match action {
|
||||||
DeviceAction::CreateBuffer(id, desc) => {
|
|
||||||
let (_, error) = self.device_create_buffer::<A>(self_id, &desc, id);
|
|
||||||
if let Some(err) = error {
|
|
||||||
error_buf.init(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DeviceAction::CreateTexture(id, desc) => {
|
DeviceAction::CreateTexture(id, desc) => {
|
||||||
let (_, error) = self.device_create_texture::<A>(self_id, &desc, id);
|
let (_, error) = self.device_create_texture::<A>(self_id, &desc, id);
|
||||||
if let Some(err) = error {
|
if let Some(err) = error {
|
||||||
|
Loading…
Reference in New Issue
Block a user