webgpu: Support more TextureFormats in GPUCanvasContext.configure() (#33504)

* `descriptor` -> `configuration` to match spec

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

* Support more `TextureFormat`s in `GPUCanvasContext.configure()`

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>

---------

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
Samson 2024-09-20 15:14:08 +02:00 committed by GitHub
parent 157e28c59b
commit 4bde9af515
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -201,26 +201,33 @@ impl GPUCanvasContextMethods for GPUCanvasContext {
} }
/// <https://gpuweb.github.io/gpuweb/#dom-gpucanvascontext-configure> /// <https://gpuweb.github.io/gpuweb/#dom-gpucanvascontext-configure>
fn Configure(&self, descriptor: &GPUCanvasConfiguration) -> Fallible<()> { fn Configure(&self, configuration: &GPUCanvasConfiguration) -> Fallible<()> {
// Step 1 is let // Step 1 is let
// Step 2 // Step 2
descriptor configuration
.device .device
.validate_texture_format_required_features(&descriptor.format)?; .validate_texture_format_required_features(&configuration.format)?;
let format = match descriptor.format { // Mapping between wr and wgpu can be determined by inspecting
GPUTextureFormat::Rgba8unorm | GPUTextureFormat::Rgba8unorm_srgb => ImageFormat::RGBA8, // https://github.com/gfx-rs/wgpu/blob/9b36a3e129da04b018257564d5129caff240cb75/wgpu-hal/src/gles/conv.rs#L10
// https://github.com/servo/webrender/blob/1e73f384a7a86e413f91e9e430436a9bd83381cd/webrender/src/device/gl.rs#L4064
let format = match configuration.format {
GPUTextureFormat::R8unorm => ImageFormat::R8,
GPUTextureFormat::Bgra8unorm | GPUTextureFormat::Bgra8unorm_srgb => ImageFormat::BGRA8, GPUTextureFormat::Bgra8unorm | GPUTextureFormat::Bgra8unorm_srgb => ImageFormat::BGRA8,
GPUTextureFormat::Rgba8unorm | GPUTextureFormat::Rgba8unorm_srgb => ImageFormat::RGBA8,
GPUTextureFormat::Rgba32float => ImageFormat::RGBAF32,
GPUTextureFormat::Rgba32sint => ImageFormat::RGBAI32,
GPUTextureFormat::Rg8unorm => ImageFormat::RG8,
_ => { _ => {
return Err(Error::Type(format!( return Err(Error::Type(format!(
"SwapChain format({:?}) not supported", "SwapChain format({:?}) not supported",
descriptor.format configuration.format
))) )))
}, },
}; };
// Step 3 // Step 3
for view_format in &descriptor.viewFormats { for view_format in &configuration.viewFormats {
descriptor configuration
.device .device
.validate_texture_format_required_features(view_format)?; .validate_texture_format_required_features(view_format)?;
} }
@ -228,16 +235,17 @@ impl GPUCanvasContextMethods for GPUCanvasContext {
// Step 4 // Step 4
let size = self.size(); let size = self.size();
let text_desc = GPUTextureDescriptor { let text_desc = GPUTextureDescriptor {
format: descriptor.format, format: configuration.format,
mipLevelCount: 1, mipLevelCount: 1,
sampleCount: 1, sampleCount: 1,
usage: descriptor.usage | GPUTextureUsageConstants::COPY_SRC, // TODO: specs // We need to add `COPY_SRC` so we can copy texture to presentation buffer
usage: configuration.usage | GPUTextureUsageConstants::COPY_SRC,
size: GPUExtent3D::GPUExtent3DDict(GPUExtent3DDict { size: GPUExtent3D::GPUExtent3DDict(GPUExtent3DDict {
width: size.width as u32, width: size.width as u32,
height: size.height as u32, height: size.height as u32,
depthOrArrayLayers: 1, depthOrArrayLayers: 1,
}), }),
viewFormats: descriptor.viewFormats.clone(), viewFormats: configuration.viewFormats.clone(),
// other members to default // other members to default
parent: GPUObjectDescriptorBase { parent: GPUObjectDescriptorBase {
label: USVString::default(), label: USVString::default(),
@ -253,15 +261,15 @@ impl GPUCanvasContextMethods for GPUCanvasContext {
buffer_ids.push( buffer_ids.push(
self.global() self.global()
.wgpu_id_hub() .wgpu_id_hub()
.create_buffer_id(descriptor.device.id().0.backend()), .create_buffer_id(configuration.device.id().0.backend()),
); );
} }
self.channel self.channel
.0 .0
.send(WebGPURequest::CreateSwapChain { .send(WebGPURequest::CreateSwapChain {
device_id: descriptor.device.id().0, device_id: configuration.device.id().0,
queue_id: descriptor.device.GetQueue().id().0, queue_id: configuration.device.GetQueue().id().0,
buffer_ids, buffer_ids,
context_id: self.context_id, context_id: self.context_id,
sender, sender,
@ -270,8 +278,9 @@ impl GPUCanvasContextMethods for GPUCanvasContext {
}) })
.expect("Failed to create WebGPU SwapChain"); .expect("Failed to create WebGPU SwapChain");
self.texture self.texture.set(Some(
.set(Some(&descriptor.device.CreateTexture(&text_desc).unwrap())); &configuration.device.CreateTexture(&text_desc).unwrap(),
));
self.webrender_image.set(Some(receiver.recv().unwrap())); self.webrender_image.set(Some(receiver.recv().unwrap()));
Ok(()) Ok(())