aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKunal Mohan <kunalmohan99@gmail.com>2020-05-23 22:04:09 +0530
committerKunal Mohan <kunalmohan99@gmail.com>2020-05-26 00:00:35 +0530
commitdd04716b852471ba75e4bf44ced0e2d481e99ab2 (patch)
tree31262d46335d21ef23bc50faab54522f6b902253
parent43f29fe0cefe2e7ce42e4172d6cb2a4ebe72ab0f (diff)
downloadservo-dd04716b852471ba75e4bf44ced0e2d481e99ab2.tar.gz
servo-dd04716b852471ba75e4bf44ced0e2d481e99ab2.zip
Add GPUSampler to WebGPU implementation
Add dom_struct and webidl for GPUSampler, implement GPUDevice.createSampler() method.
-rw-r--r--components/script/dom/bindings/trace.rs3
-rw-r--r--components/script/dom/gpudevice.rs110
-rw-r--r--components/script/dom/gpusampler.rs77
-rw-r--r--components/script/dom/identityhub.rs94
-rw-r--r--components/script/dom/mod.rs1
-rw-r--r--components/script/dom/webidls/GPUDevice.webidl2
-rw-r--r--components/script/dom/webidls/GPUSampler.webidl43
-rw-r--r--components/script/script_thread.rs1
-rw-r--r--components/webgpu/lib.rs129
9 files changed, 318 insertions, 142 deletions
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index ba174193cdf..29160e61186 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -160,7 +160,7 @@ use uuid::Uuid;
use webgpu::{
wgpu::command::RawPass, WebGPU, WebGPUAdapter, WebGPUBindGroup, WebGPUBindGroupLayout,
WebGPUBuffer, WebGPUCommandBuffer, WebGPUCommandEncoder, WebGPUComputePipeline, WebGPUDevice,
- WebGPUPipelineLayout, WebGPUQueue, WebGPUShaderModule,
+ WebGPUPipelineLayout, WebGPUQueue, WebGPUSampler, WebGPUShaderModule,
};
use webrender_api::{DocumentId, ImageKey};
use webxr_api::SwapChainId as WebXRSwapChainId;
@@ -559,6 +559,7 @@ unsafe_no_jsmanaged_fields!(WebGPUComputePipeline);
unsafe_no_jsmanaged_fields!(WebGPUPipelineLayout);
unsafe_no_jsmanaged_fields!(WebGPUQueue);
unsafe_no_jsmanaged_fields!(WebGPUShaderModule);
+unsafe_no_jsmanaged_fields!(WebGPUSampler);
unsafe_no_jsmanaged_fields!(WebGPUCommandBuffer);
unsafe_no_jsmanaged_fields!(WebGPUCommandEncoder);
unsafe_no_jsmanaged_fields!(WebGPUDevice);
diff --git a/components/script/dom/gpudevice.rs b/components/script/dom/gpudevice.rs
index fa773a74694..2a5c84e99af 100644
--- a/components/script/dom/gpudevice.rs
+++ b/components/script/dom/gpudevice.rs
@@ -16,6 +16,9 @@ use crate::dom::bindings::codegen::Bindings::GPUDeviceBinding::{
GPUCommandEncoderDescriptor, GPUDeviceMethods,
};
use crate::dom::bindings::codegen::Bindings::GPUPipelineLayoutBinding::GPUPipelineLayoutDescriptor;
+use crate::dom::bindings::codegen::Bindings::GPUSamplerBinding::{
+ GPUAddressMode, GPUCompareFunction, GPUFilterMode, GPUSamplerDescriptor,
+};
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};
@@ -32,6 +35,7 @@ use crate::dom::gpucommandencoder::GPUCommandEncoder;
use crate::dom::gpucomputepipeline::GPUComputePipeline;
use crate::dom::gpupipelinelayout::GPUPipelineLayout;
use crate::dom::gpuqueue::GPUQueue;
+use crate::dom::gpusampler::GPUSampler;
use crate::dom::gpushadermodule::GPUShaderModule;
use crate::script_runtime::JSContext as SafeJSContext;
use dom_struct::dom_struct;
@@ -44,11 +48,7 @@ use std::ptr::{self, NonNull};
use webgpu::wgpu::binding_model::{
BindGroupEntry, BindGroupLayoutEntry, BindingResource, BindingType, BufferBinding,
};
-use webgpu::wgt::{
- BufferDescriptor, BufferUsage, ShaderStage, TextureComponentType, TextureFormat,
- TextureViewDimension,
-};
-use webgpu::{WebGPU, WebGPUDevice, WebGPUQueue, WebGPURequest};
+use webgpu::{wgt, WebGPU, WebGPUDevice, WebGPUQueue, WebGPURequest, WebGPUSampler};
#[dom_struct]
pub struct GPUDevice {
@@ -110,15 +110,15 @@ impl GPUDevice {
fn validate_buffer_descriptor(
&self,
descriptor: &GPUBufferDescriptor,
- ) -> (bool, BufferDescriptor<std::string::String>) {
+ ) -> (bool, wgt::BufferDescriptor<std::string::String>) {
// TODO: Record a validation error in the current scope if the descriptor is invalid.
- let wgpu_usage = BufferUsage::from_bits(descriptor.usage);
+ let wgpu_usage = wgt::BufferUsage::from_bits(descriptor.usage);
let valid = wgpu_usage.is_some() && descriptor.size > 0;
if valid {
(
true,
- BufferDescriptor {
+ wgt::BufferDescriptor {
size: descriptor.size,
usage: wgpu_usage.unwrap(),
label: Default::default(),
@@ -127,9 +127,9 @@ impl GPUDevice {
} else {
(
false,
- BufferDescriptor {
+ wgt::BufferDescriptor {
size: 0,
- usage: BufferUsage::STORAGE,
+ usage: wgt::BufferUsage::empty(),
label: Default::default(),
},
)
@@ -280,9 +280,9 @@ impl GPUDeviceMethods for GPUDevice {
max_storage_textures_per_shader_stage: limits.maxStorageTexturesPerShaderStage as i32,
max_samplers_per_shader_stage: limits.maxSamplersPerShaderStage as i32,
};
- validation_map.insert(ShaderStage::VERTEX, maxLimits.clone());
- validation_map.insert(ShaderStage::FRAGMENT, maxLimits.clone());
- validation_map.insert(ShaderStage::COMPUTE, maxLimits.clone());
+ validation_map.insert(wgt::ShaderStage::VERTEX, maxLimits.clone());
+ validation_map.insert(wgt::ShaderStage::FRAGMENT, maxLimits.clone());
+ validation_map.insert(wgt::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 =
@@ -295,11 +295,11 @@ impl GPUDeviceMethods for GPUDevice {
.map(|bind| {
// TODO: binding must be >= 0
storeBindings.insert(bind.binding);
- let visibility = match ShaderStage::from_bits(bind.visibility) {
+ let visibility = match wgt::ShaderStage::from_bits(bind.visibility) {
Some(visibility) => visibility,
None => {
valid = false;
- ShaderStage::from_bits(0).unwrap()
+ wgt::ShaderStage::from_bits(0).unwrap()
},
};
let ty = match bind.type_ {
@@ -375,9 +375,9 @@ impl GPUDeviceMethods for GPUDevice {
has_dynamic_offset: bind.hasDynamicOffset,
multisampled: bind.multisampled,
// Use as default for now
- texture_component_type: TextureComponentType::Float,
- storage_texture_format: TextureFormat::Rgba8UnormSrgb,
- view_dimension: TextureViewDimension::D2,
+ texture_component_type: wgt::TextureComponentType::Float,
+ storage_texture_format: wgt::TextureFormat::Rgba8UnormSrgb,
+ view_dimension: wgt::TextureViewDimension::D2,
}
})
.collect::<Vec<BindGroupLayoutEntry>>();
@@ -507,7 +507,7 @@ impl GPUDeviceMethods for GPUDevice {
let buffer_size = bind.resource.buffer.size();
let resource_size = bind.resource.size.unwrap_or(buffer_size);
let length = bind.resource.offset.checked_add(resource_size);
- let usage = BufferUsage::from_bits(bind.resource.buffer.usage()).unwrap();
+ let usage = wgt::BufferUsage::from_bits(bind.resource.buffer.usage()).unwrap();
length.is_some() &&
buffer_size >= length.unwrap() && // check buffer OOB
@@ -515,9 +515,9 @@ impl GPUDeviceMethods for GPUDevice {
bind.resource.offset < buffer_size && // on Vulkan offset must be less than size of buffer
descriptor.layout.bindings().iter().any(|layout_bind| {
let ty = match layout_bind.type_ {
- GPUBindingType::Storage_buffer => BufferUsage::STORAGE,
+ GPUBindingType::Storage_buffer => wgt::BufferUsage::STORAGE,
// GPUBindingType::Readonly_storage_buffer => BufferUsage::STORAGE_READ,
- GPUBindingType::Uniform_buffer => BufferUsage::UNIFORM,
+ GPUBindingType::Uniform_buffer => wgt::BufferUsage::UNIFORM,
_ => unimplemented!(),
};
// binding must be present in layout
@@ -641,4 +641,72 @@ impl GPUDeviceMethods for GPUDevice {
GPUCommandEncoder::new(&self.global(), self.channel.clone(), encoder, true)
}
+ /// https://gpuweb.github.io/gpuweb/#dom-gpudevice-createsampler
+ fn CreateSampler(&self, descriptor: &GPUSamplerDescriptor) -> DomRoot<GPUSampler> {
+ let sampler_id = self
+ .global()
+ .wgpu_id_hub()
+ .lock()
+ .create_sampler_id(self.device.0.backend());
+ let compare_enable = descriptor.compare.is_some();
+ let desc = wgt::SamplerDescriptor {
+ label: Default::default(),
+ address_mode_u: assign_address_mode(descriptor.addressModeU),
+ address_mode_v: assign_address_mode(descriptor.addressModeV),
+ address_mode_w: assign_address_mode(descriptor.addressModeW),
+ mag_filter: assign_filter_mode(descriptor.magFilter),
+ min_filter: assign_filter_mode(descriptor.minFilter),
+ mipmap_filter: assign_filter_mode(descriptor.mipmapFilter),
+ lod_min_clamp: *descriptor.lodMinClamp,
+ lod_max_clamp: *descriptor.lodMaxClamp,
+ compare: if let Some(c) = descriptor.compare {
+ match c {
+ GPUCompareFunction::Never => wgt::CompareFunction::Never,
+ GPUCompareFunction::Less => wgt::CompareFunction::Less,
+ GPUCompareFunction::Equal => wgt::CompareFunction::Equal,
+ GPUCompareFunction::Less_equal => wgt::CompareFunction::LessEqual,
+ GPUCompareFunction::Greater => wgt::CompareFunction::Greater,
+ GPUCompareFunction::Not_equal => wgt::CompareFunction::NotEqual,
+ GPUCompareFunction::Greater_equal => wgt::CompareFunction::GreaterEqual,
+ GPUCompareFunction::Always => wgt::CompareFunction::Always,
+ }
+ } else {
+ wgt::CompareFunction::Undefined
+ },
+ };
+ self.channel
+ .0
+ .send(WebGPURequest::CreateSampler {
+ device_id: self.device.0,
+ sampler_id,
+ descriptor: desc,
+ })
+ .expect("Failed to create WebGPU sampler");
+
+ let sampler = WebGPUSampler(sampler_id);
+
+ GPUSampler::new(
+ &self.global(),
+ self.channel.clone(),
+ self.device,
+ compare_enable,
+ sampler,
+ true,
+ )
+ }
+}
+
+fn assign_address_mode(address_mode: GPUAddressMode) -> wgt::AddressMode {
+ match address_mode {
+ GPUAddressMode::Clamp_to_edge => wgt::AddressMode::ClampToEdge,
+ GPUAddressMode::Repeat => wgt::AddressMode::Repeat,
+ GPUAddressMode::Mirror_repeat => wgt::AddressMode::MirrorRepeat,
+ }
+}
+
+fn assign_filter_mode(filter_mode: GPUFilterMode) -> wgt::FilterMode {
+ match filter_mode {
+ GPUFilterMode::Nearest => wgt::FilterMode::Nearest,
+ GPUFilterMode::Linear => wgt::FilterMode::Linear,
+ }
}
diff --git a/components/script/dom/gpusampler.rs b/components/script/dom/gpusampler.rs
new file mode 100644
index 00000000000..eab237a4c8f
--- /dev/null
+++ b/components/script/dom/gpusampler.rs
@@ -0,0 +1,77 @@
+/* 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::GPUSamplerBinding::GPUSamplerMethods;
+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, WebGPUDevice, WebGPUSampler};
+
+#[dom_struct]
+pub struct GPUSampler {
+ reflector_: Reflector,
+ #[ignore_malloc_size_of = "channels are hard"]
+ channel: WebGPU,
+ label: DomRefCell<Option<DOMString>>,
+ device: WebGPUDevice,
+ compare_enable: bool,
+ sampler: WebGPUSampler,
+ valid: Cell<bool>,
+}
+
+impl GPUSampler {
+ fn new_inherited(
+ channel: WebGPU,
+ device: WebGPUDevice,
+ compare_enable: bool,
+ sampler: WebGPUSampler,
+ valid: bool,
+ ) -> GPUSampler {
+ Self {
+ reflector_: Reflector::new(),
+ channel,
+ label: DomRefCell::new(None),
+ valid: Cell::new(valid),
+ device,
+ sampler,
+ compare_enable,
+ }
+ }
+
+ pub fn new(
+ global: &GlobalScope,
+ channel: WebGPU,
+ device: WebGPUDevice,
+ compare_enable: bool,
+ sampler: WebGPUSampler,
+ valid: bool,
+ ) -> DomRoot<GPUSampler> {
+ reflect_dom_object(
+ Box::new(GPUSampler::new_inherited(
+ channel,
+ device,
+ compare_enable,
+ sampler,
+ valid,
+ )),
+ global,
+ )
+ }
+}
+
+impl GPUSamplerMethods for GPUSampler {
+ /// 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;
+ }
+}
diff --git a/components/script/dom/identityhub.rs b/components/script/dom/identityhub.rs
index 880d8e0b5f4..8ba21e36969 100644
--- a/components/script/dom/identityhub.rs
+++ b/components/script/dom/identityhub.rs
@@ -7,7 +7,7 @@ use webgpu::wgpu::{
hub::IdentityManager,
id::{
AdapterId, BindGroupId, BindGroupLayoutId, BufferId, CommandEncoderId, ComputePipelineId,
- DeviceId, PipelineLayoutId, ShaderModuleId,
+ DeviceId, PipelineLayoutId, SamplerId, ShaderModuleId,
},
};
use webgpu::wgt::Backend;
@@ -23,11 +23,11 @@ pub struct IdentityHub {
pipeline_layouts: IdentityManager,
shader_modules: IdentityManager,
command_encoders: IdentityManager,
- backend: Backend,
+ samplers: IdentityManager,
}
impl IdentityHub {
- fn new(backend: Backend) -> Self {
+ fn new() -> Self {
IdentityHub {
adapters: IdentityManager::default(),
devices: IdentityManager::default(),
@@ -38,45 +38,9 @@ impl IdentityHub {
pipeline_layouts: IdentityManager::default(),
shader_modules: IdentityManager::default(),
command_encoders: IdentityManager::default(),
- backend,
+ samplers: IdentityManager::default(),
}
}
-
- fn create_adapter_id(&mut self) -> AdapterId {
- self.adapters.alloc(self.backend)
- }
-
- fn create_device_id(&mut self) -> DeviceId {
- self.devices.alloc(self.backend)
- }
-
- fn create_buffer_id(&mut self) -> BufferId {
- self.buffers.alloc(self.backend)
- }
-
- fn create_bind_group_id(&mut self) -> BindGroupId {
- self.bind_groups.alloc(self.backend)
- }
-
- fn create_bind_group_layout_id(&mut self) -> BindGroupLayoutId {
- 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)
- }
-
- fn create_shader_module_id(&mut self) -> ShaderModuleId {
- self.shader_modules.alloc(self.backend)
- }
-
- fn create_command_encoder_id(&mut self) -> CommandEncoderId {
- self.command_encoders.alloc(self.backend)
- }
}
#[derive(Debug)]
@@ -98,14 +62,14 @@ impl Identities {
Identities {
surface: IdentityManager::default(),
#[cfg(any(target_os = "linux", target_os = "windows"))]
- vk_hub: IdentityHub::new(Backend::Vulkan),
+ vk_hub: IdentityHub::new(),
#[cfg(target_os = "windows")]
- dx12_hub: IdentityHub::new(Backend::Dx12),
+ dx12_hub: IdentityHub::new(),
#[cfg(target_os = "windows")]
- dx11_hub: IdentityHub::new(Backend::Dx11),
+ dx11_hub: IdentityHub::new(),
#[cfg(any(target_os = "ios", target_os = "macos"))]
- metal_hub: IdentityHub::new(Backend::Metal),
- dummy_hub: IdentityHub::new(Backend::Empty),
+ metal_hub: IdentityHub::new(),
+ dummy_hub: IdentityHub::new(),
}
}
@@ -123,22 +87,22 @@ impl Identities {
}
}
- fn hubs(&mut self) -> Vec<&mut IdentityHub> {
+ fn hubs(&mut self) -> Vec<(&mut IdentityHub, Backend)> {
vec![
#[cfg(any(target_os = "linux", target_os = "windows"))]
- &mut self.vk_hub,
+ (&mut self.vk_hub, Backend::Vulkan),
#[cfg(target_os = "windows")]
- &mut self.dx12_hub,
+ (&mut self.dx12_hub, Backend::Dx12),
#[cfg(target_os = "windows")]
- &mut self.dx11_hub,
+ (&mut self.dx11_hub, Backend::Dx11),
#[cfg(any(target_os = "ios", target_os = "macos"))]
- &mut self.metal_hub,
- &mut self.dummy_hub,
+ (&mut self.metal_hub, Backend::Metal),
+ (&mut self.dummy_hub, Backend::Empty),
]
}
pub fn create_device_id(&mut self, backend: Backend) -> DeviceId {
- self.select(backend).create_device_id()
+ self.select(backend).devices.alloc(backend)
}
pub fn kill_device_id(&mut self, id: DeviceId) {
@@ -147,8 +111,8 @@ impl Identities {
pub fn create_adapter_ids(&mut self) -> SmallVec<[AdapterId; 4]> {
let mut ids = SmallVec::new();
- for hub in self.hubs() {
- ids.push(hub.create_adapter_id())
+ for hubs in self.hubs() {
+ ids.push(hubs.0.adapters.alloc(hubs.1));
}
ids
}
@@ -158,7 +122,7 @@ impl Identities {
}
pub fn create_buffer_id(&mut self, backend: Backend) -> BufferId {
- self.select(backend).create_buffer_id()
+ self.select(backend).buffers.alloc(backend)
}
pub fn kill_buffer_id(&mut self, id: BufferId) {
@@ -166,7 +130,7 @@ impl Identities {
}
pub fn create_bind_group_id(&mut self, backend: Backend) -> BindGroupId {
- self.select(backend).create_bind_group_id()
+ self.select(backend).bind_groups.alloc(backend)
}
pub fn kill_bind_group_id(&mut self, id: BindGroupId) {
@@ -174,7 +138,7 @@ impl Identities {
}
pub fn create_bind_group_layout_id(&mut self, backend: Backend) -> BindGroupLayoutId {
- self.select(backend).create_bind_group_layout_id()
+ self.select(backend).bind_group_layouts.alloc(backend)
}
pub fn kill_bind_group_layout_id(&mut self, id: BindGroupLayoutId) {
@@ -182,7 +146,7 @@ impl Identities {
}
pub fn create_compute_pipeline_id(&mut self, backend: Backend) -> ComputePipelineId {
- self.select(backend).create_compute_pipeline_id()
+ self.select(backend).compute_pipelines.alloc(backend)
}
pub fn kill_compute_pipeline_id(&mut self, id: ComputePipelineId) {
@@ -190,7 +154,7 @@ impl Identities {
}
pub fn create_pipeline_layout_id(&mut self, backend: Backend) -> PipelineLayoutId {
- self.select(backend).create_pipeline_layout_id()
+ self.select(backend).pipeline_layouts.alloc(backend)
}
pub fn kill_pipeline_layout_id(&mut self, id: PipelineLayoutId) {
@@ -198,7 +162,7 @@ impl Identities {
}
pub fn create_shader_module_id(&mut self, backend: Backend) -> ShaderModuleId {
- self.select(backend).create_shader_module_id()
+ self.select(backend).shader_modules.alloc(backend)
}
pub fn kill_shader_module_id(&mut self, id: ShaderModuleId) {
@@ -206,10 +170,18 @@ impl Identities {
}
pub fn create_command_encoder_id(&mut self, backend: Backend) -> CommandEncoderId {
- self.select(backend).create_command_encoder_id()
+ self.select(backend).command_encoders.alloc(backend)
}
pub fn kill_command_buffer_id(&mut self, id: CommandEncoderId) {
self.select(id.backend()).command_encoders.free(id);
}
+
+ pub fn create_sampler_id(&mut self, backend: Backend) -> SamplerId {
+ self.select(backend).samplers.alloc(backend)
+ }
+
+ pub fn kill_sampler_id(&mut self, id: SamplerId) {
+ self.select(id.backend()).samplers.free(id);
+ }
}
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index 9536f113417..f76bdc498ad 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -332,6 +332,7 @@ pub mod gpucomputepipeline;
pub mod gpudevice;
pub mod gpupipelinelayout;
pub mod gpuqueue;
+pub mod gpusampler;
pub mod gpushadermodule;
pub mod gpushaderstage;
pub mod hashchangeevent;
diff --git a/components/script/dom/webidls/GPUDevice.webidl b/components/script/dom/webidls/GPUDevice.webidl
index 9c7195c9b18..13f7ab37caa 100644
--- a/components/script/dom/webidls/GPUDevice.webidl
+++ b/components/script/dom/webidls/GPUDevice.webidl
@@ -14,7 +14,7 @@ interface GPUDevice : EventTarget {
GPUBuffer createBuffer(GPUBufferDescriptor descriptor);
GPUMappedBuffer createBufferMapped(GPUBufferDescriptor descriptor);
// GPUTexture createTexture(GPUTextureDescriptor descriptor);
- // GPUSampler createSampler(optional GPUSamplerDescriptor descriptor = {});
+ GPUSampler createSampler(optional GPUSamplerDescriptor descriptor = {});
GPUBindGroupLayout createBindGroupLayout(GPUBindGroupLayoutDescriptor descriptor);
GPUPipelineLayout createPipelineLayout(GPUPipelineLayoutDescriptor descriptor);
diff --git a/components/script/dom/webidls/GPUSampler.webidl b/components/script/dom/webidls/GPUSampler.webidl
new file mode 100644
index 00000000000..11673139e55
--- /dev/null
+++ b/components/script/dom/webidls/GPUSampler.webidl
@@ -0,0 +1,43 @@
+/* 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/#gpusampler
+[Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"]
+interface GPUSampler {
+};
+GPUSampler includes GPUObjectBase;
+
+dictionary GPUSamplerDescriptor : GPUObjectDescriptorBase {
+ GPUAddressMode addressModeU = "clamp-to-edge";
+ GPUAddressMode addressModeV = "clamp-to-edge";
+ GPUAddressMode addressModeW = "clamp-to-edge";
+ GPUFilterMode magFilter = "nearest";
+ GPUFilterMode minFilter = "nearest";
+ GPUFilterMode mipmapFilter = "nearest";
+ float lodMinClamp = 0;
+ float lodMaxClamp = 0xfffff; // TODO: Update this. Value in spec was too big
+ GPUCompareFunction compare;
+};
+
+enum GPUAddressMode {
+ "clamp-to-edge",
+ "repeat",
+ "mirror-repeat"
+};
+
+enum GPUFilterMode {
+ "nearest",
+ "linear"
+};
+
+enum GPUCompareFunction {
+ "never",
+ "less",
+ "equal",
+ "less-equal",
+ "greater",
+ "not-equal",
+ "greater-equal",
+ "always"
+};
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index c3e2694149f..294027582fa 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -2014,6 +2014,7 @@ impl ScriptThread {
self.gpu_id_hub.lock().kill_bind_group_layout_id(id)
},
WebGPUMsg::FreeCommandBuffer(id) => self.gpu_id_hub.lock().kill_command_buffer_id(id),
+ WebGPUMsg::FreeSampler(id) => self.gpu_id_hub.lock().kill_sampler_id(id),
WebGPUMsg::FreeShaderModule(id) => self.gpu_id_hub.lock().kill_shader_module_id(id),
_ => {},
}
diff --git a/components/webgpu/lib.rs b/components/webgpu/lib.rs
index d27d1a5b186..3704bdb6acc 100644
--- a/components/webgpu/lib.rs
+++ b/components/webgpu/lib.rs
@@ -16,18 +16,15 @@ use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use serde::{Deserialize, Serialize};
use servo_config::pref;
use smallvec::SmallVec;
+use std::ffi::CString;
use std::ptr;
use wgpu::{
binding_model::{
BindGroupDescriptor, BindGroupEntry, BindGroupLayoutDescriptor, BindGroupLayoutEntry,
},
- id::{
- AdapterId, BindGroupId, BindGroupLayoutId, BufferId, CommandBufferId, CommandEncoderId,
- ComputePipelineId, DeviceId, PipelineLayoutId, QueueId, ShaderModuleId,
- },
+ id,
instance::RequestAdapterOptions,
};
-use wgt::{BufferAddress, BufferDescriptor, CommandBufferDescriptor, DeviceDescriptor};
#[derive(Debug, Deserialize, Serialize)]
pub enum WebGPUResponse {
@@ -39,7 +36,7 @@ pub enum WebGPUResponse {
RequestDevice {
device_id: WebGPUDevice,
queue_id: WebGPUQueue,
- _descriptor: DeviceDescriptor,
+ _descriptor: wgt::DeviceDescriptor,
},
}
@@ -49,94 +46,99 @@ pub type WebGPUResponseResult = Result<WebGPUResponse, String>;
pub enum WebGPURequest {
CommandEncoderFinish {
sender: IpcSender<WebGPUCommandBuffer>,
- command_encoder_id: CommandEncoderId,
+ command_encoder_id: id::CommandEncoderId,
// TODO(zakorgy): Serialize CommandBufferDescriptor in wgpu-core
// wgpu::command::CommandBufferDescriptor,
},
CopyBufferToBuffer {
- command_encoder_id: CommandEncoderId,
- source_id: BufferId,
- source_offset: BufferAddress,
- destination_id: BufferId,
- destination_offset: BufferAddress,
- size: BufferAddress,
+ command_encoder_id: id::CommandEncoderId,
+ source_id: id::BufferId,
+ source_offset: wgt::BufferAddress,
+ destination_id: id::BufferId,
+ destination_offset: wgt::BufferAddress,
+ size: wgt::BufferAddress,
},
CreateBindGroup {
sender: IpcSender<WebGPUBindGroup>,
- device_id: DeviceId,
- bind_group_id: BindGroupId,
- bind_group_layout_id: BindGroupLayoutId,
+ device_id: id::DeviceId,
+ bind_group_id: id::BindGroupId,
+ bind_group_layout_id: id::BindGroupLayoutId,
bindings: Vec<BindGroupEntry>,
},
CreateBindGroupLayout {
sender: IpcSender<WebGPUBindGroupLayout>,
- device_id: DeviceId,
- bind_group_layout_id: BindGroupLayoutId,
+ device_id: id::DeviceId,
+ bind_group_layout_id: id::BindGroupLayoutId,
bindings: Vec<BindGroupLayoutEntry>,
},
CreateBuffer {
sender: IpcSender<WebGPUBuffer>,
- device_id: DeviceId,
- buffer_id: BufferId,
- descriptor: BufferDescriptor<String>,
+ device_id: id::DeviceId,
+ buffer_id: id::BufferId,
+ descriptor: wgt::BufferDescriptor<String>,
},
CreateBufferMapped {
sender: IpcSender<WebGPUBuffer>,
- device_id: DeviceId,
- buffer_id: BufferId,
- descriptor: BufferDescriptor<String>,
+ device_id: id::DeviceId,
+ buffer_id: id::BufferId,
+ descriptor: wgt::BufferDescriptor<String>,
},
CreateCommandEncoder {
sender: IpcSender<WebGPUCommandEncoder>,
- device_id: DeviceId,
+ device_id: id::DeviceId,
// TODO(zakorgy): Serialize CommandEncoderDescriptor in wgpu-core
// wgpu::command::CommandEncoderDescriptor,
- command_encoder_id: CommandEncoderId,
+ command_encoder_id: id::CommandEncoderId,
},
CreateComputePipeline {
sender: IpcSender<WebGPUComputePipeline>,
- device_id: DeviceId,
- compute_pipeline_id: ComputePipelineId,
- pipeline_layout_id: PipelineLayoutId,
- program_id: ShaderModuleId,
+ device_id: id::DeviceId,
+ compute_pipeline_id: id::ComputePipelineId,
+ pipeline_layout_id: id::PipelineLayoutId,
+ program_id: id::ShaderModuleId,
entry_point: String,
},
CreatePipelineLayout {
sender: IpcSender<WebGPUPipelineLayout>,
- device_id: DeviceId,
- pipeline_layout_id: PipelineLayoutId,
- bind_group_layouts: Vec<BindGroupLayoutId>,
+ device_id: id::DeviceId,
+ pipeline_layout_id: id::PipelineLayoutId,
+ bind_group_layouts: Vec<id::BindGroupLayoutId>,
+ },
+ CreateSampler {
+ device_id: id::DeviceId,
+ sampler_id: id::SamplerId,
+ descriptor: wgt::SamplerDescriptor<String>,
},
CreateShaderModule {
sender: IpcSender<WebGPUShaderModule>,
- device_id: DeviceId,
- program_id: ShaderModuleId,
+ device_id: id::DeviceId,
+ program_id: id::ShaderModuleId,
program: Vec<u32>,
},
- DestroyBuffer(BufferId),
+ DestroyBuffer(id::BufferId),
Exit(IpcSender<()>),
RequestAdapter {
sender: IpcSender<WebGPUResponseResult>,
options: RequestAdapterOptions,
- ids: SmallVec<[AdapterId; 4]>,
+ ids: SmallVec<[id::AdapterId; 4]>,
},
RequestDevice {
sender: IpcSender<WebGPUResponseResult>,
adapter_id: WebGPUAdapter,
- descriptor: DeviceDescriptor,
- device_id: DeviceId,
+ descriptor: wgt::DeviceDescriptor,
+ device_id: id::DeviceId,
},
RunComputePass {
- command_encoder_id: CommandEncoderId,
+ command_encoder_id: id::CommandEncoderId,
pass_data: Vec<u8>,
},
Submit {
- queue_id: QueueId,
- command_buffers: Vec<CommandBufferId>,
+ queue_id: id::QueueId,
+ command_buffers: Vec<id::CommandBufferId>,
},
UnmapBuffer {
- device_id: DeviceId,
- buffer_id: BufferId,
+ device_id: id::DeviceId,
+ buffer_id: id::BufferId,
array_buffer: Vec<u8>,
},
}
@@ -230,7 +232,7 @@ impl WGPU {
let global = &self.global;
let command_buffer_id = gfx_select!(command_encoder_id => global.command_encoder_finish(
command_encoder_id,
- &CommandBufferDescriptor::default()
+ &wgt::CommandBufferDescriptor::default()
));
if let Err(e) = sender.send(WebGPUCommandBuffer(command_buffer_id)) {
warn!(
@@ -312,7 +314,7 @@ impl WGPU {
descriptor,
} => {
let global = &self.global;
- let desc = BufferDescriptor {
+ let desc = wgt::BufferDescriptor {
size: descriptor.size,
usage: descriptor.usage,
label: ptr::null(),
@@ -333,7 +335,7 @@ impl WGPU {
descriptor,
} => {
let global = &self.global;
- let desc = BufferDescriptor {
+ let desc = wgt::BufferDescriptor {
size: descriptor.size,
usage: descriptor.usage,
label: ptr::null(),
@@ -414,6 +416,16 @@ impl WGPU {
)
}
},
+ WebGPURequest::CreateSampler {
+ device_id,
+ sampler_id,
+ descriptor,
+ } => {
+ let global = &self.global;
+ let st = CString::new(descriptor.label.as_bytes()).unwrap();
+ let _ = gfx_select!(sampler_id =>
+ global.device_create_sampler(device_id, &descriptor.map_label(|_| st.as_ptr()), sampler_id));
+ },
WebGPURequest::CreateShaderModule {
sender,
device_id,
@@ -579,14 +591,15 @@ macro_rules! webgpu_resource {
};
}
-webgpu_resource!(WebGPUAdapter, AdapterId);
-webgpu_resource!(WebGPUBindGroup, BindGroupId);
-webgpu_resource!(WebGPUBindGroupLayout, BindGroupLayoutId);
-webgpu_resource!(WebGPUBuffer, BufferId);
-webgpu_resource!(WebGPUCommandBuffer, CommandBufferId);
-webgpu_resource!(WebGPUCommandEncoder, CommandEncoderId);
-webgpu_resource!(WebGPUComputePipeline, ComputePipelineId);
-webgpu_resource!(WebGPUDevice, DeviceId);
-webgpu_resource!(WebGPUPipelineLayout, PipelineLayoutId);
-webgpu_resource!(WebGPUQueue, QueueId);
-webgpu_resource!(WebGPUShaderModule, ShaderModuleId);
+webgpu_resource!(WebGPUAdapter, id::AdapterId);
+webgpu_resource!(WebGPUBindGroup, id::BindGroupId);
+webgpu_resource!(WebGPUBindGroupLayout, id::BindGroupLayoutId);
+webgpu_resource!(WebGPUBuffer, id::BufferId);
+webgpu_resource!(WebGPUCommandBuffer, id::CommandBufferId);
+webgpu_resource!(WebGPUCommandEncoder, id::CommandEncoderId);
+webgpu_resource!(WebGPUComputePipeline, id::ComputePipelineId);
+webgpu_resource!(WebGPUDevice, id::DeviceId);
+webgpu_resource!(WebGPUPipelineLayout, id::PipelineLayoutId);
+webgpu_resource!(WebGPUQueue, id::QueueId);
+webgpu_resource!(WebGPUSampler, id::SamplerId);
+webgpu_resource!(WebGPUShaderModule, id::ShaderModuleId);