diff --git a/components/script/dom/gpucanvascontext.rs b/components/script/dom/gpucanvascontext.rs index 618cc885229..1309ca4c32d 100644 --- a/components/script/dom/gpucanvascontext.rs +++ b/components/script/dom/gpucanvascontext.rs @@ -19,7 +19,7 @@ use webrender_api::units::DeviceIntSize; use webrender_api::ImageKey; use super::bindings::codegen::Bindings::WebGPUBinding::{ - GPUCanvasAlphaMode, GPUTextureUsageConstants, + GPUCanvasAlphaMode, GPUTextureFormat, GPUTextureUsageConstants, }; use super::bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas; use super::bindings::error::{Error, Fallible}; @@ -104,6 +104,15 @@ impl HTMLCanvasElementOrOffscreenCanvas { } } +/// +fn supported_context_format(format: GPUTextureFormat) -> bool { + // TODO: GPUTextureFormat::Rgba16float + matches!( + format, + GPUTextureFormat::Bgra8unorm | GPUTextureFormat::Rgba8unorm + ) +} + #[derive(Clone, Debug, Default, JSTraceable, MallocSizeOf)] /// Helps observe changes on swapchain struct DrawingBuffer { @@ -340,15 +349,26 @@ impl GPUCanvasContextMethods for GPUCanvasContext { /// fn Configure(&self, configuration: &GPUCanvasConfiguration) -> Fallible<()> { - // Step 4 + // Step 1: Let device be configuration.device + let device = &configuration.device; + + // Step 5: Let descriptor be the GPUTextureDescriptor for the canvas and configuration. let descriptor = self.texture_descriptor_for_canvas(configuration); - // Step 2&3 - let (mut desc, _) = convert_texture_descriptor(&descriptor, &configuration.device)?; + // Step 2&3: Validate texture format required features + let (mut desc, _) = convert_texture_descriptor(&descriptor, device)?; desc.label = Some(Cow::Borrowed( "dummy texture for texture descriptor validation", )); + // Step 4: If Supported context formats does not contain configuration.format, throw a TypeError + if !supported_context_format(configuration.format) { + return Err(Error::Type(format!( + "Unsupported context format: {:?}", + configuration.format + ))); + } + // Step 5 self.configuration.replace(Some(configuration.clone())); @@ -363,7 +383,7 @@ impl GPUCanvasContextMethods for GPUCanvasContext { self.channel .0 .send(WebGPURequest::ValidateTextureDescriptor { - device_id: configuration.device.id().0, + device_id: device.id().0, texture_id, descriptor: desc, }) diff --git a/components/webgpu/swapchain.rs b/components/webgpu/swapchain.rs index 078ab280d3d..fe7f65dd61f 100644 --- a/components/webgpu/swapchain.rs +++ b/components/webgpu/swapchain.rs @@ -39,6 +39,17 @@ impl MallocSizeOf for WebGPUContextId { } } +impl ContextConfiguration { + fn format(&self) -> ImageFormat { + match self.format { + wgt::TextureFormat::Rgba8Unorm => ImageFormat::RGBA8, + wgt::TextureFormat::Bgra8Unorm => ImageFormat::BGRA8, + // TODO: wgt::TextureFormat::Rgba16Float + _ => unreachable!("Unsupported canvas context format in configuration"), + } + } +} + pub type WGPUImageMap = Arc>>; /// Presentation id encodes current configuration and current image @@ -383,17 +394,11 @@ impl crate::WGPU { let presentation_id = context_data.next_presentation_id(); context_data.check_and_update_presentation_id(presentation_id); - // If configuration is not provided or presentation format is not valid - // the context will be dummy until recreation - let format = config.as_ref().and_then(|config| match config.format { - wgt::TextureFormat::Rgba8Unorm => Some(ImageFormat::RGBA8), - wgt::TextureFormat::Bgra8Unorm => Some(ImageFormat::BGRA8), - _ => None, - }); - - let needs_image_update = if let Some(format) = format { - let config = config.expect("Config should exist when valid format is available"); - let new_image_desc = WebGPUImageDescriptor::new(format, size, config.is_opaque); + // If configuration is not provided + // the context will be dummy/empty until recreation + let needs_image_update = if let Some(config) = config { + let new_image_desc = + WebGPUImageDescriptor::new(config.format(), size, config.is_opaque); let needs_swapchain_rebuild = context_data.swap_chain.is_none() || new_image_desc.buffer_size() != context_data.image_desc.buffer_size(); if needs_swapchain_rebuild { diff --git a/components/webgpu/wgpu_thread.rs b/components/webgpu/wgpu_thread.rs index 5a69d12aa23..70ecb79d8e2 100644 --- a/components/webgpu/wgpu_thread.rs +++ b/components/webgpu/wgpu_thread.rs @@ -551,21 +551,7 @@ impl WGPU { { warn!("Unable to send FreeTexture({:?}) ({:?})", texture_id, e); }; - if let Some(error) = error { - self.dispatch_error(device_id, Error::from_error(error)); - continue; - } - // Supported context formats - // TODO: wgt::TextureFormat::Rgba16Float, when wr supports HDR - if !matches!( - descriptor.format, - wgt::TextureFormat::Bgra8Unorm | wgt::TextureFormat::Rgba8Unorm - ) { - self.dispatch_error( - device_id, - Error::Validation("Unsupported context format".to_string()), - ); - } + self.maybe_dispatch_wgpu_error(device_id, error); }, WebGPURequest::DestroyContext { context_id } => { self.destroy_context(context_id); diff --git a/tests/wpt/webgpu/meta/webgpu/cts.https.html.ini b/tests/wpt/webgpu/meta/webgpu/cts.https.html.ini index 3950b3b0ed7..cb2b6434640 100644 --- a/tests/wpt/webgpu/meta/webgpu/cts.https.html.ini +++ b/tests/wpt/webgpu/meta/webgpu/cts.https.html.ini @@ -10509,8 +10509,6 @@ [:format="bc1-rgba-unorm";canvasType="onscreen";enable_required_feature=false] [:format="bc1-rgba-unorm";canvasType="onscreen";enable_required_feature=true] - expected: - if os == "linux" and not debug: FAIL [:format="bc1-rgba-unorm-srgb";canvasType="offscreen";enable_required_feature=false] @@ -10519,8 +10517,6 @@ [:format="bc1-rgba-unorm-srgb";canvasType="onscreen";enable_required_feature=false] [:format="bc1-rgba-unorm-srgb";canvasType="onscreen";enable_required_feature=true] - expected: - if os == "linux" and not debug: FAIL [:format="bc2-rgba-unorm";canvasType="offscreen";enable_required_feature=false] @@ -10529,8 +10525,6 @@ [:format="bc2-rgba-unorm";canvasType="onscreen";enable_required_feature=false] [:format="bc2-rgba-unorm";canvasType="onscreen";enable_required_feature=true] - expected: - if os == "linux" and not debug: FAIL [:format="bc2-rgba-unorm-srgb";canvasType="offscreen";enable_required_feature=false] @@ -10539,8 +10533,6 @@ [:format="bc2-rgba-unorm-srgb";canvasType="onscreen";enable_required_feature=false] [:format="bc2-rgba-unorm-srgb";canvasType="onscreen";enable_required_feature=true] - expected: - if os == "linux" and not debug: FAIL [:format="bc3-rgba-unorm";canvasType="offscreen";enable_required_feature=false] @@ -10549,8 +10541,6 @@ [:format="bc3-rgba-unorm";canvasType="onscreen";enable_required_feature=false] [:format="bc3-rgba-unorm";canvasType="onscreen";enable_required_feature=true] - expected: - if os == "linux" and not debug: FAIL [:format="bc3-rgba-unorm-srgb";canvasType="offscreen";enable_required_feature=false] @@ -10559,8 +10549,6 @@ [:format="bc3-rgba-unorm-srgb";canvasType="onscreen";enable_required_feature=false] [:format="bc3-rgba-unorm-srgb";canvasType="onscreen";enable_required_feature=true] - expected: - if os == "linux" and not debug: FAIL [:format="bc4-r-snorm";canvasType="offscreen";enable_required_feature=false] @@ -10569,8 +10557,6 @@ [:format="bc4-r-snorm";canvasType="onscreen";enable_required_feature=false] [:format="bc4-r-snorm";canvasType="onscreen";enable_required_feature=true] - expected: - if os == "linux" and not debug: FAIL [:format="bc4-r-unorm";canvasType="offscreen";enable_required_feature=false] @@ -10579,8 +10565,6 @@ [:format="bc4-r-unorm";canvasType="onscreen";enable_required_feature=false] [:format="bc4-r-unorm";canvasType="onscreen";enable_required_feature=true] - expected: - if os == "linux" and not debug: FAIL [:format="bc5-rg-snorm";canvasType="offscreen";enable_required_feature=false] @@ -10589,8 +10573,6 @@ [:format="bc5-rg-snorm";canvasType="onscreen";enable_required_feature=false] [:format="bc5-rg-snorm";canvasType="onscreen";enable_required_feature=true] - expected: - if os == "linux" and not debug: FAIL [:format="bc5-rg-unorm";canvasType="offscreen";enable_required_feature=false] @@ -10599,8 +10581,6 @@ [:format="bc5-rg-unorm";canvasType="onscreen";enable_required_feature=false] [:format="bc5-rg-unorm";canvasType="onscreen";enable_required_feature=true] - expected: - if os == "linux" and not debug: FAIL [:format="bc6h-rgb-float";canvasType="offscreen";enable_required_feature=false] @@ -10609,8 +10589,6 @@ [:format="bc6h-rgb-float";canvasType="onscreen";enable_required_feature=false] [:format="bc6h-rgb-float";canvasType="onscreen";enable_required_feature=true] - expected: - if os == "linux" and not debug: FAIL [:format="bc6h-rgb-ufloat";canvasType="offscreen";enable_required_feature=false] @@ -10619,8 +10597,6 @@ [:format="bc6h-rgb-ufloat";canvasType="onscreen";enable_required_feature=false] [:format="bc6h-rgb-ufloat";canvasType="onscreen";enable_required_feature=true] - expected: - if os == "linux" and not debug: FAIL [:format="bc7-rgba-unorm";canvasType="offscreen";enable_required_feature=false] @@ -10629,8 +10605,6 @@ [:format="bc7-rgba-unorm";canvasType="onscreen";enable_required_feature=false] [:format="bc7-rgba-unorm";canvasType="onscreen";enable_required_feature=true] - expected: - if os == "linux" and not debug: FAIL [:format="bc7-rgba-unorm-srgb";canvasType="offscreen";enable_required_feature=false] @@ -10639,8 +10613,6 @@ [:format="bc7-rgba-unorm-srgb";canvasType="onscreen";enable_required_feature=false] [:format="bc7-rgba-unorm-srgb";canvasType="onscreen";enable_required_feature=true] - expected: - if os == "linux" and not debug: FAIL [:format="depth32float-stencil8";canvasType="offscreen";enable_required_feature=false] @@ -10649,8 +10621,6 @@ [:format="depth32float-stencil8";canvasType="onscreen";enable_required_feature=false] [:format="depth32float-stencil8";canvasType="onscreen";enable_required_feature=true] - expected: - if os == "linux" and not debug: FAIL [:format="eac-r11snorm";canvasType="offscreen";enable_required_feature=false] @@ -548643,88 +548613,48 @@ [:canvasType="onscreen";format="astc-8x8-unorm-srgb"] [:canvasType="onscreen";format="bc1-rgba-unorm"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="bc1-rgba-unorm-srgb"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="bc2-rgba-unorm"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="bc2-rgba-unorm-srgb"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="bc3-rgba-unorm"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="bc3-rgba-unorm-srgb"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="bc4-r-snorm"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="bc4-r-unorm"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="bc5-rg-snorm"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="bc5-rg-unorm"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="bc6h-rgb-float"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="bc6h-rgb-ufloat"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="bc7-rgba-unorm"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="bc7-rgba-unorm-srgb"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="bgra8unorm"] expected: if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="bgra8unorm-srgb"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="depth16unorm"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="depth24plus"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="depth24plus-stencil8"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="depth32float"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="depth32float-stencil8"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="eac-r11snorm"] @@ -548747,148 +548677,80 @@ [:canvasType="onscreen";format="etc2-rgba8unorm-srgb"] [:canvasType="onscreen";format="r16float"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="r16sint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="r16uint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="r32float"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="r32sint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="r32uint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="r8sint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="r8snorm"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="r8uint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="r8unorm"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rg11b10ufloat"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rg16float"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rg16sint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rg16uint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rg32float"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rg32sint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rg32uint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rg8sint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rg8snorm"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rg8uint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rg8unorm"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rgb10a2uint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rgb10a2unorm"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rgb9e5ufloat"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rgba16float"] expected: if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rgba16sint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rgba16uint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rgba32float"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rgba32sint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rgba32uint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rgba8sint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rgba8snorm"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rgba8uint"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rgba8unorm"] expected: if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="rgba8unorm-srgb"] - expected: - if os == "linux" and not debug: FAIL [:canvasType="onscreen";format="stencil8"] - expected: - if os == "linux" and not debug: FAIL [cts.https.html?q=webgpu:web_platform,canvas,configure:size_zero_after_configure:*]