diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/bindings/trace.rs | 2 | ||||
-rw-r--r-- | components/script/dom/gpubindgrouplayout.rs | 10 | ||||
-rw-r--r-- | components/script/dom/gpubuffer.rs | 14 | ||||
-rw-r--r-- | components/script/dom/gpucommandencoder.rs | 93 | ||||
-rw-r--r-- | components/script/dom/gpucomputepassencoder.rs | 18 | ||||
-rw-r--r-- | components/script/dom/gpudevice.rs | 16 | ||||
-rw-r--r-- | components/script/dom/webidls/GPUBindGroup.webidl | 10 | ||||
-rw-r--r-- | components/script/dom/webidls/GPUBindGroupLayout.webidl | 6 | ||||
-rw-r--r-- | components/script/dom/webidls/GPUBuffer.webidl | 4 | ||||
-rw-r--r-- | components/script/dom/webidls/GPUCommandEncoder.webidl | 6 | ||||
-rw-r--r-- | components/script/dom/webidls/GPUComputePassEncoder.webidl | 2 |
11 files changed, 136 insertions, 45 deletions
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 083ad3752d3..976ca568e92 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -37,6 +37,7 @@ use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::{DOMString, USVString}; use crate::dom::bindings::utils::WindowProxyHandler; use crate::dom::gpubuffer::GPUBufferState; +use crate::dom::gpucommandencoder::GPUCommandEncoderState; use crate::dom::htmlimageelement::SourceSet; use crate::dom::htmlmediaelement::{HTMLMediaElementFetchContext, MediaFrameRenderer}; use crate::dom::identityhub::Identities; @@ -559,6 +560,7 @@ unsafe_no_jsmanaged_fields!(WebGPUCommandEncoder); unsafe_no_jsmanaged_fields!(WebGPUDevice); unsafe_no_jsmanaged_fields!(Option<RawPass>); unsafe_no_jsmanaged_fields!(GPUBufferState); +unsafe_no_jsmanaged_fields!(GPUCommandEncoderState); unsafe_no_jsmanaged_fields!(WebXRSwapChainId); unsafe_no_jsmanaged_fields!(MediaList); unsafe_no_jsmanaged_fields!( diff --git a/components/script/dom/gpubindgrouplayout.rs b/components/script/dom/gpubindgrouplayout.rs index da1e8a19446..c57fc272328 100644 --- a/components/script/dom/gpubindgrouplayout.rs +++ b/components/script/dom/gpubindgrouplayout.rs @@ -4,7 +4,7 @@ use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::GPUBindGroupLayoutBinding::{ - GPUBindGroupLayoutBindings, GPUBindGroupLayoutMethods, + GPUBindGroupLayoutEntry, GPUBindGroupLayoutMethods, }; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::DomRoot; @@ -20,7 +20,7 @@ pub struct GPUBindGroupLayout { label: DomRefCell<Option<DOMString>>, bind_group_layout: WebGPUBindGroupLayout, #[ignore_malloc_size_of = "defined in webgpu"] - bindings: Vec<GPUBindGroupLayoutBindings>, + bindings: Vec<GPUBindGroupLayoutEntry>, #[ignore_malloc_size_of = "defined in webgpu"] channel: WebGPU, valid: Cell<bool>, @@ -30,7 +30,7 @@ impl GPUBindGroupLayout { fn new_inherited( channel: WebGPU, bind_group_layout: WebGPUBindGroupLayout, - bindings: Vec<GPUBindGroupLayoutBindings>, + bindings: Vec<GPUBindGroupLayoutEntry>, valid: bool, ) -> GPUBindGroupLayout { Self { @@ -47,7 +47,7 @@ impl GPUBindGroupLayout { global: &GlobalScope, channel: WebGPU, bind_group_layout: WebGPUBindGroupLayout, - bindings: Vec<GPUBindGroupLayoutBindings>, + bindings: Vec<GPUBindGroupLayoutEntry>, valid: bool, ) -> DomRoot<GPUBindGroupLayout> { reflect_dom_object( @@ -71,7 +71,7 @@ impl GPUBindGroupLayout { self.bind_group_layout } - pub fn bindings(&self) -> &[GPUBindGroupLayoutBindings] { + pub fn bindings(&self) -> &[GPUBindGroupLayoutEntry] { &self.bindings } } diff --git a/components/script/dom/gpubuffer.rs b/components/script/dom/gpubuffer.rs index 5da4c445c3e..17379437fc8 100644 --- a/components/script/dom/gpubuffer.rs +++ b/components/script/dom/gpubuffer.rs @@ -3,7 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::cell::{DomRefCell, Ref}; -use crate::dom::bindings::codegen::Bindings::GPUBufferBinding::{GPUBufferMethods, GPUBufferSize}; +use crate::dom::bindings::codegen::Bindings::GPUBufferBinding::{GPUBufferMethods, GPUSize64}; use crate::dom::bindings::error::Error; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; @@ -44,7 +44,7 @@ pub struct GPUBuffer { #[ignore_malloc_size_of = "defined in webgpu"] channel: WebGPU, label: DomRefCell<Option<DOMString>>, - size: GPUBufferSize, + size: GPUSize64, usage: u32, state: DomRefCell<GPUBufferState>, buffer: WebGPUBuffer, @@ -60,7 +60,7 @@ impl GPUBuffer { buffer: WebGPUBuffer, device: WebGPUDevice, state: GPUBufferState, - size: GPUBufferSize, + size: GPUSize64, usage: u32, valid: bool, mapping: RootedTraceableBox<Heap<*mut JSObject>>, @@ -86,7 +86,7 @@ impl GPUBuffer { buffer: WebGPUBuffer, device: WebGPUDevice, state: GPUBufferState, - size: GPUBufferSize, + size: GPUSize64, usage: u32, valid: bool, mapping: RootedTraceableBox<Heap<*mut JSObject>>, @@ -105,7 +105,7 @@ impl GPUBuffer { self.buffer } - pub fn size(&self) -> GPUBufferSize { + pub fn size(&self) -> GPUSize64 { self.size } @@ -116,6 +116,10 @@ impl GPUBuffer { pub fn state(&self) -> Ref<GPUBufferState> { self.state.borrow() } + + pub fn valid(&self) -> bool { + self.valid.get() + } } impl Drop for GPUBuffer { diff --git a/components/script/dom/gpucommandencoder.rs b/components/script/dom/gpucommandencoder.rs index 46d0872643e..16cfb993ec1 100644 --- a/components/script/dom/gpucommandencoder.rs +++ b/components/script/dom/gpucommandencoder.rs @@ -3,6 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::codegen::Bindings::GPUBufferBinding::GPUSize64; use crate::dom::bindings::codegen::Bindings::GPUCommandEncoderBinding::{ GPUCommandBufferDescriptor, GPUCommandEncoderMethods, GPUComputePassDescriptor, }; @@ -16,9 +17,23 @@ use crate::dom::gpucommandbuffer::GPUCommandBuffer; use crate::dom::gpucomputepassencoder::GPUComputePassEncoder; use dom_struct::dom_struct; use ipc_channel::ipc; +use std::cell::Cell; use std::collections::HashSet; +use webgpu::wgpu::resource::BufferUsage; use webgpu::{WebGPU, WebGPUCommandEncoder, WebGPURequest}; +const BUFFER_COPY_ALIGN_MASK: u64 = 3; + +// https://gpuweb.github.io/gpuweb/#enumdef-encoder-state +#[derive(MallocSizeOf, PartialEq)] +#[allow(dead_code)] +pub enum GPUCommandEncoderState { + Open, + EncodingRenderPass, + EncodingComputePass, + Closed, +} + #[dom_struct] pub struct GPUCommandEncoder { reflector_: Reflector, @@ -27,16 +42,24 @@ pub struct GPUCommandEncoder { label: DomRefCell<Option<DOMString>>, encoder: WebGPUCommandEncoder, buffers: DomRefCell<HashSet<DomRoot<GPUBuffer>>>, + state: DomRefCell<GPUCommandEncoderState>, + valid: Cell<bool>, } impl GPUCommandEncoder { - pub fn new_inherited(channel: WebGPU, encoder: WebGPUCommandEncoder) -> GPUCommandEncoder { + pub fn new_inherited( + channel: WebGPU, + encoder: WebGPUCommandEncoder, + valid: bool, + ) -> GPUCommandEncoder { GPUCommandEncoder { channel, reflector_: Reflector::new(), label: DomRefCell::new(None), encoder, buffers: DomRefCell::new(HashSet::new()), + state: DomRefCell::new(GPUCommandEncoderState::Open), + valid: Cell::new(valid), } } @@ -44,14 +67,30 @@ impl GPUCommandEncoder { global: &GlobalScope, channel: WebGPU, encoder: WebGPUCommandEncoder, + valid: bool, ) -> DomRoot<GPUCommandEncoder> { reflect_dom_object( - Box::new(GPUCommandEncoder::new_inherited(channel, encoder)), + Box::new(GPUCommandEncoder::new_inherited(channel, encoder, valid)), global, ) } } +impl GPUCommandEncoder { + pub fn id(&self) -> WebGPUCommandEncoder { + self.encoder + } + + pub fn set_state(&self, set: GPUCommandEncoderState, expect: GPUCommandEncoderState) { + if *self.state.borrow() == expect { + *self.state.borrow_mut() = set; + } else { + self.valid.set(false); + *self.state.borrow_mut() = GPUCommandEncoderState::Closed; + } + } +} + impl GPUCommandEncoderMethods for GPUCommandEncoder { /// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label fn GetLabel(&self) -> Option<DOMString> { @@ -68,18 +107,59 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { &self, _descriptor: &GPUComputePassDescriptor, ) -> DomRoot<GPUComputePassEncoder> { - GPUComputePassEncoder::new(&self.global(), self.channel.clone(), self.encoder) + self.set_state( + GPUCommandEncoderState::EncodingComputePass, + GPUCommandEncoderState::Open, + ); + GPUComputePassEncoder::new(&self.global(), self.channel.clone(), &self) } /// https://gpuweb.github.io/gpuweb/#dom-gpucommandencoder-copybuffertobuffer fn CopyBufferToBuffer( &self, source: &GPUBuffer, - source_offset: u64, + source_offset: GPUSize64, destination: &GPUBuffer, - destination_offset: u64, - size: u64, + destination_offset: GPUSize64, + size: GPUSize64, ) { + let mut valid = match source_offset.checked_add(size) { + Some(_) => true, + None => false, + }; + valid &= match destination_offset.checked_add(size) { + Some(_) => true, + None => false, + }; + valid &= match BufferUsage::from_bits(source.usage()) { + Some(usage) => usage.contains(BufferUsage::COPY_SRC), + None => false, + }; + valid &= match BufferUsage::from_bits(destination.usage()) { + Some(usage) => usage.contains(BufferUsage::COPY_DST), + None => false, + }; + valid &= (*self.state.borrow() == GPUCommandEncoderState::Open) && + source.valid() && + destination.valid() & + !(size & BUFFER_COPY_ALIGN_MASK == 0) & + !(source_offset & BUFFER_COPY_ALIGN_MASK == 0) & + !(destination_offset & BUFFER_COPY_ALIGN_MASK == 0) & + (source.size() >= source_offset + size) & + (destination.size() >= destination_offset + size); + + if source.id().0 == destination.id().0 { + //TODO: maybe forbid this case based on https://github.com/gpuweb/gpuweb/issues/783 + valid &= source_offset > destination_offset + size || + source_offset + size < destination_offset; + } + + if !valid { + // TODO: Record an error in the current scope. + self.valid.set(false); + return; + } + self.buffers.borrow_mut().insert(DomRoot::from_ref(source)); self.buffers .borrow_mut() @@ -110,6 +190,7 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { }) .expect("Failed to send Finish"); + *self.state.borrow_mut() = GPUCommandEncoderState::Closed; let buffer = receiver.recv().unwrap(); GPUCommandBuffer::new( &self.global(), diff --git a/components/script/dom/gpucomputepassencoder.rs b/components/script/dom/gpucomputepassencoder.rs index c7e742cae84..eb4c20c0075 100644 --- a/components/script/dom/gpucomputepassencoder.rs +++ b/components/script/dom/gpucomputepassencoder.rs @@ -5,10 +5,11 @@ use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::GPUComputePassEncoderBinding::GPUComputePassEncoderMethods; 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::DOMString; use crate::dom::globalscope::GlobalScope; use crate::dom::gpubindgroup::GPUBindGroup; +use crate::dom::gpucommandencoder::{GPUCommandEncoder, GPUCommandEncoderState}; use crate::dom::gpucomputepipeline::GPUComputePipeline; use dom_struct::dom_struct; use std::cell::RefCell; @@ -20,7 +21,7 @@ use webgpu::{ }, RawPass, }, - WebGPU, WebGPUCommandEncoder, WebGPURequest, + WebGPU, WebGPURequest, }; #[dom_struct] @@ -31,22 +32,24 @@ pub struct GPUComputePassEncoder { label: DomRefCell<Option<DOMString>>, #[ignore_malloc_size_of = "defined in wgpu-core"] raw_pass: RefCell<Option<RawPass>>, + command_encoder: Dom<GPUCommandEncoder>, } impl GPUComputePassEncoder { - fn new_inherited(channel: WebGPU, parent: WebGPUCommandEncoder) -> GPUComputePassEncoder { + fn new_inherited(channel: WebGPU, parent: &GPUCommandEncoder) -> GPUComputePassEncoder { GPUComputePassEncoder { channel, reflector_: Reflector::new(), label: DomRefCell::new(None), - raw_pass: RefCell::new(Some(RawPass::new_compute(parent.0))), + raw_pass: RefCell::new(Some(RawPass::new_compute(parent.id().0))), + command_encoder: Dom::from_ref(parent), } } pub fn new( global: &GlobalScope, channel: WebGPU, - parent: WebGPUCommandEncoder, + parent: &GPUCommandEncoder, ) -> DomRoot<GPUComputePassEncoder> { reflect_dom_object( Box::new(GPUComputePassEncoder::new_inherited(channel, parent)), @@ -87,6 +90,11 @@ impl GPUComputePassEncoderMethods for GPUComputePassEncoder { pass_data, }) .unwrap(); + + self.command_encoder.set_state( + GPUCommandEncoderState::Open, + GPUCommandEncoderState::EncodingComputePass, + ); } } diff --git a/components/script/dom/gpudevice.rs b/components/script/dom/gpudevice.rs index 29fe2cda39d..f1e6bffda0b 100644 --- a/components/script/dom/gpudevice.rs +++ b/components/script/dom/gpudevice.rs @@ -8,7 +8,7 @@ use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::GPUAdapterBinding::GPULimits; use crate::dom::bindings::codegen::Bindings::GPUBindGroupBinding::GPUBindGroupDescriptor; use crate::dom::bindings::codegen::Bindings::GPUBindGroupLayoutBinding::{ - GPUBindGroupLayoutBindings, GPUBindGroupLayoutDescriptor, GPUBindingType, + GPUBindGroupLayoutDescriptor, GPUBindGroupLayoutEntry, GPUBindingType, }; use crate::dom::bindings::codegen::Bindings::GPUBufferBinding::GPUBufferDescriptor; use crate::dom::bindings::codegen::Bindings::GPUComputePipelineBinding::GPUComputePipelineDescriptor; @@ -295,7 +295,7 @@ impl GPUDeviceMethods for GPUDevice { let mut valid = true; let bindings = descriptor - .bindings + .entries .iter() .map(|bind| { // TODO: binding must be >= 0 @@ -410,9 +410,9 @@ impl GPUDeviceMethods for GPUDevice { let bgl = receiver.recv().unwrap(); let binds = descriptor - .bindings + .entries .iter() - .map(|bind| GPUBindGroupLayoutBindings { + .map(|bind| GPUBindGroupLayoutEntry { binding: bind.binding, hasDynamicOffset: bind.hasDynamicOffset, multisampled: bind.multisampled, @@ -494,9 +494,9 @@ impl GPUDeviceMethods for GPUDevice { /// https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbindgroup fn CreateBindGroup(&self, descriptor: &GPUBindGroupDescriptor) -> DomRoot<GPUBindGroup> { let alignment: u64 = 256; - let mut valid = descriptor.layout.bindings().len() == descriptor.bindings.len(); + let mut valid = descriptor.layout.bindings().len() == descriptor.entries.len(); - valid &= descriptor.bindings.iter().all(|bind| { + valid &= descriptor.entries.iter().all(|bind| { let buffer_size = bind.resource.buffer.size(); let resource_size = bind.resource.size.unwrap_or(buffer_size); let length = bind.resource.offset.checked_add(resource_size); @@ -521,7 +521,7 @@ impl GPUDeviceMethods for GPUDevice { }); let bindings = descriptor - .bindings + .entries .iter() .map(|bind| BindGroupBinding { binding: bind.binding, @@ -632,6 +632,6 @@ impl GPUDeviceMethods for GPUDevice { .expect("Failed to create WebGPU command encoder"); let encoder = receiver.recv().unwrap(); - GPUCommandEncoder::new(&self.global(), self.channel.clone(), encoder) + GPUCommandEncoder::new(&self.global(), self.channel.clone(), encoder, true) } } diff --git a/components/script/dom/webidls/GPUBindGroup.webidl b/components/script/dom/webidls/GPUBindGroup.webidl index 537fda29a63..f905755d6fb 100644 --- a/components/script/dom/webidls/GPUBindGroup.webidl +++ b/components/script/dom/webidls/GPUBindGroup.webidl @@ -10,14 +10,12 @@ GPUBindGroup includes GPUObjectBase; dictionary GPUBindGroupDescriptor : GPUObjectDescriptorBase { required GPUBindGroupLayout layout; - required sequence<GPUBindGroupBindings> bindings; + required sequence<GPUBindGroupEntry> entries; }; typedef /*(GPUSampler or GPUTextureView or*/ GPUBufferBindings/*)*/ GPUBindingResource; -// Note: Servo codegen doesn't like the name `GPUBindGroupBinding` because it's already occupied -// dictionary GPUBindGroupBinding { -dictionary GPUBindGroupBindings { +dictionary GPUBindGroupEntry { required unsigned long binding; required GPUBindingResource resource; }; @@ -26,6 +24,6 @@ dictionary GPUBindGroupBindings { // dictionary GPUBufferBinding { dictionary GPUBufferBindings { required GPUBuffer buffer; - GPUBufferSize offset = 0; - GPUBufferSize size; + GPUSize64 offset = 0; + GPUSize64 size; }; diff --git a/components/script/dom/webidls/GPUBindGroupLayout.webidl b/components/script/dom/webidls/GPUBindGroupLayout.webidl index 930a1dd84cc..b5327f107d3 100644 --- a/components/script/dom/webidls/GPUBindGroupLayout.webidl +++ b/components/script/dom/webidls/GPUBindGroupLayout.webidl @@ -9,12 +9,10 @@ interface GPUBindGroupLayout { GPUBindGroupLayout includes GPUObjectBase; dictionary GPUBindGroupLayoutDescriptor : GPUObjectDescriptorBase { - required sequence<GPUBindGroupLayoutBindings> bindings; + required sequence<GPUBindGroupLayoutEntry> entries; }; -// Note: Servo codegen doesn't like the name `GPUBindGroupLayoutBinding` because it's already occupied -// dictionary GPUBindGroupLayoutBinding { -dictionary GPUBindGroupLayoutBindings { +dictionary GPUBindGroupLayoutEntry { required unsigned long binding; required GPUShaderStageFlags visibility; required GPUBindingType type; diff --git a/components/script/dom/webidls/GPUBuffer.webidl b/components/script/dom/webidls/GPUBuffer.webidl index 1688060b514..be18b54bce7 100644 --- a/components/script/dom/webidls/GPUBuffer.webidl +++ b/components/script/dom/webidls/GPUBuffer.webidl @@ -14,11 +14,11 @@ interface GPUBuffer { GPUBuffer includes GPUObjectBase; dictionary GPUBufferDescriptor : GPUObjectDescriptorBase { - required GPUBufferSize size; + required GPUSize64 size; required GPUBufferUsageFlags usage; }; -typedef unsigned long long GPUBufferSize; +typedef unsigned long long GPUSize64; typedef unsigned long GPUBufferUsageFlags; diff --git a/components/script/dom/webidls/GPUCommandEncoder.webidl b/components/script/dom/webidls/GPUCommandEncoder.webidl index 481c720260f..f6801e46e96 100644 --- a/components/script/dom/webidls/GPUCommandEncoder.webidl +++ b/components/script/dom/webidls/GPUCommandEncoder.webidl @@ -10,10 +10,10 @@ interface GPUCommandEncoder { void copyBufferToBuffer( GPUBuffer source, - GPUBufferSize sourceOffset, + GPUSize64 sourceOffset, GPUBuffer destination, - GPUBufferSize destinationOffset, - GPUBufferSize size); + GPUSize64 destinationOffset, + GPUSize64 size); // void copyBufferToTexture( // GPUBufferCopyView source, diff --git a/components/script/dom/webidls/GPUComputePassEncoder.webidl b/components/script/dom/webidls/GPUComputePassEncoder.webidl index 6d0423a3fec..0b19cf98134 100644 --- a/components/script/dom/webidls/GPUComputePassEncoder.webidl +++ b/components/script/dom/webidls/GPUComputePassEncoder.webidl @@ -7,7 +7,7 @@ interface GPUComputePassEncoder { void setPipeline(GPUComputePipeline pipeline); void dispatch(GPUSize32 x, optional GPUSize32 y = 1, optional GPUSize32 z = 1); - // void dispatchIndirect(GPUBuffer indirectBuffer, GPUBufferSize indirectOffset); + // void dispatchIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset); void endPass(); }; |