webgpu: Simplify presentation and handle cleared in script (#38717)

There are many important changes here:

- Generalize the presentation buffer into standalone staging buffers
that hold their own state. This allow them to be used by getImage.
- Move all clear handling to the ScriptThread and send the configuration
on each request present/getimage, thus avoiding any recreate/clearing
messages. This means that we prepare staging buffers lazily, on the
first request.

Try run for this change:
https://github.com/sagudev/servo/actions/runs/17341982368
Testing: This is covered by existing WebGPU CTS tests. There are some
bad expectations updates, but they are also on main (presumably from
last update the rendering work) although I think CTS is actually wrong
(see https://github.com/gpuweb/cts/issues/4440).
Fixes: #36820
Fixes: #37705
Fixes: #33368 (we now keep reference alive in hashmap)

---------

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
Sam 2025-09-09 05:35:12 +02:00 committed by GitHub
parent 8d2723b2c9
commit 1f0f079203
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 1023 additions and 935 deletions

View file

@ -12,6 +12,7 @@ use ipc_channel::ipc::{IpcSender, IpcSharedMemory};
use pixels::IpcSnapshot;
use serde::{Deserialize, Serialize};
use webrender_api::ImageKey;
use webrender_api::euclid::default::Size2D;
use webrender_api::units::DeviceIntSize;
use wgpu_core::Label;
use wgpu_core::binding_model::{
@ -52,6 +53,13 @@ use crate::{
WebGPURenderPipelineResponse,
};
#[derive(Debug, Deserialize, Serialize)]
pub struct PendingTexture {
pub texture_id: TextureId,
pub encoder_id: CommandEncoderId,
pub configuration: ContextConfiguration,
}
#[derive(Debug, Deserialize, Serialize)]
pub enum WebGPURequest {
BufferMapAsync {
@ -152,22 +160,18 @@ pub enum WebGPURequest {
size: DeviceIntSize,
sender: IpcSender<(WebGPUContextId, ImageKey)>,
},
/// Recreates swapchain (if needed)
UpdateContext {
/// Present texture to WebRender
Present {
context_id: WebGPUContextId,
size: DeviceIntSize,
configuration: Option<ContextConfiguration>,
pending_texture: Option<PendingTexture>,
size: Size2D<u32>,
canvas_epoch: Epoch,
},
/// Reads texture to swapchains buffer and maps it
SwapChainPresent {
context_id: WebGPUContextId,
texture_id: TextureId,
encoder_id: CommandEncoderId,
canvas_epoch: Option<Epoch>,
},
/// Obtains image from latest presentation buffer (same as wr update)
/// Create [`pixels::Snapshot`] with contents of the last present operation
/// or provided pending texture and send it over provided [`IpcSender`].
GetImage {
context_id: WebGPUContextId,
pending_texture: Option<PendingTexture>,
sender: IpcSender<IpcSnapshot>,
},
ValidateTextureDescriptor {