mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Initial implementation of GPUBindGroupLayout for WebGPU
Added WebIDL bindings for `GPUBindGroupLayout`, `GPUBindGroupLayoutDescriptor`, `GPUBindingType`, `GPUShaderStage` and `GPUBindGroupLayoutBinding` (Note: The servo's codegen doesn't like the name, because its already occupied). Implemented the `createBindGroupLayout` function of `GPUDevice`.
This commit is contained in:
parent
95614f57f1
commit
9cf007472b
13 changed files with 397 additions and 11 deletions
25
Cargo.lock
generated
25
Cargo.lock
generated
|
@ -3904,7 +3904,25 @@ version = "0.2.0"
|
|||
source = "git+https://github.com/servo/webrender#edac864107cf43732ec66a9d3288e869a70ce1de"
|
||||
dependencies = [
|
||||
"euclid",
|
||||
"peek-poke-derive",
|
||||
"peek-poke-derive 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peek-poke"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/kvark/peek-poke?rev=969bd7fe2be1a83f87916dc8b388c63cfd457075#969bd7fe2be1a83f87916dc8b388c63cfd457075"
|
||||
dependencies = [
|
||||
"peek-poke-derive 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peek-poke-derive"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/kvark/peek-poke?rev=969bd7fe2be1a83f87916dc8b388c63cfd457075#969bd7fe2be1a83f87916dc8b388c63cfd457075"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.1",
|
||||
"quote 1.0.2",
|
||||
"syn 1.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -6456,7 +6474,7 @@ dependencies = [
|
|||
"derive_more 0.13.0",
|
||||
"euclid",
|
||||
"malloc_size_of_derive",
|
||||
"peek-poke",
|
||||
"peek-poke 0.2.0 (git+https://github.com/servo/webrender)",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"serde_derive",
|
||||
|
@ -6545,7 +6563,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "wgpu-core"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/gfx-rs/wgpu#c0fa61a064c3572ee60d6c4c6a59ca0571394200"
|
||||
source = "git+https://github.com/gfx-rs/wgpu#881222a9477036e9e3504045452d88abfe5ae177"
|
||||
dependencies = [
|
||||
"arrayvec 0.5.1",
|
||||
"battery",
|
||||
|
@ -6560,6 +6578,7 @@ dependencies = [
|
|||
"gfx-hal",
|
||||
"log",
|
||||
"parking_lot",
|
||||
"peek-poke 0.2.0 (git+https://github.com/kvark/peek-poke?rev=969bd7fe2be1a83f87916dc8b388c63cfd457075)",
|
||||
"rendy-descriptor",
|
||||
"rendy-memory",
|
||||
"serde",
|
||||
|
|
|
@ -151,7 +151,7 @@ use tendril::stream::LossyDecoder;
|
|||
use tendril::{StrTendril, TendrilSink};
|
||||
use time::{Duration, Timespec, Tm};
|
||||
use uuid::Uuid;
|
||||
use webgpu::{WebGPU, WebGPUAdapter, WebGPUBuffer, WebGPUDevice};
|
||||
use webgpu::{WebGPU, WebGPUAdapter, WebGPUBindGroupLayout, WebGPUBuffer, WebGPUDevice};
|
||||
use webrender_api::{DocumentId, ImageKey};
|
||||
use webvr_traits::{WebVRGamepadData, WebVRGamepadHand, WebVRGamepadState};
|
||||
use webxr_api::SwapChainId as WebXRSwapChainId;
|
||||
|
@ -530,6 +530,7 @@ unsafe_no_jsmanaged_fields!(WebGPU);
|
|||
unsafe_no_jsmanaged_fields!(WebGPUAdapter);
|
||||
unsafe_no_jsmanaged_fields!(WebGPUDevice);
|
||||
unsafe_no_jsmanaged_fields!(WebGPUBuffer);
|
||||
unsafe_no_jsmanaged_fields!(WebGPUBindGroupLayout);
|
||||
unsafe_no_jsmanaged_fields!(GPUBufferState);
|
||||
unsafe_no_jsmanaged_fields!(WebXRSwapChainId);
|
||||
unsafe_no_jsmanaged_fields!(MediaList);
|
||||
|
|
75
components/script/dom/gpubindgrouplayout.rs
Normal file
75
components/script/dom/gpubindgrouplayout.rs
Normal file
|
@ -0,0 +1,75 @@
|
|||
/* 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::GPUBindGroupLayoutBinding::{
|
||||
self, GPUBindGroupLayoutBindings, GPUBindGroupLayoutMethods,
|
||||
};
|
||||
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 std::cell::Cell;
|
||||
use webgpu::{WebGPU, WebGPUBindGroupLayout};
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUBindGroupLayout {
|
||||
reflector_: Reflector,
|
||||
label: DomRefCell<Option<DOMString>>,
|
||||
bind_group_layout: WebGPUBindGroupLayout,
|
||||
#[ignore_malloc_size_of = "defined in webgpu"]
|
||||
bindings: Vec<GPUBindGroupLayoutBindings>,
|
||||
#[ignore_malloc_size_of = "defined in webgpu"]
|
||||
channel: WebGPU,
|
||||
valid: Cell<bool>,
|
||||
}
|
||||
|
||||
impl GPUBindGroupLayout {
|
||||
fn new_inherited(
|
||||
channel: WebGPU,
|
||||
bind_group_layout: WebGPUBindGroupLayout,
|
||||
bindings: Vec<GPUBindGroupLayoutBindings>,
|
||||
valid: bool,
|
||||
) -> GPUBindGroupLayout {
|
||||
Self {
|
||||
reflector_: Reflector::new(),
|
||||
channel,
|
||||
label: DomRefCell::new(None),
|
||||
bind_group_layout,
|
||||
bindings,
|
||||
valid: Cell::new(valid),
|
||||
}
|
||||
}
|
||||
pub fn new(
|
||||
global: &GlobalScope,
|
||||
channel: WebGPU,
|
||||
bind_group_layout: WebGPUBindGroupLayout,
|
||||
bindings: Vec<GPUBindGroupLayoutBindings>,
|
||||
valid: bool,
|
||||
) -> DomRoot<GPUBindGroupLayout> {
|
||||
reflect_dom_object(
|
||||
Box::new(GPUBindGroupLayout::new_inherited(
|
||||
channel,
|
||||
bind_group_layout,
|
||||
bindings,
|
||||
valid,
|
||||
)),
|
||||
global,
|
||||
GPUBindGroupLayoutBinding::Wrap,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl GPUBindGroupLayoutMethods for GPUBindGroupLayout {
|
||||
/// 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,6 +5,10 @@
|
|||
#![allow(unsafe_code)]
|
||||
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUAdapterBinding::GPULimits;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUBindGroupLayoutBinding::{
|
||||
GPUBindGroupLayoutBindings, GPUBindGroupLayoutDescriptor, GPUBindingType,
|
||||
};
|
||||
use crate::dom::bindings::codegen::Bindings::GPUBufferBinding::GPUBufferDescriptor;
|
||||
use crate::dom::bindings::codegen::Bindings::GPUDeviceBinding::{self, GPUDeviceMethods};
|
||||
use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods;
|
||||
|
@ -15,6 +19,7 @@ use crate::dom::bindings::str::DOMString;
|
|||
use crate::dom::eventtarget::EventTarget;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::gpuadapter::GPUAdapter;
|
||||
use crate::dom::gpubindgrouplayout::GPUBindGroupLayout;
|
||||
use crate::dom::gpubuffer::{GPUBuffer, GPUBufferState};
|
||||
use crate::dom::window::Window;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
|
@ -23,7 +28,9 @@ use ipc_channel::ipc;
|
|||
use js::jsapi::{Heap, JSObject};
|
||||
use js::jsval::{JSVal, ObjectValue, UndefinedValue};
|
||||
use js::typedarray::{ArrayBuffer, CreateWith};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::ptr::{self, NonNull};
|
||||
use webgpu::wgpu::binding_model::{BindGroupLayoutBinding, BindingType, ShaderStage};
|
||||
use webgpu::wgpu::resource::{BufferDescriptor, BufferUsage};
|
||||
use webgpu::{WebGPU, WebGPUBuffer, WebGPUDevice, WebGPURequest};
|
||||
|
||||
|
@ -229,4 +236,177 @@ impl GPUDeviceMethods for GPUDevice {
|
|||
self.resolve_create_buffer_mapped(cx, buffer, array_buffer, wgpu_descriptor, valid)
|
||||
}
|
||||
}
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#GPUDevice-createBindGroupLayout
|
||||
fn CreateBindGroupLayout(
|
||||
&self,
|
||||
descriptor: &GPUBindGroupLayoutDescriptor,
|
||||
) -> DomRoot<GPUBindGroupLayout> {
|
||||
#[derive(Clone)]
|
||||
struct MaxLimits {
|
||||
max_uniform_buffers_per_shader_stage: i32,
|
||||
max_storage_buffers_per_shader_stage: i32,
|
||||
max_sampled_textures_per_shader_stage: i32,
|
||||
max_storage_textures_per_shader_stage: i32,
|
||||
max_samplers_per_shader_stage: i32,
|
||||
}
|
||||
let mut storeBindings = HashSet::new();
|
||||
// TODO: We should have these limits on device creation
|
||||
let limits = GPULimits::empty();
|
||||
|
||||
let mut validation_map = HashMap::new();
|
||||
let maxLimits = MaxLimits {
|
||||
max_uniform_buffers_per_shader_stage: limits.maxUniformBuffersPerShaderStage as i32,
|
||||
max_storage_buffers_per_shader_stage: limits.maxStorageBuffersPerShaderStage as i32,
|
||||
max_sampled_textures_per_shader_stage: limits.maxSampledTexturesPerShaderStage as i32,
|
||||
max_storage_textures_per_shader_stage: limits.maxStorageTexturesPerShaderStage as i32,
|
||||
max_samplers_per_shader_stage: limits.maxSamplersPerShaderStage as i32,
|
||||
};
|
||||
validation_map.insert(
|
||||
webgpu::wgpu::binding_model::ShaderStage::VERTEX,
|
||||
maxLimits.clone(),
|
||||
);
|
||||
validation_map.insert(
|
||||
webgpu::wgpu::binding_model::ShaderStage::FRAGMENT,
|
||||
maxLimits.clone(),
|
||||
);
|
||||
validation_map.insert(
|
||||
webgpu::wgpu::binding_model::ShaderStage::COMPUTE,
|
||||
maxLimits.clone(),
|
||||
);
|
||||
let mut max_dynamic_uniform_buffers_per_pipeline_layout =
|
||||
limits.maxDynamicUniformBuffersPerPipelineLayout as i32;
|
||||
let mut max_dynamic_storage_buffers_per_pipeline_layout =
|
||||
limits.maxDynamicStorageBuffersPerPipelineLayout as i32;
|
||||
let mut valid = true;
|
||||
|
||||
let bindings = descriptor
|
||||
.bindings
|
||||
.iter()
|
||||
.map(|bind| {
|
||||
// TODO: binding must be >= 0
|
||||
storeBindings.insert(bind.binding);
|
||||
let visibility = match ShaderStage::from_bits(bind.visibility) {
|
||||
Some(visibility) => visibility,
|
||||
None => {
|
||||
valid = false;
|
||||
ShaderStage::from_bits(0).unwrap()
|
||||
},
|
||||
};
|
||||
let ty = match bind.type_ {
|
||||
GPUBindingType::Uniform_buffer => {
|
||||
if let Some(limit) = validation_map.get_mut(&visibility) {
|
||||
limit.max_uniform_buffers_per_shader_stage -= 1;
|
||||
}
|
||||
if bind.hasDynamicOffset {
|
||||
max_dynamic_uniform_buffers_per_pipeline_layout -= 1;
|
||||
};
|
||||
BindingType::UniformBuffer
|
||||
},
|
||||
GPUBindingType::Storage_buffer => {
|
||||
if let Some(limit) = validation_map.get_mut(&visibility) {
|
||||
limit.max_storage_buffers_per_shader_stage -= 1;
|
||||
}
|
||||
if bind.hasDynamicOffset {
|
||||
max_dynamic_storage_buffers_per_pipeline_layout -= 1;
|
||||
};
|
||||
BindingType::StorageBuffer
|
||||
},
|
||||
GPUBindingType::Readonly_storage_buffer => {
|
||||
if let Some(limit) = validation_map.get_mut(&visibility) {
|
||||
limit.max_storage_buffers_per_shader_stage -= 1;
|
||||
}
|
||||
if bind.hasDynamicOffset {
|
||||
max_dynamic_storage_buffers_per_pipeline_layout -= 1;
|
||||
};
|
||||
BindingType::ReadonlyStorageBuffer
|
||||
},
|
||||
GPUBindingType::Sampled_texture => {
|
||||
if let Some(limit) = validation_map.get_mut(&visibility) {
|
||||
limit.max_sampled_textures_per_shader_stage -= 1;
|
||||
}
|
||||
if bind.hasDynamicOffset {
|
||||
valid = false
|
||||
};
|
||||
BindingType::SampledTexture
|
||||
},
|
||||
GPUBindingType::Storage_texture => {
|
||||
if let Some(limit) = validation_map.get_mut(&visibility) {
|
||||
limit.max_storage_textures_per_shader_stage -= 1;
|
||||
}
|
||||
if bind.hasDynamicOffset {
|
||||
valid = false
|
||||
};
|
||||
BindingType::StorageTexture
|
||||
},
|
||||
GPUBindingType::Sampler => {
|
||||
if let Some(limit) = validation_map.get_mut(&visibility) {
|
||||
limit.max_samplers_per_shader_stage -= 1;
|
||||
}
|
||||
if bind.hasDynamicOffset {
|
||||
valid = false
|
||||
};
|
||||
BindingType::Sampler
|
||||
},
|
||||
};
|
||||
|
||||
BindGroupLayoutBinding {
|
||||
binding: bind.binding,
|
||||
visibility,
|
||||
ty,
|
||||
dynamic: bind.hasDynamicOffset,
|
||||
multisampled: bind.multisampled,
|
||||
texture_dimension: webgpu::wgpu::resource::TextureViewDimension::D2, // Use as default for now
|
||||
}
|
||||
})
|
||||
.collect::<Vec<BindGroupLayoutBinding>>();
|
||||
|
||||
// bindings are unique
|
||||
valid &= storeBindings.len() == bindings.len();
|
||||
|
||||
// Ensure that values do not exceed the max limit for each ShaderStage.
|
||||
valid &= validation_map.values().all(|stage| {
|
||||
stage.max_uniform_buffers_per_shader_stage >= 0 &&
|
||||
stage.max_storage_buffers_per_shader_stage >= 0 &&
|
||||
stage.max_sampled_textures_per_shader_stage >= 0 &&
|
||||
stage.max_storage_textures_per_shader_stage >= 0 &&
|
||||
stage.max_samplers_per_shader_stage >= 0
|
||||
});
|
||||
|
||||
// DynamicValues does not exceed the max limit for the pipeline
|
||||
valid &= max_dynamic_uniform_buffers_per_pipeline_layout >= 0 &&
|
||||
max_dynamic_storage_buffers_per_pipeline_layout >= 0;
|
||||
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
if let Some(window) = self.global().downcast::<Window>() {
|
||||
let id = window
|
||||
.Navigator()
|
||||
.create_bind_group_layout_id(self.device.0.backend());
|
||||
self.channel
|
||||
.0
|
||||
.send(WebGPURequest::CreateBindGroupLayout(
|
||||
sender,
|
||||
self.device,
|
||||
id,
|
||||
bindings.clone(),
|
||||
))
|
||||
.expect("Failed to create WebGPU BindGroupLayout");
|
||||
}
|
||||
let bgl = receiver.recv().unwrap();
|
||||
|
||||
let binds = descriptor
|
||||
.bindings
|
||||
.iter()
|
||||
.map(|bind| GPUBindGroupLayoutBindings {
|
||||
binding: bind.binding,
|
||||
hasDynamicOffset: bind.hasDynamicOffset,
|
||||
multisampled: bind.multisampled,
|
||||
type_: bind.type_,
|
||||
visibility: bind.visibility,
|
||||
//texture_dimension: bind.texture_dimension
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
GPUBindGroupLayout::new(&self.global(), self.channel.clone(), bgl, binds, valid)
|
||||
}
|
||||
}
|
||||
|
|
11
components/script/dom/gpushaderstage.rs
Normal file
11
components/script/dom/gpushaderstage.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
/* 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::reflector::Reflector;
|
||||
use dom_struct::dom_struct;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct GPUShaderStage {
|
||||
reflector_: Reflector,
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
use smallvec::SmallVec;
|
||||
use webgpu::wgpu::{
|
||||
hub::IdentityManager,
|
||||
id::{AdapterId, BufferId, DeviceId},
|
||||
id::{AdapterId, BindGroupLayoutId, BufferId, DeviceId},
|
||||
Backend,
|
||||
};
|
||||
|
||||
|
@ -14,6 +14,7 @@ pub struct IdentityHub {
|
|||
adapters: IdentityManager,
|
||||
devices: IdentityManager,
|
||||
buffers: IdentityManager,
|
||||
bind_group_layouts: IdentityManager,
|
||||
backend: Backend,
|
||||
}
|
||||
|
||||
|
@ -23,6 +24,7 @@ impl IdentityHub {
|
|||
adapters: IdentityManager::default(),
|
||||
devices: IdentityManager::default(),
|
||||
buffers: IdentityManager::default(),
|
||||
bind_group_layouts: IdentityManager::default(),
|
||||
backend,
|
||||
}
|
||||
}
|
||||
|
@ -35,9 +37,13 @@ impl IdentityHub {
|
|||
self.devices.alloc(self.backend)
|
||||
}
|
||||
|
||||
pub fn create_buffer_id(&mut self) -> BufferId {
|
||||
fn create_buffer_id(&mut self) -> BufferId {
|
||||
self.buffers.alloc(self.backend)
|
||||
}
|
||||
|
||||
fn create_bind_group_layout_id(&mut self) -> BindGroupLayoutId {
|
||||
self.bind_group_layouts.alloc(self.backend)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -119,4 +125,18 @@ impl Identities {
|
|||
_ => self.dummy_hub.create_buffer_id(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_bind_group_layout_id(&mut self, backend: Backend) -> BindGroupLayoutId {
|
||||
match backend {
|
||||
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
||||
Backend::Vulkan => self.vk_hub.create_bind_group_layout_id(),
|
||||
#[cfg(target_os = "windows")]
|
||||
Backend::Dx12 => self.dx12_hub.create_bind_group_layout_id(),
|
||||
#[cfg(target_os = "windows")]
|
||||
Backend::Dx11 => self.dx11_hub.create_bind_group_layout_id(),
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
Backend::Metal => self.metal_hub.create_bind_group_layout_id(),
|
||||
_ => self.dummy_hub.create_bind_group_layout_id(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -318,9 +318,11 @@ pub mod gamepadlist;
|
|||
pub mod globalscope;
|
||||
pub mod gpu;
|
||||
pub mod gpuadapter;
|
||||
pub mod gpubindgrouplayout;
|
||||
pub mod gpubuffer;
|
||||
pub mod gpubufferusage;
|
||||
pub mod gpudevice;
|
||||
pub mod gpushaderstage;
|
||||
pub mod hashchangeevent;
|
||||
pub mod headers;
|
||||
pub mod history;
|
||||
|
|
|
@ -28,7 +28,7 @@ use smallvec::SmallVec;
|
|||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use webgpu::wgpu::{
|
||||
id::{AdapterId, BufferId, DeviceId},
|
||||
id::{AdapterId, BindGroupLayoutId, BufferId, DeviceId},
|
||||
Backend,
|
||||
};
|
||||
|
||||
|
@ -88,6 +88,12 @@ impl Navigator {
|
|||
pub fn create_buffer_id(&self, backend: Backend) -> BufferId {
|
||||
self.gpu_id_hub.borrow_mut().create_buffer_id(backend)
|
||||
}
|
||||
|
||||
pub fn create_bind_group_layout_id(&self, backend: Backend) -> BindGroupLayoutId {
|
||||
self.gpu_id_hub
|
||||
.borrow_mut()
|
||||
.create_bind_group_layout_id(backend)
|
||||
}
|
||||
}
|
||||
|
||||
impl NavigatorMethods for Navigator {
|
||||
|
|
34
components/script/dom/webidls/GPUBindGroupLayout.webidl
Normal file
34
components/script/dom/webidls/GPUBindGroupLayout.webidl
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* 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/#gpubindgrouplayout
|
||||
[Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"]
|
||||
interface GPUBindGroupLayout {
|
||||
};
|
||||
GPUBindGroupLayout includes GPUObjectBase;
|
||||
|
||||
dictionary GPUBindGroupLayoutDescriptor : GPUObjectDescriptorBase {
|
||||
required sequence<GPUBindGroupLayoutBindings> bindings;
|
||||
};
|
||||
|
||||
// Note: Servo codegen doesn't like the name `GPUBindGroupLayoutBinding` because it's already occupied
|
||||
// dictionary GPUBindGroupLayoutBinding {
|
||||
dictionary GPUBindGroupLayoutBindings {
|
||||
required unsigned long binding;
|
||||
required GPUShaderStageFlags visibility;
|
||||
required GPUBindingType type;
|
||||
//GPUTextureViewDimension textureDimension = "2d";
|
||||
//GPUTextureComponentType textureComponentType = "float";
|
||||
boolean multisampled = false;
|
||||
boolean hasDynamicOffset = false;
|
||||
};
|
||||
|
||||
enum GPUBindingType {
|
||||
"uniform-buffer",
|
||||
"storage-buffer",
|
||||
"readonly-storage-buffer",
|
||||
"sampler",
|
||||
"sampled-texture",
|
||||
"storage-texture"
|
||||
};
|
|
@ -11,12 +11,12 @@ interface GPUDevice : EventTarget {
|
|||
|
||||
GPUBuffer createBuffer(GPUBufferDescriptor descriptor);
|
||||
GPUMappedBuffer createBufferMapped(GPUBufferDescriptor descriptor);
|
||||
/*Promise<GPUMappedBuffer> createBufferMappedAsync(GPUBufferDescriptor descriptor);
|
||||
GPUTexture createTexture(GPUTextureDescriptor descriptor);
|
||||
GPUSampler createSampler(optional GPUSamplerDescriptor descriptor = {});
|
||||
//Promise<GPUMappedBuffer> createBufferMappedAsync(GPUBufferDescriptor descriptor);
|
||||
//GPUTexture createTexture(GPUTextureDescriptor descriptor);
|
||||
//GPUSampler createSampler(optional GPUSamplerDescriptor descriptor = {});
|
||||
|
||||
GPUBindGroupLayout createBindGroupLayout(GPUBindGroupLayoutDescriptor descriptor);
|
||||
GPUPipelineLayout createPipelineLayout(GPUPipelineLayoutDescriptor descriptor);
|
||||
/*GPUPipelineLayout createPipelineLayout(GPUPipelineLayoutDescriptor descriptor);
|
||||
GPUBindGroup createBindGroup(GPUBindGroupDescriptor descriptor);
|
||||
|
||||
GPUShaderModule createShaderModule(GPUShaderModuleDescriptor descriptor);
|
||||
|
|
13
components/script/dom/webidls/GPUShaderStage.webidl
Normal file
13
components/script/dom/webidls/GPUShaderStage.webidl
Normal file
|
@ -0,0 +1,13 @@
|
|||
/* 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/#typedefdef-gpushaderstageflags
|
||||
[Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"]
|
||||
interface GPUShaderStage {
|
||||
const GPUShaderStageFlags VERTEX = 0x1;
|
||||
const GPUShaderStageFlags FRAGMENT = 0x2;
|
||||
const GPUShaderStageFlags COMPUTE = 0x4;
|
||||
};
|
||||
|
||||
typedef unsigned long GPUShaderStageFlags;
|
|
@ -48,6 +48,12 @@ pub enum WebGPURequest {
|
|||
wgpu::id::BufferId,
|
||||
wgpu::resource::BufferDescriptor,
|
||||
),
|
||||
CreateBindGroupLayout(
|
||||
IpcSender<WebGPUBindGroupLayout>,
|
||||
WebGPUDevice,
|
||||
wgpu::id::BindGroupLayoutId,
|
||||
Vec<wgpu::binding_model::BindGroupLayoutBinding>,
|
||||
),
|
||||
UnmapBuffer(WebGPUBuffer),
|
||||
DestroyBuffer(WebGPUBuffer),
|
||||
}
|
||||
|
@ -220,6 +226,22 @@ impl WGPU {
|
|||
let global = &self.global;
|
||||
gfx_select!(buffer.0 => global.buffer_destroy(buffer.0));
|
||||
},
|
||||
WebGPURequest::CreateBindGroupLayout(sender, device, id, bindings) => {
|
||||
let global = &self.global;
|
||||
let descriptor = wgpu_core::binding_model::BindGroupLayoutDescriptor {
|
||||
bindings: bindings.as_ptr(),
|
||||
bindings_length: bindings.len(),
|
||||
};
|
||||
let bgl_id = gfx_select!(id => global.device_create_bind_group_layout(device.0, &descriptor, id));
|
||||
let bgl = WebGPUBindGroupLayout(bgl_id);
|
||||
|
||||
if let Err(e) = sender.send(bgl) {
|
||||
warn!(
|
||||
"Failed to send response to WebGPURequest::CreateBufferMapped ({})",
|
||||
e
|
||||
)
|
||||
}
|
||||
},
|
||||
WebGPURequest::Exit(sender) => {
|
||||
self.deinit();
|
||||
if let Err(e) = sender.send(()) {
|
||||
|
@ -250,3 +272,4 @@ macro_rules! webgpu_resource {
|
|||
webgpu_resource!(WebGPUAdapter, wgpu::id::AdapterId);
|
||||
webgpu_resource!(WebGPUDevice, wgpu::id::DeviceId);
|
||||
webgpu_resource!(WebGPUBuffer, wgpu::id::BufferId);
|
||||
webgpu_resource!(WebGPUBindGroupLayout, wgpu::id::BindGroupLayoutId);
|
||||
|
|
|
@ -33,6 +33,8 @@ packages = [
|
|||
"gleam",
|
||||
"mach",
|
||||
"nix",
|
||||
"peek-poke",
|
||||
"peek-poke-derive",
|
||||
"wayland-sys",
|
||||
|
||||
# https://github.com/servo/servo/pull/23288#issuecomment-494687746
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue