aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/gpubindgroup.rs54
-rw-r--r--components/script/dom/gpubindgrouplayout.rs58
-rw-r--r--components/script/dom/gpubuffer.rs53
-rw-r--r--components/script/dom/gpucommandencoder.rs55
-rw-r--r--components/script/dom/gpucomputepipeline.rs44
-rw-r--r--components/script/dom/gpuconvert.rs48
-rw-r--r--components/script/dom/gpudevice.rs471
-rw-r--r--components/script/dom/gpupipelinelayout.rs52
-rw-r--r--components/script/dom/gpuqueue.rs1
-rw-r--r--components/script/dom/gpurenderbundleencoder.rs59
-rw-r--r--components/script/dom/gpurenderpipeline.rs32
-rw-r--r--components/script/dom/gpusampler.rs55
-rw-r--r--components/script/dom/gpushadermodule.rs41
-rw-r--r--components/script/dom/gputexture.rs57
14 files changed, 594 insertions, 486 deletions
diff --git a/components/script/dom/gpubindgroup.rs b/components/script/dom/gpubindgroup.rs
index 2c4fa1bd2e8..2aae7174265 100644
--- a/components/script/dom/gpubindgroup.rs
+++ b/components/script/dom/gpubindgroup.rs
@@ -2,16 +2,23 @@
* 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 std::borrow::Cow;
+
use dom_struct::dom_struct;
+use webgpu::wgc::binding_model::BindGroupDescriptor;
use webgpu::{WebGPU, WebGPUBindGroup, WebGPUDevice, WebGPURequest};
use crate::dom::bindings::cell::DomRefCell;
-use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUBindGroupMethods;
-use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
+use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
+ GPUBindGroupDescriptor, GPUBindGroupMethods,
+};
+use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
+use crate::dom::gpuconvert::convert_label;
+use crate::dom::gpudevice::GPUDevice;
#[dom_struct]
pub struct GPUBindGroup {
@@ -66,6 +73,49 @@ impl GPUBindGroup {
pub fn id(&self) -> &WebGPUBindGroup {
&self.bind_group
}
+
+ /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbindgroup>
+ pub fn create(
+ device: &GPUDevice,
+ descriptor: &GPUBindGroupDescriptor,
+ ) -> DomRoot<GPUBindGroup> {
+ let entries = descriptor
+ .entries
+ .iter()
+ .map(|bind| bind.into())
+ .collect::<Vec<_>>();
+
+ let desc = BindGroupDescriptor {
+ label: convert_label(&descriptor.parent),
+ layout: descriptor.layout.id().0,
+ entries: Cow::Owned(entries),
+ };
+
+ let bind_group_id = device
+ .global()
+ .wgpu_id_hub()
+ .create_bind_group_id(device.id().0.backend());
+ device
+ .channel()
+ .0
+ .send(WebGPURequest::CreateBindGroup {
+ device_id: device.id().0,
+ bind_group_id,
+ descriptor: desc,
+ })
+ .expect("Failed to create WebGPU BindGroup");
+
+ let bind_group = WebGPUBindGroup(bind_group_id);
+
+ GPUBindGroup::new(
+ &device.global(),
+ device.channel().clone(),
+ bind_group,
+ device.id(),
+ &descriptor.layout,
+ descriptor.parent.label.clone(),
+ )
+ }
}
impl Drop for GPUBindGroup {
diff --git a/components/script/dom/gpubindgrouplayout.rs b/components/script/dom/gpubindgrouplayout.rs
index 2a4cb199d41..875eff8e3fc 100644
--- a/components/script/dom/gpubindgrouplayout.rs
+++ b/components/script/dom/gpubindgrouplayout.rs
@@ -2,15 +2,23 @@
* 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 std::borrow::Cow;
+
use dom_struct::dom_struct;
+use webgpu::wgc::binding_model::BindGroupLayoutDescriptor;
use webgpu::{WebGPU, WebGPUBindGroupLayout, WebGPURequest};
use crate::dom::bindings::cell::DomRefCell;
-use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUBindGroupLayoutMethods;
-use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
+use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
+ GPUBindGroupLayoutDescriptor, GPUBindGroupLayoutMethods,
+};
+use crate::dom::bindings::error::Fallible;
+use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
+use crate::dom::gpuconvert::{convert_bind_group_layout_entry, convert_label};
+use crate::dom::gpudevice::GPUDevice;
#[dom_struct]
pub struct GPUBindGroupLayout {
@@ -58,6 +66,52 @@ impl GPUBindGroupLayout {
pub fn id(&self) -> WebGPUBindGroupLayout {
self.bind_group_layout
}
+
+ /// <https://gpuweb.github.io/gpuweb/#GPUDevice-createBindGroupLayout>
+ pub fn create(
+ device: &GPUDevice,
+ descriptor: &GPUBindGroupLayoutDescriptor,
+ ) -> Fallible<DomRoot<GPUBindGroupLayout>> {
+ let entries = descriptor
+ .entries
+ .iter()
+ .map(|bgle| convert_bind_group_layout_entry(bgle, device))
+ .collect::<Fallible<Result<Vec<_>, _>>>()?;
+
+ let desc = match entries {
+ Ok(entries) => Some(BindGroupLayoutDescriptor {
+ label: convert_label(&descriptor.parent),
+ entries: Cow::Owned(entries),
+ }),
+ Err(error) => {
+ device.dispatch_error(error);
+ None
+ },
+ };
+
+ let bind_group_layout_id = device
+ .global()
+ .wgpu_id_hub()
+ .create_bind_group_layout_id(device.id().0.backend());
+ device
+ .channel()
+ .0
+ .send(WebGPURequest::CreateBindGroupLayout {
+ device_id: device.id().0,
+ bind_group_layout_id,
+ descriptor: desc,
+ })
+ .expect("Failed to create WebGPU BindGroupLayout");
+
+ let bgl = WebGPUBindGroupLayout(bind_group_layout_id);
+
+ Ok(GPUBindGroupLayout::new(
+ &device.global(),
+ device.channel().clone(),
+ bgl,
+ descriptor.parent.label.clone(),
+ ))
+ }
}
impl Drop for GPUBindGroupLayout {
diff --git a/components/script/dom/gpubuffer.rs b/components/script/dom/gpubuffer.rs
index a8d8d204163..3b5631bce7c 100644
--- a/components/script/dom/gpubuffer.rs
+++ b/components/script/dom/gpubuffer.rs
@@ -14,14 +14,15 @@ use webgpu::{wgt, Mapping, WebGPU, WebGPUBuffer, WebGPURequest, WebGPUResponse};
use super::bindings::buffer_source::DataBlock;
use super::bindings::codegen::Bindings::WebGPUBinding::{
- GPUBufferMapState, GPUFlagsConstant, GPUMapModeFlags,
+ GPUBufferDescriptor, GPUBufferMapState, GPUFlagsConstant, GPUMapModeFlags,
};
+use super::gpuconvert::convert_label;
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
GPUBufferMethods, GPUMapModeConstants, GPUSize64,
};
use crate::dom::bindings::error::{Error, Fallible};
-use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
+use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
@@ -130,6 +131,54 @@ impl GPUBuffer {
pub fn id(&self) -> WebGPUBuffer {
self.buffer
}
+
+ /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbuffer>
+ pub fn create(
+ device: &GPUDevice,
+ descriptor: &GPUBufferDescriptor,
+ ) -> Fallible<DomRoot<GPUBuffer>> {
+ let desc = wgt::BufferDescriptor {
+ label: convert_label(&descriptor.parent),
+ size: descriptor.size as wgt::BufferAddress,
+ usage: wgt::BufferUsages::from_bits_retain(descriptor.usage),
+ mapped_at_creation: descriptor.mappedAtCreation,
+ };
+ let id = device
+ .global()
+ .wgpu_id_hub()
+ .create_buffer_id(device.id().0.backend());
+
+ device
+ .channel()
+ .0
+ .send(WebGPURequest::CreateBuffer {
+ device_id: device.id().0,
+ buffer_id: id,
+ descriptor: desc,
+ })
+ .expect("Failed to create WebGPU buffer");
+
+ let buffer = WebGPUBuffer(id);
+ let mapping = if descriptor.mappedAtCreation {
+ Some(ActiveBufferMapping::new(
+ GPUMapModeConstants::WRITE,
+ 0..descriptor.size,
+ )?)
+ } else {
+ None
+ };
+
+ Ok(GPUBuffer::new(
+ &device.global(),
+ device.channel().clone(),
+ buffer,
+ device,
+ descriptor.size,
+ descriptor.usage,
+ mapping,
+ descriptor.parent.label.clone(),
+ ))
+ }
}
impl Drop for GPUBuffer {
diff --git a/components/script/dom/gpucommandencoder.rs b/components/script/dom/gpucommandencoder.rs
index ed37fb910e0..6b930932bb7 100644
--- a/components/script/dom/gpucommandencoder.rs
+++ b/components/script/dom/gpucommandencoder.rs
@@ -4,15 +4,18 @@
use dom_struct::dom_struct;
use webgpu::wgc::command as wgpu_com;
-use webgpu::wgt::Color;
-use webgpu::{self, wgt, WebGPU, WebGPUComputePass, WebGPURenderPass, WebGPURequest};
+use webgpu::{
+ wgt, WebGPU, WebGPUCommandBuffer, WebGPUCommandEncoder, WebGPUComputePass, WebGPUDevice,
+ WebGPURenderPass, WebGPURequest,
+};
use super::bindings::error::Fallible;
use super::gpuconvert::convert_label;
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
- GPUCommandBufferDescriptor, GPUCommandEncoderMethods, GPUComputePassDescriptor, GPUExtent3D,
- GPUImageCopyBuffer, GPUImageCopyTexture, GPURenderPassDescriptor, GPUSize64,
+ GPUCommandBufferDescriptor, GPUCommandEncoderDescriptor, GPUCommandEncoderMethods,
+ GPUComputePassDescriptor, GPUExtent3D, GPUImageCopyBuffer, GPUImageCopyTexture,
+ GPURenderPassDescriptor, GPUSize64,
};
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
@@ -33,7 +36,7 @@ pub struct GPUCommandEncoder {
channel: WebGPU,
label: DomRefCell<USVString>,
#[no_trace]
- encoder: webgpu::WebGPUCommandEncoder,
+ encoder: WebGPUCommandEncoder,
device: Dom<GPUDevice>,
}
@@ -41,7 +44,7 @@ impl GPUCommandEncoder {
pub fn new_inherited(
channel: WebGPU,
device: &GPUDevice,
- encoder: webgpu::WebGPUCommandEncoder,
+ encoder: WebGPUCommandEncoder,
label: USVString,
) -> Self {
Self {
@@ -57,7 +60,7 @@ impl GPUCommandEncoder {
global: &GlobalScope,
channel: WebGPU,
device: &GPUDevice,
- encoder: webgpu::WebGPUCommandEncoder,
+ encoder: WebGPUCommandEncoder,
label: USVString,
) -> DomRoot<Self> {
reflect_dom_object(
@@ -70,13 +73,45 @@ impl GPUCommandEncoder {
}
impl GPUCommandEncoder {
- pub fn id(&self) -> webgpu::WebGPUCommandEncoder {
+ pub fn id(&self) -> WebGPUCommandEncoder {
self.encoder
}
- pub fn device_id(&self) -> webgpu::WebGPUDevice {
+ pub fn device_id(&self) -> WebGPUDevice {
self.device.id()
}
+
+ /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createcommandencoder>
+ pub fn create(
+ device: &GPUDevice,
+ descriptor: &GPUCommandEncoderDescriptor,
+ ) -> DomRoot<GPUCommandEncoder> {
+ let command_encoder_id = device
+ .global()
+ .wgpu_id_hub()
+ .create_command_encoder_id(device.id().0.backend());
+ device
+ .channel()
+ .0
+ .send(WebGPURequest::CreateCommandEncoder {
+ device_id: device.id().0,
+ command_encoder_id,
+ desc: wgt::CommandEncoderDescriptor {
+ label: convert_label(&descriptor.parent),
+ },
+ })
+ .expect("Failed to create WebGPU command encoder");
+
+ let encoder = WebGPUCommandEncoder(command_encoder_id);
+
+ GPUCommandEncoder::new(
+ &device.global(),
+ device.channel().clone(),
+ device,
+ encoder,
+ descriptor.parent.label.clone(),
+ )
+ }
}
impl GPUCommandEncoderMethods for GPUCommandEncoder {
@@ -283,7 +318,7 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder {
})
.expect("Failed to send Finish");
- let buffer = webgpu::WebGPUCommandBuffer(self.encoder.0.into_command_buffer_id());
+ let buffer = WebGPUCommandBuffer(self.encoder.0.into_command_buffer_id());
GPUCommandBuffer::new(
&self.global(),
self.channel.clone(),
diff --git a/components/script/dom/gpucomputepipeline.rs b/components/script/dom/gpucomputepipeline.rs
index 392f111ffa1..bf58302da52 100644
--- a/components/script/dom/gpucomputepipeline.rs
+++ b/components/script/dom/gpucomputepipeline.rs
@@ -3,16 +3,21 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use dom_struct::dom_struct;
-use webgpu::{WebGPU, WebGPUBindGroupLayout, WebGPUComputePipeline, WebGPURequest};
+use ipc_channel::ipc::IpcSender;
+use webgpu::wgc::pipeline::ComputePipelineDescriptor;
+use webgpu::{WebGPU, WebGPUBindGroupLayout, WebGPUComputePipeline, WebGPURequest, WebGPUResponse};
use crate::dom::bindings::cell::DomRefCell;
-use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUComputePipelineMethods;
+use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
+ GPUComputePipelineDescriptor, GPUComputePipelineMethods,
+};
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
+use crate::dom::gpuconvert::convert_label;
use crate::dom::gpudevice::GPUDevice;
#[dom_struct]
@@ -63,6 +68,41 @@ impl GPUComputePipeline {
pub fn id(&self) -> &WebGPUComputePipeline {
&self.compute_pipeline
}
+
+ /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createcomputepipeline>
+ pub fn create(
+ device: &GPUDevice,
+ descriptor: &GPUComputePipelineDescriptor,
+ async_sender: Option<IpcSender<WebGPUResponse>>,
+ ) -> WebGPUComputePipeline {
+ let compute_pipeline_id = device
+ .global()
+ .wgpu_id_hub()
+ .create_compute_pipeline_id(device.id().0.backend());
+
+ let (layout, implicit_ids, _) = device.get_pipeline_layout_data(&descriptor.parent.layout);
+
+ let desc = ComputePipelineDescriptor {
+ label: convert_label(&descriptor.parent.parent),
+ layout,
+ stage: (&descriptor.compute).into(),
+ cache: None,
+ };
+
+ device
+ .channel()
+ .0
+ .send(WebGPURequest::CreateComputePipeline {
+ device_id: device.id().0,
+ compute_pipeline_id,
+ descriptor: desc,
+ implicit_ids,
+ async_sender,
+ })
+ .expect("Failed to create WebGPU ComputePipeline");
+
+ WebGPUComputePipeline(compute_pipeline_id)
+ }
}
impl GPUComputePipelineMethods for GPUComputePipeline {
diff --git a/components/script/dom/gpuconvert.rs b/components/script/dom/gpuconvert.rs
index acba9634787..1eb7c9fb977 100644
--- a/components/script/dom/gpuconvert.rs
+++ b/components/script/dom/gpuconvert.rs
@@ -5,20 +5,23 @@
use std::borrow::Cow;
use std::num::NonZeroU64;
+use webgpu::wgc::binding_model::{BindGroupEntry, BindingResource, BufferBinding};
use webgpu::wgc::command as wgpu_com;
use webgpu::wgc::pipeline::ProgrammableStageDescriptor;
use webgpu::wgt::{self, AstcBlock, AstcChannel};
-use super::bindings::codegen::Bindings::WebGPUBinding::GPUProgrammableStage;
+use super::bindings::codegen::Bindings::WebGPUBinding::{
+ GPUProgrammableStage, GPUTextureDimension,
+};
use super::bindings::error::Error;
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
- GPUAddressMode, GPUBindGroupLayoutEntry, GPUBlendComponent, GPUBlendFactor, GPUBlendOperation,
- GPUBufferBindingType, GPUColor, GPUCompareFunction, GPUCullMode, GPUExtent3D, GPUFilterMode,
- GPUFrontFace, GPUImageCopyBuffer, GPUImageCopyTexture, GPUImageDataLayout, GPUIndexFormat,
- GPULoadOp, GPUObjectDescriptorBase, GPUOrigin3D, GPUPrimitiveState, GPUPrimitiveTopology,
- GPUSamplerBindingType, GPUStencilOperation, GPUStorageTextureAccess, GPUStoreOp,
- GPUTextureAspect, GPUTextureFormat, GPUTextureSampleType, GPUTextureViewDimension,
- GPUVertexFormat,
+ GPUAddressMode, GPUBindGroupEntry, GPUBindGroupLayoutEntry, GPUBindingResource,
+ GPUBlendComponent, GPUBlendFactor, GPUBlendOperation, GPUBufferBindingType, GPUColor,
+ GPUCompareFunction, GPUCullMode, GPUExtent3D, GPUFilterMode, GPUFrontFace, GPUImageCopyBuffer,
+ GPUImageCopyTexture, GPUImageDataLayout, GPUIndexFormat, GPULoadOp, GPUObjectDescriptorBase,
+ GPUOrigin3D, GPUPrimitiveState, GPUPrimitiveTopology, GPUSamplerBindingType,
+ GPUStencilOperation, GPUStorageTextureAccess, GPUStoreOp, GPUTextureAspect, GPUTextureFormat,
+ GPUTextureSampleType, GPUTextureViewDimension, GPUVertexFormat,
};
use crate::dom::bindings::error::Fallible;
use crate::dom::types::GPUDevice;
@@ -624,3 +627,32 @@ impl<'a> From<&GPUProgrammableStage> for ProgrammableStageDescriptor<'a> {
}
}
}
+
+impl From<&GPUBindGroupEntry> for BindGroupEntry<'_> {
+ fn from(entry: &GPUBindGroupEntry) -> Self {
+ Self {
+ binding: entry.binding,
+ resource: match entry.resource {
+ GPUBindingResource::GPUSampler(ref s) => BindingResource::Sampler(s.id().0),
+ GPUBindingResource::GPUTextureView(ref t) => BindingResource::TextureView(t.id().0),
+ GPUBindingResource::GPUBufferBinding(ref b) => {
+ BindingResource::Buffer(BufferBinding {
+ buffer_id: b.buffer.id().0,
+ offset: b.offset,
+ size: b.size.and_then(wgt::BufferSize::new),
+ })
+ },
+ },
+ }
+ }
+}
+
+impl From<GPUTextureDimension> for wgt::TextureDimension {
+ fn from(dimension: GPUTextureDimension) -> Self {
+ match dimension {
+ GPUTextureDimension::_1d => wgt::TextureDimension::D1,
+ GPUTextureDimension::_2d => wgt::TextureDimension::D2,
+ GPUTextureDimension::_3d => wgt::TextureDimension::D3,
+ }
+ }
+}
diff --git a/components/script/dom/gpudevice.rs b/components/script/dom/gpudevice.rs
index 2a531128db4..33daf8217b9 100644
--- a/components/script/dom/gpudevice.rs
+++ b/components/script/dom/gpudevice.rs
@@ -11,23 +11,18 @@ use std::rc::Rc;
use dom_struct::dom_struct;
use js::jsapi::{Heap, JSObject};
use webgpu::wgc::id::{BindGroupLayoutId, PipelineLayoutId};
+use webgpu::wgc::pipeline as wgpu_pipe;
use webgpu::wgc::pipeline::RenderPipelineDescriptor;
-use webgpu::wgc::{
- binding_model as wgpu_bind, command as wgpu_com, pipeline as wgpu_pipe, resource as wgpu_res,
-};
-use webgpu::wgt::{BlendComponent, TextureFormat};
+use webgpu::wgt::TextureFormat;
use webgpu::{
- self, wgt, PopError, WebGPU, WebGPUComputePipeline, WebGPURenderPipeline, WebGPURequest,
+ wgt, PopError, WebGPU, WebGPUComputePipeline, WebGPURenderPipeline, WebGPURequest,
WebGPUResponse,
};
-use super::bindings::codegen::Bindings::WebGPUBinding::{
- GPUMapModeConstants, GPUPipelineErrorReason, GPUTextureFormat,
-};
+use super::bindings::codegen::Bindings::WebGPUBinding::{GPUPipelineErrorReason, GPUTextureFormat};
use super::bindings::codegen::UnionTypes::GPUPipelineLayoutOrGPUAutoLayoutMode;
use super::bindings::error::Fallible;
use super::gpu::AsyncWGPUListener;
-use super::gpuconvert::convert_bind_group_layout_entry;
use super::gpudevicelostinfo::GPUDeviceLostInfo;
use super::gpupipelineerror::GPUPipelineError;
use super::gpusupportedlimits::GPUSupportedLimits;
@@ -36,12 +31,12 @@ use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::EventBinding::EventInit;
use crate::dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
- GPUBindGroupDescriptor, GPUBindGroupLayoutDescriptor, GPUBindingResource, GPUBufferDescriptor,
+ GPUBindGroupDescriptor, GPUBindGroupLayoutDescriptor, GPUBufferDescriptor,
GPUCommandEncoderDescriptor, GPUComputePipelineDescriptor, GPUDeviceLostReason,
GPUDeviceMethods, GPUErrorFilter, GPUPipelineLayoutDescriptor,
GPURenderBundleEncoderDescriptor, GPURenderPipelineDescriptor, GPUSamplerDescriptor,
GPUShaderModuleDescriptor, GPUSupportedLimitsMethods, GPUTextureDescriptor,
- GPUTextureDimension, GPUUncapturedErrorEventInit, GPUVertexStepMode,
+ GPUUncapturedErrorEventInit, GPUVertexStepMode,
};
use crate::dom::bindings::error::Error;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
@@ -54,7 +49,7 @@ use crate::dom::gpu::response_async;
use crate::dom::gpuadapter::GPUAdapter;
use crate::dom::gpubindgroup::GPUBindGroup;
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
-use crate::dom::gpubuffer::{ActiveBufferMapping, GPUBuffer};
+use crate::dom::gpubuffer::GPUBuffer;
use crate::dom::gpucommandencoder::GPUCommandEncoder;
use crate::dom::gpucomputepipeline::GPUComputePipeline;
use crate::dom::gpuconvert::convert_label;
@@ -211,7 +206,7 @@ impl GPUDevice {
self.lost_promise.borrow().is_fulfilled()
}
- fn get_pipeline_layout_data(
+ pub fn get_pipeline_layout_data(
&self,
layout: &GPUPipelineLayoutOrGPUAutoLayoutMode,
) -> (
@@ -241,7 +236,7 @@ impl GPUDevice {
}
}
- fn parse_render_pipeline<'a>(
+ pub fn parse_render_pipeline<'a>(
&self,
descriptor: &GPURenderPipelineDescriptor,
) -> Fallible<(
@@ -401,46 +396,7 @@ impl GPUDeviceMethods for GPUDevice {
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbuffer>
fn CreateBuffer(&self, descriptor: &GPUBufferDescriptor) -> Fallible<DomRoot<GPUBuffer>> {
- let desc = wgpu_res::BufferDescriptor {
- label: convert_label(&descriptor.parent),
- size: descriptor.size as wgt::BufferAddress,
- usage: wgt::BufferUsages::from_bits_retain(descriptor.usage),
- mapped_at_creation: descriptor.mappedAtCreation,
- };
- let id = self
- .global()
- .wgpu_id_hub()
- .create_buffer_id(self.device.0.backend());
-
- self.channel
- .0
- .send(WebGPURequest::CreateBuffer {
- device_id: self.device.0,
- buffer_id: id,
- descriptor: desc,
- })
- .expect("Failed to create WebGPU buffer");
-
- let buffer = webgpu::WebGPUBuffer(id);
- let mapping = if descriptor.mappedAtCreation {
- Some(ActiveBufferMapping::new(
- GPUMapModeConstants::WRITE,
- 0..descriptor.size,
- )?)
- } else {
- None
- };
-
- Ok(GPUBuffer::new(
- &self.global(),
- self.channel.clone(),
- buffer,
- self,
- descriptor.size,
- descriptor.usage,
- mapping,
- descriptor.parent.label.clone(),
- ))
+ GPUBuffer::create(self, descriptor)
}
/// <https://gpuweb.github.io/gpuweb/#GPUDevice-createBindGroupLayout>
@@ -449,44 +405,7 @@ impl GPUDeviceMethods for GPUDevice {
&self,
descriptor: &GPUBindGroupLayoutDescriptor,
) -> Fallible<DomRoot<GPUBindGroupLayout>> {
- let entries = descriptor
- .entries
- .iter()
- .map(|bgle| convert_bind_group_layout_entry(bgle, &self))
- .collect::<Fallible<Result<Vec<_>, _>>>()?;
-
- let desc = match entries {
- Ok(entries) => Some(wgpu_bind::BindGroupLayoutDescriptor {
- label: convert_label(&descriptor.parent),
- entries: Cow::Owned(entries),
- }),
- Err(error) => {
- self.dispatch_error(error);
- None
- },
- };
-
- let bind_group_layout_id = self
- .global()
- .wgpu_id_hub()
- .create_bind_group_layout_id(self.device.0.backend());
- self.channel
- .0
- .send(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);
-
- Ok(GPUBindGroupLayout::new(
- &self.global(),
- self.channel.clone(),
- bgl,
- descriptor.parent.label.clone(),
- ))
+ GPUBindGroupLayout::create(self, descriptor)
}
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createpipelinelayout>
@@ -494,100 +413,12 @@ impl GPUDeviceMethods for GPUDevice {
&self,
descriptor: &GPUPipelineLayoutDescriptor,
) -> DomRoot<GPUPipelineLayout> {
- let desc = wgpu_bind::PipelineLayoutDescriptor {
- label: convert_label(&descriptor.parent),
- bind_group_layouts: Cow::Owned(
- descriptor
- .bindGroupLayouts
- .iter()
- .map(|each| each.id().0)
- .collect::<Vec<_>>(),
- ),
- push_constant_ranges: Cow::Owned(vec![]),
- };
-
- let pipeline_layout_id = self
- .global()
- .wgpu_id_hub()
- .create_pipeline_layout_id(self.device.0.backend());
- self.channel
- .0
- .send(WebGPURequest::CreatePipelineLayout {
- device_id: self.device.0,
- pipeline_layout_id,
- descriptor: desc,
- })
- .expect("Failed to create WebGPU PipelineLayout");
-
- let bgls = descriptor
- .bindGroupLayouts
- .iter()
- .map(|each| each.id())
- .collect::<Vec<_>>();
- let pipeline_layout = webgpu::WebGPUPipelineLayout(pipeline_layout_id);
- GPUPipelineLayout::new(
- &self.global(),
- self.channel.clone(),
- pipeline_layout,
- descriptor.parent.label.clone(),
- bgls,
- )
+ GPUPipelineLayout::create(self, descriptor)
}
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbindgroup>
fn CreateBindGroup(&self, descriptor: &GPUBindGroupDescriptor) -> DomRoot<GPUBindGroup> {
- let entries = descriptor
- .entries
- .iter()
- .map(|bind| wgpu_bind::BindGroupEntry {
- binding: bind.binding,
- resource: match bind.resource {
- GPUBindingResource::GPUSampler(ref s) => {
- wgpu_bind::BindingResource::Sampler(s.id().0)
- },
- GPUBindingResource::GPUTextureView(ref t) => {
- wgpu_bind::BindingResource::TextureView(t.id().0)
- },
- GPUBindingResource::GPUBufferBinding(ref b) => {
- wgpu_bind::BindingResource::Buffer(wgpu_bind::BufferBinding {
- buffer_id: b.buffer.id().0,
- offset: b.offset,
- size: b.size.and_then(wgt::BufferSize::new),
- })
- },
- },
- })
- .collect::<Vec<_>>();
-
- let desc = wgpu_bind::BindGroupDescriptor {
- label: convert_label(&descriptor.parent),
- layout: descriptor.layout.id().0,
- entries: Cow::Owned(entries),
- };
-
- let bind_group_id = self
- .global()
- .wgpu_id_hub()
- .create_bind_group_id(self.device.0.backend());
- self.channel
- .0
- .send(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);
-
- GPUBindGroup::new(
- &self.global(),
- self.channel.clone(),
- bind_group,
- self.device,
- &descriptor.layout,
- descriptor.parent.label.clone(),
- )
+ GPUBindGroup::create(self, descriptor)
}
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createshadermodule>
@@ -596,30 +427,7 @@ impl GPUDeviceMethods for GPUDevice {
descriptor: RootedTraceableBox<GPUShaderModuleDescriptor>,
comp: InRealm,
) -> DomRoot<GPUShaderModule> {
- let program_id = self
- .global()
- .wgpu_id_hub()
- .create_shader_module_id(self.device.0.backend());
- let promise = Promise::new_in_current_realm(comp);
- let shader_module = GPUShaderModule::new(
- &self.global(),
- self.channel.clone(),
- webgpu::WebGPUShaderModule(program_id),
- descriptor.parent.label.clone(),
- promise.clone(),
- );
- let sender = response_async(&promise, &*shader_module);
- self.channel
- .0
- .send(WebGPURequest::CreateShaderModule {
- device_id: self.device.0,
- program_id,
- program: descriptor.code.0.clone(),
- label: None,
- sender,
- })
- .expect("Failed to create WebGPU ShaderModule");
- shader_module
+ GPUShaderModule::create(self, descriptor, comp)
}
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createcomputepipeline>
@@ -627,32 +435,7 @@ impl GPUDeviceMethods for GPUDevice {
&self,
descriptor: &GPUComputePipelineDescriptor,
) -> DomRoot<GPUComputePipeline> {
- let compute_pipeline_id = self
- .global()
- .wgpu_id_hub()
- .create_compute_pipeline_id(self.device.0.backend());
-
- let (layout, implicit_ids, _) = self.get_pipeline_layout_data(&descriptor.parent.layout);
-
- let desc = wgpu_pipe::ComputePipelineDescriptor {
- label: convert_label(&descriptor.parent.parent),
- layout,
- stage: (&descriptor.compute).into(),
- cache: None,
- };
-
- self.channel
- .0
- .send(WebGPURequest::CreateComputePipeline {
- device_id: self.device.0,
- compute_pipeline_id,
- descriptor: desc,
- implicit_ids,
- async_sender: None,
- })
- .expect("Failed to create WebGPU ComputePipeline");
-
- let compute_pipeline = webgpu::WebGPUComputePipeline(compute_pipeline_id);
+ let compute_pipeline = GPUComputePipeline::create(self, descriptor, None);
GPUComputePipeline::new(
&self.global(),
compute_pipeline,
@@ -669,30 +452,7 @@ impl GPUDeviceMethods for GPUDevice {
) -> Rc<Promise> {
let promise = Promise::new_in_current_realm(comp);
let sender = response_async(&promise, self);
- let compute_pipeline_id = self
- .global()
- .wgpu_id_hub()
- .create_compute_pipeline_id(self.device.0.backend());
-
- let (layout, implicit_ids, _) = self.get_pipeline_layout_data(&descriptor.parent.layout);
-
- let desc = wgpu_pipe::ComputePipelineDescriptor {
- label: convert_label(&descriptor.parent.parent),
- layout,
- stage: (&descriptor.compute).into(),
- cache: None,
- };
-
- self.channel
- .0
- .send(WebGPURequest::CreateComputePipeline {
- device_id: self.device.0,
- compute_pipeline_id,
- descriptor: desc,
- implicit_ids,
- async_sender: Some(sender),
- })
- .expect("Failed to create WebGPU ComputePipeline");
+ GPUComputePipeline::create(self, descriptor, Some(sender));
promise
}
@@ -701,130 +461,17 @@ impl GPUDeviceMethods for GPUDevice {
&self,
descriptor: &GPUCommandEncoderDescriptor,
) -> DomRoot<GPUCommandEncoder> {
- let command_encoder_id = self
- .global()
- .wgpu_id_hub()
- .create_command_encoder_id(self.device.0.backend());
- self.channel
- .0
- .send(WebGPURequest::CreateCommandEncoder {
- device_id: self.device.0,
- command_encoder_id,
- desc: wgt::CommandEncoderDescriptor {
- label: convert_label(&descriptor.parent),
- },
- })
- .expect("Failed to create WebGPU command encoder");
-
- let encoder = webgpu::WebGPUCommandEncoder(command_encoder_id);
-
- GPUCommandEncoder::new(
- &self.global(),
- self.channel.clone(),
- self,
- encoder,
- descriptor.parent.label.clone(),
- )
+ GPUCommandEncoder::create(self, descriptor)
}
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createtexture>
fn CreateTexture(&self, descriptor: &GPUTextureDescriptor) -> Fallible<DomRoot<GPUTexture>> {
- let size = (&descriptor.size).try_into()?;
- let desc = wgpu_res::TextureDescriptor {
- label: convert_label(&descriptor.parent),
- size,
- mip_level_count: descriptor.mipLevelCount,
- sample_count: descriptor.sampleCount,
- dimension: match descriptor.dimension {
- GPUTextureDimension::_1d => wgt::TextureDimension::D1,
- GPUTextureDimension::_2d => wgt::TextureDimension::D2,
- GPUTextureDimension::_3d => wgt::TextureDimension::D3,
- },
- format: self.validate_texture_format_required_features(&descriptor.format)?,
- usage: wgt::TextureUsages::from_bits_retain(descriptor.usage),
- view_formats: descriptor
- .viewFormats
- .iter()
- .map(|tf| self.validate_texture_format_required_features(tf))
- .collect::<Fallible<_>>()?,
- };
-
- let texture_id = self
- .global()
- .wgpu_id_hub()
- .create_texture_id(self.device.0.backend());
-
- self.channel
- .0
- .send(WebGPURequest::CreateTexture {
- device_id: self.device.0,
- texture_id,
- descriptor: desc,
- })
- .expect("Failed to create WebGPU Texture");
-
- let texture = webgpu::WebGPUTexture(texture_id);
-
- Ok(GPUTexture::new(
- &self.global(),
- texture,
- self,
- self.channel.clone(),
- size,
- descriptor.mipLevelCount,
- descriptor.sampleCount,
- descriptor.dimension,
- descriptor.format,
- descriptor.usage,
- descriptor.parent.label.clone(),
- ))
+ GPUTexture::create(self, descriptor)
}
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createsampler>
fn CreateSampler(&self, descriptor: &GPUSamplerDescriptor) -> DomRoot<GPUSampler> {
- let sampler_id = self
- .global()
- .wgpu_id_hub()
- .create_sampler_id(self.device.0.backend());
- let compare_enable = descriptor.compare.is_some();
- let desc = wgpu_res::SamplerDescriptor {
- label: convert_label(&descriptor.parent),
- address_modes: [
- descriptor.addressModeU.into(),
- descriptor.addressModeV.into(),
- descriptor.addressModeW.into(),
- ],
- mag_filter: descriptor.magFilter.into(),
- min_filter: descriptor.minFilter.into(),
- mipmap_filter: descriptor.mipmapFilter.into(),
- lod_min_clamp: *descriptor.lodMinClamp,
- lod_max_clamp: *descriptor.lodMaxClamp,
- compare: descriptor
- .compare
- .map(|gpu_compare_function| gpu_compare_function.into()),
- anisotropy_clamp: 1,
- border_color: None,
- };
-
- self.channel
- .0
- .send(WebGPURequest::CreateSampler {
- device_id: self.device.0,
- sampler_id,
- descriptor: desc,
- })
- .expect("Failed to create WebGPU sampler");
-
- let sampler = webgpu::WebGPUSampler(sampler_id);
-
- GPUSampler::new(
- &self.global(),
- self.channel.clone(),
- self.device,
- compare_enable,
- sampler,
- descriptor.parent.label.clone(),
- )
+ GPUSampler::create(self, descriptor)
}
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createrenderpipeline>
@@ -833,25 +480,7 @@ impl GPUDeviceMethods for GPUDevice {
descriptor: &GPURenderPipelineDescriptor,
) -> Fallible<DomRoot<GPURenderPipeline>> {
let (implicit_ids, desc) = self.parse_render_pipeline(&descriptor)?;
-
- let render_pipeline_id = self
- .global()
- .wgpu_id_hub()
- .create_render_pipeline_id(self.device.0.backend());
-
- self.channel
- .0
- .send(WebGPURequest::CreateRenderPipeline {
- device_id: self.device.0,
- render_pipeline_id,
- descriptor: desc,
- implicit_ids,
- async_sender: None,
- })
- .expect("Failed to create WebGPU render pipeline");
-
- let render_pipeline = webgpu::WebGPURenderPipeline(render_pipeline_id);
-
+ let render_pipeline = GPURenderPipeline::create(self, implicit_ids, desc, None)?;
Ok(GPURenderPipeline::new(
&self.global(),
render_pipeline,
@@ -867,26 +496,9 @@ impl GPUDeviceMethods for GPUDevice {
comp: InRealm,
) -> Fallible<Rc<Promise>> {
let (implicit_ids, desc) = self.parse_render_pipeline(&descriptor)?;
-
let promise = Promise::new_in_current_realm(comp);
let sender = response_async(&promise, self);
-
- let render_pipeline_id = self
- .global()
- .wgpu_id_hub()
- .create_render_pipeline_id(self.device.0.backend());
-
- self.channel
- .0
- .send(WebGPURequest::CreateRenderPipeline {
- device_id: self.device.0,
- render_pipeline_id,
- descriptor: desc,
- implicit_ids,
- async_sender: Some(sender),
- })
- .expect("Failed to create WebGPU render pipeline");
-
+ GPURenderPipeline::create(self, implicit_ids, desc, Some(sender))?;
Ok(promise)
}
@@ -895,46 +507,7 @@ impl GPUDeviceMethods for GPUDevice {
&self,
descriptor: &GPURenderBundleEncoderDescriptor,
) -> Fallible<DomRoot<GPURenderBundleEncoder>> {
- let desc = wgpu_com::RenderBundleEncoderDescriptor {
- label: convert_label(&descriptor.parent.parent),
- color_formats: Cow::Owned(
- descriptor
- .parent
- .colorFormats
- .iter()
- .map(|format| {
- self.validate_texture_format_required_features(format)
- .map(|f| Some(f))
- })
- .collect::<Fallible<Vec<_>>>()?,
- ),
- depth_stencil: descriptor
- .parent
- .depthStencilFormat
- .map(|dsf| {
- self.validate_texture_format_required_features(&dsf)
- .map(|format| wgt::RenderBundleDepthStencil {
- format,
- depth_read_only: descriptor.depthReadOnly,
- stencil_read_only: descriptor.stencilReadOnly,
- })
- })
- .transpose()?,
- sample_count: descriptor.parent.sampleCount,
- multiview: None,
- };
-
- // Handle error gracefully
- let render_bundle_encoder =
- wgpu_com::RenderBundleEncoder::new(&desc, self.device.0, None).unwrap();
-
- Ok(GPURenderBundleEncoder::new(
- &self.global(),
- render_bundle_encoder,
- self,
- self.channel.clone(),
- descriptor.parent.parent.label.clone(),
- ))
+ GPURenderBundleEncoder::create(self, descriptor)
}
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-pusherrorscope>
diff --git a/components/script/dom/gpupipelinelayout.rs b/components/script/dom/gpupipelinelayout.rs
index c2554f3b882..00d7e4a0cec 100644
--- a/components/script/dom/gpupipelinelayout.rs
+++ b/components/script/dom/gpupipelinelayout.rs
@@ -2,15 +2,22 @@
* 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 std::borrow::Cow;
+
use dom_struct::dom_struct;
+use webgpu::wgc::binding_model::PipelineLayoutDescriptor;
use webgpu::{WebGPU, WebGPUBindGroupLayout, WebGPUPipelineLayout, WebGPURequest};
use crate::dom::bindings::cell::DomRefCell;
-use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUPipelineLayoutMethods;
-use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
+use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
+ GPUPipelineLayoutDescriptor, GPUPipelineLayoutMethods,
+};
+use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
+use crate::dom::gpuconvert::convert_label;
+use crate::dom::gpudevice::GPUDevice;
#[dom_struct]
pub struct GPUPipelineLayout {
@@ -68,6 +75,47 @@ impl GPUPipelineLayout {
pub fn bind_group_layouts(&self) -> Vec<WebGPUBindGroupLayout> {
self.bind_group_layouts.clone()
}
+
+ /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createpipelinelayout>
+ pub fn create(
+ device: &GPUDevice,
+ descriptor: &GPUPipelineLayoutDescriptor,
+ ) -> DomRoot<GPUPipelineLayout> {
+ let bgls = descriptor
+ .bindGroupLayouts
+ .iter()
+ .map(|each| each.id())
+ .collect::<Vec<_>>();
+
+ let desc = PipelineLayoutDescriptor {
+ label: convert_label(&descriptor.parent),
+ bind_group_layouts: Cow::Owned(bgls.iter().map(|l| l.0).collect::<Vec<_>>()),
+ push_constant_ranges: Cow::Owned(vec![]),
+ };
+
+ let pipeline_layout_id = device
+ .global()
+ .wgpu_id_hub()
+ .create_pipeline_layout_id(device.id().0.backend());
+ device
+ .channel()
+ .0
+ .send(WebGPURequest::CreatePipelineLayout {
+ device_id: device.id().0,
+ pipeline_layout_id,
+ descriptor: desc,
+ })
+ .expect("Failed to create WebGPU PipelineLayout");
+
+ let pipeline_layout = WebGPUPipelineLayout(pipeline_layout_id);
+ GPUPipelineLayout::new(
+ &device.global(),
+ device.channel().clone(),
+ pipeline_layout,
+ descriptor.parent.label.clone(),
+ bgls,
+ )
+ }
}
impl GPUPipelineLayoutMethods for GPUPipelineLayout {
diff --git a/components/script/dom/gpuqueue.rs b/components/script/dom/gpuqueue.rs
index 76ef9d5b475..a82e68dcf8f 100644
--- a/components/script/dom/gpuqueue.rs
+++ b/components/script/dom/gpuqueue.rs
@@ -6,7 +6,6 @@ use std::rc::Rc;
use dom_struct::dom_struct;
use ipc_channel::ipc::IpcSharedMemory;
-use webgpu::wgt::Extent3d;
use webgpu::{wgt, WebGPU, WebGPUQueue, WebGPURequest, WebGPUResponse};
use super::bindings::codegen::Bindings::WebGPUBinding::{GPUImageCopyTexture, GPUImageDataLayout};
diff --git a/components/script/dom/gpurenderbundleencoder.rs b/components/script/dom/gpurenderbundleencoder.rs
index 2a4d8c7bfaa..483e3e5ef32 100644
--- a/components/script/dom/gpurenderbundleencoder.rs
+++ b/components/script/dom/gpurenderbundleencoder.rs
@@ -2,15 +2,20 @@
* 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 std::borrow::Cow;
+
use dom_struct::dom_struct;
-use webgpu::wgc::command::{bundle_ffi as wgpu_bundle, RenderBundleEncoder};
+use webgpu::wgc::command::{
+ bundle_ffi as wgpu_bundle, RenderBundleEncoder, RenderBundleEncoderDescriptor,
+};
use webgpu::{wgt, WebGPU, WebGPURenderBundle, WebGPURequest};
use super::bindings::codegen::Bindings::WebGPUBinding::GPUIndexFormat;
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
- GPURenderBundleDescriptor, GPURenderBundleEncoderMethods,
+ GPURenderBundleDescriptor, GPURenderBundleEncoderDescriptor, GPURenderBundleEncoderMethods,
};
+use crate::dom::bindings::import::module::Fallible;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
@@ -70,6 +75,56 @@ impl GPURenderBundleEncoder {
}
}
+impl GPURenderBundleEncoder {
+ /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createrenderbundleencoder>
+ pub fn create(
+ device: &GPUDevice,
+ descriptor: &GPURenderBundleEncoderDescriptor,
+ ) -> Fallible<DomRoot<GPURenderBundleEncoder>> {
+ let desc = RenderBundleEncoderDescriptor {
+ label: convert_label(&descriptor.parent.parent),
+ color_formats: Cow::Owned(
+ descriptor
+ .parent
+ .colorFormats
+ .iter()
+ .map(|format| {
+ device
+ .validate_texture_format_required_features(format)
+ .map(|f| Some(f))
+ })
+ .collect::<Fallible<Vec<_>>>()?,
+ ),
+ depth_stencil: descriptor
+ .parent
+ .depthStencilFormat
+ .map(|dsf| {
+ device
+ .validate_texture_format_required_features(&dsf)
+ .map(|format| wgt::RenderBundleDepthStencil {
+ format,
+ depth_read_only: descriptor.depthReadOnly,
+ stencil_read_only: descriptor.stencilReadOnly,
+ })
+ })
+ .transpose()?,
+ sample_count: descriptor.parent.sampleCount,
+ multiview: None,
+ };
+
+ // Handle error gracefully
+ let render_bundle_encoder = RenderBundleEncoder::new(&desc, device.id().0, None).unwrap();
+
+ Ok(GPURenderBundleEncoder::new(
+ &device.global(),
+ render_bundle_encoder,
+ device,
+ device.channel().clone(),
+ descriptor.parent.parent.label.clone(),
+ ))
+ }
+}
+
impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder {
/// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
fn Label(&self) -> USVString {
diff --git a/components/script/dom/gpurenderpipeline.rs b/components/script/dom/gpurenderpipeline.rs
index 9b4e64198ab..c0e9506835b 100644
--- a/components/script/dom/gpurenderpipeline.rs
+++ b/components/script/dom/gpurenderpipeline.rs
@@ -3,7 +3,10 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use dom_struct::dom_struct;
-use webgpu::{WebGPU, WebGPUBindGroupLayout, WebGPURenderPipeline, WebGPURequest};
+use ipc_channel::ipc::IpcSender;
+use webgpu::wgc::id::{BindGroupLayoutId, PipelineLayoutId};
+use webgpu::wgc::pipeline::RenderPipelineDescriptor;
+use webgpu::{WebGPU, WebGPUBindGroupLayout, WebGPURenderPipeline, WebGPURequest, WebGPUResponse};
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPURenderPipelineMethods;
@@ -63,6 +66,33 @@ impl GPURenderPipeline {
pub fn id(&self) -> WebGPURenderPipeline {
self.render_pipeline
}
+
+ /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createrenderpipeline>
+ pub fn create(
+ device: &GPUDevice,
+ implicit_ids: Option<(PipelineLayoutId, Vec<BindGroupLayoutId>)>,
+ descriptor: RenderPipelineDescriptor<'static>,
+ async_sender: Option<IpcSender<WebGPUResponse>>,
+ ) -> Fallible<WebGPURenderPipeline> {
+ let render_pipeline_id = device
+ .global()
+ .wgpu_id_hub()
+ .create_render_pipeline_id(device.id().0.backend());
+
+ device
+ .channel()
+ .0
+ .send(WebGPURequest::CreateRenderPipeline {
+ device_id: device.id().0,
+ render_pipeline_id,
+ descriptor,
+ implicit_ids,
+ async_sender,
+ })
+ .expect("Failed to create WebGPU render pipeline");
+
+ Ok(WebGPURenderPipeline(render_pipeline_id))
+ }
}
impl GPURenderPipelineMethods for GPURenderPipeline {
diff --git a/components/script/dom/gpusampler.rs b/components/script/dom/gpusampler.rs
index 5a7ce54814d..874d907e069 100644
--- a/components/script/dom/gpusampler.rs
+++ b/components/script/dom/gpusampler.rs
@@ -3,14 +3,19 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use dom_struct::dom_struct;
+use webgpu::wgc::resource::SamplerDescriptor;
use webgpu::{WebGPU, WebGPUDevice, WebGPURequest, WebGPUSampler};
use crate::dom::bindings::cell::DomRefCell;
-use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUSamplerMethods;
-use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
+use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
+ GPUSamplerDescriptor, GPUSamplerMethods,
+};
+use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::USVString;
use crate::dom::globalscope::GlobalScope;
+use crate::dom::gpuconvert::convert_label;
+use crate::dom::gpudevice::GPUDevice;
#[dom_struct]
pub struct GPUSampler {
@@ -69,6 +74,52 @@ impl GPUSampler {
pub fn id(&self) -> WebGPUSampler {
self.sampler
}
+
+ /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createsampler>
+ pub fn create(device: &GPUDevice, descriptor: &GPUSamplerDescriptor) -> DomRoot<GPUSampler> {
+ let sampler_id = device
+ .global()
+ .wgpu_id_hub()
+ .create_sampler_id(device.id().0.backend());
+ let compare_enable = descriptor.compare.is_some();
+ let desc = SamplerDescriptor {
+ label: convert_label(&descriptor.parent),
+ address_modes: [
+ descriptor.addressModeU.into(),
+ descriptor.addressModeV.into(),
+ descriptor.addressModeW.into(),
+ ],
+ mag_filter: descriptor.magFilter.into(),
+ min_filter: descriptor.minFilter.into(),
+ mipmap_filter: descriptor.mipmapFilter.into(),
+ lod_min_clamp: *descriptor.lodMinClamp,
+ lod_max_clamp: *descriptor.lodMaxClamp,
+ compare: descriptor.compare.map(Into::into),
+ anisotropy_clamp: 1,
+ border_color: None,
+ };
+
+ device
+ .channel()
+ .0
+ .send(WebGPURequest::CreateSampler {
+ device_id: device.id().0,
+ sampler_id,
+ descriptor: desc,
+ })
+ .expect("Failed to create WebGPU sampler");
+
+ let sampler = WebGPUSampler(sampler_id);
+
+ GPUSampler::new(
+ &device.global(),
+ device.channel().clone(),
+ device.id(),
+ compare_enable,
+ sampler,
+ descriptor.parent.label.clone(),
+ )
+ }
}
impl GPUSamplerMethods for GPUSampler {
diff --git a/components/script/dom/gpushadermodule.rs b/components/script/dom/gpushadermodule.rs
index f7af6360673..f245765b36a 100644
--- a/components/script/dom/gpushadermodule.rs
+++ b/components/script/dom/gpushadermodule.rs
@@ -10,12 +10,18 @@ use webgpu::{WebGPU, WebGPURequest, WebGPUResponse, WebGPUShaderModule};
use super::gpu::AsyncWGPUListener;
use super::gpucompilationinfo::GPUCompilationInfo;
use super::promise::Promise;
+use super::types::GPUDevice;
use crate::dom::bindings::cell::DomRefCell;
-use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUShaderModuleMethods;
+use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
+ GPUShaderModuleDescriptor, GPUShaderModuleMethods,
+};
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::USVString;
+use crate::dom::bindings::trace::RootedTraceableBox;
use crate::dom::globalscope::GlobalScope;
+use crate::dom::gpu::response_async;
+use crate::realms::InRealm;
#[dom_struct]
pub struct GPUShaderModule {
@@ -69,6 +75,39 @@ impl GPUShaderModule {
pub fn id(&self) -> WebGPUShaderModule {
self.shader_module
}
+
+ /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createshadermodule>
+ pub fn create(
+ device: &GPUDevice,
+ descriptor: RootedTraceableBox<GPUShaderModuleDescriptor>,
+ comp: InRealm,
+ ) -> DomRoot<GPUShaderModule> {
+ let program_id = device
+ .global()
+ .wgpu_id_hub()
+ .create_shader_module_id(device.id().0.backend());
+ let promise = Promise::new_in_current_realm(comp);
+ let shader_module = GPUShaderModule::new(
+ &device.global(),
+ device.channel().clone(),
+ WebGPUShaderModule(program_id),
+ descriptor.parent.label.clone(),
+ promise.clone(),
+ );
+ let sender = response_async(&promise, &*shader_module);
+ device
+ .channel()
+ .0
+ .send(WebGPURequest::CreateShaderModule {
+ device_id: device.id().0,
+ program_id,
+ program: descriptor.code.0.clone(),
+ label: None,
+ sender,
+ })
+ .expect("Failed to create WebGPU ShaderModule");
+ shader_module
+ }
}
impl GPUShaderModuleMethods for GPUShaderModule {
diff --git a/components/script/dom/gputexture.rs b/components/script/dom/gputexture.rs
index af063b8ae3d..7f0d64e9336 100644
--- a/components/script/dom/gputexture.rs
+++ b/components/script/dom/gputexture.rs
@@ -12,8 +12,8 @@ use webgpu::{wgt, WebGPU, WebGPURequest, WebGPUTexture, WebGPUTextureView};
use super::bindings::error::Fallible;
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
- GPUTextureAspect, GPUTextureDimension, GPUTextureFormat, GPUTextureMethods,
- GPUTextureViewDescriptor,
+ GPUTextureAspect, GPUTextureDescriptor, GPUTextureDimension, GPUTextureFormat,
+ GPUTextureMethods, GPUTextureViewDescriptor,
};
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
@@ -128,6 +128,59 @@ impl GPUTexture {
pub fn id(&self) -> WebGPUTexture {
self.texture
}
+
+ /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createtexture>
+ pub fn create(
+ device: &GPUDevice,
+ descriptor: &GPUTextureDescriptor,
+ ) -> Fallible<DomRoot<GPUTexture>> {
+ let size = (&descriptor.size).try_into()?;
+ let desc = wgt::TextureDescriptor {
+ label: convert_label(&descriptor.parent),
+ size,
+ mip_level_count: descriptor.mipLevelCount,
+ sample_count: descriptor.sampleCount,
+ dimension: descriptor.dimension.into(),
+ format: device.validate_texture_format_required_features(&descriptor.format)?,
+ usage: wgt::TextureUsages::from_bits_retain(descriptor.usage),
+ view_formats: descriptor
+ .viewFormats
+ .iter()
+ .map(|tf| device.validate_texture_format_required_features(tf))
+ .collect::<Fallible<_>>()?,
+ };
+
+ let texture_id = device
+ .global()
+ .wgpu_id_hub()
+ .create_texture_id(device.id().0.backend());
+
+ device
+ .channel()
+ .0
+ .send(WebGPURequest::CreateTexture {
+ device_id: device.id().0,
+ texture_id,
+ descriptor: desc,
+ })
+ .expect("Failed to create WebGPU Texture");
+
+ let texture = WebGPUTexture(texture_id);
+
+ Ok(GPUTexture::new(
+ &device.global(),
+ texture,
+ device,
+ device.channel().clone(),
+ size,
+ descriptor.mipLevelCount,
+ descriptor.sampleCount,
+ descriptor.dimension,
+ descriptor.format,
+ descriptor.usage,
+ descriptor.parent.label.clone(),
+ ))
+ }
}
impl GPUTextureMethods for GPUTexture {