aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/bindings/trace.rs2
-rw-r--r--components/script/dom/gpubindgrouplayout.rs10
-rw-r--r--components/script/dom/gpubuffer.rs14
-rw-r--r--components/script/dom/gpucommandencoder.rs93
-rw-r--r--components/script/dom/gpucomputepassencoder.rs18
-rw-r--r--components/script/dom/gpudevice.rs16
-rw-r--r--components/script/dom/webidls/GPUBindGroup.webidl10
-rw-r--r--components/script/dom/webidls/GPUBindGroupLayout.webidl6
-rw-r--r--components/script/dom/webidls/GPUBuffer.webidl4
-rw-r--r--components/script/dom/webidls/GPUCommandEncoder.webidl6
-rw-r--r--components/script/dom/webidls/GPUComputePassEncoder.webidl2
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();
};