Skip to content

Commit

Permalink
Initial implementation of GPUComputePipeline
Browse files Browse the repository at this point in the history
Added WebIDL bindings for `GPUComputePipeline`.
Implemented the `createComputePipeline` function of `GPUDevice`.
  • Loading branch information
Istvan Miklos committed Feb 11, 2020
1 parent a8621c4 commit 9031369
Show file tree
Hide file tree
Showing 11 changed files with 180 additions and 8 deletions.
5 changes: 3 additions & 2 deletions components/script/dom/bindings/trace.rs
Expand Up @@ -152,8 +152,8 @@ use tendril::{StrTendril, TendrilSink};
use time::{Duration, Timespec, Tm};
use uuid::Uuid;
use webgpu::{
WebGPU, WebGPUAdapter, WebGPUBindGroup, WebGPUBindGroupLayout, WebGPUBuffer, WebGPUDevice,
WebGPUPipelineLayout, WebGPUShaderModule,
WebGPU, WebGPUAdapter, WebGPUBindGroup, WebGPUBindGroupLayout, WebGPUBuffer,
WebGPUComputePipeline, WebGPUDevice, WebGPUPipelineLayout, WebGPUShaderModule,
};
use webrender_api::{DocumentId, ImageKey};
use webvr_traits::{WebVRGamepadData, WebVRGamepadHand, WebVRGamepadState};
Expand Down Expand Up @@ -535,6 +535,7 @@ unsafe_no_jsmanaged_fields!(WebGPUDevice);
unsafe_no_jsmanaged_fields!(WebGPUBuffer);
unsafe_no_jsmanaged_fields!(WebGPUBindGroup);
unsafe_no_jsmanaged_fields!(WebGPUBindGroupLayout);
unsafe_no_jsmanaged_fields!(WebGPUComputePipeline);
unsafe_no_jsmanaged_fields!(WebGPUPipelineLayout);
unsafe_no_jsmanaged_fields!(WebGPUShaderModule);
unsafe_no_jsmanaged_fields!(GPUBufferState);
Expand Down
9 changes: 7 additions & 2 deletions components/script/dom/globalscope.rs
Expand Up @@ -99,8 +99,8 @@ use time::{get_time, Timespec};
use uuid::Uuid;
use webgpu::wgpu::{
id::{
AdapterId, BindGroupId, BindGroupLayoutId, BufferId, DeviceId, PipelineLayoutId,
ShaderModuleId,
AdapterId, BindGroupId, BindGroupLayoutId, BufferId, ComputePipelineId, DeviceId,
PipelineLayoutId, ShaderModuleId,
},
Backend,
};
Expand Down Expand Up @@ -2137,6 +2137,11 @@ impl GlobalScope {
.borrow_mut()
.create_shader_module_id(backend)
}
pub fn wgpu_create_compute_pipeline_id(&self, backend: Backend) -> ComputePipelineId {
self.gpu_id_hub
.borrow_mut()
.create_compute_pipeline_id(backend)
}
}

