diff options
author | Istvan Miklos <istvan.miklos@h-lab.eu> | 2019-11-12 12:56:57 +0100 |
---|---|---|
committer | Istvan Miklos <istvan.miklos@h-lab.eu> | 2019-12-05 11:50:33 +0100 |
commit | b15d2bb7d70870e26e1834099bf5fdcdcbb8d673 (patch) | |
tree | 80f2ab39a3afe7c38ec4934070cff03642e80521 /components/script/dom | |
parent | 7aa68c8fe7ca0865a7323ab1e5b9526efa588ca2 (diff) | |
download | servo-b15d2bb7d70870e26e1834099bf5fdcdcbb8d673.tar.gz servo-b15d2bb7d70870e26e1834099bf5fdcdcbb8d673.zip |
Initial implementation of GPUDevice for WebGPU
Added the WebIDL bindigs for GPUDevice, GPUObjectDescriptorBase, GPUDeviceDescriptor, GPUObjectBase
Implemented the `requestDevice` function of `GPUAdapter`
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/bindings/codegen/Bindings.conf | 4 | ||||
-rw-r--r-- | components/script/dom/bindings/trace.rs | 5 | ||||
-rw-r--r-- | components/script/dom/gpuadapter.rs | 64 | ||||
-rw-r--r-- | components/script/dom/gpudevice.rs | 91 | ||||
-rw-r--r-- | components/script/dom/identityhub.rs | 4 | ||||
-rw-r--r-- | components/script/dom/mod.rs | 1 | ||||
-rw-r--r-- | components/script/dom/navigator.rs | 6 | ||||
-rw-r--r-- | components/script/dom/webidls/GPUAdapter.webidl | 22 | ||||
-rw-r--r-- | components/script/dom/webidls/GPUDevice.webidl | 31 | ||||
-rw-r--r-- | components/script/dom/webidls/GPUObjectBase.webidl | 13 |
10 files changed, 235 insertions, 6 deletions
diff --git a/components/script/dom/bindings/codegen/Bindings.conf b/components/script/dom/bindings/codegen/Bindings.conf index 5dc9e141ed5..31a041945fd 100644 --- a/components/script/dom/bindings/codegen/Bindings.conf +++ b/components/script/dom/bindings/codegen/Bindings.conf @@ -138,6 +138,10 @@ DOMInterfaces = { 'GPU': { 'inCompartments': ['RequestAdapter'], +}, + +'GPUAdapter': { + 'inCompartments': ['RequestDevice'], } } diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 65717bb81bf..1cefa9eeed8 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -146,7 +146,7 @@ use tendril::stream::LossyDecoder; use tendril::{StrTendril, TendrilSink}; use time::{Duration, Timespec}; use uuid::Uuid; -use webgpu::{WebGPU, WebGPUAdapter}; +use webgpu::{WebGPU, WebGPUAdapter, WebGPUDevice}; use webrender_api::{DocumentId, ImageKey}; use webvr_traits::{WebVRGamepadData, WebVRGamepadHand, WebVRGamepadState}; use webxr_api::SwapChainId as WebXRSwapChainId; @@ -504,9 +504,10 @@ unsafe_no_jsmanaged_fields!(WebGLTextureId); unsafe_no_jsmanaged_fields!(WebGLVertexArrayId); unsafe_no_jsmanaged_fields!(WebGLVersion); unsafe_no_jsmanaged_fields!(WebGLSLVersion); -unsafe_no_jsmanaged_fields!(WebGPU); unsafe_no_jsmanaged_fields!(RefCell<Identities>); +unsafe_no_jsmanaged_fields!(WebGPU); unsafe_no_jsmanaged_fields!(WebGPUAdapter); +unsafe_no_jsmanaged_fields!(WebGPUDevice); unsafe_no_jsmanaged_fields!(WebXRSwapChainId); unsafe_no_jsmanaged_fields!(MediaList); unsafe_no_jsmanaged_fields!(WebVRGamepadData, WebVRGamepadState, WebVRGamepadHand); diff --git a/components/script/dom/gpuadapter.rs b/components/script/dom/gpuadapter.rs index ec970439e8a..34b6fc38d45 100644 --- a/components/script/dom/gpuadapter.rs +++ b/components/script/dom/gpuadapter.rs @@ -2,16 +2,29 @@ * 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::dom::bindings::codegen::Bindings::GPUAdapterBinding::{self, GPUAdapterMethods}; +use crate::compartments::InCompartment; +use crate::dom::bindings::codegen::Bindings::GPUAdapterBinding::{ + self, GPUAdapterMethods, GPUDeviceDescriptor, +}; +use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods; +use crate::dom::bindings::error::Error; +use crate::dom::bindings::inheritance::Castable; +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::str::DOMString; use crate::dom::globalscope::GlobalScope; +use crate::dom::gpu::response_async; +use crate::dom::gpu::AsyncWGPUListener; +use crate::dom::gpudevice::GPUDevice; +use crate::dom::promise::Promise; +use crate::dom::window::Window; use crate::script_runtime::JSContext as SafeJSContext; use dom_struct::dom_struct; use js::jsapi::{Heap, JSObject}; use std::ptr::NonNull; -use webgpu::WebGPUAdapter; +use std::rc::Rc; +use webgpu::{wgpu, WebGPUAdapter, WebGPURequest, WebGPUResponse}; #[dom_struct] pub struct GPUAdapter { @@ -60,4 +73,51 @@ impl GPUAdapterMethods for GPUAdapter { fn Extensions(&self, _cx: SafeJSContext) -> NonNull<JSObject> { NonNull::new(self.extensions.get()).unwrap() } + + /// https://gpuweb.github.io/gpuweb/#dom-gpuadapter-requestdevice + fn RequestDevice(&self, descriptor: &GPUDeviceDescriptor, comp: InCompartment) -> Rc<Promise> { + let promise = Promise::new_in_current_compartment(&self.global(), comp); + let sender = response_async(&promise, self); + let desc = wgpu::DeviceDescriptor { + extensions: wgpu::Extensions { + anisotropic_filtering: descriptor.extensions.anisotropicFiltering, + }, + limits: wgpu::Limits { + max_bind_groups: descriptor.limits.maxBindGroups, + }, + }; + if let Some(window) = self.global().downcast::<Window>() { + let id = window.Navigator().create_device_id(); + match window.webgpu_channel() { + Some(thread) => thread + .0 + .send(WebGPURequest::RequestDevice(sender, self.adapter, desc, id)) + .unwrap(), + None => promise.reject_error(Error::Type("No WebGPU thread...".to_owned())), + } + } else { + promise.reject_error(Error::Type("No WebGPU thread...".to_owned())) + }; + promise + } +} + +impl AsyncWGPUListener for GPUAdapter { + fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) { + match response { + WebGPUResponse::RequestDevice(device_id, _descriptor) => { + let device = GPUDevice::new( + &self.global(), + &self, + Heap::default(), + Heap::default(), + device_id, + ); + promise.resolve_native(&device); + }, + _ => promise.reject_error(Error::Type( + "Wrong response type from WebGPU thread...".to_owned(), + )), + } + } } diff --git a/components/script/dom/gpudevice.rs b/components/script/dom/gpudevice.rs new file mode 100644 index 00000000000..d04ae97483a --- /dev/null +++ b/components/script/dom/gpudevice.rs @@ -0,0 +1,91 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::codegen::Bindings::GPUDeviceBinding::{self, GPUDeviceMethods}; +use crate::dom::bindings::reflector::reflect_dom_object; +use crate::dom::bindings::root::{Dom, DomRoot}; +use crate::dom::bindings::str::DOMString; +use crate::dom::eventtarget::EventTarget; +use crate::dom::globalscope::GlobalScope; +use crate::dom::gpuadapter::GPUAdapter; +use crate::script_runtime::JSContext as SafeJSContext; +use dom_struct::dom_struct; +use js::jsapi::{Heap, JSObject}; +use std::ptr::NonNull; +use webgpu::WebGPUDevice; + +#[dom_struct] +pub struct GPUDevice { + eventtarget: EventTarget, + adapter: Dom<GPUAdapter>, + #[ignore_malloc_size_of = "mozjs"] + extensions: Heap<*mut JSObject>, + #[ignore_malloc_size_of = "mozjs"] + limits: Heap<*mut JSObject>, + label: DomRefCell<Option<DOMString>>, + device: WebGPUDevice, +} + +impl GPUDevice { + fn new_inherited( + adapter: &GPUAdapter, + extensions: Heap<*mut JSObject>, + limits: Heap<*mut JSObject>, + device: WebGPUDevice, + ) -> GPUDevice { + Self { + eventtarget: EventTarget::new_inherited(), + adapter: Dom::from_ref(adapter), + extensions, + limits, + label: DomRefCell::new(None), + device, + } + } + + #[allow(unsafe_code)] + pub fn new( + global: &GlobalScope, + adapter: &GPUAdapter, + extensions: Heap<*mut JSObject>, + limits: Heap<*mut JSObject>, + device: WebGPUDevice, + ) -> DomRoot<GPUDevice> { + reflect_dom_object( + Box::new(GPUDevice::new_inherited( + adapter, extensions, limits, device, + )), + global, + GPUDeviceBinding::Wrap, + ) + } +} + +impl GPUDeviceMethods for GPUDevice { + /// https://gpuweb.github.io/gpuweb/#dom-gpudevice-adapter + fn Adapter(&self) -> DomRoot<GPUAdapter> { + DomRoot::from_ref(&self.adapter) + } + + /// https://gpuweb.github.io/gpuweb/#dom-gpudevice-extensions + fn Extensions(&self, _cx: SafeJSContext) -> NonNull<JSObject> { + NonNull::new(self.extensions.get()).unwrap() + } + + /// https://gpuweb.github.io/gpuweb/#dom-gpudevice-limits + fn Limits(&self, _cx: SafeJSContext) -> NonNull<JSObject> { + NonNull::new(self.extensions.get()).unwrap() + } + + /// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label + fn GetLabel(&self) -> Option<DOMString> { + self.label.borrow().clone() + } + + /// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label + fn SetLabel(&self, value: Option<DOMString>) { + *self.label.borrow_mut() = value; + } +} diff --git a/components/script/dom/identityhub.rs b/components/script/dom/identityhub.rs index 489eaacc78d..6c79a3c5f46 100644 --- a/components/script/dom/identityhub.rs +++ b/components/script/dom/identityhub.rs @@ -44,4 +44,8 @@ impl Identities { pub fn create_adapter_id(&mut self) -> AdapterId { self.hub.adapters.alloc() } + + pub fn create_device_id(&mut self) -> DeviceId { + self.hub.devices.alloc() + } } diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index d348633df88..bb1110389c6 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -317,6 +317,7 @@ pub mod gamepadlist; pub mod globalscope; pub mod gpu; pub mod gpuadapter; +pub mod gpudevice; pub mod hashchangeevent; pub mod headers; pub mod history; diff --git a/components/script/dom/navigator.rs b/components/script/dom/navigator.rs index 9121f7ef54d..c813af4ea99 100644 --- a/components/script/dom/navigator.rs +++ b/components/script/dom/navigator.rs @@ -26,7 +26,7 @@ use crate::dom::xr::XR; use dom_struct::dom_struct; use std::cell::RefCell; use std::rc::Rc; -use webgpu::wgpu::AdapterId; +use webgpu::wgpu::{AdapterId, DeviceId}; #[dom_struct] pub struct Navigator { @@ -76,6 +76,10 @@ impl Navigator { pub fn create_adapter_id(&self) -> AdapterId { self.gpu_id_hub.borrow_mut().create_adapter_id() } + + pub fn create_device_id(&self) -> DeviceId { + self.gpu_id_hub.borrow_mut().create_device_id() + } } impl NavigatorMethods for Navigator { diff --git a/components/script/dom/webidls/GPUAdapter.webidl b/components/script/dom/webidls/GPUAdapter.webidl index 0c2118a5f56..cc664fabffa 100644 --- a/components/script/dom/webidls/GPUAdapter.webidl +++ b/components/script/dom/webidls/GPUAdapter.webidl @@ -10,5 +10,25 @@ interface GPUAdapter { //readonly attribute GPULimits limits; Don’t expose higher limits for now. // May reject with DOMException // TODO: DOMException("OperationError")? - // Promise<GPUDevice> requestDevice(optional GPUDeviceDescriptor descriptor = {}); + Promise<GPUDevice> requestDevice(optional GPUDeviceDescriptor descriptor = {}); +}; + +dictionary GPUDeviceDescriptor : GPUObjectDescriptorBase { + GPUExtensions extensions = {}; + GPULimits limits = {}; +}; + +dictionary GPUExtensions { + boolean anisotropicFiltering = false; +}; + +dictionary GPULimits { + unsigned long maxBindGroups = 4; + unsigned long maxDynamicUniformBuffersPerPipelineLayout = 8; + unsigned long maxDynamicStorageBuffersPerPipelineLayout = 4; + unsigned long maxSampledTexturesPerShaderStage = 16; + unsigned long maxSamplersPerShaderStage = 16; + unsigned long maxStorageBuffersPerShaderStage = 4; + unsigned long maxStorageTexturesPerShaderStage = 4; + unsigned long maxUniformBuffersPerShaderStage = 12; }; diff --git a/components/script/dom/webidls/GPUDevice.webidl b/components/script/dom/webidls/GPUDevice.webidl new file mode 100644 index 00000000000..1cd441e6ef3 --- /dev/null +++ b/components/script/dom/webidls/GPUDevice.webidl @@ -0,0 +1,31 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +// https://gpuweb.github.io/gpuweb/#gpudevice +[Exposed=(Window, DedicatedWorker)/*, Serializable */, Pref="dom.webgpu.enabled"] +interface GPUDevice : EventTarget { + readonly attribute GPUAdapter adapter; + readonly attribute object extensions; + readonly attribute object limits; + + /*GPUBuffer createBuffer(GPUBufferDescriptor descriptor); + GPUMappedBuffer createBufferMapped(GPUBufferDescriptor descriptor); + Promise<GPUMappedBuffer> createBufferMappedAsync(GPUBufferDescriptor descriptor); + GPUTexture createTexture(GPUTextureDescriptor descriptor); + GPUSampler createSampler(optional GPUSamplerDescriptor descriptor = {}); + + GPUBindGroupLayout createBindGroupLayout(GPUBindGroupLayoutDescriptor descriptor); + GPUPipelineLayout createPipelineLayout(GPUPipelineLayoutDescriptor descriptor); + GPUBindGroup createBindGroup(GPUBindGroupDescriptor descriptor); + + GPUShaderModule createShaderModule(GPUShaderModuleDescriptor descriptor); + GPUComputePipeline createComputePipeline(GPUComputePipelineDescriptor descriptor); + GPURenderPipeline createRenderPipeline(GPURenderPipelineDescriptor descriptor); + + GPUCommandEncoder createCommandEncoder(optional GPUCommandEncoderDescriptor descriptor = {}); + GPURenderBundleEncoder createRenderBundleEncoder(GPURenderBundleEncoderDescriptor descriptor); + + GPUQueue getQueue();*/ +}; +GPUDevice includes GPUObjectBase; diff --git a/components/script/dom/webidls/GPUObjectBase.webidl b/components/script/dom/webidls/GPUObjectBase.webidl new file mode 100644 index 00000000000..c9a35992fb8 --- /dev/null +++ b/components/script/dom/webidls/GPUObjectBase.webidl @@ -0,0 +1,13 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +// https://gpuweb.github.io/gpuweb/#gpuobjectbase +[Exposed=(Window)] +interface mixin GPUObjectBase { + attribute DOMString? label; +}; + +dictionary GPUObjectDescriptorBase { + DOMString? label; +}; |