Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial implementation of GPUCommandEncoder #25702

Merged
merged 3 commits into from Feb 12, 2020
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Initial implementation of GPUComputePipeline

Added WebIDL bindings for `GPUComputePipeline`.
Implemented the `createComputePipeline` function of `GPUDevice`.
  • Loading branch information
imiklos committed Feb 11, 2020
commit 9031369c19f3274a1dee4e15e67c0c539d8aa976
@@ -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};
@@ -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);
@@ -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,
};
@@ -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 {
@@ -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;
}
}
@@ -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;
@@ -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;
@@ -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)
}
}
@@ -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> {
@@ -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> {
@@ -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,
};
@@ -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,
@@ -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,
@@ -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)
}
@@ -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()
}
@@ -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;
@@ -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;
};
@@ -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);
@@ -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,
@@ -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(()) {
@@ -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);
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.