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

Next

Initial implementation of GPUShaderModule

Added WebIDL bindings for `GPUShaderModule`.
Implemented the `createShaderModule` function of `GPUDevice`.
  • Loading branch information
imiklos committed Feb 11, 2020
commit a8621c4ed9d87f6d168fd9b70e0cf501a4033632
@@ -153,7 +153,7 @@ use time::{Duration, Timespec, Tm};
use uuid::Uuid;
use webgpu::{
WebGPU, WebGPUAdapter, WebGPUBindGroup, WebGPUBindGroupLayout, WebGPUBuffer, WebGPUDevice,
WebGPUPipelineLayout,
WebGPUPipelineLayout, WebGPUShaderModule,
};
use webrender_api::{DocumentId, ImageKey};
use webvr_traits::{WebVRGamepadData, WebVRGamepadHand, WebVRGamepadState};
@@ -536,6 +536,7 @@ unsafe_no_jsmanaged_fields!(WebGPUBuffer);
unsafe_no_jsmanaged_fields!(WebGPUBindGroup);
unsafe_no_jsmanaged_fields!(WebGPUBindGroupLayout);
unsafe_no_jsmanaged_fields!(WebGPUPipelineLayout);
unsafe_no_jsmanaged_fields!(WebGPUShaderModule);
unsafe_no_jsmanaged_fields!(GPUBufferState);
unsafe_no_jsmanaged_fields!(WebXRSwapChainId);
unsafe_no_jsmanaged_fields!(MediaList);
@@ -98,7 +98,10 @@ use std::sync::Arc;
use time::{get_time, Timespec};
use uuid::Uuid;
use webgpu::wgpu::{
id::{AdapterId, BindGroupId, BindGroupLayoutId, BufferId, DeviceId, PipelineLayoutId},
id::{
AdapterId, BindGroupId, BindGroupLayoutId, BufferId, DeviceId, PipelineLayoutId,
ShaderModuleId,
},
Backend,
};

@@ -2128,6 +2131,12 @@ impl GlobalScope {
.borrow_mut()
.create_pipeline_layout_id(backend)
}

pub fn wgpu_create_shader_module_id(&self, backend: Backend) -> ShaderModuleId {
self.gpu_id_hub
.borrow_mut()
.create_shader_module_id(backend)
}
}

fn timestamp_in_ms(time: Timespec) -> u64 {
@@ -13,16 +13,20 @@ use crate::dom::bindings::codegen::Bindings::GPUBindGroupLayoutBinding::{
use crate::dom::bindings::codegen::Bindings::GPUBufferBinding::GPUBufferDescriptor;
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;
use crate::dom::bindings::codegen::UnionTypes::Uint32ArrayOrString::{String, Uint32Array};
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::bindings::trace::RootedTraceableBox;
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::gpuadapter::GPUAdapter;
use crate::dom::gpubindgroup::GPUBindGroup;
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
use crate::dom::gpubuffer::{GPUBuffer, GPUBufferState};
use crate::dom::gpupipelinelayout::GPUPipelineLayout;
use crate::dom::gpushadermodule::GPUShaderModule;
use crate::script_runtime::JSContext as SafeJSContext;
use dom_struct::dom_struct;
use ipc_channel::ipc;
@@ -523,9 +527,36 @@ impl GPUDeviceMethods for GPUDevice {
descriptor.layout.id(),
bindings,
))
.expect("Failed to create WebGPU PipelineLayout");
.expect("Failed to create WebGPU BindGroup");

let bind_group = receiver.recv().unwrap();
GPUBindGroup::new(&self.global(), bind_group, valid)
}

