From 8cb5fad8286d87f2e852d870581d4f867afaf435 Mon Sep 17 00:00:00 2001 From: Kunal Mohan Date: Sat, 1 Aug 2020 16:32:37 +0530 Subject: [PATCH 1/4] Report errors from void returning operations --- Cargo.lock | 6 +- components/script/dom/gpubuffer.rs | 17 ++--- components/script/dom/gpucommandencoder.rs | 46 +++++++++++-- .../script/dom/gpucomputepassencoder.rs | 2 + components/script/dom/gpudevice.rs | 8 ++- components/script/dom/gpuqueue.rs | 25 +++++-- components/script/dom/gpurenderpassencoder.rs | 2 + components/script/dom/webidls/GPU.webidl | 3 +- .../script/dom/webidls/GPUAdapter.webidl | 3 +- components/webgpu/lib.rs | 66 +++++++++++++++---- 10 files changed, 140 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3782b7ba3c5..967f78829d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3701,7 +3701,7 @@ checksum = "0419348c027fa7be448d2ae7ea0e4e04c2334c31dc4e74ab29f00a2a7ca69204" [[package]] name = "naga" version = "0.1.0" -source = "git+https://github.com/gfx-rs/naga?rev=94802078c3bc5d138f497419ea3e7a869f10916d#94802078c3bc5d138f497419ea3e7a869f10916d" +source = "git+https://github.com/gfx-rs/naga?rev=1eb637038dd15fc1dad770eca8e6943424dbc122#1eb637038dd15fc1dad770eca8e6943424dbc122" dependencies = [ "bitflags", "fxhash", @@ -6911,7 +6911,7 @@ dependencies = [ [[package]] name = "wgpu-core" version = "0.5.0" -source = "git+https://github.com/gfx-rs/wgpu#9e4839eb049707629fa8a91e3603085433f352a4" +source = "git+https://github.com/gfx-rs/wgpu#872a6c4c2bab5591838219c34e0cbf5fa9c2ec85" dependencies = [ "arrayvec 0.5.1", "bitflags", @@ -6938,7 +6938,7 @@ dependencies = [ [[package]] name = "wgpu-types" version = "0.5.0" -source = "git+https://github.com/gfx-rs/wgpu#9e4839eb049707629fa8a91e3603085433f352a4" +source = "git+https://github.com/gfx-rs/wgpu#872a6c4c2bab5591838219c34e0cbf5fa9c2ec85" dependencies = [ "bitflags", "serde", diff --git a/components/script/dom/gpubuffer.rs b/components/script/dom/gpubuffer.rs index 1a9c9d14f2f..0650e1390e1 100644 --- a/components/script/dom/gpubuffer.rs +++ b/components/script/dom/gpubuffer.rs @@ -8,10 +8,11 @@ use crate::dom::bindings::codegen::Bindings::GPUMapModeBinding::GPUMapModeConsta use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; -use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::USVString; use crate::dom::globalscope::GlobalScope; use crate::dom::gpu::{response_async, AsyncWGPUListener}; +use crate::dom::gpudevice::GPUDevice; use crate::dom::promise::Promise; use crate::realms::InRealm; use crate::script_runtime::JSContext; @@ -25,9 +26,7 @@ use std::ffi::c_void; use std::ops::Range; use std::ptr::NonNull; use std::rc::Rc; -use webgpu::{ - wgpu::device::HostMap, WebGPU, WebGPUBuffer, WebGPUDevice, WebGPURequest, WebGPUResponse, -}; +use webgpu::{wgpu::device::HostMap, WebGPU, WebGPUBuffer, WebGPURequest, WebGPUResponse}; const RANGE_OFFSET_ALIGN_MASK: u64 = 8; const RANGE_SIZE_ALIGN_MASK: u64 = 4; @@ -61,7 +60,7 @@ pub struct GPUBuffer { label: DomRefCell>, state: Cell, buffer: WebGPUBuffer, - device: WebGPUDevice, + device: Dom, size: GPUSize64, #[ignore_malloc_size_of = "promises are hard"] map_promise: DomRefCell>>, @@ -72,7 +71,7 @@ impl GPUBuffer { fn new_inherited( channel: WebGPU, buffer: WebGPUBuffer, - device: WebGPUDevice, + device: &GPUDevice, state: GPUBufferState, size: GPUSize64, map_info: DomRefCell>, @@ -83,7 +82,7 @@ impl GPUBuffer { channel, label: DomRefCell::new(label), state: Cell::new(state), - device, + device: Dom::from_ref(device), buffer, map_promise: DomRefCell::new(None), size, @@ -96,7 +95,7 @@ impl GPUBuffer { global: &GlobalScope, channel: WebGPU, buffer: WebGPUBuffer, - device: WebGPUDevice, + device: &GPUDevice, state: GPUBufferState, size: GPUSize64, map_info: DomRefCell>, @@ -145,6 +144,8 @@ impl GPUBufferMethods for GPUBuffer { let m_range = m_info.mapping_range.clone(); if let Err(e) = self.channel.0.send(WebGPURequest::UnmapBuffer { buffer_id: self.id().0, + device_id: self.device.id().0, + scope_id: self.device.use_current_scope(), array_buffer: IpcSharedMemory::from_bytes(m_info.mapping.borrow().as_slice()), is_map_read: m_info.map_mode == Some(GPUMapModeConstants::READ), offset: m_range.start, diff --git a/components/script/dom/gpucommandencoder.rs b/components/script/dom/gpucommandencoder.rs index 510b650a396..6e3b01787f8 100644 --- a/components/script/dom/gpucommandencoder.rs +++ b/components/script/dom/gpucommandencoder.rs @@ -29,7 +29,7 @@ use std::borrow::Cow; use std::cell::Cell; use std::collections::HashSet; use webgpu::wgpu::command as wgpu_com; -use webgpu::{self, wgt, WebGPU, WebGPURequest}; +use webgpu::{self, identity::WebGPUOpResult, wgt, WebGPU, WebGPURequest}; // https://gpuweb.github.io/gpuweb/#enumdef-encoder-state #[derive(MallocSizeOf, PartialEq)] @@ -103,6 +103,10 @@ impl GPUCommandEncoder { *self.state.borrow_mut() = GPUCommandEncoderState::Closed; } } + + pub fn device(&self) -> &GPUDevice { + &*self.device + } } impl GPUCommandEncoderMethods for GPUCommandEncoder { @@ -254,9 +258,15 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { size: GPUSize64, ) { let valid = *self.state.borrow() == GPUCommandEncoderState::Open; + let scope_id = self.device.use_current_scope(); if !valid { - // TODO: Record an error in the current scope. + self.device.handle_server_msg( + scope_id, + WebGPUOpResult::ValidationError(String::from( + "CommandEncoder is not in Open State", + )), + ); self.valid.set(false); return; } @@ -269,6 +279,8 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { .0 .send(WebGPURequest::CopyBufferToBuffer { command_encoder_id: self.encoder.0, + device_id: self.device.id().0, + scope_id, source_id: source.id().0, source_offset, destination_id: destination.id().0, @@ -286,9 +298,15 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { copy_size: GPUExtent3D, ) { let valid = *self.state.borrow() == GPUCommandEncoderState::Open; + let scope_id = self.device.use_current_scope(); if !valid { - // TODO: Record an error in the current scope. + self.device.handle_server_msg( + scope_id, + WebGPUOpResult::ValidationError(String::from( + "CommandEncoder is not in Open State", + )), + ); self.valid.set(false); return; } @@ -301,6 +319,8 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { .0 .send(WebGPURequest::CopyBufferToTexture { command_encoder_id: self.encoder.0, + device_id: self.device.id().0, + scope_id, source: convert_buffer_cv(source), destination: convert_texture_cv(destination), copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict(©_size)), @@ -316,9 +336,15 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { copy_size: GPUExtent3D, ) { let valid = *self.state.borrow() == GPUCommandEncoderState::Open; + let scope_id = self.device.use_current_scope(); if !valid { - // TODO: Record an error in the current scope. + self.device.handle_server_msg( + scope_id, + WebGPUOpResult::ValidationError(String::from( + "CommandEncoder is not in Open State", + )), + ); self.valid.set(false); return; } @@ -331,6 +357,8 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { .0 .send(WebGPURequest::CopyTextureToBuffer { command_encoder_id: self.encoder.0, + device_id: self.device.id().0, + scope_id, source: convert_texture_cv(source), destination: convert_buffer_cv(destination), copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict(©_size)), @@ -346,9 +374,15 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { copy_size: GPUExtent3D, ) { let valid = *self.state.borrow() == GPUCommandEncoderState::Open; + let scope_id = self.device.use_current_scope(); if !valid { - // TODO: Record an error in the current scope. + self.device.handle_server_msg( + scope_id, + WebGPUOpResult::ValidationError(String::from( + "CommandEncoder is not in Open State", + )), + ); self.valid.set(false); return; } @@ -357,6 +391,8 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { .0 .send(WebGPURequest::CopyTextureToTexture { command_encoder_id: self.encoder.0, + device_id: self.device.id().0, + scope_id, source: convert_texture_cv(source), destination: convert_texture_cv(destination), copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict(©_size)), diff --git a/components/script/dom/gpucomputepassencoder.rs b/components/script/dom/gpucomputepassencoder.rs index 1cfcdf7a25c..f35313295e6 100644 --- a/components/script/dom/gpucomputepassencoder.rs +++ b/components/script/dom/gpucomputepassencoder.rs @@ -93,6 +93,8 @@ impl GPUComputePassEncoderMethods for GPUComputePassEncoder { .0 .send(WebGPURequest::RunComputePass { command_encoder_id: self.command_encoder.id().0, + device_id: self.command_encoder.device().id().0, + scope_id: self.command_encoder.device().use_current_scope(), compute_pass, }) .expect("Failed to send RunComputePass"); diff --git a/components/script/dom/gpudevice.rs b/components/script/dom/gpudevice.rs index 7719d937e96..adde335bd47 100644 --- a/components/script/dom/gpudevice.rs +++ b/components/script/dom/gpudevice.rs @@ -148,12 +148,14 @@ impl GPUDevice { label: Option, ) -> DomRoot { let queue = GPUQueue::new(global, channel.clone(), queue); - reflect_dom_object( + let device = reflect_dom_object( Box::new(GPUDevice::new_inherited( channel, adapter, extensions, limits, device, &queue, label, )), global, - ) + ); + queue.set_device(&*device); + device } } @@ -341,7 +343,7 @@ impl GPUDeviceMethods for GPUDevice { &self.global(), self.channel.clone(), buffer, - self.device, + &self, state, descriptor.size, map_info, diff --git a/components/script/dom/gpuqueue.rs b/components/script/dom/gpuqueue.rs index e04471ebb34..d5c742555c7 100644 --- a/components/script/dom/gpuqueue.rs +++ b/components/script/dom/gpuqueue.rs @@ -11,24 +11,25 @@ use crate::dom::bindings::codegen::Bindings::GPUQueueBinding::GPUQueueMethods; use crate::dom::bindings::codegen::Bindings::GPUTextureBinding::GPUExtent3D; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; -use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::USVString; use crate::dom::globalscope::GlobalScope; use crate::dom::gpubuffer::{GPUBuffer, GPUBufferState}; use crate::dom::gpucommandbuffer::GPUCommandBuffer; use crate::dom::gpucommandencoder::{convert_texture_cv, convert_texture_data_layout}; -use crate::dom::gpudevice::{convert_texture_size_to_dict, convert_texture_size_to_wgt}; +use crate::dom::gpudevice::{convert_texture_size_to_dict, convert_texture_size_to_wgt, GPUDevice}; use dom_struct::dom_struct; use ipc_channel::ipc::IpcSharedMemory; use js::rust::CustomAutoRooterGuard; use js::typedarray::ArrayBuffer; -use webgpu::{wgt, WebGPU, WebGPUQueue, WebGPURequest}; +use webgpu::{identity::WebGPUOpResult, wgt, WebGPU, WebGPUQueue, WebGPURequest}; #[dom_struct] pub struct GPUQueue { reflector_: Reflector, #[ignore_malloc_size_of = "defined in webgpu"] channel: WebGPU, + device: DomRefCell>>, label: DomRefCell>, queue: WebGPUQueue, } @@ -38,6 +39,7 @@ impl GPUQueue { GPUQueue { channel, reflector_: Reflector::new(), + device: DomRefCell::new(None), label: DomRefCell::new(None), queue, } @@ -48,6 +50,12 @@ impl GPUQueue { } } +impl GPUQueue { + pub fn set_device(&self, device: &GPUDevice) { + *self.device.borrow_mut() = Some(Dom::from_ref(device)); + } +} + impl GPUQueueMethods for GPUQueue { /// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label fn GetLabel(&self) -> Option { @@ -67,8 +75,14 @@ impl GPUQueueMethods for GPUQueue { _ => false, }) }); + let scope_id = self.device.borrow().as_ref().unwrap().use_current_scope(); if !valid { - // TODO: Generate error to the ErrorScope + self.device.borrow().as_ref().unwrap().handle_server_msg( + scope_id, + WebGPUOpResult::ValidationError(String::from( + "Referenced GPUBuffer(s) are not Unmapped", + )), + ); return; } let command_buffers = command_buffers.iter().map(|cb| cb.id().0).collect(); @@ -76,6 +90,7 @@ impl GPUQueueMethods for GPUQueue { .0 .send(WebGPURequest::Submit { queue_id: self.queue.0, + scope_id, command_buffers, }) .unwrap(); @@ -111,6 +126,7 @@ impl GPUQueueMethods for GPUQueue { ); if let Err(e) = self.channel.0.send(WebGPURequest::WriteBuffer { queue_id: self.queue.0, + scope_id: self.device.borrow().as_ref().unwrap().use_current_scope(), buffer_id: buffer.id().0, buffer_offset, data: final_data, @@ -144,6 +160,7 @@ impl GPUQueueMethods for GPUQueue { if let Err(e) = self.channel.0.send(WebGPURequest::WriteTexture { queue_id: self.queue.0, + scope_id: self.device.borrow().as_ref().unwrap().use_current_scope(), texture_cv, data_layout: texture_layout, size: write_size, diff --git a/components/script/dom/gpurenderpassencoder.rs b/components/script/dom/gpurenderpassencoder.rs index a3c620e7ee2..8117bfc3636 100644 --- a/components/script/dom/gpurenderpassencoder.rs +++ b/components/script/dom/gpurenderpassencoder.rs @@ -165,6 +165,8 @@ impl GPURenderPassEncoderMethods for GPURenderPassEncoder { .0 .send(WebGPURequest::RunRenderPass { command_encoder_id: self.command_encoder.id().0, + device_id: self.command_encoder.device().id().0, + scope_id: self.command_encoder.device().use_current_scope(), render_pass, }) .expect("Failed to send RunRenderPass"); diff --git a/components/script/dom/webidls/GPU.webidl b/components/script/dom/webidls/GPU.webidl index 856c5027569..e0e6eb57b27 100644 --- a/components/script/dom/webidls/GPU.webidl +++ b/components/script/dom/webidls/GPU.webidl @@ -5,8 +5,7 @@ // https://gpuweb.github.io/gpuweb/#gpu-interface [Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"] interface GPU { - // May reject with DOMException // TODO: DOMException("OperationError")? - Promise requestAdapter(optional GPURequestAdapterOptions options = {}); + Promise requestAdapter(optional GPURequestAdapterOptions options = {}); }; // https://gpuweb.github.io/gpuweb/#dictdef-gpurequestadapteroptions diff --git a/components/script/dom/webidls/GPUAdapter.webidl b/components/script/dom/webidls/GPUAdapter.webidl index 7fc2e8438f5..d9eba879bd1 100644 --- a/components/script/dom/webidls/GPUAdapter.webidl +++ b/components/script/dom/webidls/GPUAdapter.webidl @@ -9,8 +9,7 @@ interface GPUAdapter { readonly attribute object extensions; //readonly attribute GPULimits limits; Don’t expose higher limits for now. - // May reject with DOMException // TODO: DOMException("OperationError")? - Promise requestDevice(optional GPUDeviceDescriptor descriptor = {}); + Promise requestDevice(optional GPUDeviceDescriptor descriptor = {}); }; dictionary GPUDeviceDescriptor : GPUObjectDescriptorBase { diff --git a/components/webgpu/lib.rs b/components/webgpu/lib.rs index da343ec9519..df42c685ae5 100644 --- a/components/webgpu/lib.rs +++ b/components/webgpu/lib.rs @@ -80,6 +80,8 @@ pub enum WebGPURequest { }, CopyBufferToBuffer { command_encoder_id: id::CommandEncoderId, + device_id: id::DeviceId, + scope_id: Option, source_id: id::BufferId, source_offset: wgt::BufferAddress, destination_id: id::BufferId, @@ -88,18 +90,24 @@ pub enum WebGPURequest { }, CopyBufferToTexture { command_encoder_id: id::CommandEncoderId, + device_id: id::DeviceId, + scope_id: Option, source: BufferCopyView, destination: TextureCopyView, copy_size: wgt::Extent3d, }, CopyTextureToBuffer { command_encoder_id: id::CommandEncoderId, + device_id: id::DeviceId, + scope_id: Option, source: TextureCopyView, destination: BufferCopyView, copy_size: wgt::Extent3d, }, CopyTextureToTexture { command_encoder_id: id::CommandEncoderId, + device_id: id::DeviceId, + scope_id: Option, source: TextureCopyView, destination: TextureCopyView, copy_size: wgt::Extent3d, @@ -213,14 +221,19 @@ pub enum WebGPURequest { }, RunComputePass { command_encoder_id: id::CommandEncoderId, + device_id: id::DeviceId, + scope_id: Option, compute_pass: ComputePass, }, RunRenderPass { command_encoder_id: id::CommandEncoderId, + device_id: id::DeviceId, + scope_id: Option, render_pass: RenderPass, }, Submit { queue_id: id::QueueId, + scope_id: Option, command_buffers: Vec, }, SwapChainPresent { @@ -230,6 +243,8 @@ pub enum WebGPURequest { }, UnmapBuffer { buffer_id: id::BufferId, + device_id: id::DeviceId, + scope_id: Option, array_buffer: IpcSharedMemory, is_map_read: bool, offset: u64, @@ -242,12 +257,14 @@ pub enum WebGPURequest { }, WriteBuffer { queue_id: id::QueueId, + scope_id: Option, buffer_id: id::BufferId, buffer_offset: u64, data: IpcSharedMemory, }, WriteTexture { queue_id: id::QueueId, + scope_id: Option, texture_cv: TextureCopyView, data_layout: wgt::TextureDataLayout, size: wgt::Extent3d, @@ -455,6 +472,8 @@ impl<'a> WGPU<'a> { }, WebGPURequest::CopyBufferToBuffer { command_encoder_id, + device_id, + scope_id, source_id, source_offset, destination_id, @@ -462,7 +481,7 @@ impl<'a> WGPU<'a> { size, } => { let global = &self.global; - let _ = gfx_select!(command_encoder_id => global.command_encoder_copy_buffer_to_buffer( + let result = gfx_select!(command_encoder_id => global.command_encoder_copy_buffer_to_buffer( command_encoder_id, source_id, source_offset, @@ -470,48 +489,58 @@ impl<'a> WGPU<'a> { destination_offset, size )); + self.send_result(device_id, scope_id, result); }, WebGPURequest::CopyBufferToTexture { command_encoder_id, + device_id, + scope_id, source, destination, copy_size, } => { let global = &self.global; - let _ = gfx_select!(command_encoder_id => global.command_encoder_copy_buffer_to_texture( + let result = gfx_select!(command_encoder_id => global.command_encoder_copy_buffer_to_texture( command_encoder_id, &source, &destination, ©_size )); + self.send_result(device_id, scope_id, result); }, WebGPURequest::CopyTextureToBuffer { command_encoder_id, + device_id, + scope_id, source, destination, copy_size, } => { let global = &self.global; - let _ = gfx_select!(command_encoder_id => global.command_encoder_copy_texture_to_buffer( + let result = gfx_select!(command_encoder_id => global.command_encoder_copy_texture_to_buffer( command_encoder_id, &source, &destination, ©_size )); + self.send_result(device_id, scope_id, result); }, WebGPURequest::CopyTextureToTexture { command_encoder_id, + device_id, + scope_id, source, destination, copy_size, } => { let global = &self.global; - let _ = gfx_select!(command_encoder_id => global.command_encoder_copy_texture_to_texture( + let result = gfx_select!(command_encoder_id => global.command_encoder_copy_texture_to_texture( command_encoder_id, &source, &destination, ©_size )); + self.send_result(device_id, scope_id, result); }, WebGPURequest::CreateBindGroup { device_id, @@ -890,30 +919,38 @@ impl<'a> WGPU<'a> { }, WebGPURequest::RunComputePass { command_encoder_id, + device_id, + scope_id, compute_pass, } => { let global = &self.global; - let _ = gfx_select!(command_encoder_id => global.command_encoder_run_compute_pass( + let result = gfx_select!(command_encoder_id => global.command_encoder_run_compute_pass( command_encoder_id, &compute_pass )); + self.send_result(device_id, scope_id, result); }, WebGPURequest::RunRenderPass { command_encoder_id, + device_id, + scope_id, render_pass, } => { let global = &self.global; - let _ = gfx_select!(command_encoder_id => global.command_encoder_run_render_pass( + let result = gfx_select!(command_encoder_id => global.command_encoder_run_render_pass( command_encoder_id, &render_pass )); + self.send_result(device_id, scope_id, result); }, WebGPURequest::Submit { queue_id, + scope_id, command_buffers, } => { let global = &self.global; - let _ = gfx_select!(queue_id => global.queue_submit(queue_id, &command_buffers)); + let result = gfx_select!(queue_id => global.queue_submit(queue_id, &command_buffers)); + self.send_result(queue_id, scope_id, result); }, WebGPURequest::SwapChainPresent { external_id, @@ -1052,6 +1089,8 @@ impl<'a> WGPU<'a> { }, WebGPURequest::UnmapBuffer { buffer_id, + device_id, + scope_id, array_buffer, is_map_read, offset, @@ -1068,7 +1107,8 @@ impl<'a> WGPU<'a> { unsafe { slice::from_raw_parts_mut(map_ptr, size as usize) } .copy_from_slice(&array_buffer); } - let _ = gfx_select!(buffer_id => global.buffer_unmap(buffer_id)); + let result = gfx_select!(buffer_id => global.buffer_unmap(buffer_id)); + self.send_result(device_id, scope_id, result); }, WebGPURequest::UpdateWebRenderData { buffer_id, @@ -1105,21 +1145,24 @@ impl<'a> WGPU<'a> { }, WebGPURequest::WriteBuffer { queue_id, + scope_id, buffer_id, buffer_offset, data, } => { let global = &self.global; //TODO: Report result to content process - let _ = gfx_select!(queue_id => global.queue_write_buffer( + let result = gfx_select!(queue_id => global.queue_write_buffer( queue_id, buffer_id, buffer_offset as wgt::BufferAddress, &data )); + self.send_result(queue_id, scope_id, result); }, WebGPURequest::WriteTexture { queue_id, + scope_id, texture_cv, data_layout, size, @@ -1127,20 +1170,21 @@ impl<'a> WGPU<'a> { } => { let global = &self.global; //TODO: Report result to content process - let _ = gfx_select!(queue_id => global.queue_write_texture( + let result = gfx_select!(queue_id => global.queue_write_texture( queue_id, &texture_cv, &data, &data_layout, &size )); + self.send_result(queue_id, scope_id, result); }, } } } } - fn send_result( + fn send_result( &self, device_id: id::DeviceId, scope_id: Option, From cd8d9162e66b9cdf03918fc3c24d855e6938edb7 Mon Sep 17 00:00:00 2001 From: Kunal Mohan Date: Sun, 2 Aug 2020 12:45:22 +0530 Subject: [PATCH 2/4] Error handling for promise returning operations --- components/script/dom/gpu.rs | 25 +++++---- components/script/dom/gpuadapter.rs | 17 ++++-- components/script/dom/gpubuffer.rs | 56 ++++++++++++------- .../script/dom/webidls/GPUBuffer.webidl | 4 +- components/webgpu/lib.rs | 46 ++++++++++----- 5 files changed, 93 insertions(+), 55 deletions(-) diff --git a/components/script/dom/gpu.rs b/components/script/dom/gpu.rs index 2839ed94835..eea21c1b988 100644 --- a/components/script/dom/gpu.rs +++ b/components/script/dom/gpu.rs @@ -41,7 +41,7 @@ impl GPU { } pub trait AsyncWGPUListener { - fn handle_response(&self, response: WebGPUResponse, promise: &Rc); + fn handle_response(&self, response: WebGPUResponseResult, promise: &Rc); } struct WGPUResponse { @@ -53,13 +53,7 @@ impl WGPUResponse { #[allow(unrooted_must_root)] fn response(self, response: WebGPUResponseResult) { let promise = self.trusted.root(); - match response { - Ok(response) => self.receiver.root().handle_response(response, &promise), - Err(error) => promise.reject_error(Error::Type(format!( - "Received error from WebGPU thread: {}", - error - ))), - } + self.receiver.root().handle_response(response, &promise); } } @@ -134,13 +128,13 @@ impl GPUMethods for GPU { } impl AsyncWGPUListener for GPU { - fn handle_response(&self, response: WebGPUResponse, promise: &Rc) { + fn handle_response(&self, response: WebGPUResponseResult, promise: &Rc) { match response { - WebGPUResponse::RequestAdapter { + Ok(WebGPUResponse::RequestAdapter { adapter_name, adapter_id, channel, - } => { + }) => { let adapter = GPUAdapter::new( &self.global(), channel, @@ -150,7 +144,14 @@ impl AsyncWGPUListener for GPU { ); promise.resolve_native(&adapter); }, - _ => promise.reject_error(Error::Operation), + Err(e) => { + warn!("Could not get GPUAdapter ({:?})", e); + promise.resolve_native(&None::); + }, + _ => { + warn!("GPU received wrong WebGPUResponse"); + promise.reject_error(Error::Operation); + }, } } } diff --git a/components/script/dom/gpuadapter.rs b/components/script/dom/gpuadapter.rs index 9392f1414fa..ca4eaacd2ae 100644 --- a/components/script/dom/gpuadapter.rs +++ b/components/script/dom/gpuadapter.rs @@ -20,7 +20,7 @@ use dom_struct::dom_struct; use js::jsapi::{Heap, JSObject}; use std::ptr::NonNull; use std::rc::Rc; -use webgpu::{wgt, WebGPU, WebGPUAdapter, WebGPURequest, WebGPUResponse}; +use webgpu::{wgt, WebGPU, WebGPUAdapter, WebGPURequest, WebGPUResponse, WebGPUResponseResult}; #[dom_struct] pub struct GPUAdapter { @@ -114,14 +114,14 @@ impl GPUAdapterMethods for GPUAdapter { } impl AsyncWGPUListener for GPUAdapter { - fn handle_response(&self, response: WebGPUResponse, promise: &Rc) { + fn handle_response(&self, response: WebGPUResponseResult, promise: &Rc) { match response { - WebGPUResponse::RequestDevice { + Ok(WebGPUResponse::RequestDevice { device_id, queue_id, _descriptor, label, - } => { + }) => { let device = GPUDevice::new( &self.global(), self.channel.clone(), @@ -135,7 +135,14 @@ impl AsyncWGPUListener for GPUAdapter { self.global().add_gpu_device(&device); promise.resolve_native(&device); }, - _ => promise.reject_error(Error::Operation), + Err(e) => { + warn!("Could not get GPUDevice({:?})", e); + promise.reject_error(Error::Operation); + }, + _ => { + warn!("GPUAdapter received wrong WebGPUResponse"); + promise.reject_error(Error::Operation); + }, } } } diff --git a/components/script/dom/gpubuffer.rs b/components/script/dom/gpubuffer.rs index 0650e1390e1..330e6a27efd 100644 --- a/components/script/dom/gpubuffer.rs +++ b/components/script/dom/gpubuffer.rs @@ -26,7 +26,10 @@ use std::ffi::c_void; use std::ops::Range; use std::ptr::NonNull; use std::rc::Rc; -use webgpu::{wgpu::device::HostMap, WebGPU, WebGPUBuffer, WebGPURequest, WebGPUResponse}; +use webgpu::{ + wgpu::device::HostMap, WebGPU, WebGPUBuffer, WebGPURequest, WebGPUResponse, + WebGPUResponseResult, +}; const RANGE_OFFSET_ALIGN_MASK: u64 = 8; const RANGE_SIZE_ALIGN_MASK: u64 = 4; @@ -197,19 +200,21 @@ impl GPUBufferMethods for GPUBuffer { &self, mode: u32, offset: GPUSize64, - size: GPUSize64, + size: Option, comp: InRealm, ) -> Rc { let promise = Promise::new_in_current_realm(&self.global(), comp); - let map_range = if size == 0 { - offset..self.size + if self.state.get() != GPUBufferState::Unmapped { + promise.reject_error(Error::Abort); + return promise; + } + let range_size = if let Some(s) = size { + s + } else if offset >= self.size { + promise.reject_error(Error::Operation); + return promise; } else { - if offset + size > self.size { - warn!("Requested mapping size is greated than buffer size"); - promise.reject_error(Error::Abort); - return promise; - } - offset..offset + size + self.size - offset }; let host_map = match mode { GPUMapModeConstants::READ => HostMap::Read, @@ -219,10 +224,8 @@ impl GPUBufferMethods for GPUBuffer { return promise; }, }; - if self.state.get() != GPUBufferState::Unmapped { - promise.reject_error(Error::Abort); - return promise; - } + + let map_range = offset..offset + range_size; let sender = response_async(&promise, self); if let Err(e) = self.channel.0.send(WebGPURequest::BufferMapAsync { @@ -257,9 +260,16 @@ impl GPUBufferMethods for GPUBuffer { &self, cx: JSContext, offset: GPUSize64, - size: GPUSize64, + size: Option, ) -> Fallible> { - let m_end = if size == 0 { self.size } else { offset + size }; + let range_size = if let Some(s) = size { + s + } else if offset >= self.size { + return Err(Error::Operation); + } else { + self.size - offset + }; + let m_end = offset + range_size; let mut info = self.map_info.borrow_mut(); let m_info = info.as_mut().unwrap(); @@ -268,7 +278,7 @@ impl GPUBufferMethods for GPUBuffer { _ => false, }; valid &= offset % RANGE_OFFSET_ALIGN_MASK == 0 && - (m_end - offset) % RANGE_SIZE_ALIGN_MASK == 0 && + range_size % RANGE_SIZE_ALIGN_MASK == 0 && offset >= m_info.mapping_range.start && m_end <= m_info.mapping_range.end; valid &= m_info @@ -286,7 +296,7 @@ impl GPUBufferMethods for GPUBuffer { let array_buffer = unsafe { NewExternalArrayBuffer( *cx, - (m_end - offset) as usize, + range_size as usize, m_info.mapping.borrow_mut()[offset as usize..m_end as usize].as_mut_ptr() as _, Some(free_func), Rc::into_raw(m_info.mapping.clone()) as _, @@ -312,9 +322,9 @@ impl GPUBufferMethods for GPUBuffer { impl AsyncWGPUListener for GPUBuffer { #[allow(unsafe_code)] - fn handle_response(&self, response: WebGPUResponse, promise: &Rc) { + fn handle_response(&self, response: WebGPUResponseResult, promise: &Rc) { match response { - WebGPUResponse::BufferMapAsync(bytes) => { + Ok(WebGPUResponse::BufferMapAsync(bytes)) => { *self .map_info .borrow_mut() @@ -325,8 +335,12 @@ impl AsyncWGPUListener for GPUBuffer { promise.resolve_native(&()); self.state.set(GPUBufferState::Mapped); }, + Err(e) => { + warn!("Could not map buffer({:?})", e); + promise.reject_error(Error::Abort); + }, _ => { - warn!("Wrong WebGPUResponse received"); + warn!("GPUBuffer received wrong WebGPUResponse"); promise.reject_error(Error::Operation); }, } diff --git a/components/script/dom/webidls/GPUBuffer.webidl b/components/script/dom/webidls/GPUBuffer.webidl index dc6936a60bf..2097db233e9 100644 --- a/components/script/dom/webidls/GPUBuffer.webidl +++ b/components/script/dom/webidls/GPUBuffer.webidl @@ -5,8 +5,8 @@ // https://gpuweb.github.io/gpuweb/#gpubuffer [Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"] interface GPUBuffer { - Promise mapAsync(GPUMapModeFlags mode, optional GPUSize64 offset = 0, optional GPUSize64 size = 0); - [Throws] ArrayBuffer getMappedRange(optional GPUSize64 offset = 0, optional GPUSize64 size = 0); + Promise mapAsync(GPUMapModeFlags mode, optional GPUSize64 offset = 0, optional GPUSize64 size); + [Throws] ArrayBuffer getMappedRange(optional GPUSize64 offset = 0, optional GPUSize64 size); void unmap(); void destroy(); diff --git a/components/webgpu/lib.rs b/components/webgpu/lib.rs index df42c685ae5..3fed81811e3 100644 --- a/components/webgpu/lib.rs +++ b/components/webgpu/lib.rs @@ -412,7 +412,7 @@ impl<'a> WGPU<'a> { } => { let map_info = BufferMapInfo { buffer_id, - sender, + sender: sender.clone(), global: &self.global, size: (map_range.end - map_range.start) as usize, external_id: None, @@ -426,22 +426,24 @@ impl<'a> WGPU<'a> { let info = Rc::from_raw( userdata as *const BufferMapInfo, ); - match status { + let msg = match status { BufferMapAsyncStatus::Success => { let global = &info.global; let data_pt = gfx_select!(info.buffer_id => global.buffer_get_mapped_range(info.buffer_id, 0, None)) .unwrap(); let data = slice::from_raw_parts(data_pt, info.size); - if let Err(e) = - info.sender.send(Ok(WebGPUResponse::BufferMapAsync( - IpcSharedMemory::from_bytes(data), - ))) - { - warn!("Could not send BufferMapAsync Response ({})", e); - } + Ok(WebGPUResponse::BufferMapAsync(IpcSharedMemory::from_bytes( + data, + ))) }, - _ => error!("Could not map buffer({:?})", info.buffer_id), + _ => { + warn!("Could not map buffer({:?})", info.buffer_id); + Err(String::from("Failed to map Buffer")) + }, + }; + if let Err(e) = info.sender.send(msg) { + warn!("Could not send BufferMapAsync Response ({})", e); } } @@ -453,7 +455,12 @@ impl<'a> WGPU<'a> { ), }; let global = &self.global; - let _ = gfx_select!(buffer_id => global.buffer_map_async(buffer_id, map_range, operation)); + let result = gfx_select!(buffer_id => global.buffer_map_async(buffer_id, map_range, operation)); + if let Err(e) = result { + if let Err(w) = sender.send(Err(format!("{:?}", e))) { + warn!("Failed to send BufferMapAsync Response ({:?})", w); + } + } }, WebGPURequest::BufferMapComplete(buffer_id) => { self.buffer_maps.remove(&buffer_id); @@ -892,14 +899,23 @@ impl<'a> WGPU<'a> { label, } => { let global = &self.global; - let result = gfx_select!(device_id => global.adapter_request_device( + let id = match gfx_select!(device_id => global.adapter_request_device( adapter_id.0, &descriptor, None, device_id - )); - // TODO: Handle error gracefully acc. to spec. - let id = result.unwrap(); + )) { + Ok(id) => id, + Err(e) => { + if let Err(w) = sender.send(Err(format!("{:?}", e))) { + warn!( + "Failed to send response to WebGPURequest::RequestDevice ({})", + w + ) + } + return; + }, + }; let device = WebGPUDevice(id); // Note: (zakorgy) Note sure if sending the queue is needed at all, // since wgpu-core uses the same id for the device and the queue From 8eff1d74de989f837eb54e80fb7296a98ef3220b Mon Sep 17 00:00:00 2001 From: Kunal Mohan Date: Sun, 2 Aug 2020 14:25:18 +0530 Subject: [PATCH 3/4] Record validation error in mapAsync() --- components/script/dom/gpubuffer.rs | 24 ++++++++++++++++++------ components/webgpu/lib.rs | 7 ++++++- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/components/script/dom/gpubuffer.rs b/components/script/dom/gpubuffer.rs index 330e6a27efd..04b8a9ed982 100644 --- a/components/script/dom/gpubuffer.rs +++ b/components/script/dom/gpubuffer.rs @@ -26,9 +26,10 @@ use std::ffi::c_void; use std::ops::Range; use std::ptr::NonNull; use std::rc::Rc; +use std::string::String; use webgpu::{ - wgpu::device::HostMap, WebGPU, WebGPUBuffer, WebGPURequest, WebGPUResponse, - WebGPUResponseResult, + identity::WebGPUOpResult, wgpu::device::HostMap, WebGPU, WebGPUBuffer, WebGPURequest, + WebGPUResponse, WebGPUResponseResult, }; const RANGE_OFFSET_ALIGN_MASK: u64 = 8; @@ -204,10 +205,6 @@ impl GPUBufferMethods for GPUBuffer { comp: InRealm, ) -> Rc { let promise = Promise::new_in_current_realm(&self.global(), comp); - if self.state.get() != GPUBufferState::Unmapped { - promise.reject_error(Error::Abort); - return promise; - } let range_size = if let Some(s) = size { s } else if offset >= self.size { @@ -216,10 +213,23 @@ impl GPUBufferMethods for GPUBuffer { } else { self.size - offset }; + let scope_id = self.device.use_current_scope(); + if self.state.get() != GPUBufferState::Unmapped { + self.device.handle_server_msg( + scope_id, + WebGPUOpResult::ValidationError(String::from("Buffer is not Unmapped")), + ); + promise.reject_error(Error::Abort); + return promise; + } let host_map = match mode { GPUMapModeConstants::READ => HostMap::Read, GPUMapModeConstants::WRITE => HostMap::Write, _ => { + self.device.handle_server_msg( + scope_id, + WebGPUOpResult::ValidationError(String::from("Invalid MapModeFlags")), + ); promise.reject_error(Error::Abort); return promise; }, @@ -231,6 +241,8 @@ impl GPUBufferMethods for GPUBuffer { if let Err(e) = self.channel.0.send(WebGPURequest::BufferMapAsync { sender, buffer_id: self.buffer.0, + device_id: self.device.id().0, + scope_id, host_map, map_range: map_range.clone(), }) { diff --git a/components/webgpu/lib.rs b/components/webgpu/lib.rs index 3fed81811e3..d73fd4045d4 100644 --- a/components/webgpu/lib.rs +++ b/components/webgpu/lib.rs @@ -67,6 +67,8 @@ pub enum WebGPURequest { BufferMapAsync { sender: IpcSender, buffer_id: id::BufferId, + device_id: id::DeviceId, + scope_id: Option, host_map: HostMap, map_range: std::ops::Range, }, @@ -407,6 +409,8 @@ impl<'a> WGPU<'a> { WebGPURequest::BufferMapAsync { sender, buffer_id, + device_id, + scope_id, host_map, map_range, } => { @@ -456,11 +460,12 @@ impl<'a> WGPU<'a> { }; let global = &self.global; let result = gfx_select!(buffer_id => global.buffer_map_async(buffer_id, map_range, operation)); - if let Err(e) = result { + if let Err(ref e) = result { if let Err(w) = sender.send(Err(format!("{:?}", e))) { warn!("Failed to send BufferMapAsync Response ({:?})", w); } } + self.send_result(device_id, scope_id, result); }, WebGPURequest::BufferMapComplete(buffer_id) => { self.buffer_maps.remove(&buffer_id); From ce6e09a3aa3b9ef20dcc8f1ff5712f7a2691aa27 Mon Sep 17 00:00:00 2001 From: Kunal Mohan Date: Mon, 3 Aug 2020 01:45:29 +0530 Subject: [PATCH 4/4] Change ErrorScopeId type to NonZeroU64 And extract it from WebGPURequest --- components/constellation/constellation.rs | 2 +- components/malloc_size_of/lib.rs | 1 + components/script/dom/bindings/trace.rs | 2 + components/script/dom/globalscope.rs | 4 +- components/script/dom/gpuadapter.rs | 19 +-- components/script/dom/gpubuffer.rs | 42 +++--- components/script/dom/gpucanvascontext.rs | 36 +++-- components/script/dom/gpucommandencoder.rs | 90 +++++++----- .../script/dom/gpucomputepassencoder.rs | 14 +- components/script/dom/gpudevice.rs | 128 ++++++++++-------- components/script/dom/gpuqueue.rs | 44 +++--- .../script/dom/gpurenderbundleencoder.rs | 16 ++- components/script/dom/gpurenderpassencoder.rs | 14 +- components/script/dom/gpuswapchain.rs | 11 +- components/script/dom/gputexture.rs | 16 ++- components/webgpu/identity.rs | 18 +-- components/webgpu/lib.rs | 70 ++-------- 17 files changed, 277 insertions(+), 250 deletions(-) diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 4b06efd0cdf..a9b114fa7bd 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -2169,7 +2169,7 @@ where options, ids, }; - if webgpu_chan.0.send(adapter_request).is_err() { + if webgpu_chan.0.send((None, adapter_request)).is_err() { return warn!("Failed to send request adapter message on WebGPU channel"); } }, diff --git a/components/malloc_size_of/lib.rs b/components/malloc_size_of/lib.rs index 9caf427f475..040d88ec6eb 100644 --- a/components/malloc_size_of/lib.rs +++ b/components/malloc_size_of/lib.rs @@ -831,6 +831,7 @@ malloc_size_of_is_0!(bool, char, str); malloc_size_of_is_0!(u8, u16, u32, u64, u128, usize); malloc_size_of_is_0!(i8, i16, i32, i64, i128, isize); malloc_size_of_is_0!(f32, f64); +malloc_size_of_is_0!(std::num::NonZeroU64); malloc_size_of_is_0!(std::sync::atomic::AtomicBool); malloc_size_of_is_0!(std::sync::atomic::AtomicIsize); diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 0a42f1b2152..02b72fc3c2d 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -138,6 +138,7 @@ use std::cell::{Cell, RefCell, UnsafeCell}; use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; use std::hash::{BuildHasher, Hash}; use std::mem; +use std::num::NonZeroU64; use std::ops::{Deref, DerefMut, Range}; use std::path::PathBuf; use std::rc::Rc; @@ -524,6 +525,7 @@ unsafe_no_jsmanaged_fields!(ActiveUniformBlockInfo); unsafe_no_jsmanaged_fields!(bool, f32, f64, String, AtomicBool, AtomicUsize, Uuid, char); unsafe_no_jsmanaged_fields!(usize, u8, u16, u32, u64); unsafe_no_jsmanaged_fields!(isize, i8, i16, i32, i64); +unsafe_no_jsmanaged_fields!(NonZeroU64); unsafe_no_jsmanaged_fields!(Error); unsafe_no_jsmanaged_fields!(ServoUrl, ImmutableOrigin, MutableOrigin); unsafe_no_jsmanaged_fields!(Image, ImageMetadata, dyn ImageCache, PendingImageId); diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 9397b48a630..ee1b5553bc7 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -127,7 +127,7 @@ use std::sync::Arc; use std::thread::JoinHandle; use time::{get_time, Timespec}; use uuid::Uuid; -use webgpu::{identity::WebGPUOpResult, WebGPUDevice}; +use webgpu::{identity::WebGPUOpResult, ErrorScopeId, WebGPUDevice}; #[derive(JSTraceable)] pub struct AutoCloseWorker { @@ -3023,7 +3023,7 @@ impl GlobalScope { pub fn handle_wgpu_msg( &self, device: WebGPUDevice, - scope: Option, + scope: Option, result: WebGPUOpResult, ) { self.gpu_devices diff --git a/components/script/dom/gpuadapter.rs b/components/script/dom/gpuadapter.rs index ca4eaacd2ae..57344185a57 100644 --- a/components/script/dom/gpuadapter.rs +++ b/components/script/dom/gpuadapter.rs @@ -97,14 +97,17 @@ impl GPUAdapterMethods for GPUAdapter { if self .channel .0 - .send(WebGPURequest::RequestDevice { - sender, - adapter_id: self.adapter, - descriptor: desc, - device_id: id, - pipeline_id, - label: descriptor.parent.label.as_ref().map(|s| s.to_string()), - }) + .send(( + None, + WebGPURequest::RequestDevice { + sender, + adapter_id: self.adapter, + descriptor: desc, + device_id: id, + pipeline_id, + label: descriptor.parent.label.as_ref().map(|s| s.to_string()), + }, + )) .is_err() { promise.reject_error(Error::Operation); diff --git a/components/script/dom/gpubuffer.rs b/components/script/dom/gpubuffer.rs index 04b8a9ed982..2d721465e68 100644 --- a/components/script/dom/gpubuffer.rs +++ b/components/script/dom/gpubuffer.rs @@ -146,15 +146,19 @@ impl GPUBufferMethods for GPUBuffer { let mut info = self.map_info.borrow_mut(); let m_info = info.as_mut().unwrap(); let m_range = m_info.mapping_range.clone(); - if let Err(e) = self.channel.0.send(WebGPURequest::UnmapBuffer { - buffer_id: self.id().0, - device_id: self.device.id().0, - scope_id: self.device.use_current_scope(), - array_buffer: IpcSharedMemory::from_bytes(m_info.mapping.borrow().as_slice()), - is_map_read: m_info.map_mode == Some(GPUMapModeConstants::READ), - offset: m_range.start, - size: m_range.end - m_range.start, - }) { + if let Err(e) = self.channel.0.send(( + self.device.use_current_scope(), + WebGPURequest::UnmapBuffer { + buffer_id: self.id().0, + device_id: self.device.id().0, + array_buffer: IpcSharedMemory::from_bytes( + m_info.mapping.borrow().as_slice(), + ), + is_map_read: m_info.map_mode == Some(GPUMapModeConstants::READ), + offset: m_range.start, + size: m_range.end - m_range.start, + }, + )) { warn!("Failed to send Buffer unmap ({:?}) ({})", self.buffer.0, e); } // Step 3.3 @@ -185,7 +189,7 @@ impl GPUBufferMethods for GPUBuffer { if let Err(e) = self .channel .0 - .send(WebGPURequest::DestroyBuffer(self.buffer.0)) + .send((None, WebGPURequest::DestroyBuffer(self.buffer.0))) { warn!( "Failed to send WebGPURequest::DestroyBuffer({:?}) ({})", @@ -238,14 +242,16 @@ impl GPUBufferMethods for GPUBuffer { let map_range = offset..offset + range_size; let sender = response_async(&promise, self); - if let Err(e) = self.channel.0.send(WebGPURequest::BufferMapAsync { - sender, - buffer_id: self.buffer.0, - device_id: self.device.id().0, + if let Err(e) = self.channel.0.send(( scope_id, - host_map, - map_range: map_range.clone(), - }) { + WebGPURequest::BufferMapAsync { + sender, + buffer_id: self.buffer.0, + device_id: self.device.id().0, + host_map, + map_range: map_range.clone(), + }, + )) { warn!( "Failed to send BufferMapAsync ({:?}) ({})", self.buffer.0, e @@ -360,7 +366,7 @@ impl AsyncWGPUListener for GPUBuffer { if let Err(e) = self .channel .0 - .send(WebGPURequest::BufferMapComplete(self.buffer.0)) + .send((None, WebGPURequest::BufferMapComplete(self.buffer.0))) { warn!( "Failed to send BufferMapComplete({:?}) ({})", diff --git a/components/script/dom/gpucanvascontext.rs b/components/script/dom/gpucanvascontext.rs index 511f78634ef..c0391d7ca61 100644 --- a/components/script/dom/gpucanvascontext.rs +++ b/components/script/dom/gpucanvascontext.rs @@ -45,7 +45,9 @@ pub struct GPUCanvasContext { impl GPUCanvasContext { fn new_inherited(canvas: &HTMLCanvasElement, size: Size2D, channel: WebGPU) -> Self { let (sender, receiver) = ipc::channel().unwrap(); - let _ = channel.0.send(WebGPURequest::CreateContext(sender)); + if let Err(e) = channel.0.send((None, WebGPURequest::CreateContext(sender))) { + warn!("Failed to send CreateContext ({:?})", e); + } let external_id = receiver.recv().unwrap(); Self { reflector_: Reflector::new(), @@ -88,11 +90,14 @@ impl GPUCanvasContext { .wgpu_id_hub() .lock() .create_command_encoder_id(texture_id.backend()); - if let Err(e) = self.channel.0.send(WebGPURequest::SwapChainPresent { - external_id: self.context_id.0, - texture_id, - encoder_id, - }) { + if let Err(e) = self.channel.0.send(( + None, + WebGPURequest::SwapChainPresent { + external_id: self.context_id.0, + texture_id, + encoder_id, + }, + )) { warn!( "Failed to send UpdateWebrenderData({:?}) ({})", self.context_id, e @@ -168,14 +173,17 @@ impl GPUCanvasContextMethods for GPUCanvasContext { self.channel .0 - .send(WebGPURequest::CreateSwapChain { - device_id: descriptor.device.id().0, - buffer_ids, - external_id: self.context_id.0, - sender, - image_desc, - image_data, - }) + .send(( + None, + WebGPURequest::CreateSwapChain { + device_id: descriptor.device.id().0, + buffer_ids, + external_id: self.context_id.0, + sender, + image_desc, + image_data, + }, + )) .expect("Failed to create WebGPU SwapChain"); let usage = if descriptor.usage % 2 == 0 { diff --git a/components/script/dom/gpucommandencoder.rs b/components/script/dom/gpucommandencoder.rs index 6e3b01787f8..9fabd77a6fa 100644 --- a/components/script/dom/gpucommandencoder.rs +++ b/components/script/dom/gpucommandencoder.rs @@ -277,16 +277,18 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { .insert(DomRoot::from_ref(destination)); self.channel .0 - .send(WebGPURequest::CopyBufferToBuffer { - command_encoder_id: self.encoder.0, - device_id: self.device.id().0, + .send(( scope_id, - source_id: source.id().0, - source_offset, - destination_id: destination.id().0, - destination_offset, - size, - }) + WebGPURequest::CopyBufferToBuffer { + command_encoder_id: self.encoder.0, + device_id: self.device.id().0, + source_id: source.id().0, + source_offset, + destination_id: destination.id().0, + destination_offset, + size, + }, + )) .expect("Failed to send CopyBufferToBuffer"); } @@ -317,14 +319,18 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { self.channel .0 - .send(WebGPURequest::CopyBufferToTexture { - command_encoder_id: self.encoder.0, - device_id: self.device.id().0, + .send(( scope_id, - source: convert_buffer_cv(source), - destination: convert_texture_cv(destination), - copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict(©_size)), - }) + WebGPURequest::CopyBufferToTexture { + command_encoder_id: self.encoder.0, + device_id: self.device.id().0, + source: convert_buffer_cv(source), + destination: convert_texture_cv(destination), + copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict( + ©_size, + )), + }, + )) .expect("Failed to send CopyBufferToTexture"); } @@ -355,14 +361,18 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { self.channel .0 - .send(WebGPURequest::CopyTextureToBuffer { - command_encoder_id: self.encoder.0, - device_id: self.device.id().0, + .send(( scope_id, - source: convert_texture_cv(source), - destination: convert_buffer_cv(destination), - copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict(©_size)), - }) + WebGPURequest::CopyTextureToBuffer { + command_encoder_id: self.encoder.0, + device_id: self.device.id().0, + source: convert_texture_cv(source), + destination: convert_buffer_cv(destination), + copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict( + ©_size, + )), + }, + )) .expect("Failed to send CopyTextureToBuffer"); } @@ -389,14 +399,18 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { self.channel .0 - .send(WebGPURequest::CopyTextureToTexture { - command_encoder_id: self.encoder.0, - device_id: self.device.id().0, + .send(( scope_id, - source: convert_texture_cv(source), - destination: convert_texture_cv(destination), - copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict(©_size)), - }) + WebGPURequest::CopyTextureToTexture { + command_encoder_id: self.encoder.0, + device_id: self.device.id().0, + source: convert_texture_cv(source), + destination: convert_texture_cv(destination), + copy_size: convert_texture_size_to_wgt(&convert_texture_size_to_dict( + ©_size, + )), + }, + )) .expect("Failed to send CopyTextureToTexture"); } @@ -404,13 +418,15 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { fn Finish(&self, descriptor: &GPUCommandBufferDescriptor) -> DomRoot { self.channel .0 - .send(WebGPURequest::CommandEncoderFinish { - command_encoder_id: self.encoder.0, - device_id: self.device.id().0, - scope_id: self.device.use_current_scope(), - // TODO(zakorgy): We should use `_descriptor` here after it's not empty - // and the underlying wgpu-core struct is serializable - }) + .send(( + self.device.use_current_scope(), + WebGPURequest::CommandEncoderFinish { + command_encoder_id: self.encoder.0, + device_id: self.device.id().0, + // TODO(zakorgy): We should use `_descriptor` here after it's not empty + // and the underlying wgpu-core struct is serializable + }, + )) .expect("Failed to send Finish"); *self.state.borrow_mut() = GPUCommandEncoderState::Closed; diff --git a/components/script/dom/gpucomputepassencoder.rs b/components/script/dom/gpucomputepassencoder.rs index f35313295e6..c55eaf86fe2 100644 --- a/components/script/dom/gpucomputepassencoder.rs +++ b/components/script/dom/gpucomputepassencoder.rs @@ -91,12 +91,14 @@ impl GPUComputePassEncoderMethods for GPUComputePassEncoder { if let Some(compute_pass) = self.compute_pass.borrow_mut().take() { self.channel .0 - .send(WebGPURequest::RunComputePass { - command_encoder_id: self.command_encoder.id().0, - device_id: self.command_encoder.device().id().0, - scope_id: self.command_encoder.device().use_current_scope(), - compute_pass, - }) + .send(( + self.command_encoder.device().use_current_scope(), + WebGPURequest::RunComputePass { + command_encoder_id: self.command_encoder.id().0, + device_id: self.command_encoder.device().id().0, + compute_pass, + }, + )) .expect("Failed to send RunComputePass"); self.command_encoder.set_state( diff --git a/components/script/dom/gpudevice.rs b/components/script/dom/gpudevice.rs index adde335bd47..9e3e6d4976d 100644 --- a/components/script/dom/gpudevice.rs +++ b/components/script/dom/gpudevice.rs @@ -71,9 +71,7 @@ use std::rc::Rc; use webgpu::wgpu::{ binding_model as wgpu_bind, command::RenderBundleEncoder, pipeline as wgpu_pipe, }; -use webgpu::{self, identity::WebGPUOpResult, wgt, WebGPU, WebGPURequest}; - -type ErrorScopeId = u64; +use webgpu::{self, identity::WebGPUOpResult, wgt, ErrorScopeId, WebGPU, WebGPURequest}; #[derive(JSTraceable, MallocSizeOf)] struct ErrorScopeInfo { @@ -131,7 +129,7 @@ impl GPUDevice { scope_context: DomRefCell::new(ScopeContext { error_scopes: HashMap::new(), scope_stack: Vec::new(), - next_scope_id: 0, + next_scope_id: ErrorScopeId::new(1).unwrap(), }), lost_promise: DomRefCell::new(None), } @@ -313,12 +311,14 @@ impl GPUDeviceMethods for GPUDevice { let scope_id = self.use_current_scope(); self.channel .0 - .send(WebGPURequest::CreateBuffer { - device_id: self.device.0, + .send(( scope_id, - buffer_id: id, - descriptor: wgpu_descriptor, - }) + WebGPURequest::CreateBuffer { + device_id: self.device.0, + buffer_id: id, + descriptor: wgpu_descriptor, + }, + )) .expect("Failed to create WebGPU buffer"); let buffer = webgpu::WebGPUBuffer(id); @@ -451,12 +451,14 @@ impl GPUDeviceMethods for GPUDevice { .create_bind_group_layout_id(self.device.0.backend()); self.channel .0 - .send(WebGPURequest::CreateBindGroupLayout { - device_id: self.device.0, - bind_group_layout_id, + .send(( scope_id, - descriptor: desc, - }) + WebGPURequest::CreateBindGroupLayout { + device_id: self.device.0, + bind_group_layout_id, + descriptor: desc, + }, + )) .expect("Failed to create WebGPU BindGroupLayout"); let bgl = webgpu::WebGPUBindGroupLayout(bind_group_layout_id); @@ -493,12 +495,14 @@ impl GPUDeviceMethods for GPUDevice { .create_pipeline_layout_id(self.device.0.backend()); self.channel .0 - .send(WebGPURequest::CreatePipelineLayout { - device_id: self.device.0, - pipeline_layout_id, - descriptor: desc, + .send(( scope_id, - }) + WebGPURequest::CreatePipelineLayout { + device_id: self.device.0, + pipeline_layout_id, + descriptor: desc, + }, + )) .expect("Failed to create WebGPU PipelineLayout"); let pipeline_layout = webgpu::WebGPUPipelineLayout(pipeline_layout_id); @@ -553,12 +557,14 @@ impl GPUDeviceMethods for GPUDevice { .create_bind_group_id(self.device.0.backend()); self.channel .0 - .send(WebGPURequest::CreateBindGroup { - device_id: self.device.0, - bind_group_id, - descriptor: desc, + .send(( scope_id, - }) + WebGPURequest::CreateBindGroup { + device_id: self.device.0, + bind_group_id, + descriptor: desc, + }, + )) .expect("Failed to create WebGPU BindGroup"); let bind_group = webgpu::WebGPUBindGroup(bind_group_id); @@ -592,12 +598,14 @@ impl GPUDeviceMethods for GPUDevice { let scope_id = self.use_current_scope(); self.channel .0 - .send(WebGPURequest::CreateShaderModule { - device_id: self.device.0, + .send(( scope_id, - program_id, - program, - }) + WebGPURequest::CreateShaderModule { + device_id: self.device.0, + program_id, + program, + }, + )) .expect("Failed to create WebGPU ShaderModule"); let shader_module = webgpu::WebGPUShaderModule(program_id); @@ -631,12 +639,14 @@ impl GPUDeviceMethods for GPUDevice { self.channel .0 - .send(WebGPURequest::CreateComputePipeline { - device_id: self.device.0, + .send(( scope_id, - compute_pipeline_id, - descriptor: desc, - }) + WebGPURequest::CreateComputePipeline { + device_id: self.device.0, + compute_pipeline_id, + descriptor: desc, + }, + )) .expect("Failed to create WebGPU ComputePipeline"); let compute_pipeline = webgpu::WebGPUComputePipeline(compute_pipeline_id); @@ -660,12 +670,14 @@ impl GPUDeviceMethods for GPUDevice { let scope_id = self.use_current_scope(); self.channel .0 - .send(WebGPURequest::CreateCommandEncoder { - device_id: self.device.0, + .send(( scope_id, - command_encoder_id, - label: descriptor.parent.label.as_ref().map(|s| s.to_string()), - }) + WebGPURequest::CreateCommandEncoder { + device_id: self.device.0, + command_encoder_id, + label: descriptor.parent.label.as_ref().map(|s| s.to_string()), + }, + )) .expect("Failed to create WebGPU command encoder"); let encoder = webgpu::WebGPUCommandEncoder(command_encoder_id); @@ -710,12 +722,14 @@ impl GPUDeviceMethods for GPUDevice { self.channel .0 - .send(WebGPURequest::CreateTexture { - device_id: self.device.0, - texture_id, - descriptor: desc, + .send(( scope_id, - }) + WebGPURequest::CreateTexture { + device_id: self.device.0, + texture_id, + descriptor: desc, + }, + )) .expect("Failed to create WebGPU Texture"); let texture = webgpu::WebGPUTexture(texture_id); @@ -761,12 +775,14 @@ impl GPUDeviceMethods for GPUDevice { let scope_id = self.use_current_scope(); self.channel .0 - .send(WebGPURequest::CreateSampler { - device_id: self.device.0, + .send(( scope_id, - sampler_id, - descriptor: desc, - }) + WebGPURequest::CreateSampler { + device_id: self.device.0, + sampler_id, + descriptor: desc, + }, + )) .expect("Failed to create WebGPU sampler"); let sampler = webgpu::WebGPUSampler(sampler_id); @@ -903,12 +919,14 @@ impl GPUDeviceMethods for GPUDevice { self.channel .0 - .send(WebGPURequest::CreateRenderPipeline { - device_id: self.device.0, - render_pipeline_id, + .send(( scope_id, - descriptor: desc, - }) + WebGPURequest::CreateRenderPipeline { + device_id: self.device.0, + render_pipeline_id, + descriptor: desc, + }, + )) .expect("Failed to create WebGPU render pipeline"); let render_pipeline = webgpu::WebGPURenderPipeline(render_pipeline_id); @@ -961,7 +979,7 @@ impl GPUDeviceMethods for GPUDevice { fn PushErrorScope(&self, filter: GPUErrorFilter) { let mut context = self.scope_context.borrow_mut(); let scope_id = context.next_scope_id; - context.next_scope_id += 1; + context.next_scope_id = ErrorScopeId::new(scope_id.get() + 1).unwrap(); let err_scope = ErrorScopeInfo { op_count: 0, error: None, diff --git a/components/script/dom/gpuqueue.rs b/components/script/dom/gpuqueue.rs index d5c742555c7..e0a1fa2e7e8 100644 --- a/components/script/dom/gpuqueue.rs +++ b/components/script/dom/gpuqueue.rs @@ -88,11 +88,13 @@ impl GPUQueueMethods for GPUQueue { let command_buffers = command_buffers.iter().map(|cb| cb.id().0).collect(); self.channel .0 - .send(WebGPURequest::Submit { - queue_id: self.queue.0, + .send(( scope_id, - command_buffers, - }) + WebGPURequest::Submit { + queue_id: self.queue.0, + command_buffers, + }, + )) .unwrap(); } @@ -124,13 +126,15 @@ impl GPUQueueMethods for GPUQueue { let final_data = IpcSharedMemory::from_bytes( &bytes[data_offset as usize..(data_offset + content_size) as usize], ); - if let Err(e) = self.channel.0.send(WebGPURequest::WriteBuffer { - queue_id: self.queue.0, - scope_id: self.device.borrow().as_ref().unwrap().use_current_scope(), - buffer_id: buffer.id().0, - buffer_offset, - data: final_data, - }) { + if let Err(e) = self.channel.0.send(( + self.device.borrow().as_ref().unwrap().use_current_scope(), + WebGPURequest::WriteBuffer { + queue_id: self.queue.0, + buffer_id: buffer.id().0, + buffer_offset, + data: final_data, + }, + )) { warn!("Failed to send WriteBuffer({:?}) ({})", buffer.id(), e); return Err(Error::Operation); } @@ -158,14 +162,16 @@ impl GPUQueueMethods for GPUQueue { let write_size = convert_texture_size_to_wgt(&convert_texture_size_to_dict(&size)); let final_data = IpcSharedMemory::from_bytes(&bytes); - if let Err(e) = self.channel.0.send(WebGPURequest::WriteTexture { - queue_id: self.queue.0, - scope_id: self.device.borrow().as_ref().unwrap().use_current_scope(), - texture_cv, - data_layout: texture_layout, - size: write_size, - data: final_data, - }) { + if let Err(e) = self.channel.0.send(( + self.device.borrow().as_ref().unwrap().use_current_scope(), + WebGPURequest::WriteTexture { + queue_id: self.queue.0, + texture_cv, + data_layout: texture_layout, + size: write_size, + data: final_data, + }, + )) { warn!( "Failed to send WriteTexture({:?}) ({})", destination.texture.id().0, diff --git a/components/script/dom/gpurenderbundleencoder.rs b/components/script/dom/gpurenderbundleencoder.rs index d227ad34ff7..7557171a9f5 100644 --- a/components/script/dom/gpurenderbundleencoder.rs +++ b/components/script/dom/gpurenderbundleencoder.rs @@ -195,13 +195,15 @@ impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder { self.channel .0 - .send(WebGPURequest::RenderBundleEncoderFinish { - render_bundle_encoder: encoder, - descriptor: desc, - render_bundle_id, - device_id: self.device.id().0, - scope_id: self.device.use_current_scope(), - }) + .send(( + self.device.use_current_scope(), + WebGPURequest::RenderBundleEncoderFinish { + render_bundle_encoder: encoder, + descriptor: desc, + render_bundle_id, + device_id: self.device.id().0, + }, + )) .expect("Failed to send RenderBundleEncoderFinish"); let render_bundle = WebGPURenderBundle(render_bundle_id); diff --git a/components/script/dom/gpurenderpassencoder.rs b/components/script/dom/gpurenderpassencoder.rs index 8117bfc3636..0e68b384ac5 100644 --- a/components/script/dom/gpurenderpassencoder.rs +++ b/components/script/dom/gpurenderpassencoder.rs @@ -163,12 +163,14 @@ impl GPURenderPassEncoderMethods for GPURenderPassEncoder { if let Some(render_pass) = self.render_pass.borrow_mut().take() { self.channel .0 - .send(WebGPURequest::RunRenderPass { - command_encoder_id: self.command_encoder.id().0, - device_id: self.command_encoder.device().id().0, - scope_id: self.command_encoder.device().use_current_scope(), - render_pass, - }) + .send(( + self.command_encoder.device().use_current_scope(), + WebGPURequest::RunRenderPass { + command_encoder_id: self.command_encoder.id().0, + device_id: self.command_encoder.device().id().0, + render_pass, + }, + )) .expect("Failed to send RunRenderPass"); self.command_encoder.set_state( diff --git a/components/script/dom/gpuswapchain.rs b/components/script/dom/gpuswapchain.rs index 1d50a00f40a..0552eea7564 100644 --- a/components/script/dom/gpuswapchain.rs +++ b/components/script/dom/gpuswapchain.rs @@ -57,10 +57,13 @@ impl GPUSwapChain { impl GPUSwapChain { pub fn destroy(&self, external_id: u64, image_key: webrender_api::ImageKey) { - if let Err(e) = self.channel.0.send(WebGPURequest::DestroySwapChain { - external_id, - image_key, - }) { + if let Err(e) = self.channel.0.send(( + None, + WebGPURequest::DestroySwapChain { + external_id, + image_key, + }, + )) { warn!( "Failed to send DestroySwapChain-ImageKey({:?}) ({})", image_key, e diff --git a/components/script/dom/gputexture.rs b/components/script/dom/gputexture.rs index e9c44858f94..64b56e82607 100644 --- a/components/script/dom/gputexture.rs +++ b/components/script/dom/gputexture.rs @@ -167,13 +167,15 @@ impl GPUTextureMethods for GPUTexture { self.channel .0 - .send(WebGPURequest::CreateTextureView { - texture_id: self.texture.0, - texture_view_id, - device_id: self.device.id().0, - descriptor: desc, + .send(( scope_id, - }) + WebGPURequest::CreateTextureView { + texture_id: self.texture.0, + texture_view_id, + device_id: self.device.id().0, + descriptor: desc, + }, + )) .expect("Failed to create WebGPU texture view"); let texture_view = WebGPUTextureView(texture_view_id); @@ -191,7 +193,7 @@ impl GPUTextureMethods for GPUTexture { if let Err(e) = self .channel .0 - .send(WebGPURequest::DestroyTexture(self.texture.0)) + .send((None, WebGPURequest::DestroyTexture(self.texture.0))) { warn!( "Failed to send WebGPURequest::DestroyTexture({:?}) ({})", diff --git a/components/webgpu/identity.rs b/components/webgpu/identity.rs index 516a296b94d..0d199f1c009 100644 --- a/components/webgpu/identity.rs +++ b/components/webgpu/identity.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::{WebGPUDevice, WebGPURequest}; +use crate::{ErrorScopeId, WebGPUDevice, WebGPURequest}; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::PipelineId; use serde::{Deserialize, Serialize}; @@ -43,7 +43,7 @@ pub enum WebGPUMsg { FreeRenderBundle(RenderBundleId), WebGPUOpResult { device: WebGPUDevice, - scope_id: Option, + scope_id: Option, pipeline_id: PipelineId, result: WebGPUOpResult, }, @@ -57,12 +57,12 @@ pub enum WebGPUMsg { #[derive(Debug)] pub struct IdentityRecycler { sender: IpcSender, - self_sender: IpcSender, + self_sender: IpcSender<(Option, WebGPURequest)>, } pub struct IdentityRecyclerFactory { pub sender: IpcSender, - pub self_sender: IpcSender, + pub self_sender: IpcSender<(Option, WebGPURequest)>, } macro_rules! impl_identity_handler { @@ -130,12 +130,14 @@ impl IdentityHandler for IdentityRecycler { } fn free(&self, id: DeviceId) { log::debug!("free device {:?}", id); - let msg = WebGPUMsg::FreeDevice(id); - if self.sender.send(msg).is_err() { + if self.sender.send(WebGPUMsg::FreeDevice(id)).is_err() { log::error!("Failed to send FreeDevice({:?}) to script", id); } - let msg_to_self = WebGPURequest::FreeDevice(id); - if self.self_sender.send(msg_to_self).is_err() { + if self + .self_sender + .send((None, WebGPURequest::FreeDevice(id))) + .is_err() + { log::error!("Failed to send FreeDevice({:?}) to server", id); } } diff --git a/components/webgpu/lib.rs b/components/webgpu/lib.rs index d73fd4045d4..7e20e30d4d6 100644 --- a/components/webgpu/lib.rs +++ b/components/webgpu/lib.rs @@ -22,6 +22,7 @@ use smallvec::SmallVec; use std::borrow::Cow; use std::collections::HashMap; use std::ffi::CString; +use std::num::NonZeroU64; use std::ptr; use std::rc::Rc; use std::slice; @@ -41,6 +42,7 @@ use wgpu::{ resource::{BufferMapAsyncStatus, BufferMapOperation}, }; +pub type ErrorScopeId = NonZeroU64; const DEVICE_POLL_INTERVAL: u64 = 100; pub const PRESENTATION_BUFFER_COUNT: usize = 10; @@ -68,7 +70,6 @@ pub enum WebGPURequest { sender: IpcSender, buffer_id: id::BufferId, device_id: id::DeviceId, - scope_id: Option, host_map: HostMap, map_range: std::ops::Range, }, @@ -76,14 +77,12 @@ pub enum WebGPURequest { CommandEncoderFinish { command_encoder_id: id::CommandEncoderId, device_id: id::DeviceId, - scope_id: Option, // TODO(zakorgy): Serialize CommandBufferDescriptor in wgpu-core // wgpu::command::CommandBufferDescriptor, }, CopyBufferToBuffer { command_encoder_id: id::CommandEncoderId, device_id: id::DeviceId, - scope_id: Option, source_id: id::BufferId, source_offset: wgt::BufferAddress, destination_id: id::BufferId, @@ -93,7 +92,6 @@ pub enum WebGPURequest { CopyBufferToTexture { command_encoder_id: id::CommandEncoderId, device_id: id::DeviceId, - scope_id: Option, source: BufferCopyView, destination: TextureCopyView, copy_size: wgt::Extent3d, @@ -101,7 +99,6 @@ pub enum WebGPURequest { CopyTextureToBuffer { command_encoder_id: id::CommandEncoderId, device_id: id::DeviceId, - scope_id: Option, source: TextureCopyView, destination: BufferCopyView, copy_size: wgt::Extent3d, @@ -109,33 +106,27 @@ pub enum WebGPURequest { CopyTextureToTexture { command_encoder_id: id::CommandEncoderId, device_id: id::DeviceId, - scope_id: Option, source: TextureCopyView, destination: TextureCopyView, copy_size: wgt::Extent3d, }, CreateBindGroup { device_id: id::DeviceId, - // TODO: Consider using NonZeroU64 to reduce enum size - scope_id: Option, bind_group_id: id::BindGroupId, descriptor: BindGroupDescriptor<'static>, }, CreateBindGroupLayout { device_id: id::DeviceId, - scope_id: Option, bind_group_layout_id: id::BindGroupLayoutId, descriptor: wgt::BindGroupLayoutDescriptor<'static>, }, CreateBuffer { device_id: id::DeviceId, - scope_id: Option, buffer_id: id::BufferId, descriptor: wgt::BufferDescriptor>, }, CreateCommandEncoder { device_id: id::DeviceId, - scope_id: Option, // TODO(zakorgy): Serialize CommandEncoderDescriptor in wgpu-core // wgpu::command::CommandEncoderDescriptor, command_encoder_id: id::CommandEncoderId, @@ -143,32 +134,27 @@ pub enum WebGPURequest { }, CreateComputePipeline { device_id: id::DeviceId, - scope_id: Option, compute_pipeline_id: id::ComputePipelineId, descriptor: ComputePipelineDescriptor<'static>, }, CreateContext(IpcSender), CreatePipelineLayout { device_id: id::DeviceId, - scope_id: Option, pipeline_layout_id: id::PipelineLayoutId, descriptor: wgt::PipelineLayoutDescriptor<'static, id::BindGroupLayoutId>, }, CreateRenderPipeline { device_id: id::DeviceId, - scope_id: Option, render_pipeline_id: id::RenderPipelineId, descriptor: RenderPipelineDescriptor<'static>, }, CreateSampler { device_id: id::DeviceId, - scope_id: Option, sampler_id: id::SamplerId, descriptor: wgt::SamplerDescriptor>, }, CreateShaderModule { device_id: id::DeviceId, - scope_id: Option, program_id: id::ShaderModuleId, program: Vec, }, @@ -182,7 +168,6 @@ pub enum WebGPURequest { }, CreateTexture { device_id: id::DeviceId, - scope_id: Option, texture_id: id::TextureId, descriptor: wgt::TextureDescriptor>, }, @@ -190,7 +175,6 @@ pub enum WebGPURequest { texture_id: id::TextureId, texture_view_id: id::TextureViewId, device_id: id::DeviceId, - scope_id: Option, descriptor: wgt::TextureViewDescriptor>, }, DestroyBuffer(id::BufferId), @@ -206,7 +190,6 @@ pub enum WebGPURequest { descriptor: wgt::RenderBundleDescriptor>, render_bundle_id: id::RenderBundleId, device_id: id::DeviceId, - scope_id: Option, }, RequestAdapter { sender: IpcSender, @@ -224,18 +207,15 @@ pub enum WebGPURequest { RunComputePass { command_encoder_id: id::CommandEncoderId, device_id: id::DeviceId, - scope_id: Option, compute_pass: ComputePass, }, RunRenderPass { command_encoder_id: id::CommandEncoderId, device_id: id::DeviceId, - scope_id: Option, render_pass: RenderPass, }, Submit { queue_id: id::QueueId, - scope_id: Option, command_buffers: Vec, }, SwapChainPresent { @@ -246,7 +226,6 @@ pub enum WebGPURequest { UnmapBuffer { buffer_id: id::BufferId, device_id: id::DeviceId, - scope_id: Option, array_buffer: IpcSharedMemory, is_map_read: bool, offset: u64, @@ -259,14 +238,12 @@ pub enum WebGPURequest { }, WriteBuffer { queue_id: id::QueueId, - scope_id: Option, buffer_id: id::BufferId, buffer_offset: u64, data: IpcSharedMemory, }, WriteTexture { queue_id: id::QueueId, - scope_id: Option, texture_cv: TextureCopyView, data_layout: wgt::TextureDataLayout, size: wgt::Extent3d, @@ -283,7 +260,7 @@ struct BufferMapInfo<'a, T> { } #[derive(Clone, Debug, Deserialize, Serialize)] -pub struct WebGPU(pub IpcSender); +pub struct WebGPU(pub IpcSender<(Option, WebGPURequest)>); impl WebGPU { pub fn new( @@ -341,14 +318,14 @@ impl WebGPU { pub fn exit(&self, sender: IpcSender<()>) -> Result<(), &'static str> { self.0 - .send(WebGPURequest::Exit(sender)) + .send((None, WebGPURequest::Exit(sender))) .map_err(|_| "Failed to send Exit message") } } struct WGPU<'a> { - receiver: IpcReceiver, - sender: IpcSender, + receiver: IpcReceiver<(Option, WebGPURequest)>, + sender: IpcSender<(Option, WebGPURequest)>, script_sender: IpcSender, global: wgpu::hub::Global, adapters: Vec, @@ -358,7 +335,8 @@ struct WGPU<'a> { // Buffers with pending mapping buffer_maps: HashMap>>, // Presentation Buffers with pending mapping - present_buffer_maps: HashMap>>, + present_buffer_maps: + HashMap, WebGPURequest)>>>, webrender_api: webrender_api::RenderApi, webrender_document: webrender_api::DocumentId, external_images: Arc>, @@ -368,8 +346,8 @@ struct WGPU<'a> { impl<'a> WGPU<'a> { fn new( - receiver: IpcReceiver, - sender: IpcSender, + receiver: IpcReceiver<(Option, WebGPURequest)>, + sender: IpcSender<(Option, WebGPURequest)>, script_sender: IpcSender, webrender_api_sender: webrender_api::RenderApiSender, webrender_document: webrender_api::DocumentId, @@ -404,13 +382,12 @@ impl<'a> WGPU<'a> { let _ = self.global.poll_all_devices(false); self.last_poll = Instant::now(); } - if let Ok(msg) = self.receiver.try_recv() { + if let Ok((scope_id, msg)) = self.receiver.try_recv() { match msg { WebGPURequest::BufferMapAsync { sender, buffer_id, device_id, - scope_id, host_map, map_range, } => { @@ -473,7 +450,6 @@ impl<'a> WGPU<'a> { WebGPURequest::CommandEncoderFinish { command_encoder_id, device_id, - scope_id, } => { let global = &self.global; let result = gfx_select!(command_encoder_id => global.command_encoder_finish( @@ -485,7 +461,6 @@ impl<'a> WGPU<'a> { WebGPURequest::CopyBufferToBuffer { command_encoder_id, device_id, - scope_id, source_id, source_offset, destination_id, @@ -506,7 +481,6 @@ impl<'a> WGPU<'a> { WebGPURequest::CopyBufferToTexture { command_encoder_id, device_id, - scope_id, source, destination, copy_size, @@ -523,7 +497,6 @@ impl<'a> WGPU<'a> { WebGPURequest::CopyTextureToBuffer { command_encoder_id, device_id, - scope_id, source, destination, copy_size, @@ -540,7 +513,6 @@ impl<'a> WGPU<'a> { WebGPURequest::CopyTextureToTexture { command_encoder_id, device_id, - scope_id, source, destination, copy_size, @@ -556,7 +528,6 @@ impl<'a> WGPU<'a> { }, WebGPURequest::CreateBindGroup { device_id, - scope_id, bind_group_id, descriptor, } => { @@ -567,7 +538,6 @@ impl<'a> WGPU<'a> { }, WebGPURequest::CreateBindGroupLayout { device_id, - scope_id, bind_group_layout_id, descriptor, } => { @@ -578,7 +548,6 @@ impl<'a> WGPU<'a> { }, WebGPURequest::CreateBuffer { device_id, - scope_id, buffer_id, descriptor, } => { @@ -597,7 +566,6 @@ impl<'a> WGPU<'a> { }, WebGPURequest::CreateCommandEncoder { device_id, - scope_id, command_encoder_id, label, } => { @@ -617,7 +585,6 @@ impl<'a> WGPU<'a> { }, WebGPURequest::CreateComputePipeline { device_id, - scope_id, compute_pipeline_id, descriptor, } => { @@ -638,7 +605,6 @@ impl<'a> WGPU<'a> { }, WebGPURequest::CreatePipelineLayout { device_id, - scope_id, pipeline_layout_id, descriptor, } => { @@ -650,7 +616,6 @@ impl<'a> WGPU<'a> { //TODO: consider https://github.com/gfx-rs/wgpu/issues/684 WebGPURequest::CreateRenderPipeline { device_id, - scope_id, render_pipeline_id, descriptor, } => { @@ -661,7 +626,6 @@ impl<'a> WGPU<'a> { }, WebGPURequest::CreateSampler { device_id, - scope_id, sampler_id, descriptor, } => { @@ -683,7 +647,6 @@ impl<'a> WGPU<'a> { }, WebGPURequest::CreateShaderModule { device_id, - scope_id, program_id, program, } => { @@ -738,7 +701,6 @@ impl<'a> WGPU<'a> { }, WebGPURequest::CreateTexture { device_id, - scope_id, texture_id, descriptor, } => { @@ -762,7 +724,6 @@ impl<'a> WGPU<'a> { texture_id, texture_view_id, device_id, - scope_id, descriptor, } => { let global = &self.global; @@ -840,7 +801,6 @@ impl<'a> WGPU<'a> { descriptor, render_bundle_id, device_id, - scope_id, } => { let global = &self.global; let st; @@ -941,7 +901,6 @@ impl<'a> WGPU<'a> { WebGPURequest::RunComputePass { command_encoder_id, device_id, - scope_id, compute_pass, } => { let global = &self.global; @@ -954,7 +913,6 @@ impl<'a> WGPU<'a> { WebGPURequest::RunRenderPass { command_encoder_id, device_id, - scope_id, render_pass, } => { let global = &self.global; @@ -966,7 +924,6 @@ impl<'a> WGPU<'a> { }, WebGPURequest::Submit { queue_id, - scope_id, command_buffers, } => { let global = &self.global; @@ -1111,7 +1068,6 @@ impl<'a> WGPU<'a> { WebGPURequest::UnmapBuffer { buffer_id, device_id, - scope_id, array_buffer, is_map_read, offset, @@ -1166,7 +1122,6 @@ impl<'a> WGPU<'a> { }, WebGPURequest::WriteBuffer { queue_id, - scope_id, buffer_id, buffer_offset, data, @@ -1183,7 +1138,6 @@ impl<'a> WGPU<'a> { }, WebGPURequest::WriteTexture { queue_id, - scope_id, texture_cv, data_layout, size, @@ -1208,7 +1162,7 @@ impl<'a> WGPU<'a> { fn send_result( &self, device_id: id::DeviceId, - scope_id: Option, + scope_id: Option, result: Result, ) { let &pipeline_id = self.devices.get(&WebGPUDevice(device_id)).unwrap();