diff options
-rw-r--r-- | Cargo.lock | 79 | ||||
-rw-r--r-- | components/script/dom/bindings/trace.rs | 2 | ||||
-rw-r--r-- | components/script/dom/globalscope.rs | 21 | ||||
-rw-r--r-- | components/script/dom/gpucommandencoder.rs | 16 | ||||
-rw-r--r-- | components/script/dom/gpudevice.rs | 139 | ||||
-rw-r--r-- | components/script/dom/gpurenderbundleencoder.rs | 19 | ||||
-rw-r--r-- | components/script/dom/gputexture.rs | 34 | ||||
-rw-r--r-- | components/script/dom/webidls/GPUTextureView.webidl | 4 | ||||
-rw-r--r-- | components/webgpu/identity.rs | 2 | ||||
-rw-r--r-- | components/webgpu/lib.rs | 91 | ||||
-rw-r--r-- | servo-tidy.toml | 1 |
11 files changed, 259 insertions, 149 deletions
diff --git a/Cargo.lock b/Cargo.lock index db8019f5286..755bc58a17d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -771,6 +771,21 @@ dependencies = [ ] [[package]] +name = "cocoa-foundation" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" +dependencies = [ + "bitflags", + "block", + "core-foundation 0.9.0", + "core-graphics-types", + "foreign-types", + "libc", + "objc", +] + +[[package]] name = "color_quant" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -921,6 +936,16 @@ dependencies = [ ] [[package]] +name = "core-foundation" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b5ed8e7e76c45974e15e41bfa8d5b0483cd90191639e01d8f5f1e606299d3fb" +dependencies = [ + "core-foundation-sys 0.8.0", + "libc", +] + +[[package]] name = "core-foundation-sys" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -933,6 +958,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" [[package]] +name = "core-foundation-sys" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a21fa21941700a3cd8fcb4091f361a6a712fac632f85d9f487cc892045d55c6" + +[[package]] name = "core-graphics" version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -957,6 +988,18 @@ dependencies = [ ] [[package]] +name = "core-graphics-types" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e92f5d519093a4178296707dbaa3880eae85a5ef5386675f361a1cf25376e93c" +dependencies = [ + "bitflags", + "core-foundation 0.9.0", + "foreign-types", + "libc", +] + +[[package]] name = "core-text" version = "13.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1889,22 +1932,21 @@ dependencies = [ [[package]] name = "gfx-backend-metal" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "412a1e0e53e9e325a7c2e0316f1a4e8a14cbe8d8bfb5f030bc3895692f8a8254" +checksum = "92804d20b194de6c84cb4bec14ec6a6dcae9c51f0a9186817fb412a590131ae6" dependencies = [ "arrayvec 0.5.1", "bitflags", "block", - "cocoa 0.20.1", + "cocoa-foundation", "copyless", - "core-graphics 0.19.0", "foreign-types", "gfx-auxil", "gfx-hal", "lazy_static", "log", - "metal", + "metal 0.20.0", "objc", "parking_lot 0.10.2", "range-alloc", @@ -1916,14 +1958,14 @@ dependencies = [ [[package]] name = "gfx-backend-vulkan" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f2e8bb53e5bea0bfec7035462a75717cd04d733963a225c816339a671ef108b" +checksum = "aec9c919cfc236d2c36aaa38609c1906a92f2df99a3c7f53022b01936f98275a" dependencies = [ "arrayvec 0.5.1", "ash", "byteorder", - "core-graphics 0.19.0", + "core-graphics-types", "gfx-hal", "lazy_static", "log", @@ -3434,6 +3476,20 @@ dependencies = [ ] [[package]] +name = "metal" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c4e8a431536529327e28c9ba6992f2cb0c15d4222f0602a16e6d7695ff3bccf" +dependencies = [ + "bitflags", + "block", + "cocoa-foundation", + "foreign-types", + "log", + "objc", +] + +[[package]] name = "metrics" version = "0.0.1" dependencies = [ @@ -5782,7 +5838,7 @@ dependencies = [ "libc", "log", "mach", - "metal", + "metal 0.18.0", "objc", "parking_lot 0.10.2", "wayland-sys 0.24.0", @@ -6861,7 +6917,7 @@ dependencies = [ [[package]] name = "wgpu-core" version = "0.5.0" -source = "git+https://github.com/gfx-rs/wgpu#8a2ee26fffcdf02fc5e7f0a29771f4720522f7d8" +source = "git+https://github.com/gfx-rs/wgpu#9e4839eb049707629fa8a91e3603085433f352a4" dependencies = [ "arrayvec 0.5.1", "bitflags", @@ -6875,7 +6931,6 @@ dependencies = [ "gfx-descriptor", "gfx-hal", "gfx-memory", - "log", "naga", "parking_lot 0.10.2", "ron", @@ -6889,7 +6944,7 @@ dependencies = [ [[package]] name = "wgpu-types" version = "0.5.0" -source = "git+https://github.com/gfx-rs/wgpu#8a2ee26fffcdf02fc5e7f0a29771f4720522f7d8" +source = "git+https://github.com/gfx-rs/wgpu#9e4839eb049707629fa8a91e3603085433f352a4" dependencies = [ "bitflags", "serde", diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index a5496a7cc17..0a42f1b2152 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -169,7 +169,6 @@ use time::{Duration, Timespec, Tm}; use uuid::Uuid; use webgpu::{ wgpu::command::{ComputePass, RenderBundleEncoder, RenderPass}, - wgt::BindGroupLayoutEntry, WebGPU, WebGPUAdapter, WebGPUBindGroup, WebGPUBindGroupLayout, WebGPUBuffer, WebGPUCommandBuffer, WebGPUCommandEncoder, WebGPUComputePipeline, WebGPUDevice, WebGPUPipelineLayout, WebGPUQueue, WebGPURenderBundle, WebGPURenderPipeline, WebGPUSampler, @@ -629,7 +628,6 @@ unsafe_no_jsmanaged_fields!(WebGPUContextId); unsafe_no_jsmanaged_fields!(WebGPUCommandBuffer); unsafe_no_jsmanaged_fields!(WebGPUCommandEncoder); unsafe_no_jsmanaged_fields!(WebGPUDevice); -unsafe_no_jsmanaged_fields!(BindGroupLayoutEntry); unsafe_no_jsmanaged_fields!(Option<RenderPass>); unsafe_no_jsmanaged_fields!(Option<RenderBundleEncoder>); unsafe_no_jsmanaged_fields!(Option<ComputePass>); diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 9806729f0e7..9397b48a630 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -5,7 +5,6 @@ use crate::dom::bindings::cell::{DomRefCell, RefMut}; use crate::dom::bindings::codegen::Bindings::BroadcastChannelBinding::BroadcastChannelMethods; use crate::dom::bindings::codegen::Bindings::EventSourceBinding::EventSourceBinding::EventSourceMethods; -use crate::dom::bindings::codegen::Bindings::GPUValidationErrorBinding::GPUError; use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::{ ImageBitmapOptions, ImageBitmapSource, }; @@ -36,8 +35,6 @@ use crate::dom::eventsource::EventSource; use crate::dom::eventtarget::EventTarget; use crate::dom::file::File; use crate::dom::gpudevice::GPUDevice; -use crate::dom::gpuoutofmemoryerror::GPUOutOfMemoryError; -use crate::dom::gpuvalidationerror::GPUValidationError; use crate::dom::htmlscriptelement::{ScriptId, SourceCode}; use crate::dom::identityhub::Identities; use crate::dom::imagebitmap::ImageBitmap; @@ -3023,18 +3020,12 @@ impl GlobalScope { let _ = self.gpu_devices.borrow_mut().remove(&device); } - pub fn handle_wgpu_msg(&self, device: WebGPUDevice, scope: u64, result: WebGPUOpResult) { - let result = match result { - WebGPUOpResult::Success => Ok(()), - WebGPUOpResult::ValidationError(m) => { - let val_err = GPUValidationError::new(&self, DOMString::from_string(m)); - Err(GPUError::GPUValidationError(val_err)) - }, - WebGPUOpResult::OutOfMemoryError => { - let oom_err = GPUOutOfMemoryError::new(&self); - Err(GPUError::GPUOutOfMemoryError(oom_err)) - }, - }; + pub fn handle_wgpu_msg( + &self, + device: WebGPUDevice, + scope: Option<u64>, + result: WebGPUOpResult, + ) { self.gpu_devices .borrow() .get(&device) diff --git a/components/script/dom/gpucommandencoder.rs b/components/script/dom/gpucommandencoder.rs index 8d8311eeae1..510b650a396 100644 --- a/components/script/dom/gpucommandencoder.rs +++ b/components/script/dom/gpucommandencoder.rs @@ -16,20 +16,20 @@ use crate::dom::bindings::codegen::UnionTypes::{ use crate::dom::bindings::num::Finite; 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::gpubuffer::GPUBuffer; use crate::dom::gpucommandbuffer::GPUCommandBuffer; use crate::dom::gpucomputepassencoder::GPUComputePassEncoder; -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 crate::dom::gpurenderpassencoder::GPURenderPassEncoder; use dom_struct::dom_struct; use std::borrow::Cow; use std::cell::Cell; use std::collections::HashSet; use webgpu::wgpu::command as wgpu_com; -use webgpu::{self, wgt, WebGPU, WebGPUDevice, WebGPURequest}; +use webgpu::{self, wgt, WebGPU, WebGPURequest}; // https://gpuweb.github.io/gpuweb/#enumdef-encoder-state #[derive(MallocSizeOf, PartialEq)] @@ -49,14 +49,14 @@ pub struct GPUCommandEncoder { encoder: webgpu::WebGPUCommandEncoder, buffers: DomRefCell<HashSet<DomRoot<GPUBuffer>>>, state: DomRefCell<GPUCommandEncoderState>, - device: WebGPUDevice, + device: Dom<GPUDevice>, valid: Cell<bool>, } impl GPUCommandEncoder { pub fn new_inherited( channel: WebGPU, - device: WebGPUDevice, + device: &GPUDevice, encoder: webgpu::WebGPUCommandEncoder, valid: bool, label: Option<USVString>, @@ -65,7 +65,7 @@ impl GPUCommandEncoder { channel, reflector_: Reflector::new(), label: DomRefCell::new(label), - device, + device: Dom::from_ref(device), encoder, buffers: DomRefCell::new(HashSet::new()), state: DomRefCell::new(GPUCommandEncoderState::Open), @@ -76,7 +76,7 @@ impl GPUCommandEncoder { pub fn new( global: &GlobalScope, channel: WebGPU, - device: WebGPUDevice, + device: &GPUDevice, encoder: webgpu::WebGPUCommandEncoder, valid: bool, label: Option<USVString>, @@ -370,6 +370,8 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { .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 }) diff --git a/components/script/dom/gpudevice.rs b/components/script/dom/gpudevice.rs index 1cd9c7653ed..7719d937e96 100644 --- a/components/script/dom/gpudevice.rs +++ b/components/script/dom/gpudevice.rs @@ -39,7 +39,7 @@ use crate::dom::bindings::codegen::UnionTypes::Uint32ArrayOrString; use crate::dom::bindings::error::Error; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::{Dom, DomRoot}; -use crate::dom::bindings::str::USVString; +use crate::dom::bindings::str::{DOMString, USVString}; use crate::dom::bindings::trace::RootedTraceableBox; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; @@ -49,6 +49,7 @@ use crate::dom::gpubindgrouplayout::GPUBindGroupLayout; use crate::dom::gpubuffer::{GPUBuffer, GPUBufferMapInfo, GPUBufferState}; use crate::dom::gpucommandencoder::GPUCommandEncoder; use crate::dom::gpucomputepipeline::GPUComputePipeline; +use crate::dom::gpuoutofmemoryerror::GPUOutOfMemoryError; use crate::dom::gpupipelinelayout::GPUPipelineLayout; use crate::dom::gpuqueue::GPUQueue; use crate::dom::gpurenderbundleencoder::GPURenderBundleEncoder; @@ -56,6 +57,7 @@ use crate::dom::gpurenderpipeline::GPURenderPipeline; use crate::dom::gpusampler::GPUSampler; use crate::dom::gpushadermodule::GPUShaderModule; use crate::dom::gputexture::GPUTexture; +use crate::dom::gpuvalidationerror::GPUValidationError; use crate::dom::promise::Promise; use crate::realms::InRealm; use crate::script_runtime::JSContext as SafeJSContext; @@ -69,13 +71,12 @@ use std::rc::Rc; use webgpu::wgpu::{ binding_model as wgpu_bind, command::RenderBundleEncoder, pipeline as wgpu_pipe, }; -use webgpu::{self, wgt, WebGPU, WebGPURequest}; +use webgpu::{self, identity::WebGPUOpResult, wgt, WebGPU, WebGPURequest}; type ErrorScopeId = u64; #[derive(JSTraceable, MallocSizeOf)] struct ErrorScopeInfo { - filter: GPUErrorFilter, op_count: u64, #[ignore_malloc_size_of = "defined in webgpu"] error: Option<GPUError>, @@ -86,7 +87,7 @@ struct ErrorScopeInfo { #[derive(JSTraceable, MallocSizeOf)] struct ScopeContext { error_scopes: HashMap<ErrorScopeId, ErrorScopeInfo>, - scope_stack: Vec<ErrorScopeId>, + scope_stack: Vec<(ErrorScopeId, GPUErrorFilter)>, next_scope_id: ErrorScopeId, } @@ -106,9 +107,6 @@ pub struct GPUDevice { scope_context: DomRefCell<ScopeContext>, #[ignore_malloc_size_of = "promises are hard"] lost_promise: DomRefCell<Option<Rc<Promise>>>, - #[ignore_malloc_size_of = "defined in webgpu"] - bind_group_layouts: - DomRefCell<HashMap<Vec<wgt::BindGroupLayoutEntry>, Dom<GPUBindGroupLayout>>>, } impl GPUDevice { @@ -136,7 +134,6 @@ impl GPUDevice { next_scope_id: 0, }), lost_promise: DomRefCell::new(None), - bind_group_layouts: DomRefCell::new(HashMap::new()), } } @@ -165,18 +162,62 @@ impl GPUDevice { self.device } - pub fn handle_server_msg(&self, scope: ErrorScopeId, result: Result<(), GPUError>) { + pub fn handle_server_msg(&self, scope: Option<ErrorScopeId>, result: WebGPUOpResult) { + let result = match result { + WebGPUOpResult::Success => Ok(()), + WebGPUOpResult::ValidationError(m) => { + let val_err = GPUValidationError::new(&self.global(), DOMString::from_string(m)); + Err(( + GPUError::GPUValidationError(val_err), + GPUErrorFilter::Validation, + )) + }, + WebGPUOpResult::OutOfMemoryError => { + let oom_err = GPUOutOfMemoryError::new(&self.global()); + Err(( + GPUError::GPUOutOfMemoryError(oom_err), + GPUErrorFilter::Out_of_memory, + )) + }, + }; + + if let Some(s_id) = scope { + if let Err((err, filter)) = result { + let scop = self + .scope_context + .borrow() + .scope_stack + .iter() + .rev() + .find(|&&(id, fil)| id <= s_id && fil == filter) + .map(|(id, _)| *id); + if let Some(s) = scop { + self.handle_error(s, err); + } else { + // Fire UncapturedErrorEvent. + } + } + self.try_remove_scope(s_id); + } else { + // Fire UncapturedErrorEvent if result is Error + } + } + + fn handle_error(&self, scope: ErrorScopeId, error: GPUError) { + let mut context = self.scope_context.borrow_mut(); + if let Some(mut err_scope) = context.error_scopes.get_mut(&scope) { + if err_scope.error.is_none() { + err_scope.error = Some(error); + } + } else { + warn!("Could not find ErrorScope with Id({})", scope); + } + } + + fn try_remove_scope(&self, scope: ErrorScopeId) { let mut context = self.scope_context.borrow_mut(); let remove = if let Some(mut err_scope) = context.error_scopes.get_mut(&scope) { err_scope.op_count -= 1; - match result { - Ok(()) => {}, - Err(e) => { - if err_scope.error.is_none() { - err_scope.error = Some(e); - } - }, - } if let Some(ref promise) = err_scope.promise { if !promise.is_fulfilled() { if let Some(ref e) = err_scope.error { @@ -191,18 +232,19 @@ impl GPUDevice { } err_scope.op_count == 0 && err_scope.promise.is_some() } else { - warn!("Could not find ErrroScope with Id({})", scope); + warn!("Could not find ErrorScope with Id({})", scope); false }; if remove { let _ = context.error_scopes.remove(&scope); + context.scope_stack.retain(|(id, _)| *id != scope); } } - fn use_current_scope(&self) -> Option<ErrorScopeId> { + pub fn use_current_scope(&self) -> Option<ErrorScopeId> { let mut context = self.scope_context.borrow_mut(); - let scope_id = context.scope_stack.last().cloned(); - scope_id.and_then(|s_id| { + let scope_id = context.scope_stack.last().copied(); + scope_id.and_then(|(s_id, _)| { context.error_scopes.get_mut(&s_id).map(|mut scope| { scope.op_count += 1; s_id @@ -265,10 +307,13 @@ impl GPUDeviceMethods for GPUDevice { .wgpu_id_hub() .lock() .create_buffer_id(self.device.0.backend()); + + let scope_id = self.use_current_scope(); self.channel .0 .send(WebGPURequest::CreateBuffer { device_id: self.device.0, + scope_id, buffer_id: id, descriptor: wgpu_descriptor, }) @@ -388,28 +433,13 @@ impl GPUDeviceMethods for GPUDevice { let scope_id = self.use_current_scope(); - // Check for equivalent GPUBindGroupLayout - { - let layout = self - .bind_group_layouts - .borrow() - .get(&entries) - .map(|bgl| DomRoot::from_ref(&**bgl)); - if let Some(l) = layout { - if let Some(i) = scope_id { - self.handle_server_msg(i, Ok(())); - } - return l; - } - } - let desc = wgt::BindGroupLayoutDescriptor { label: descriptor .parent .label .as_ref() .map(|s| Cow::Owned(s.to_string())), - entries: Cow::Owned(entries.clone()), + entries: Cow::Owned(entries), }; let bind_group_layout_id = self @@ -429,17 +459,11 @@ impl GPUDeviceMethods for GPUDevice { let bgl = webgpu::WebGPUBindGroupLayout(bind_group_layout_id); - let layout = GPUBindGroupLayout::new( + GPUBindGroupLayout::new( &self.global(), bgl, descriptor.parent.label.as_ref().cloned(), - ); - - self.bind_group_layouts - .borrow_mut() - .insert(entries, Dom::from_ref(&*layout)); - - layout + ) } /// https://gpuweb.github.io/gpuweb/#dom-gpudevice-createpipelinelayout @@ -562,10 +586,13 @@ impl GPUDeviceMethods for GPUDevice { .wgpu_id_hub() .lock() .create_shader_module_id(self.device.0.backend()); + + let scope_id = self.use_current_scope(); self.channel .0 .send(WebGPURequest::CreateShaderModule { device_id: self.device.0, + scope_id, program_id, program, }) @@ -628,10 +655,12 @@ impl GPUDeviceMethods for GPUDevice { .wgpu_id_hub() .lock() .create_command_encoder_id(self.device.0.backend()); + let scope_id = self.use_current_scope(); self.channel .0 .send(WebGPURequest::CreateCommandEncoder { device_id: self.device.0, + scope_id, command_encoder_id, label: descriptor.parent.label.as_ref().map(|s| s.to_string()), }) @@ -642,7 +671,7 @@ impl GPUDeviceMethods for GPUDevice { GPUCommandEncoder::new( &self.global(), self.channel.clone(), - self.device, + &self, encoder, true, descriptor.parent.label.as_ref().cloned(), @@ -675,12 +704,15 @@ impl GPUDeviceMethods for GPUDevice { .lock() .create_texture_id(self.device.0.backend()); + let scope_id = self.use_current_scope(); + self.channel .0 .send(WebGPURequest::CreateTexture { device_id: self.device.0, texture_id, descriptor: desc, + scope_id, }) .expect("Failed to create WebGPU Texture"); @@ -689,7 +721,7 @@ impl GPUDeviceMethods for GPUDevice { GPUTexture::new( &self.global(), texture, - self.device, + &self, self.channel.clone(), size, descriptor.mipLevelCount, @@ -723,10 +755,13 @@ impl GPUDeviceMethods for GPUDevice { anisotropy_clamp: None, ..Default::default() }; + + let scope_id = self.use_current_scope(); self.channel .0 .send(WebGPURequest::CreateSampler { device_id: self.device.0, + scope_id, sampler_id, descriptor: desc, }) @@ -914,7 +949,7 @@ impl GPUDeviceMethods for GPUDevice { GPURenderBundleEncoder::new( &self.global(), render_bundle_encoder, - self.device, + &self, self.channel.clone(), descriptor.parent.label.as_ref().cloned(), ) @@ -926,13 +961,12 @@ impl GPUDeviceMethods for GPUDevice { let scope_id = context.next_scope_id; context.next_scope_id += 1; let err_scope = ErrorScopeInfo { - filter, op_count: 0, error: None, promise: None, }; let res = context.error_scopes.insert(scope_id, err_scope); - context.scope_stack.push(scope_id); + context.scope_stack.push((scope_id, filter)); assert!(res.is_none()); } @@ -940,8 +974,8 @@ impl GPUDeviceMethods for GPUDevice { fn PopErrorScope(&self, comp: InRealm) -> Rc<Promise> { let mut context = self.scope_context.borrow_mut(); let promise = Promise::new_in_current_realm(&self.global(), comp); - let scope_id = if let Some(e) = context.scope_stack.pop() { - e + let scope_id = if let Some((e, _)) = context.scope_stack.last() { + *e } else { promise.reject_error(Error::Operation); return promise; @@ -963,6 +997,7 @@ impl GPUDeviceMethods for GPUDevice { }; if remove { let _ = context.error_scopes.remove(&scope_id); + let _ = context.scope_stack.pop(); } promise } diff --git a/components/script/dom/gpurenderbundleencoder.rs b/components/script/dom/gpurenderbundleencoder.rs index 5759b09b299..d227ad34ff7 100644 --- a/components/script/dom/gpurenderbundleencoder.rs +++ b/components/script/dom/gpurenderbundleencoder.rs @@ -6,17 +6,18 @@ use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::GPURenderBundleBinding::GPURenderBundleDescriptor; use crate::dom::bindings::codegen::Bindings::GPURenderBundleEncoderBinding::GPURenderBundleEncoderMethods; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, 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::gpubindgroup::GPUBindGroup; use crate::dom::gpubuffer::GPUBuffer; +use crate::dom::gpudevice::GPUDevice; use crate::dom::gpurenderbundle::GPURenderBundle; use crate::dom::gpurenderpipeline::GPURenderPipeline; use dom_struct::dom_struct; use webgpu::{ wgpu::command::{bundle_ffi as wgpu_bundle, RenderBundleEncoder}, - wgt, WebGPU, WebGPUDevice, WebGPURenderBundle, WebGPURequest, + wgt, WebGPU, WebGPURenderBundle, WebGPURequest, }; #[dom_struct] @@ -24,7 +25,7 @@ pub struct GPURenderBundleEncoder { reflector_: Reflector, #[ignore_malloc_size_of = "channels are hard"] channel: WebGPU, - device: WebGPUDevice, + device: Dom<GPUDevice>, #[ignore_malloc_size_of = "defined in wgpu-core"] render_bundle_encoder: DomRefCell<Option<RenderBundleEncoder>>, label: DomRefCell<Option<USVString>>, @@ -33,14 +34,14 @@ pub struct GPURenderBundleEncoder { impl GPURenderBundleEncoder { fn new_inherited( render_bundle_encoder: RenderBundleEncoder, - device: WebGPUDevice, + device: &GPUDevice, channel: WebGPU, label: Option<USVString>, ) -> Self { Self { reflector_: Reflector::new(), render_bundle_encoder: DomRefCell::new(Some(render_bundle_encoder)), - device, + device: Dom::from_ref(device), channel, label: DomRefCell::new(label), } @@ -49,7 +50,7 @@ impl GPURenderBundleEncoder { pub fn new( global: &GlobalScope, render_bundle_encoder: RenderBundleEncoder, - device: WebGPUDevice, + device: &GPUDevice, channel: WebGPU, label: Option<USVString>, ) -> DomRoot<Self> { @@ -190,7 +191,7 @@ impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder { .global() .wgpu_id_hub() .lock() - .create_render_bundle_id(self.device.0.backend()); + .create_render_bundle_id(self.device.id().0.backend()); self.channel .0 @@ -198,6 +199,8 @@ impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder { render_bundle_encoder: encoder, descriptor: desc, render_bundle_id, + device_id: self.device.id().0, + scope_id: self.device.use_current_scope(), }) .expect("Failed to send RenderBundleEncoderFinish"); @@ -205,7 +208,7 @@ impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder { GPURenderBundle::new( &self.global(), render_bundle, - self.device, + self.device.id(), self.channel.clone(), descriptor.parent.label.as_ref().cloned(), ) diff --git a/components/script/dom/gputexture.rs b/components/script/dom/gputexture.rs index 4a6256ee369..e9c44858f94 100644 --- a/components/script/dom/gputexture.rs +++ b/components/script/dom/gputexture.rs @@ -10,21 +10,21 @@ use crate::dom::bindings::codegen::Bindings::GPUTextureViewBinding::{ GPUTextureAspect, GPUTextureViewDescriptor, GPUTextureViewDimension, }; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, 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::gpudevice::{convert_texture_format, convert_texture_view_dimension}; +use crate::dom::gpudevice::{convert_texture_format, convert_texture_view_dimension, GPUDevice}; use crate::dom::gputextureview::GPUTextureView; use dom_struct::dom_struct; use std::string::String; -use webgpu::{wgt, WebGPU, WebGPUDevice, WebGPURequest, WebGPUTexture, WebGPUTextureView}; +use webgpu::{wgt, WebGPU, WebGPURequest, WebGPUTexture, WebGPUTextureView}; #[dom_struct] pub struct GPUTexture { reflector_: Reflector, texture: WebGPUTexture, label: DomRefCell<Option<USVString>>, - device: WebGPUDevice, + device: Dom<GPUDevice>, #[ignore_malloc_size_of = "channels are hard"] channel: WebGPU, #[ignore_malloc_size_of = "defined in webgpu"] @@ -39,7 +39,7 @@ pub struct GPUTexture { impl GPUTexture { fn new_inherited( texture: WebGPUTexture, - device: WebGPUDevice, + device: &GPUDevice, channel: WebGPU, texture_size: GPUExtent3DDict, mip_level_count: u32, @@ -53,7 +53,7 @@ impl GPUTexture { reflector_: Reflector::new(), texture, label: DomRefCell::new(label), - device, + device: Dom::from_ref(device), channel, texture_size, mip_level_count, @@ -67,7 +67,7 @@ impl GPUTexture { pub fn new( global: &GlobalScope, texture: WebGPUTexture, - device: WebGPUDevice, + device: &GPUDevice, channel: WebGPU, texture_size: GPUExtent3DDict, mip_level_count: u32, @@ -126,7 +126,7 @@ impl GPUTextureMethods for GPUTexture { match self.dimension { GPUTextureDimension::_1d => GPUTextureViewDimension::_1d, GPUTextureDimension::_2d => { - if self.texture_size.depth > 1 && descriptor.arrayLayerCount == 0 { + if self.texture_size.depth > 1 && descriptor.arrayLayerCount.is_none() { GPUTextureViewDimension::_2d_array } else { GPUTextureViewDimension::_2d @@ -152,31 +152,27 @@ impl GPUTextureMethods for GPUTexture { GPUTextureAspect::Depth_only => wgt::TextureAspect::DepthOnly, }, base_mip_level: descriptor.baseMipLevel, - level_count: if descriptor.mipLevelCount == 0 { - self.mip_level_count - descriptor.baseMipLevel - } else { - descriptor.mipLevelCount - }, + level_count: descriptor.mipLevelCount.as_ref().copied(), base_array_layer: descriptor.baseArrayLayer, - array_layer_count: if descriptor.arrayLayerCount == 0 { - self.texture_size.depth - descriptor.baseArrayLayer - } else { - descriptor.arrayLayerCount - }, + array_layer_count: descriptor.arrayLayerCount.as_ref().copied(), }; let texture_view_id = self .global() .wgpu_id_hub() .lock() - .create_texture_view_id(self.device.0.backend()); + .create_texture_view_id(self.device.id().0.backend()); + + let scope_id = self.device.use_current_scope(); self.channel .0 .send(WebGPURequest::CreateTextureView { texture_id: self.texture.0, texture_view_id, + device_id: self.device.id().0, descriptor: desc, + scope_id, }) .expect("Failed to create WebGPU texture view"); diff --git a/components/script/dom/webidls/GPUTextureView.webidl b/components/script/dom/webidls/GPUTextureView.webidl index 91d2b31ee93..f6b8b7d1317 100644 --- a/components/script/dom/webidls/GPUTextureView.webidl +++ b/components/script/dom/webidls/GPUTextureView.webidl @@ -13,9 +13,9 @@ dictionary GPUTextureViewDescriptor : GPUObjectDescriptorBase { GPUTextureViewDimension dimension; GPUTextureAspect aspect = "all"; GPUIntegerCoordinate baseMipLevel = 0; - GPUIntegerCoordinate mipLevelCount = 0; + GPUIntegerCoordinate mipLevelCount; GPUIntegerCoordinate baseArrayLayer = 0; - GPUIntegerCoordinate arrayLayerCount = 0; + GPUIntegerCoordinate arrayLayerCount; }; enum GPUTextureViewDimension { diff --git a/components/webgpu/identity.rs b/components/webgpu/identity.rs index 8a76868a2df..516a296b94d 100644 --- a/components/webgpu/identity.rs +++ b/components/webgpu/identity.rs @@ -43,7 +43,7 @@ pub enum WebGPUMsg { FreeRenderBundle(RenderBundleId), WebGPUOpResult { device: WebGPUDevice, - scope_id: u64, + scope_id: Option<u64>, pipeline_id: PipelineId, result: WebGPUOpResult, }, diff --git a/components/webgpu/lib.rs b/components/webgpu/lib.rs index 66394086159..da343ec9519 100644 --- a/components/webgpu/lib.rs +++ b/components/webgpu/lib.rs @@ -73,6 +73,8 @@ pub enum WebGPURequest { BufferMapComplete(id::BufferId), CommandEncoderFinish { command_encoder_id: id::CommandEncoderId, + device_id: id::DeviceId, + scope_id: Option<u64>, // TODO(zakorgy): Serialize CommandBufferDescriptor in wgpu-core // wgpu::command::CommandBufferDescriptor, }, @@ -117,11 +119,13 @@ pub enum WebGPURequest { }, CreateBuffer { device_id: id::DeviceId, + scope_id: Option<u64>, buffer_id: id::BufferId, descriptor: wgt::BufferDescriptor<Option<String>>, }, CreateCommandEncoder { device_id: id::DeviceId, + scope_id: Option<u64>, // TODO(zakorgy): Serialize CommandEncoderDescriptor in wgpu-core // wgpu::command::CommandEncoderDescriptor, command_encoder_id: id::CommandEncoderId, @@ -148,11 +152,13 @@ pub enum WebGPURequest { }, CreateSampler { device_id: id::DeviceId, + scope_id: Option<u64>, sampler_id: id::SamplerId, descriptor: wgt::SamplerDescriptor<Option<String>>, }, CreateShaderModule { device_id: id::DeviceId, + scope_id: Option<u64>, program_id: id::ShaderModuleId, program: Vec<u32>, }, @@ -166,12 +172,15 @@ pub enum WebGPURequest { }, CreateTexture { device_id: id::DeviceId, + scope_id: Option<u64>, texture_id: id::TextureId, descriptor: wgt::TextureDescriptor<Option<String>>, }, CreateTextureView { texture_id: id::TextureId, texture_view_id: id::TextureViewId, + device_id: id::DeviceId, + scope_id: Option<u64>, descriptor: wgt::TextureViewDescriptor<Option<String>>, }, DestroyBuffer(id::BufferId), @@ -186,6 +195,8 @@ pub enum WebGPURequest { render_bundle_encoder: RenderBundleEncoder, descriptor: wgt::RenderBundleDescriptor<Option<String>>, render_bundle_id: id::RenderBundleId, + device_id: id::DeviceId, + scope_id: Option<u64>, }, RequestAdapter { sender: IpcSender<WebGPUResponseResult>, @@ -430,12 +441,17 @@ impl<'a> WGPU<'a> { WebGPURequest::BufferMapComplete(buffer_id) => { self.buffer_maps.remove(&buffer_id); }, - WebGPURequest::CommandEncoderFinish { command_encoder_id } => { + WebGPURequest::CommandEncoderFinish { + command_encoder_id, + device_id, + scope_id, + } => { let global = &self.global; - let _ = gfx_select!(command_encoder_id => global.command_encoder_finish( + let result = gfx_select!(command_encoder_id => global.command_encoder_finish( command_encoder_id, &wgt::CommandBufferDescriptor::default() )); + self.send_result(device_id, scope_id, result); }, WebGPURequest::CopyBufferToBuffer { command_encoder_id, @@ -506,9 +522,7 @@ impl<'a> WGPU<'a> { let global = &self.global; let result = gfx_select!(bind_group_id => global.device_create_bind_group(device_id, &descriptor, bind_group_id)); - if let Some(s_id) = scope_id { - self.send_result(device_id, s_id, result); - } + self.send_result(device_id, scope_id, result); }, WebGPURequest::CreateBindGroupLayout { device_id, @@ -519,12 +533,11 @@ impl<'a> WGPU<'a> { let global = &self.global; let result = gfx_select!(bind_group_layout_id => global.device_create_bind_group_layout(device_id, &descriptor, bind_group_layout_id)); - if let Some(s_id) = scope_id { - self.send_result(device_id, s_id, result); - } + self.send_result(device_id, scope_id, result); }, WebGPURequest::CreateBuffer { device_id, + scope_id, buffer_id, descriptor, } => { @@ -537,11 +550,13 @@ impl<'a> WGPU<'a> { }, None => ptr::null(), }; - let _ = gfx_select!(buffer_id => + let result = gfx_select!(buffer_id => global.device_create_buffer(device_id, &descriptor.map_label(|_| label), buffer_id)); + self.send_result(device_id, scope_id, result); }, WebGPURequest::CreateCommandEncoder { device_id, + scope_id, command_encoder_id, label, } => { @@ -555,8 +570,9 @@ impl<'a> WGPU<'a> { None => ptr::null(), }; let desc = wgt::CommandEncoderDescriptor { label }; - let _ = gfx_select!(command_encoder_id => + let result = gfx_select!(command_encoder_id => global.device_create_command_encoder(device_id, &desc, command_encoder_id)); + self.send_result(device_id, scope_id, result); }, WebGPURequest::CreateComputePipeline { device_id, @@ -567,9 +583,7 @@ impl<'a> WGPU<'a> { let global = &self.global; let result = gfx_select!(compute_pipeline_id => global.device_create_compute_pipeline(device_id, &descriptor, compute_pipeline_id)); - if let Some(s_id) = scope_id { - self.send_result(device_id, s_id, result); - } + self.send_result(device_id, scope_id, result); }, WebGPURequest::CreateContext(sender) => { let id = self @@ -590,9 +604,7 @@ impl<'a> WGPU<'a> { let global = &self.global; let result = gfx_select!(pipeline_layout_id => global.device_create_pipeline_layout(device_id, &descriptor, pipeline_layout_id)); - if let Some(s_id) = scope_id { - self.send_result(device_id, s_id, result); - } + self.send_result(device_id, scope_id, result); }, //TODO: consider https://github.com/gfx-rs/wgpu/issues/684 WebGPURequest::CreateRenderPipeline { @@ -604,12 +616,11 @@ impl<'a> WGPU<'a> { let global = &self.global; let result = gfx_select!(render_pipeline_id => global.device_create_render_pipeline(device_id, &descriptor, render_pipeline_id)); - if let Some(s_id) = scope_id { - self.send_result(device_id, s_id, result); - } + self.send_result(device_id, scope_id, result); }, WebGPURequest::CreateSampler { device_id, + scope_id, sampler_id, descriptor, } => { @@ -622,22 +633,25 @@ impl<'a> WGPU<'a> { }, None => ptr::null(), }; - let _ = gfx_select!(sampler_id => global.device_create_sampler( + let result = gfx_select!(sampler_id => global.device_create_sampler( device_id, &descriptor.map_label(|_| label), sampler_id )); + self.send_result(device_id, scope_id, result); }, WebGPURequest::CreateShaderModule { device_id, + scope_id, program_id, program, } => { let global = &self.global; let source = wgpu_core::pipeline::ShaderModuleSource::SpirV(Cow::Owned(program)); - let _ = gfx_select!(program_id => + let result = gfx_select!(program_id => global.device_create_shader_module(device_id, source, program_id)); + self.send_result(device_id, scope_id, result); }, WebGPURequest::CreateSwapChain { device_id, @@ -683,6 +697,7 @@ impl<'a> WGPU<'a> { }, WebGPURequest::CreateTexture { device_id, + scope_id, texture_id, descriptor, } => { @@ -695,15 +710,18 @@ impl<'a> WGPU<'a> { }, None => ptr::null(), }; - let _ = gfx_select!(texture_id => global.device_create_texture( + let result = gfx_select!(texture_id => global.device_create_texture( device_id, &descriptor.map_label(|_| label), texture_id )); + self.send_result(device_id, scope_id, result); }, WebGPURequest::CreateTextureView { texture_id, texture_view_id, + device_id, + scope_id, descriptor, } => { let global = &self.global; @@ -715,15 +733,16 @@ impl<'a> WGPU<'a> { }, None => ptr::null(), }; - let _ = gfx_select!(texture_view_id => global.texture_create_view( + let result = gfx_select!(texture_view_id => global.texture_create_view( texture_id, Some(&descriptor.map_label(|_| label)), texture_view_id )); + self.send_result(device_id, scope_id, result); }, WebGPURequest::DestroyBuffer(buffer) => { let global = &self.global; - gfx_select!(buffer => global.buffer_destroy(buffer)); + gfx_select!(buffer => global.buffer_destroy(buffer, false)); }, WebGPURequest::DestroySwapChain { external_id, @@ -737,10 +756,10 @@ impl<'a> WGPU<'a> { .unwrap(); let global = &self.global; for b_id in data.available_buffer_ids.iter() { - gfx_select!(b_id => global.buffer_destroy(*b_id)); + gfx_select!(b_id => global.buffer_destroy(*b_id, false)); } for b_id in data.queued_buffer_ids.iter() { - gfx_select!(b_id => global.buffer_destroy(*b_id)); + gfx_select!(b_id => global.buffer_destroy(*b_id, false)); } for b_id in data.unassigned_buffer_ids.iter() { if let Err(e) = self.script_sender.send(WebGPUMsg::FreeBuffer(*b_id)) { @@ -779,6 +798,8 @@ impl<'a> WGPU<'a> { render_bundle_encoder, descriptor, render_bundle_id, + device_id, + scope_id, } => { let global = &self.global; let st; @@ -789,11 +810,12 @@ impl<'a> WGPU<'a> { }, None => ptr::null(), }; - let _ = gfx_select!(render_bundle_id => global.render_bundle_encoder_finish( + let result = gfx_select!(render_bundle_id => global.render_bundle_encoder_finish( render_bundle_encoder, &descriptor.map_label(|_| label), render_bundle_id )); + self.send_result(device_id, scope_id, result); }, WebGPURequest::RequestAdapter { sender, @@ -1088,7 +1110,8 @@ impl<'a> WGPU<'a> { data, } => { let global = &self.global; - gfx_select!(queue_id => global.queue_write_buffer( + //TODO: Report result to content process + let _ = gfx_select!(queue_id => global.queue_write_buffer( queue_id, buffer_id, buffer_offset as wgt::BufferAddress, @@ -1103,7 +1126,8 @@ impl<'a> WGPU<'a> { data, } => { let global = &self.global; - gfx_select!(queue_id => global.queue_write_texture( + //TODO: Report result to content process + let _ = gfx_select!(queue_id => global.queue_write_texture( queue_id, &texture_cv, &data, @@ -1119,7 +1143,7 @@ impl<'a> WGPU<'a> { fn send_result<U: id::TypedId, T: std::fmt::Debug>( &self, device_id: id::DeviceId, - scope_id: u64, + scope_id: Option<u64>, result: Result<U, T>, ) { let &pipeline_id = self.devices.get(&WebGPUDevice(device_id)).unwrap(); @@ -1128,7 +1152,12 @@ impl<'a> WGPU<'a> { scope_id, pipeline_id, result: if let Err(e) = result { - WebGPUOpResult::ValidationError(format!("{:?}", e)) + let err = format!("{:?}", e); + if err.contains("OutOfMemory") { + WebGPUOpResult::OutOfMemoryError + } else { + WebGPUOpResult::ValidationError(err) + } } else { WebGPUOpResult::Success }, diff --git a/servo-tidy.toml b/servo-tidy.toml index 935ba0a205f..88ac7171773 100644 --- a/servo-tidy.toml +++ b/servo-tidy.toml @@ -34,6 +34,7 @@ packages = [ "cocoa", "gleam", "libloading", + "metal", "miniz_oxide", "parking_lot", "parking_lot_core", |