/// https://gpuweb.github.io/gpuweb/#dom-gpudevice-createshadermodule
fn CreateShaderModule(
&self,
descriptor: RootedTraceableBox<GPUShaderModuleDescriptor>,
) -> DomRoot<GPUShaderModule> {
let (sender, receiver) = ipc::channel().unwrap();
let program: Vec<u32> = match &descriptor.code {
Uint32Array(program) => program.to_vec(),
String(program) => program.chars().map(|c| c as u32).collect::<Vec<u32>>(),
};
let id = self
.global()
.wgpu_create_shader_module_id(self.device.0.backend());
self.channel
.0
.send(WebGPURequest::CreateShaderModule(
sender,
self.device,
id,
program,
))
.expect("Failed to create WebGPU ShaderModule");

let shader_module = receiver.recv().unwrap();
GPUShaderModule::new(&self.global(), shader_module)
}
}
@@ -0,0 +1,54 @@
/* 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::GPUShaderModuleBinding::{
self, GPUShaderModuleMethods,
};
use crate::dom::bindings::reflector::{reflect_dom_object, 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::WebGPUShaderModule;

#[dom_struct]
pub struct GPUShaderModule {
reflector_: Reflector,
label: DomRefCell<Option<DOMString>>,
shader_module: WebGPUShaderModule,
}

impl GPUShaderModule {
fn new_inherited(shader_module: WebGPUShaderModule) -> GPUShaderModule {
Self {
reflector_: Reflector::new(),
label: DomRefCell::new(None),
shader_module,
}
}

pub fn new(
global: &GlobalScope,
shader_module: WebGPUShaderModule,
) -> DomRoot<GPUShaderModule> {
reflect_dom_object(
Box::new(GPUShaderModule::new_inherited(shader_module)),
global,
GPUShaderModuleBinding::Wrap,
)
}
}

impl GPUShaderModuleMethods for GPUShaderModule {
/// 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;
}
}
@@ -5,7 +5,10 @@
use smallvec::SmallVec;
use webgpu::wgpu::{
hub::IdentityManager,
id::{AdapterId, BindGroupId, BindGroupLayoutId, BufferId, DeviceId, PipelineLayoutId},
id::{
AdapterId, BindGroupId, BindGroupLayoutId, BufferId, DeviceId, PipelineLayoutId,
ShaderModuleId,
},
Backend,
};

@@ -17,6 +20,7 @@ pub struct IdentityHub {
bind_groups: IdentityManager,
bind_group_layouts: IdentityManager,
pipeline_layouts: IdentityManager,
shader_modules: IdentityManager,
backend: Backend,
}

@@ -29,6 +33,7 @@ impl IdentityHub {
bind_groups: IdentityManager::default(),
bind_group_layouts: IdentityManager::default(),
pipeline_layouts: IdentityManager::default(),
shader_modules: IdentityManager::default(),
backend,
}
}
@@ -56,6 +61,10 @@ impl IdentityHub {
fn create_pipeline_layout_id(&mut self) -> PipelineLayoutId {
self.pipeline_layouts.alloc(self.backend)
}

fn create_shader_module_id(&mut self) -> ShaderModuleId {
self.shader_modules.alloc(self.backend)
}
}

#[derive(Debug)]
@@ -133,17 +142,7 @@ impl Identities {
}

pub fn create_bind_group_id(&mut self, backend: Backend) -> BindGroupId {
match backend {
#[cfg(any(target_os = "linux", target_os = "windows"))]
Backend::Vulkan => self.vk_hub.create_bind_group_id(),
#[cfg(target_os = "windows")]
Backend::Dx12 => self.dx12_hub.create_bind_group_id(),
#[cfg(target_os = "windows")]
Backend::Dx11 => self.dx11_hub.create_bind_group_id(),
#[cfg(any(target_os = "ios", target_os = "macos"))]
Backend::Metal => self.metal_hub.create_bind_group_id(),
_ => self.dummy_hub.create_bind_group_id(),
}
self.select(backend).create_bind_group_id()
}

pub fn create_bind_group_layout_id(&mut self, backend: Backend) -> BindGroupLayoutId {
@@ -153,4 +152,8 @@ impl Identities {
pub fn create_pipeline_layout_id(&mut self, backend: Backend) -> PipelineLayoutId {
self.select(backend).create_pipeline_layout_id()
}

pub fn create_shader_module_id(&mut self, backend: Backend) -> ShaderModuleId {
self.select(backend).create_shader_module_id()
}
}
@@ -324,6 +324,7 @@ pub mod gpubuffer;
pub mod gpubufferusage;
pub mod gpudevice;
pub mod gpupipelinelayout;
pub mod gpushadermodule;
pub mod gpushaderstage;
pub mod hashchangeevent;
pub mod headers;
@@ -19,8 +19,8 @@ interface GPUDevice : EventTarget {
GPUPipelineLayout createPipelineLayout(GPUPipelineLayoutDescriptor descriptor);
GPUBindGroup createBindGroup(GPUBindGroupDescriptor descriptor);

/*GPUShaderModule createShaderModule(GPUShaderModuleDescriptor descriptor);
GPUComputePipeline createComputePipeline(GPUComputePipelineDescriptor descriptor);
GPUShaderModule createShaderModule(GPUShaderModuleDescriptor descriptor);
/*GPUComputePipeline createComputePipeline(GPUComputePipelineDescriptor descriptor);
GPURenderPipeline createRenderPipeline(GPURenderPipelineDescriptor descriptor);
GPUCommandEncoder createCommandEncoder(optional GPUCommandEncoderDescriptor descriptor = {});
@@ -0,0 +1,15 @@
/* 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/#gpushadermodule
[Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"]
interface GPUShaderModule {
};
GPUShaderModule includes GPUObjectBase;

typedef (Uint32Array or DOMString) GPUShaderCode;

dictionary GPUShaderModuleDescriptor : GPUObjectDescriptorBase {
required GPUShaderCode code;
};
@@ -65,6 +65,12 @@ pub enum WebGPURequest {
wgpu::id::PipelineLayoutId,
Vec<wgpu::id::BindGroupLayoutId>,
),
CreateShaderModule(
IpcSender<WebGPUShaderModule>,
WebGPUDevice,
wgpu::id::ShaderModuleId,
Vec<u32>,
),
UnmapBuffer(WebGPUBuffer),
DestroyBuffer(WebGPUBuffer),
}
@@ -286,6 +292,24 @@ impl WGPU {
)
}
},
WebGPURequest::CreateShaderModule(sender, device, id, program) => {
let global = &self.global;
let descriptor = wgpu_core::pipeline::ShaderModuleDescriptor {
code: wgpu_core::U32Array {
bytes: program.as_ptr(),
length: program.len(),
},
};
let sm_id = gfx_select!(id => global.device_create_shader_module(device.0, &descriptor, id));
let shader_module = WebGPUShaderModule(sm_id);

if let Err(e) = sender.send(shader_module) {
warn!(
"Failed to send response to WebGPURequest::CreateShaderModule ({})",
e
)
}
},
WebGPURequest::Exit(sender) => {
self.deinit();
if let Err(e) = sender.send(()) {
@@ -319,3 +343,4 @@ webgpu_resource!(WebGPUBuffer, wgpu::id::BufferId);
webgpu_resource!(WebGPUBindGroup, wgpu::id::BindGroupId);
webgpu_resource!(WebGPUBindGroupLayout, wgpu::id::BindGroupLayoutId);
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.