fn timestamp_in_ms(time: Timespec) -> u64 {
Expand Down
55 changes: 55 additions & 0 deletions components/script/dom/gpucomputepipeline.rs
@@ -0,0 +1,55 @@
/* 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::GPUComputePipelineBinding::{
GPUComputePipelineBinding, GPUComputePipelineMethods,
};
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::Reflector;
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
use webgpu::WebGPUComputePipeline;

#[dom_struct]
pub struct GPUComputePipeline {
reflector_: Reflector,
label: DomRefCell<Option<DOMString>>,
compute_pipeline: WebGPUComputePipeline,
}

impl GPUComputePipeline {
fn new_inherited(compute_pipeline: WebGPUComputePipeline) -> GPUComputePipeline {
Self {
reflector_: Reflector::new(),
label: DomRefCell::new(None),
compute_pipeline,
}
}

pub fn new(
global: &GlobalScope,
compute_pipeline: WebGPUComputePipeline,
) -> DomRoot<GPUComputePipeline> {
reflect_dom_object(
Box::new(GPUComputePipeline::new_inherited(compute_pipeline)),
global,
GPUComputePipelineBinding::Wrap,
)
}
}

impl GPUComputePipelineMethods for GPUComputePipeline {
/// 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;
}
}
30 changes: 30 additions & 0 deletions components/script/dom/gpudevice.rs
Expand Up @@ -11,6 +11,7 @@ use crate::dom::bindings::codegen::Bindings::GPUBindGroupLayoutBinding::{
GPUBindGroupLayoutBindings, GPUBindGroupLayoutDescriptor, GPUBindingType,
};
use crate::dom::bindings::codegen::Bindings::GPUBufferBinding::GPUBufferDescriptor;
use crate::dom::bindings::codegen::Bindings::GPUComputePipelineBinding::GPUComputePipelineDescriptor;
use crate::dom::bindings::codegen::Bindings::GPUDeviceBinding::{self, GPUDeviceMethods};
use crate::dom::bindings::codegen::Bindings::GPUPipelineLayoutBinding::GPUPipelineLayoutDescriptor;
use crate::dom::bindings::codegen::Bindings::GPUShaderModuleBinding::GPUShaderModuleDescriptor;
Expand All @@ -25,6 +26,7 @@ use crate::dom::gpuadapter::GPUAdapter;
use crate::dom::gpubindgroup::GPUBindGroup;
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
use crate::dom::gpubuffer::{GPUBuffer, GPUBufferState};
use crate::dom::gpucomputepipeline::GPUComputePipeline;
use crate::dom::gpupipelinelayout::GPUPipelineLayout;
use crate::dom::gpushadermodule::GPUShaderModule;
use crate::script_runtime::JSContext as SafeJSContext;
Expand Down Expand Up @@ -559,4 +561,32 @@ impl GPUDeviceMethods for GPUDevice {
let shader_module = receiver.recv().unwrap();
GPUShaderModule::new(&self.global(), shader_module)
}

/// https://gpuweb.github.io/gpuweb/#dom-gpudevice-createcomputepipeline
fn CreateComputePipeline(
&self,
descriptor: &GPUComputePipelineDescriptor,
) -> DomRoot<GPUComputePipeline> {
let pipeline = descriptor.parent.layout.id();
let program = descriptor.computeStage.module.id();
let entry_point = descriptor.computeStage.entryPoint.to_string();
let id = self
.global()
.wgpu_create_compute_pipeline_id(self.device.0.backend());
let (sender, receiver) = ipc::channel().unwrap();
self.channel
.0
.send(WebGPURequest::CreateComputePipeline(
sender,
self.device,
id,
pipeline.0,
program.0,
entry_point,
))
.expect("Failed to create WebGPU ComputePipeline");

let compute_pipeline = receiver.recv().unwrap();
GPUComputePipeline::new(&self.global(), compute_pipeline)
}
}
6 changes: 6 additions & 0 deletions components/script/dom/gpupipelinelayout.rs
Expand Up @@ -56,6 +56,12 @@ impl GPUPipelineLayout {
}
}

impl GPUPipelineLayout {
pub fn id(&self) -> WebGPUPipelineLayout {
self.pipeline_layout
}
}

impl GPUPipelineLayoutMethods for GPUPipelineLayout {
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
fn GetLabel(&self) -> Option<DOMString> {
Expand Down
6 changes: 6 additions & 0 deletions components/script/dom/gpushadermodule.rs
Expand Up @@ -41,6 +41,12 @@ impl GPUShaderModule {
}
}

impl GPUShaderModule {
pub fn id(&self) -> WebGPUShaderModule {
self.shader_module
}
}

impl GPUShaderModuleMethods for GPUShaderModule {
/// https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label
fn GetLabel(&self) -> Option<DOMString> {
Expand Down
14 changes: 12 additions & 2 deletions components/script/dom/identityhub.rs
Expand Up @@ -6,8 +6,8 @@ use smallvec::SmallVec;
use webgpu::wgpu::{
hub::IdentityManager,
id::{
AdapterId, BindGroupId, BindGroupLayoutId, BufferId, DeviceId, PipelineLayoutId,
ShaderModuleId,
AdapterId, BindGroupId, BindGroupLayoutId, BufferId, ComputePipelineId, DeviceId,
PipelineLayoutId, ShaderModuleId,
},
Backend,
};
Expand All @@ -19,6 +19,7 @@ pub struct IdentityHub {
buffers: IdentityManager,
bind_groups: IdentityManager,
bind_group_layouts: IdentityManager,
compute_pipelines: IdentityManager,
pipeline_layouts: IdentityManager,
shader_modules: IdentityManager,
backend: Backend,
Expand All @@ -32,6 +33,7 @@ impl IdentityHub {
buffers: IdentityManager::default(),
bind_groups: IdentityManager::default(),
bind_group_layouts: IdentityManager::default(),
compute_pipelines: IdentityManager::default(),
pipeline_layouts: IdentityManager::default(),
shader_modules: IdentityManager::default(),
backend,
Expand All @@ -58,6 +60,10 @@ impl IdentityHub {
self.bind_group_layouts.alloc(self.backend)
}

fn create_compute_pipeline_id(&mut self) -> ComputePipelineId {
self.compute_pipelines.alloc(self.backend)
}

fn create_pipeline_layout_id(&mut self) -> PipelineLayoutId {
self.pipeline_layouts.alloc(self.backend)
}
Expand Down Expand Up @@ -149,6 +155,10 @@ impl Identities {
self.select(backend).create_bind_group_layout_id()
}

pub fn create_compute_pipeline_id(&mut self, backend: Backend) -> ComputePipelineId {
self.select(backend).create_compute_pipeline_id()
}

pub fn create_pipeline_layout_id(&mut self, backend: Backend) -> PipelineLayoutId {
self.select(backend).create_pipeline_layout_id()
}
Expand Down
1 change: 1 addition & 0 deletions components/script/dom/mod.rs
Expand Up @@ -322,6 +322,7 @@ pub mod gpubindgroup;
pub mod gpubindgrouplayout;
pub mod gpubuffer;
pub mod gpubufferusage;
pub mod gpucomputepipeline;
pub mod gpudevice;
pub mod gpupipelinelayout;
pub mod gpushadermodule;
Expand Down
22 changes: 22 additions & 0 deletions components/script/dom/webidls/GPUComputePipeline.webidl
@@ -0,0 +1,22 @@
/* 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/#gpucomputepipeline
[Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"]
interface GPUComputePipeline {
};
GPUComputePipeline includes GPUObjectBase;

dictionary GPUPipelineDescriptorBase : GPUObjectDescriptorBase {
required GPUPipelineLayout layout;
};

dictionary GPUProgrammableStageDescriptor {
required GPUShaderModule module;
required DOMString entryPoint;
};

dictionary GPUComputePipelineDescriptor : GPUPipelineDescriptorBase {
required GPUProgrammableStageDescriptor computeStage;
};
4 changes: 2 additions & 2 deletions components/script/dom/webidls/GPUDevice.webidl
Expand Up @@ -20,8 +20,8 @@ interface GPUDevice : EventTarget {
GPUBindGroup createBindGroup(GPUBindGroupDescriptor descriptor);

GPUShaderModule createShaderModule(GPUShaderModuleDescriptor descriptor);
/*GPUComputePipeline createComputePipeline(GPUComputePipelineDescriptor descriptor);
GPURenderPipeline createRenderPipeline(GPURenderPipelineDescriptor descriptor);
GPUComputePipeline createComputePipeline(GPUComputePipelineDescriptor descriptor);
/*GPURenderPipeline createRenderPipeline(GPURenderPipelineDescriptor descriptor);
GPUCommandEncoder createCommandEncoder(optional GPUCommandEncoderDescriptor descriptor = {});
GPURenderBundleEncoder createRenderBundleEncoder(GPURenderBundleEncoderDescriptor descriptor);
Expand Down
36 changes: 36 additions & 0 deletions components/webgpu/lib.rs
Expand Up @@ -59,6 +59,14 @@ pub enum WebGPURequest {
wgpu::id::BindGroupLayoutId,
Vec<wgpu::binding_model::BindGroupLayoutBinding>,
),
CreateComputePipeline(
IpcSender<WebGPUComputePipeline>,
WebGPUDevice,
wgpu::id::ComputePipelineId,
wgpu::id::PipelineLayoutId,
wgpu::id::ShaderModuleId,
String,
),
CreatePipelineLayout(
IpcSender<WebGPUPipelineLayout>,
WebGPUDevice,
Expand Down Expand Up @@ -310,6 +318,33 @@ impl WGPU {
)
}
},
WebGPURequest::CreateComputePipeline(
sender,
device,
id,
layout,
program,
entry,
) => {
let global = &self.global;
let entry_point = std::ffi::CString::new(entry).unwrap();
let descriptor = wgpu_core::pipeline::ComputePipelineDescriptor {
layout,
compute_stage: wgpu_core::pipeline::ProgrammableStageDescriptor {
module: program,
entry_point: entry_point.as_ptr(),
},
};
let cp_id = gfx_select!(id => global.device_create_compute_pipeline(device.0, &descriptor, id));
let compute_pipeline = WebGPUComputePipeline(cp_id);

if let Err(e) = sender.send(compute_pipeline) {
warn!(
"Failed to send response to WebGPURequest::CreateComputePipeline ({})",
e
)
}
},
WebGPURequest::Exit(sender) => {
self.deinit();
if let Err(e) = sender.send(()) {
Expand Down Expand Up @@ -342,5 +377,6 @@ webgpu_resource!(WebGPUDevice, wgpu::id::DeviceId);
webgpu_resource!(WebGPUBuffer, wgpu::id::BufferId);
webgpu_resource!(WebGPUBindGroup, wgpu::id::BindGroupId);
webgpu_resource!(WebGPUBindGroupLayout, wgpu::id::BindGroupLayoutId);
webgpu_resource!(WebGPUComputePipeline, wgpu::id::ComputePipelineId);
webgpu_resource!(WebGPUPipelineLayout, wgpu::id::PipelineLayoutId);
webgpu_resource!(WebGPUShaderModule, wgpu::id::ShaderModuleId);

0 comments on commit 9031369

Please sign in to comment.