mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Auto merge of #25677 - szeged:wgpu_shader_module, r=jdm
Initial implementation of GPUShaderModule Added WebIDL bindings for `GPUShaderModule`. Implemented the `createShaderModule` function of `GPUDevice`. <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes addresses a part of #24706 <!-- Either: --> cc @kvark @jdm @zakorgy <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
This commit is contained in:
commit
419954474b
9 changed files with 156 additions and 17 deletions
|
@ -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,9 +13,12 @@ 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;
|
||||
|
@ -23,6 +26,7 @@ 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)
|
||||
}
|
||||
}
|
||||
|
|
54
components/script/dom/gpushadermodule.rs
Normal file
54
components/script/dom/gpushadermodule.rs
Normal file
|
@ -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 = {});
|
||||
|
|
15
components/script/dom/webidls/GPUShaderModule.webidl
Normal file
15
components/script/dom/webidls/GPUShaderModule.webidl
Normal file
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue