diff options
author | Kunal Mohan <kunalmohan99@gmail.com> | 2020-05-23 22:04:09 +0530 |
---|---|---|
committer | Kunal Mohan <kunalmohan99@gmail.com> | 2020-05-26 00:00:35 +0530 |
commit | dd04716b852471ba75e4bf44ced0e2d481e99ab2 (patch) | |
tree | 31262d46335d21ef23bc50faab54522f6b902253 | |
parent | 43f29fe0cefe2e7ce42e4172d6cb2a4ebe72ab0f (diff) | |
download | servo-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.rs | 3 | ||||
-rw-r--r-- | components/script/dom/gpudevice.rs | 110 | ||||
-rw-r--r-- | components/script/dom/gpusampler.rs | 77 | ||||
-rw-r--r-- | components/script/dom/identityhub.rs | 94 | ||||
-rw-r--r-- | components/script/dom/mod.rs | 1 | ||||
-rw-r--r-- | components/script/dom/webidls/GPUDevice.webidl | 2 | ||||
-rw-r--r-- | components/script/dom/webidls/GPUSampler.webidl | 43 | ||||
-rw-r--r-- | components/script/script_thread.rs | 1 | ||||
-rw-r--r-- | components/webgpu/lib.rs | 129 |
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); |