diff options
author | Samson <16504129+sagudev@users.noreply.github.com> | 2024-08-19 16:06:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-19 14:06:30 +0000 |
commit | 94ff89a5e4c1c99118b6240845bb283d58ebb149 (patch) | |
tree | d73aefc38bfdef08446e934edce779e669a22f85 /components/script | |
parent | f45c98496e0e473b404fe898ba7ef184c8a46b33 (diff) | |
download | servo-94ff89a5e4c1c99118b6240845bb283d58ebb149.tar.gz servo-94ff89a5e4c1c99118b6240845bb283d58ebb149.zip |
webgpu: Sync various parts of spec (#33009)
* Sync `GPUObjectDescriptorBase` (label is not option anymore)
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* Sync `GPUFeatureName`
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* shader_f16 feature is not usable in wgpu so disable it
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* sync `GPUTextureFormat`
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* `validate_texture_format_required_features`
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* Sync `GPUTexture` attributes
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* Make `entryPoint` in `GPUProgrammableStage` optional
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* Set good expectations
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* Bad expectations because naga does not support cons declarations
Also fail on firefox, where skipped before due to missing device features
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* Bad expectation, also fails on firefox
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* Bad expectations, because naga does not support `let pos = positions[vertex_index];`
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* Set expectation
external texture does not work in firefox too (again naga)
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* set bad expectations, because naga does not support `enable`
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* Set bad expectations for, `Texture with '' label has been destroyed`
also fails in firefox with same reason
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* one bad expectation
also on firefox
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* expect that also matches firefox
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* more expect
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* Use only 1 proc for _webgpu
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
* better doc comment
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
---------
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/gpuadapter.rs | 20 | ||||
-rw-r--r-- | components/script/dom/gpucanvascontext.rs | 15 | ||||
-rw-r--r-- | components/script/dom/gpucommandencoder.rs | 6 | ||||
-rw-r--r-- | components/script/dom/gpuconvert.rs | 137 | ||||
-rw-r--r-- | components/script/dom/gpudevice.rs | 310 | ||||
-rw-r--r-- | components/script/dom/gpurenderbundleencoder.rs | 2 | ||||
-rw-r--r-- | components/script/dom/gpusupportedfeatures.rs | 82 | ||||
-rw-r--r-- | components/script/dom/gputexture.rs | 61 | ||||
-rw-r--r-- | components/script/dom/webidls/WebGPU.webidl | 101 |
9 files changed, 550 insertions, 184 deletions
diff --git a/components/script/dom/gpuadapter.rs b/components/script/dom/gpuadapter.rs index ef6dee69c77..14743dad91f 100644 --- a/components/script/dom/gpuadapter.rs +++ b/components/script/dom/gpuadapter.rs @@ -110,10 +110,10 @@ impl GPUAdapterMethods for GPUAdapter { // Step 2 let promise = Promise::new_in_current_realm(comp); let sender = response_async(&promise, self); - let mut features = wgt::Features::empty(); + let mut required_features = wgt::Features::empty(); for &ext in descriptor.requiredFeatures.iter() { if let Some(feature) = gpu_to_wgt_feature(ext) { - features.insert(feature); + required_features.insert(feature); } else { promise.reject_error(Error::Type(format!( "{} is not supported feature", @@ -123,21 +123,23 @@ impl GPUAdapterMethods for GPUAdapter { } } - let mut desc = wgt::DeviceDescriptor { - required_features: features, - required_limits: wgt::Limits::default(), - label: None, - memory_hints: MemoryHints::MemoryUsage, - }; + let mut required_limits = wgt::Limits::default(); if let Some(limits) = &descriptor.requiredLimits { for (limit, value) in (*limits).iter() { - if !set_limit(&mut desc.required_limits, limit.as_ref(), *value) { + if !set_limit(&mut required_limits, limit.as_ref(), *value) { warn!("Unknown GPUDevice limit: {limit}"); promise.reject_error(Error::Operation); return promise; } } } + + let desc = wgt::DeviceDescriptor { + required_features, + required_limits, + label: Some(descriptor.parent.label.to_string()), + memory_hints: MemoryHints::MemoryUsage, + }; let device_id = self .global() .wgpu_id_hub() diff --git a/components/script/dom/gpucanvascontext.rs b/components/script/dom/gpucanvascontext.rs index 08226de337c..edcf099b89b 100644 --- a/components/script/dom/gpucanvascontext.rs +++ b/components/script/dom/gpucanvascontext.rs @@ -20,6 +20,7 @@ use super::bindings::codegen::Bindings::WebGPUBinding::GPUTextureUsageConstants; use super::bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas; use super::bindings::error::{Error, Fallible}; use super::bindings::root::MutNullableDom; +use super::bindings::str::USVString; use super::gputexture::GPUTexture; use crate::dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElement_Binding::HTMLCanvasElementMethods; use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{ @@ -207,7 +208,9 @@ impl GPUCanvasContextMethods for GPUCanvasContext { fn Configure(&self, descriptor: &GPUCanvasConfiguration) -> Fallible<()> { // Step 1 is let // Step 2 - // TODO: device features + descriptor + .device + .validate_texture_format_required_features(&descriptor.format)?; let format = match descriptor.format { GPUTextureFormat::Rgba8unorm | GPUTextureFormat::Rgba8unorm_srgb => ImageFormat::RGBA8, GPUTextureFormat::Bgra8unorm | GPUTextureFormat::Bgra8unorm_srgb => ImageFormat::BGRA8, @@ -220,7 +223,11 @@ impl GPUCanvasContextMethods for GPUCanvasContext { }; // Step 3 - // TODO: device features + for view_format in &descriptor.viewFormats { + descriptor + .device + .validate_texture_format_required_features(view_format)?; + } // Step 4 let size = self.size(); @@ -236,7 +243,9 @@ impl GPUCanvasContextMethods for GPUCanvasContext { }), viewFormats: descriptor.viewFormats.clone(), // other members to default - parent: GPUObjectDescriptorBase { label: None }, + parent: GPUObjectDescriptorBase { + label: USVString::default(), + }, dimension: GPUTextureDimension::_2d, }; diff --git a/components/script/dom/gpucommandencoder.rs b/components/script/dom/gpucommandencoder.rs index 9243176be11..9cd5af180a8 100644 --- a/components/script/dom/gpucommandencoder.rs +++ b/components/script/dom/gpucommandencoder.rs @@ -124,7 +124,7 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { self.channel.clone(), self, WebGPUComputePass(compute_pass_id), - descriptor.parent.label.clone().unwrap_or_default(), + descriptor.parent.label.clone(), ) } @@ -213,7 +213,7 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { self.channel.clone(), WebGPURenderPass(render_pass_id), self, - descriptor.parent.label.clone().unwrap_or_default(), + descriptor.parent.label.clone(), ) } @@ -324,7 +324,7 @@ impl GPUCommandEncoderMethods for GPUCommandEncoder { self.channel.clone(), buffer, self.buffers.borrow_mut().drain().collect(), - descriptor.parent.label.clone().unwrap_or_default(), + descriptor.parent.label.clone(), ) } } diff --git a/components/script/dom/gpuconvert.rs b/components/script/dom/gpuconvert.rs index bdfa9b8dd35..0cf9b5a3b12 100644 --- a/components/script/dom/gpuconvert.rs +++ b/components/script/dom/gpuconvert.rs @@ -5,7 +5,7 @@ use std::borrow::Cow; use webgpu::wgc::command as wgpu_com; -use webgpu::wgt; +use webgpu::wgt::{self, AstcBlock, AstcChannel}; use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{ GPUAddressMode, GPUBlendComponent, GPUBlendFactor, GPUBlendOperation, GPUCompareFunction, @@ -67,8 +67,135 @@ pub fn convert_texture_format(format: GPUTextureFormat) -> wgt::TextureFormat { GPUTextureFormat::Bc6h_rgb_ufloat => wgt::TextureFormat::Bc6hRgbUfloat, GPUTextureFormat::Bc7_rgba_unorm => wgt::TextureFormat::Bc7RgbaUnorm, GPUTextureFormat::Bc7_rgba_unorm_srgb => wgt::TextureFormat::Bc7RgbaUnormSrgb, - GPUTextureFormat::Rg11b10float => wgt::TextureFormat::Rg11b10Float, GPUTextureFormat::Bc6h_rgb_float => wgt::TextureFormat::Bc6hRgbFloat, + GPUTextureFormat::Rgb9e5ufloat => wgt::TextureFormat::Rgb9e5Ufloat, + GPUTextureFormat::Rgb10a2uint => wgt::TextureFormat::Rgb10a2Uint, + GPUTextureFormat::Rg11b10ufloat => wgt::TextureFormat::Rg11b10Float, + GPUTextureFormat::Stencil8 => wgt::TextureFormat::Stencil8, + GPUTextureFormat::Depth16unorm => wgt::TextureFormat::Depth16Unorm, + GPUTextureFormat::Depth32float_stencil8 => wgt::TextureFormat::Depth32FloatStencil8, + GPUTextureFormat::Etc2_rgb8unorm => wgt::TextureFormat::Etc2Rgb8Unorm, + GPUTextureFormat::Etc2_rgb8unorm_srgb => wgt::TextureFormat::Etc2Rgb8UnormSrgb, + GPUTextureFormat::Etc2_rgb8a1unorm => wgt::TextureFormat::Etc2Rgb8A1Unorm, + GPUTextureFormat::Etc2_rgb8a1unorm_srgb => wgt::TextureFormat::Etc2Rgb8A1UnormSrgb, + GPUTextureFormat::Etc2_rgba8unorm => wgt::TextureFormat::Etc2Rgba8Unorm, + GPUTextureFormat::Etc2_rgba8unorm_srgb => wgt::TextureFormat::Etc2Rgba8UnormSrgb, + GPUTextureFormat::Eac_r11unorm => wgt::TextureFormat::EacR11Unorm, + GPUTextureFormat::Eac_r11snorm => wgt::TextureFormat::EacR11Snorm, + GPUTextureFormat::Eac_rg11unorm => wgt::TextureFormat::EacRg11Unorm, + GPUTextureFormat::Eac_rg11snorm => wgt::TextureFormat::EacRg11Snorm, + GPUTextureFormat::Astc_4x4_unorm => wgt::TextureFormat::Astc { + block: AstcBlock::B4x4, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc_4x4_unorm_srgb => wgt::TextureFormat::Astc { + block: AstcBlock::B4x4, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc_5x4_unorm => wgt::TextureFormat::Astc { + block: AstcBlock::B5x4, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc_5x4_unorm_srgb => wgt::TextureFormat::Astc { + block: AstcBlock::B5x4, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc_5x5_unorm => wgt::TextureFormat::Astc { + block: AstcBlock::B5x5, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc_5x5_unorm_srgb => wgt::TextureFormat::Astc { + block: AstcBlock::B5x5, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc_6x5_unorm => wgt::TextureFormat::Astc { + block: AstcBlock::B6x5, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc_6x5_unorm_srgb => wgt::TextureFormat::Astc { + block: AstcBlock::B6x5, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc_6x6_unorm => wgt::TextureFormat::Astc { + block: AstcBlock::B6x6, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc_6x6_unorm_srgb => wgt::TextureFormat::Astc { + block: AstcBlock::B6x6, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc_8x5_unorm => wgt::TextureFormat::Astc { + block: AstcBlock::B8x5, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc_8x5_unorm_srgb => wgt::TextureFormat::Astc { + block: AstcBlock::B8x5, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc_8x6_unorm => wgt::TextureFormat::Astc { + block: AstcBlock::B8x6, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc_8x6_unorm_srgb => wgt::TextureFormat::Astc { + block: AstcBlock::B8x6, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc_8x8_unorm => wgt::TextureFormat::Astc { + block: AstcBlock::B8x8, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc_8x8_unorm_srgb => wgt::TextureFormat::Astc { + block: AstcBlock::B8x8, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc_10x5_unorm => wgt::TextureFormat::Astc { + block: AstcBlock::B10x5, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc_10x5_unorm_srgb => wgt::TextureFormat::Astc { + block: AstcBlock::B10x5, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc_10x6_unorm => wgt::TextureFormat::Astc { + block: AstcBlock::B10x6, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc_10x6_unorm_srgb => wgt::TextureFormat::Astc { + block: AstcBlock::B10x6, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc_10x8_unorm => wgt::TextureFormat::Astc { + block: AstcBlock::B10x8, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc_10x8_unorm_srgb => wgt::TextureFormat::Astc { + block: AstcBlock::B10x8, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc_10x10_unorm => wgt::TextureFormat::Astc { + block: AstcBlock::B10x10, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc_10x10_unorm_srgb => wgt::TextureFormat::Astc { + block: AstcBlock::B10x10, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc_12x10_unorm => wgt::TextureFormat::Astc { + block: AstcBlock::B12x10, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc_12x10_unorm_srgb => wgt::TextureFormat::Astc { + block: AstcBlock::B12x10, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc_12x12_unorm => wgt::TextureFormat::Astc { + block: AstcBlock::B12x12, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc_12x12_unorm_srgb => wgt::TextureFormat::Astc { + block: AstcBlock::B12x12, + channel: AstcChannel::UnormSrgb, + }, } } @@ -329,5 +456,9 @@ pub fn convert_ic_texture(ic_texture: &GPUImageCopyTexture) -> wgpu_com::ImageCo } pub fn convert_label(parent: &GPUObjectDescriptorBase) -> Option<Cow<'static, str>> { - parent.label.as_ref().map(|s| Cow::Owned(s.to_string())) + if parent.label.is_empty() { + None + } else { + Some(Cow::Owned(parent.label.to_string())) + } } diff --git a/components/script/dom/gpudevice.rs b/components/script/dom/gpudevice.rs index 88842f505ef..e3f19813890 100644 --- a/components/script/dom/gpudevice.rs +++ b/components/script/dom/gpudevice.rs @@ -18,12 +18,13 @@ use webgpu::wgc::pipeline::RenderPipelineDescriptor; use webgpu::wgc::{ binding_model as wgpu_bind, command as wgpu_com, pipeline as wgpu_pipe, resource as wgpu_res, }; +use webgpu::wgt::TextureFormat; use webgpu::{ self, wgt, PopError, WebGPU, WebGPUComputePipeline, WebGPURenderPipeline, WebGPURequest, WebGPUResponse, }; -use super::bindings::codegen::Bindings::WebGPUBinding::GPUPipelineErrorReason; +use super::bindings::codegen::Bindings::WebGPUBinding::{GPUPipelineErrorReason, GPUTextureFormat}; use super::bindings::codegen::UnionTypes::GPUPipelineLayoutOrGPUAutoLayoutMode; use super::bindings::error::Fallible; use super::gpu::AsyncWGPUListener; @@ -190,6 +191,28 @@ impl GPUDevice { let _ = self.eventtarget.DispatchEvent(ev.event()); } + /// <https://gpuweb.github.io/gpuweb/#abstract-opdef-validate-texture-format-required-features> + /// + /// Validates that the device suppports required features, + /// and if so returns an ok containing wgpu's `TextureFormat` + pub fn validate_texture_format_required_features( + &self, + format: &GPUTextureFormat, + ) -> Fallible<TextureFormat> { + let texture_format = convert_texture_format(*format); + if self + .features + .wgpu_features() + .contains(texture_format.required_features()) + { + Ok(texture_format) + } else { + Err(Error::Type(format!( + "{texture_format:?} is not supported by this GPUDevice" + ))) + } + } + fn get_pipeline_layout_data( &self, layout: &GPUPipelineLayoutOrGPUAutoLayoutMode, @@ -223,10 +246,10 @@ impl GPUDevice { fn parse_render_pipeline( &self, descriptor: &GPURenderPipelineDescriptor, - ) -> ( + ) -> Fallible<( Option<(PipelineLayoutId, Vec<BindGroupLayoutId>)>, RenderPipelineDescriptor<'static>, - ) { + )> { let (layout, implicit_ids, _) = self.get_pipeline_layout_data(&descriptor.parent.layout); let desc = wgpu_pipe::RenderPipelineDescriptor { @@ -236,7 +259,12 @@ impl GPUDevice { vertex: wgpu_pipe::VertexState { stage: wgpu_pipe::ProgrammableStageDescriptor { module: descriptor.vertex.parent.module.id().0, - entry_point: Some(Cow::Owned(descriptor.vertex.parent.entryPoint.to_string())), + entry_point: descriptor + .vertex + .parent + .entryPoint + .as_ref() + .map(|ep| Cow::Owned(ep.to_string())), constants: Cow::Owned(HashMap::new()), zero_initialize_workgroup_memory: true, }, @@ -269,59 +297,88 @@ impl GPUDevice { fragment: descriptor .fragment .as_ref() - .map(|stage| wgpu_pipe::FragmentState { - stage: wgpu_pipe::ProgrammableStageDescriptor { - module: stage.parent.module.id().0, - entry_point: Some(Cow::Owned(stage.parent.entryPoint.to_string())), - constants: Cow::Owned(HashMap::new()), - zero_initialize_workgroup_memory: true, - }, - targets: Cow::Owned( - stage - .targets - .iter() - .map(|state| { - Some(wgt::ColorTargetState { - format: convert_texture_format(state.format), - write_mask: wgt::ColorWrites::from_bits_retain(state.writeMask), - blend: state.blend.as_ref().map(|blend| wgt::BlendState { - color: convert_blend_component(&blend.color), - alpha: convert_blend_component(&blend.alpha), - }), + .map(|stage| -> Fallible<wgpu_pipe::FragmentState> { + Ok(wgpu_pipe::FragmentState { + stage: wgpu_pipe::ProgrammableStageDescriptor { + module: stage.parent.module.id().0, + entry_point: stage + .parent + .entryPoint + .as_ref() + .map(|ep| Cow::Owned(ep.to_string())), + constants: Cow::Owned(HashMap::new()), + zero_initialize_workgroup_memory: true, + }, + targets: Cow::Owned( + stage + .targets + .iter() + .map(|state| { + self.validate_texture_format_required_features(&state.format) + .map(|format| { + Some(wgt::ColorTargetState { + format, + write_mask: wgt::ColorWrites::from_bits_retain( + state.writeMask, + ), + blend: state.blend.as_ref().map(|blend| { + wgt::BlendState { + color: convert_blend_component( + &blend.color, + ), + alpha: convert_blend_component( + &blend.alpha, + ), + } + }), + }) + }) }) - }) - .collect::<Vec<_>>(), - ), - }), + .collect::<Result<Vec<_>, _>>()?, + ), + }) + }) + .transpose()?, primitive: convert_primitive_state(&descriptor.primitive), - depth_stencil: descriptor.depthStencil.as_ref().map(|dss_desc| { - wgt::DepthStencilState { - format: convert_texture_format(dss_desc.format), - depth_write_enabled: dss_desc.depthWriteEnabled, - depth_compare: convert_compare_function(dss_desc.depthCompare), - stencil: wgt::StencilState { - front: wgt::StencilFaceState { - compare: convert_compare_function(dss_desc.stencilFront.compare), - fail_op: convert_stencil_op(dss_desc.stencilFront.failOp), - depth_fail_op: convert_stencil_op(dss_desc.stencilFront.depthFailOp), - pass_op: convert_stencil_op(dss_desc.stencilFront.passOp), - }, - back: wgt::StencilFaceState { - compare: convert_compare_function(dss_desc.stencilBack.compare), - fail_op: convert_stencil_op(dss_desc.stencilBack.failOp), - depth_fail_op: convert_stencil_op(dss_desc.stencilBack.depthFailOp), - pass_op: convert_stencil_op(dss_desc.stencilBack.passOp), - }, - read_mask: dss_desc.stencilReadMask, - write_mask: dss_desc.stencilWriteMask, - }, - bias: wgt::DepthBiasState { - constant: dss_desc.depthBias, - slope_scale: *dss_desc.depthBiasSlopeScale, - clamp: *dss_desc.depthBiasClamp, - }, - } - }), + depth_stencil: descriptor + .depthStencil + .as_ref() + .map(|dss_desc| { + self.validate_texture_format_required_features(&dss_desc.format) + .map(|format| wgt::DepthStencilState { + format, + depth_write_enabled: dss_desc.depthWriteEnabled, + depth_compare: convert_compare_function(dss_desc.depthCompare), + stencil: wgt::StencilState { + front: wgt::StencilFaceState { + compare: convert_compare_function( + dss_desc.stencilFront.compare, + ), + fail_op: convert_stencil_op(dss_desc.stencilFront.failOp), + depth_fail_op: convert_stencil_op( + dss_desc.stencilFront.depthFailOp, + ), + pass_op: convert_stencil_op(dss_desc.stencilFront.passOp), + }, + back: wgt::StencilFaceState { + compare: convert_compare_function(dss_desc.stencilBack.compare), + fail_op: convert_stencil_op(dss_desc.stencilBack.failOp), + depth_fail_op: convert_stencil_op( + dss_desc.stencilBack.depthFailOp, + ), + pass_op: convert_stencil_op(dss_desc.stencilBack.passOp), + }, + read_mask: dss_desc.stencilReadMask, + write_mask: dss_desc.stencilWriteMask, + }, + bias: wgt::DepthBiasState { + constant: dss_desc.depthBias, + slope_scale: *dss_desc.depthBiasSlopeScale, + clamp: *dss_desc.depthBiasClamp, + }, + }) + }) + .transpose()?, multisample: wgt::MultisampleState { count: descriptor.multisample.count, mask: descriptor.multisample.mask as u64, @@ -329,7 +386,7 @@ impl GPUDevice { }, multiview: None, }; - (implicit_ids, desc) + Ok((implicit_ids, desc)) } /// <https://gpuweb.github.io/gpuweb/#lose-the-device> @@ -420,7 +477,7 @@ impl GPUDeviceMethods for GPUDevice { state, descriptor.size, map_info, - descriptor.parent.label.clone().unwrap_or_default(), + descriptor.parent.label.clone(), )) } @@ -429,7 +486,8 @@ impl GPUDeviceMethods for GPUDevice { fn CreateBindGroupLayout( &self, descriptor: &GPUBindGroupLayoutDescriptor, - ) -> DomRoot<GPUBindGroupLayout> { + ) -> Fallible<DomRoot<GPUBindGroupLayout>> { + // TODO(sagudev): pass invalid bits to wgpu let mut valid = true; let entries = descriptor .entries @@ -471,7 +529,7 @@ impl GPUDeviceMethods for GPUDevice { wgt::StorageTextureAccess::WriteOnly }, }, - format: convert_texture_format(storage.format), + format: self.validate_texture_format_required_features(&storage.format)?, view_dimension: convert_view_dimension(storage.viewDimension), } } else if let Some(texture) = &bind.texture { @@ -495,14 +553,14 @@ impl GPUDeviceMethods for GPUDevice { todo!("Handle error"); }; - wgt::BindGroupLayoutEntry { + Ok(wgt::BindGroupLayoutEntry { binding: bind.binding, visibility, ty, count: None, - } + }) }) - .collect::<Vec<_>>(); + .collect::<Fallible<Vec<_>>>()?; let desc = if valid { Some(wgpu_bind::BindGroupLayoutDescriptor { @@ -531,12 +589,12 @@ impl GPUDeviceMethods for GPUDevice { let bgl = webgpu::WebGPUBindGroupLayout(bind_group_layout_id); - GPUBindGroupLayout::new( + Ok(GPUBindGroupLayout::new( &self.global(), self.channel.clone(), bgl, - descriptor.parent.label.clone().unwrap_or_default(), - ) + descriptor.parent.label.clone(), + )) } /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createpipelinelayout> @@ -579,7 +637,7 @@ impl GPUDeviceMethods for GPUDevice { &self.global(), self.channel.clone(), pipeline_layout, - descriptor.parent.label.clone().unwrap_or_default(), + descriptor.parent.label.clone(), bgls, ) } @@ -636,7 +694,7 @@ impl GPUDeviceMethods for GPUDevice { bind_group, self.device, &descriptor.layout, - descriptor.parent.label.clone().unwrap_or_default(), + descriptor.parent.label.clone(), ) } @@ -655,7 +713,7 @@ impl GPUDeviceMethods for GPUDevice { &self.global(), self.channel.clone(), webgpu::WebGPUShaderModule(program_id), - descriptor.parent.label.clone().unwrap_or_default(), + descriptor.parent.label.clone(), promise.clone(), ); let sender = response_async(&promise, &*shader_module); @@ -689,7 +747,11 @@ impl GPUDeviceMethods for GPUDevice { layout, stage: wgpu_pipe::ProgrammableStageDescriptor { module: descriptor.compute.module.id().0, - entry_point: Some(Cow::Owned(descriptor.compute.entryPoint.to_string())), + entry_point: descriptor + .compute + .entryPoint + .as_ref() + .map(|ep| Cow::Owned(ep.to_string())), constants: Cow::Owned(HashMap::new()), zero_initialize_workgroup_memory: true, }, @@ -711,7 +773,7 @@ impl GPUDeviceMethods for GPUDevice { GPUComputePipeline::new( &self.global(), compute_pipeline, - descriptor.parent.parent.label.clone().unwrap_or_default(), + descriptor.parent.parent.label.clone(), self, ) } @@ -736,7 +798,11 @@ impl GPUDeviceMethods for GPUDevice { layout, stage: wgpu_pipe::ProgrammableStageDescriptor { module: descriptor.compute.module.id().0, - entry_point: Some(Cow::Owned(descriptor.compute.entryPoint.to_string())), + entry_point: descriptor + .compute + .entryPoint + .as_ref() + .map(|ep| Cow::Owned(ep.to_string())), constants: Cow::Owned(HashMap::new()), zero_initialize_workgroup_memory: true, }, @@ -781,33 +847,37 @@ impl GPUDeviceMethods for GPUDevice { self.channel.clone(), self, encoder, - descriptor.parent.label.clone().unwrap_or_default(), + descriptor.parent.label.clone(), ) } /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createtexture> fn CreateTexture(&self, descriptor: &GPUTextureDescriptor) -> Fallible<DomRoot<GPUTexture>> { + // TODO(sagudev): This should be https://gpuweb.github.io/gpuweb/#abstract-opdef-validate-gpuextent3d-shape let size = convert_texture_size_to_dict(&descriptor.size); - let desc = wgt::TextureUsages::from_bits(descriptor.usage).map(|usg| { - wgpu_res::TextureDescriptor { - label: convert_label(&descriptor.parent), - size: convert_texture_size_to_wgt(&size), - mip_level_count: descriptor.mipLevelCount, - sample_count: descriptor.sampleCount, - dimension: match descriptor.dimension { - GPUTextureDimension::_1d => wgt::TextureDimension::D1, - GPUTextureDimension::_2d => wgt::TextureDimension::D2, - GPUTextureDimension::_3d => wgt::TextureDimension::D3, - }, - format: convert_texture_format(descriptor.format), - usage: usg, - view_formats: descriptor - .viewFormats - .iter() - .map(|tf| convert_texture_format(*tf)) - .collect(), - } - }); + // TODO(sagudev): We should pass invalid bits to wgpu + let desc = wgt::TextureUsages::from_bits(descriptor.usage) + .map(|usg| -> Fallible<_> { + Ok(wgpu_res::TextureDescriptor { + label: convert_label(&descriptor.parent), + size: convert_texture_size_to_wgt(&size), + mip_level_count: descriptor.mipLevelCount, + sample_count: descriptor.sampleCount, + dimension: match descriptor.dimension { + GPUTextureDimension::_1d => wgt::TextureDimension::D1, + GPUTextureDimension::_2d => wgt::TextureDimension::D2, + GPUTextureDimension::_3d => wgt::TextureDimension::D3, + }, + format: self.validate_texture_format_required_features(&descriptor.format)?, + usage: usg, + view_formats: descriptor + .viewFormats + .iter() + .map(|tf| self.validate_texture_format_required_features(tf)) + .collect::<Fallible<_>>()?, + }) + }) + .transpose()?; let texture_id = self .global() @@ -839,7 +909,7 @@ impl GPUDeviceMethods for GPUDevice { descriptor.dimension, descriptor.format, descriptor.usage, - descriptor.parent.label.clone().unwrap_or_default(), + descriptor.parent.label.clone(), )) } @@ -884,7 +954,7 @@ impl GPUDeviceMethods for GPUDevice { self.device, compare_enable, sampler, - descriptor.parent.label.clone().unwrap_or_default(), + descriptor.parent.label.clone(), ) } @@ -892,8 +962,8 @@ impl GPUDeviceMethods for GPUDevice { fn CreateRenderPipeline( &self, descriptor: &GPURenderPipelineDescriptor, - ) -> DomRoot<GPURenderPipeline> { - let (implicit_ids, desc) = self.parse_render_pipeline(&descriptor); + ) -> Fallible<DomRoot<GPURenderPipeline>> { + let (implicit_ids, desc) = self.parse_render_pipeline(&descriptor)?; let render_pipeline_id = self .global() @@ -913,12 +983,12 @@ impl GPUDeviceMethods for GPUDevice { let render_pipeline = webgpu::WebGPURenderPipeline(render_pipeline_id); - GPURenderPipeline::new( + Ok(GPURenderPipeline::new( &self.global(), render_pipeline, - descriptor.parent.parent.label.clone().unwrap_or_default(), + descriptor.parent.parent.label.clone(), self, - ) + )) } /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createrenderpipelineasync> @@ -926,10 +996,10 @@ impl GPUDeviceMethods for GPUDevice { &self, descriptor: &GPURenderPipelineDescriptor, comp: InRealm, - ) -> Rc<Promise> { - let promise = Promise::new_in_current_realm(comp); - let (implicit_ids, desc) = self.parse_render_pipeline(&descriptor); + ) -> Fallible<Rc<Promise>> { + let (implicit_ids, desc) = self.parse_render_pipeline(&descriptor)?; + let promise = Promise::new_in_current_realm(comp); let sender = response_async(&promise, self); let render_pipeline_id = self @@ -948,14 +1018,14 @@ impl GPUDeviceMethods for GPUDevice { }) .expect("Failed to create WebGPU render pipeline"); - promise + Ok(promise) } /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createrenderbundleencoder> fn CreateRenderBundleEncoder( &self, descriptor: &GPURenderBundleEncoderDescriptor, - ) -> DomRoot<GPURenderBundleEncoder> { + ) -> Fallible<DomRoot<GPURenderBundleEncoder>> { let desc = wgpu_com::RenderBundleEncoderDescriptor { label: convert_label(&descriptor.parent.parent), color_formats: Cow::Owned( @@ -963,16 +1033,24 @@ impl GPUDeviceMethods for GPUDevice { .parent .colorFormats .iter() - .map(|f| Some(convert_texture_format(*f))) - .collect::<Vec<_>>(), + .map(|format| { + self.validate_texture_format_required_features(format) + .map(|f| Some(f)) + }) + .collect::<Fallible<Vec<_>>>()?, ), - depth_stencil: descriptor.parent.depthStencilFormat.map(|dsf| { - wgt::RenderBundleDepthStencil { - format: convert_texture_format(dsf), - depth_read_only: descriptor.depthReadOnly, - stencil_read_only: descriptor.stencilReadOnly, - } - }), + depth_stencil: descriptor + .parent + .depthStencilFormat + .map(|dsf| { + self.validate_texture_format_required_features(&dsf) + .map(|format| wgt::RenderBundleDepthStencil { + format, + depth_read_only: descriptor.depthReadOnly, + stencil_read_only: descriptor.stencilReadOnly, + }) + }) + .transpose()?, sample_count: descriptor.parent.sampleCount, multiview: None, }; @@ -981,13 +1059,13 @@ impl GPUDeviceMethods for GPUDevice { let render_bundle_encoder = wgpu_com::RenderBundleEncoder::new(&desc, self.device.0, None).unwrap(); - GPURenderBundleEncoder::new( + Ok(GPURenderBundleEncoder::new( &self.global(), render_bundle_encoder, self, self.channel.clone(), - descriptor.parent.parent.label.clone().unwrap_or_default(), - ) + descriptor.parent.parent.label.clone(), + )) } /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-pusherrorscope> diff --git a/components/script/dom/gpurenderbundleencoder.rs b/components/script/dom/gpurenderbundleencoder.rs index 3a2880051a9..2a4d8c7bfaa 100644 --- a/components/script/dom/gpurenderbundleencoder.rs +++ b/components/script/dom/gpurenderbundleencoder.rs @@ -222,7 +222,7 @@ impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder { render_bundle, self.device.id(), self.channel.clone(), - descriptor.parent.label.clone().unwrap_or_default(), + descriptor.parent.label.clone(), ) } } diff --git a/components/script/dom/gpusupportedfeatures.rs b/components/script/dom/gpusupportedfeatures.rs index e0abd5b9def..1bf284b28b5 100644 --- a/components/script/dom/gpusupportedfeatures.rs +++ b/components/script/dom/gpusupportedfeatures.rs @@ -9,7 +9,7 @@ use std::str::FromStr; use dom_struct::dom_struct; use indexmap::IndexSet; use js::rust::HandleObject; -use webgpu::wgt; +use webgpu::wgt::Features; use super::bindings::like::Setlike; use crate::dom::bindings::cell::DomRefCell; @@ -39,43 +39,66 @@ pub struct GPUSupportedFeatures { // internal storage for features #[custom_trace] internal: DomRefCell<IndexSet<GPUFeatureName>>, + #[ignore_malloc_size_of = "defined in wgpu-types"] + #[no_trace] + features: Features, } impl GPUSupportedFeatures { fn new( global: &GlobalScope, proto: Option<HandleObject>, - features: wgt::Features, + features: Features, ) -> DomRoot<GPUSupportedFeatures> { let mut set = IndexSet::new(); - if features.contains(wgt::Features::DEPTH_CLIP_CONTROL) { + if features.contains(Features::DEPTH_CLIP_CONTROL) { set.insert(GPUFeatureName::Depth_clip_control); } - if features.contains(wgt::Features::DEPTH32FLOAT_STENCIL8) { + if features.contains(Features::DEPTH32FLOAT_STENCIL8) { set.insert(GPUFeatureName::Depth32float_stencil8); } - if features.contains(wgt::Features::PIPELINE_STATISTICS_QUERY) { - set.insert(GPUFeatureName::Pipeline_statistics_query); - } - if features.contains(wgt::Features::TEXTURE_COMPRESSION_BC) { + if features.contains(Features::TEXTURE_COMPRESSION_BC) { set.insert(GPUFeatureName::Texture_compression_bc); } - if features.contains(wgt::Features::TEXTURE_COMPRESSION_ETC2) { + // TODO: texture-compression-bc-sliced-3d when wgpu supports it + if features.contains(Features::TEXTURE_COMPRESSION_ETC2) { set.insert(GPUFeatureName::Texture_compression_etc2); } - if features.contains(wgt::Features::TEXTURE_COMPRESSION_ASTC) { + if features.contains(Features::TEXTURE_COMPRESSION_ASTC) { set.insert(GPUFeatureName::Texture_compression_astc); } - if features.contains(wgt::Features::TIMESTAMP_QUERY) { + if features.contains(Features::TIMESTAMP_QUERY) { set.insert(GPUFeatureName::Timestamp_query); } - if features.contains(wgt::Features::INDIRECT_FIRST_INSTANCE) { + if features.contains(Features::INDIRECT_FIRST_INSTANCE) { set.insert(GPUFeatureName::Indirect_first_instance); } + // While this feature exists in wgpu, it's not supported by naga yet + // https://github.com/gfx-rs/wgpu/issues/4384 + /* + if features.contains(Features::SHADER_F16) { + set.insert(GPUFeatureName::Shader_f16); + } + */ + if features.contains(Features::RG11B10UFLOAT_RENDERABLE) { + set.insert(GPUFeatureName::Rg11b10ufloat_renderable); + } + if features.contains(Features::BGRA8UNORM_STORAGE) { + set.insert(GPUFeatureName::Bgra8unorm_storage); + } + if features.contains(Features::FLOAT32_FILTERABLE) { + set.insert(GPUFeatureName::Float32_filterable); + } + // TODO: clip-distances when wgpu supports it + if features.contains(Features::DUAL_SOURCE_BLENDING) { + set.insert(GPUFeatureName::Dual_source_blending); + } + reflect_dom_object_with_proto( Box::new(GPUSupportedFeatures { reflector: Reflector::new(), internal: DomRefCell::new(set), + features, }), global, proto, @@ -86,29 +109,42 @@ impl GPUSupportedFeatures { pub fn Constructor( global: &GlobalScope, proto: Option<HandleObject>, - features: wgt::Features, + features: Features, ) -> Fallible<DomRoot<GPUSupportedFeatures>> { Ok(GPUSupportedFeatures::new(global, proto, features)) } } +impl GPUSupportedFeatures { + pub fn wgpu_features(&self) -> Features { + self.features + } +} + impl GPUSupportedFeaturesMethods for GPUSupportedFeatures { fn Size(&self) -> u32 { self.internal.size() } } -pub fn gpu_to_wgt_feature(feature: GPUFeatureName) -> Option<wgt::Features> { +pub fn gpu_to_wgt_feature(feature: GPUFeatureName) -> Option<Features> { match feature { - GPUFeatureName::Depth_clip_control => Some(wgt::Features::DEPTH_CLIP_CONTROL), - GPUFeatureName::Depth24unorm_stencil8 => None, - GPUFeatureName::Depth32float_stencil8 => Some(wgt::Features::DEPTH32FLOAT_STENCIL8), - GPUFeatureName::Pipeline_statistics_query => Some(wgt::Features::PIPELINE_STATISTICS_QUERY), - GPUFeatureName::Texture_compression_bc => Some(wgt::Features::TEXTURE_COMPRESSION_BC), - GPUFeatureName::Texture_compression_etc2 => Some(wgt::Features::TEXTURE_COMPRESSION_ETC2), - GPUFeatureName::Texture_compression_astc => Some(wgt::Features::TEXTURE_COMPRESSION_ASTC), - GPUFeatureName::Timestamp_query => Some(wgt::Features::TIMESTAMP_QUERY), - GPUFeatureName::Indirect_first_instance => Some(wgt::Features::INDIRECT_FIRST_INSTANCE), + GPUFeatureName::Depth_clip_control => Some(Features::DEPTH_CLIP_CONTROL), + GPUFeatureName::Depth32float_stencil8 => Some(Features::DEPTH32FLOAT_STENCIL8), + GPUFeatureName::Texture_compression_bc => Some(Features::TEXTURE_COMPRESSION_BC), + GPUFeatureName::Texture_compression_etc2 => Some(Features::TEXTURE_COMPRESSION_ETC2), + GPUFeatureName::Texture_compression_astc => Some(Features::TEXTURE_COMPRESSION_ASTC), + GPUFeatureName::Timestamp_query => Some(Features::TIMESTAMP_QUERY), + GPUFeatureName::Indirect_first_instance => Some(Features::INDIRECT_FIRST_INSTANCE), + // While this feature exists in wgpu, it's not supported by naga yet + // https://github.com/gfx-rs/wgpu/issues/4384 + GPUFeatureName::Shader_f16 => None, + GPUFeatureName::Rg11b10ufloat_renderable => Some(Features::RG11B10UFLOAT_RENDERABLE), + GPUFeatureName::Bgra8unorm_storage => Some(Features::BGRA8UNORM_STORAGE), + GPUFeatureName::Float32_filterable => Some(Features::FLOAT32_FILTERABLE), + GPUFeatureName::Dual_source_blending => Some(Features::DUAL_SOURCE_BLENDING), + GPUFeatureName::Texture_compression_bc_sliced_3d => None, + GPUFeatureName::Clip_distances => None, } } diff --git a/components/script/dom/gputexture.rs b/components/script/dom/gputexture.rs index a6d05aba973..9547f173d48 100644 --- a/components/script/dom/gputexture.rs +++ b/components/script/dom/gputexture.rs @@ -9,6 +9,7 @@ use dom_struct::dom_struct; use webgpu::wgc::resource; use webgpu::{wgt, WebGPU, WebGPURequest, WebGPUTexture, WebGPUTextureView}; +use super::bindings::error::Fallible; use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{ GPUExtent3DDict, GPUTextureAspect, GPUTextureDimension, GPUTextureFormat, GPUTextureMethods, @@ -18,9 +19,7 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::USVString; use crate::dom::globalscope::GlobalScope; -use crate::dom::gpuconvert::{ - convert_label, convert_texture_format, convert_texture_view_dimension, -}; +use crate::dom::gpuconvert::{convert_label, convert_texture_view_dimension}; use crate::dom::gpudevice::GPUDevice; use crate::dom::gputextureview::GPUTextureView; @@ -142,13 +141,19 @@ impl GPUTextureMethods for GPUTexture { } /// <https://gpuweb.github.io/gpuweb/#dom-gputexture-createview> - fn CreateView(&self, descriptor: &GPUTextureViewDescriptor) -> DomRoot<GPUTextureView> { + fn CreateView( + &self, + descriptor: &GPUTextureViewDescriptor, + ) -> Fallible<DomRoot<GPUTextureView>> { let desc = if !matches!(descriptor.mipLevelCount, Some(0)) && !matches!(descriptor.arrayLayerCount, Some(0)) { Some(resource::TextureViewDescriptor { label: convert_label(&descriptor.parent), - format: descriptor.format.map(convert_texture_format), + format: descriptor + .format + .map(|f| self.device.validate_texture_format_required_features(&f)) + .transpose()?, dimension: descriptor.dimension.map(convert_texture_view_dimension), range: wgt::ImageSubresourceRange { aspect: match descriptor.aspect { @@ -187,13 +192,13 @@ impl GPUTextureMethods for GPUTexture { let texture_view = WebGPUTextureView(texture_view_id); - GPUTextureView::new( + Ok(GPUTextureView::new( &self.global(), self.channel.clone(), texture_view, self, - descriptor.parent.label.clone().unwrap_or_default(), - ) + descriptor.parent.label.clone(), + )) } /// <https://gpuweb.github.io/gpuweb/#dom-gputexture-destroy> @@ -212,4 +217,44 @@ impl GPUTextureMethods for GPUTexture { }; self.destroyed.set(true); } + + /// <https://gpuweb.github.io/gpuweb/#dom-gputexture-width> + fn Width(&self) -> u32 { + self.texture_size.width + } + + /// <https://gpuweb.github.io/gpuweb/#dom-gputexture-height> + fn Height(&self) -> u32 { + self.texture_size.height + } + + /// <https://gpuweb.github.io/gpuweb/#dom-gputexture-depthorarraylayers> + fn DepthOrArrayLayers(&self) -> u32 { + self.texture_size.depthOrArrayLayers + } + + /// <https://gpuweb.github.io/gpuweb/#dom-gputexture-miplevelcount> + fn MipLevelCount(&self) -> u32 { + self.mip_level_count + } + + /// <https://gpuweb.github.io/gpuweb/#dom-gputexture-samplecount> + fn SampleCount(&self) -> u32 { + self.sample_count + } + + /// <https://gpuweb.github.io/gpuweb/#dom-gputexture-dimension> + fn Dimension(&self) -> GPUTextureDimension { + self.dimension + } + + /// <https://gpuweb.github.io/gpuweb/#dom-gputexture-format> + fn Format(&self) -> GPUTextureFormat { + self.format + } + + /// <https://gpuweb.github.io/gpuweb/#dom-gputexture-usage> + fn Usage(&self) -> u32 { + self.texture_usage + } } diff --git a/components/script/dom/webidls/WebGPU.webidl b/components/script/dom/webidls/WebGPU.webidl index e03d48c8211..db7889aff73 100644 --- a/components/script/dom/webidls/WebGPU.webidl +++ b/components/script/dom/webidls/WebGPU.webidl @@ -11,7 +11,7 @@ interface mixin GPUObjectBase { }; dictionary GPUObjectDescriptorBase { - USVString label; + USVString label = ""; }; [Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"] @@ -100,21 +100,26 @@ interface GPUAdapter { Promise<GPUAdapterInfo> requestAdapterInfo(optional sequence<DOMString> unmaskHints = []); }; -dictionary GPUDeviceDescriptor { +dictionary GPUDeviceDescriptor: GPUObjectDescriptorBase { sequence<GPUFeatureName> requiredFeatures = []; - record<DOMString, GPUSize64> requiredLimits; + record<DOMString, GPUSize64> requiredLimits;// = {}; }; enum GPUFeatureName { "depth-clip-control", - "depth24unorm-stencil8", "depth32float-stencil8", - "pipeline-statistics-query", "texture-compression-bc", + "texture-compression-bc-sliced-3d", "texture-compression-etc2", "texture-compression-astc", "timestamp-query", "indirect-first-instance", + "shader-f16", + "rg11b10ufloat-renderable", + "bgra8unorm-storage", + "float32-filterable", + "clip-distances", + "dual-source-blending", }; [Exposed=(Window, DedicatedWorker), /*Serializable,*/ Pref="dom.webgpu.enabled"] @@ -134,22 +139,24 @@ interface GPUDevice: EventTarget { [NewObject] GPUSampler createSampler(optional GPUSamplerDescriptor descriptor = {}); + [Throws] GPUBindGroupLayout createBindGroupLayout(GPUBindGroupLayoutDescriptor descriptor); GPUPipelineLayout createPipelineLayout(GPUPipelineLayoutDescriptor descriptor); GPUBindGroup createBindGroup(GPUBindGroupDescriptor descriptor); GPUShaderModule createShaderModule(GPUShaderModuleDescriptor descriptor); GPUComputePipeline createComputePipeline(GPUComputePipelineDescriptor descriptor); + [Throws] GPURenderPipeline createRenderPipeline(GPURenderPipelineDescriptor descriptor); [NewObject] Promise<GPUComputePipeline> createComputePipelineAsync(GPUComputePipelineDescriptor descriptor); - [NewObject] + [Throws, NewObject] Promise<GPURenderPipeline> createRenderPipelineAsync(GPURenderPipelineDescriptor descriptor); [NewObject] GPUCommandEncoder createCommandEncoder(optional GPUCommandEncoderDescriptor descriptor = {}); - [NewObject] + [Throws, NewObject] GPURenderBundleEncoder createRenderBundleEncoder(GPURenderBundleEncoderDescriptor descriptor); //[NewObject] //GPUQuerySet createQuerySet(GPUQuerySetDescriptor descriptor); @@ -199,10 +206,19 @@ interface GPUMapMode { [Exposed=(Window, DedicatedWorker), Serializable , Pref="dom.webgpu.enabled"] interface GPUTexture { - [NewObject] + [Throws, NewObject] GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {}); undefined destroy(); + + readonly attribute GPUIntegerCoordinateOut width; + readonly attribute GPUIntegerCoordinateOut height; + readonly attribute GPUIntegerCoordinateOut depthOrArrayLayers; + readonly attribute GPUIntegerCoordinateOut mipLevelCount; + readonly attribute GPUSize32Out sampleCount; + readonly attribute GPUTextureDimension dimension; + readonly attribute GPUTextureFormat format; + readonly attribute GPUFlagsConstant usage; }; GPUTexture includes GPUObjectBase; @@ -293,8 +309,10 @@ enum GPUTextureFormat { "bgra8unorm", "bgra8unorm-srgb", // Packed 32-bit formats + "rgb9e5ufloat", + "rgb10a2uint", "rgb10a2unorm", - "rg11b10float", + "rg11b10ufloat", // 64-bit formats "rg32uint", @@ -309,13 +327,16 @@ enum GPUTextureFormat { "rgba32sint", "rgba32float", - // Depth and stencil formats - //"stencil8", //TODO - //"depth16unorm", + // Depth/stencil formats + "stencil8", + "depth16unorm", "depth24plus", "depth24plus-stencil8", "depth32float", + // "depth32float-stencil8" feature + "depth32float-stencil8", + // BC compressed formats usable if "texture-compression-bc" is both // supported by the device/user agent and enabled in requestDevice. "bc1-rgba-unorm", @@ -333,11 +354,49 @@ enum GPUTextureFormat { "bc7-rgba-unorm", "bc7-rgba-unorm-srgb", - // "depth24unorm-stencil8" feature - //"depth24unorm-stencil8", - - // "depth32float-stencil8" feature - //"depth32float-stencil8", + // ETC2 compressed formats usable if "texture-compression-etc2" is both + // supported by the device/user agent and enabled in requestDevice. + "etc2-rgb8unorm", + "etc2-rgb8unorm-srgb", + "etc2-rgb8a1unorm", + "etc2-rgb8a1unorm-srgb", + "etc2-rgba8unorm", + "etc2-rgba8unorm-srgb", + "eac-r11unorm", + "eac-r11snorm", + "eac-rg11unorm", + "eac-rg11snorm", + + // ASTC compressed formats usable if "texture-compression-astc" is both + // supported by the device/user agent and enabled in requestDevice. + "astc-4x4-unorm", + "astc-4x4-unorm-srgb", + "astc-5x4-unorm", + "astc-5x4-unorm-srgb", + "astc-5x5-unorm", + "astc-5x5-unorm-srgb", + "astc-6x5-unorm", + "astc-6x5-unorm-srgb", + "astc-6x6-unorm", + "astc-6x6-unorm-srgb", + "astc-8x5-unorm", + "astc-8x5-unorm-srgb", + "astc-8x6-unorm", + "astc-8x6-unorm-srgb", + "astc-8x8-unorm", + "astc-8x8-unorm-srgb", + "astc-10x5-unorm", + "astc-10x5-unorm-srgb", + "astc-10x6-unorm", + "astc-10x6-unorm-srgb", + "astc-10x8-unorm", + "astc-10x8-unorm-srgb", + "astc-10x10-unorm", + "astc-10x10-unorm-srgb", + "astc-12x10-unorm", + "astc-12x10-unorm-srgb", + "astc-12x12-unorm", + "astc-12x12-unorm-srgb", }; [Exposed=(Window, DedicatedWorker), Pref="dom.webgpu.enabled"] @@ -547,7 +606,7 @@ interface mixin GPUPipelineBase { dictionary GPUProgrammableStage { required GPUShaderModule module; - required USVString entryPoint; + USVString entryPoint; }; [Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"] @@ -1160,6 +1219,12 @@ typedef [EnforceRange] unsigned long GPUIndex32; typedef [EnforceRange] unsigned long GPUSize32; typedef [EnforceRange] long GPUSignedOffset32; +typedef unsigned long long GPUSize64Out; +typedef unsigned long GPUIntegerCoordinateOut; +typedef unsigned long GPUSize32Out; + +typedef unsigned long GPUFlagsConstant; + dictionary GPUColorDict { required double r; required double g; |