Graphite Dawn / WebGPU: non-finite clear color in beginRenderPass

79 views
Skip to first unread message

corey....@gmail.com

unread,
Feb 18, 2026, 3:57:51 PM (10 days ago) Feb 18
to skia-discuss
We’re seeing a crash when using Skia Graphite with the Dawn/WebGPU backend in a WASM app (many offscreen draws, ~36+ large images). The browser throws: 
Error: TypeError: The provided double value is non-finite
Location: Inside the browser’s GPUCommandEncoder.beginRenderPass() (Dawn/WebGPU validation).

We narrowed it down to a bad clear color. 
We hooked GPUCommandEncoder.prototype.beginRenderPass in JS to:
  1. Log the descriptor (including colorAttachments[].clearValue) when the call throws.
  1. Sanitize clearValue (clamp r,g,b,a to finite, default alpha to 1) before calling the real beginRenderPass.
After sanitizinclearValue, the crash stopped. When we let the original call throw and logged the descriptor, we saw a non-finite value in the clear color, e.g.:
  • clearValue{ r: ~1.7e-313, g: ~4.2e-317, b: null, a: ~5e-324 } (or similar garbage)
  • So at least one component (we saw b) was non-finite or null, which triggers the WebIDL “non-finite double” check and the exception.

The failu
re is coming from the render pass clear value passed into beginRenderPass, not from other parameters. Our app only uses Skia’s API (e.gcanvas->clear(SkColor)); we don’t build WebGPU render pass descriptors ourselves, so we’re assuming the non-finite clear value is produced in the Graphite/Dawn path when building the WebGPU render pass (e.g. when converting a clear color to the descriptor’s clearValue).


Questions
  • Has anyone else seen non-finite or garbage clear values in the Graphite Dawn → WebGPU path (e.g. under load or with many offscreen targets)?
  • Is there a known bug or planned fix in Skia/Dawn for ensuring render pass clear colors are always finite before calling the WebGPU API?

I believe we're at Skia 139.0.3

Thanks,

Corey

corey....@gmail.com

unread,
Feb 18, 2026, 8:55:03 PM (10 days ago) Feb 18
to skia-discuss
Reverted to the version we had previous and all is well. 134.0.14.  FWIW.

Michael Ludwig

unread,
Feb 19, 2026, 12:56:55 PM (9 days ago) Feb 19
to skia-discuss
Are you using `SkCanvas::clear(SkColor)` or `SkCanvas::clear(SkColor4f, sk_sp<SkColorSpace>)`?  Even if those colors (either 8-bit or floating point) are finite, if there is something about the colorspace conversion that is leading to non-finite values, that would be helpful in terms of where this bad color came from.  Skia has some best efforts to avoid non-finite values in geometry and bounding boxes, but I think colors are a bit of a missed area.  We do validate `SkShaders::Color` and `SkGradients::Foo` for finite color inputs, but I'm not seeing code for validating a paint's color or for validating that the outcome with colorspace conversion is valid. I think generally this may have stemmed from historically low impact to color values being non-finite (they'd be restricted to the pixels writing them, vs. geometry/bounds becoming non-finite possibly then leading to lots of rasterization that wasn't expected).

corey....@gmail.com

unread,
Feb 20, 2026, 8:30:31 AM (9 days ago) Feb 20
to skia-discuss
We never call it with a color space, always one argument and I've validated the colors.

Something changed between Skia 134 and 139 for sure to start causing this. I suppose I have no choice but to bisect Skia (kinda painful)? Nothing really jumps out in the release notes.

corey....@gmail.com

unread,
Feb 20, 2026, 9:58:17 AM (9 days ago) Feb 20
to skia-discuss
Good news — we were able to narrow this down significantly. The crash goes away entirely when we set fInternalMultisampleCount = 1 on the Graphite context options. With the default (4x MSAA), it crashes under load every time.

So the non-finite value isn't coming from our clear colors or any color space conversion on our side — it's coming from Skia's MSAA resolve emulation path internally. Since we're on Emscripten/WASM, Dawn doesn't have native MSAA resolve support, so Graphite takes the emulateLoadStoreResolveTexture path in DawnCommandBuffer. That path constructs a new render pass descriptor for the resolve blit, and somewhere in that process the fClearColor on the RenderPassDesc ends up with non-finite values that get passed straight through to wgpuCommandEncoderBeginRenderPass.

This is 100% a regression from m134 to m139 — the exact same application code worked fine before. Our commit is 87d8e1a22e2b6d8ed039a53091abfd81691e6eb6.

For now we can work around it by disabling MSAA locally but this isn't going to be able to be deployed so obviously that's not ideal long-term. Is there any chance someone on your side could take a look at the resolve emulation path? That would save us from having to bisect ~5 milestones of Skia commits, which is... not fun. Happy to provide any additional info that would help reproduce this.
Reply all
Reply to author
Forward
0 new messages