Skip to content

[Tracking] Re-enable the GPU backends currently opted out of CI (no OpenGL or Metal coverage anywhere) #4591

Description

@mattleibow

Description

Umbrella issue. #4575 made GPU backends required rather than silently skipped — a backend that cannot run must now be declared via SKIASHARP_TEST_SKIP_GPU, not inferred from a caught exception. That change did its job: it turned a set of invisible skips into a visible, enumerable list of gaps.

This issue tracks closing them. Every opt-out below is a coverage hole, each with a known cause. None of them existed as "we chose not to test this" — they were all previously skipping without anything in the build saying so.

Today CI has no OpenGL coverage anywhere, and no Metal coverage anywhere.

Current opt-outs

Leg Backends skipped Why Tracking
Linux ganesh-gl Nine test classes create GLX contexts concurrently → host crashes, exit 7, no results #4590
Windows (.NET Framework) ganesh-gl Agent ships only the generic OpenGL 1.1 implementation — no WGL_ARB_* extensions, so WglContext cannot come up this issue
Windows (.NET Core) ganesh-gl same this issue
Linux (Azure Linux) ganesh-gl container image has no X server, Mesa or ICD this issue
Linux (Azure Linux, No Deps) ganesh-gl same this issue
Linux (Alpine) ganesh-gl same this issue
Linux (Alpine, No Deps) ganesh-gl same this issue
Windows (Nano Server) ganesh-gl same this issue
macOS ganesh-metal, graphite-metal x64 pool virtualizes Metal; creating a device + queue leaves state that hangs the host on shutdown (job killed at the 180 min timeout, no TRX) #4555
iOS ganesh-metal, graphite-metal simulator's virtualized Metal; also cannot compile Graphite's gradient pipeline #4555
Mac Catalyst ganesh-metal, graphite-metal a Catalyst app never sees the Mac2 GPU family Skia requires #4555
WASM graphite-dawn navigator.gpu.requestAdapter() returns null — the DeviceRunners CLI's wasm test launches a headless browser with no WebGPU and exposes no browser-argument passthrough upstream (DeviceRunners)
WASM (.NET Preview) graphite-dawn same upstream (DeviceRunners)

What still works

Not everything is opted out — these are genuinely covered and must stay green:

  • raster on all 13 legs
  • ganesh-vulkan + graphite-vulkan on Windows, Linux, Android (including software lavapipe on Linux and SwiftShader on Windows)
  • ganesh-direct3d and ganesh-vulkan-sharpvk on Windows

Work items

1. Linux OpenGL — #4590. Put every class calling SKTest.CreateGlContext() into one xUnit collection so GLX contexts are never created concurrently, mirroring GpuRenderingCollection (visual) and VulkanGpuRenderingCollection (Vulkan). Then drop the Linux opt-out. This is the most tractable item and the one most likely to restore real coverage.

2. Windows OpenGL. The agents have no usable GL. Investigated during #4575:

  • Mesa (mesa-dist-win) works — verified correct per-arch PE headers and the required WGL extensions present. opengl32.dll + libgallium_wgl.dll would go into System32/SysWOW64 exactly as the Vulkan loader already does in scripts/infra/native/windows/install-vulkan-icd.ps1, and needs no test-code change. Blocker is that it has no trustworthy package feed — it would need mirroring.
  • Silk.NET.OpenGLES.ANGLE.Native does not work — every published version ships 32-bit binaries in runtimes/win-x64/. Verified across all 4 versions. Do not reach for it.

3. Container images. Same Mesa question as (2) but for Linux/Alpine images. Lower value — these images exist to prove SkiaSharp works without extra dependencies, so software GL there may be out of scope by design. Worth an explicit decision so the opt-out becomes intentional rather than pending.

4. Metal — #4555. All three Apple legs are virtualized and each fails differently. We already run device tests, so an Apple Silicon pool (or a real device for iOS) would likely resolve all three at once and is probably cheaper than chasing each symptom.

5. WASM / Dawn — upstream. Needs a browser-argument passthrough in the DeviceRunners CLI. Measured on Chrome 150 (the version scripts/infra/managed/install-chrome.sh now pins):

Flags requestAdapter()
--disable-gpu (CI-like) null
(none) ok — real GPU
--enable-unsafe-webgpu --use-webgpu-adapter=swiftshader ok — SwiftShader
the above plus --disable-gpu ok — SwiftShader

The last row matters: WebGPU works with no GPU at all, so this needs no special agent hardware — only the ability to pass the flags. forceFallbackAdapter: true does not help; the software adapter must be enabled at launch.

Golden coverage gaps

Independent of the opt-outs, these have no committed goldens, so re-enabling a backend also means harvesting and reviewing them:

Definition of done

scripts/azure-templates-stages-test.yml contains no SKIASHARP_TEST_SKIP_GPU entries, and GpuPolicy.RequiredOn is satisfied on every leg it names.

Partial progress is fine and expected — each row removed is a real gain. The opt-out mechanism is deliberately per-leg so items can be closed one at a time.

Related

Version of SkiaSharp

Nightly / CI.

IDE / Editor

N/A — CI only (dnceng-publicmono-SkiaSharp).

Platform / Operating System

Windows, macOS, Linux, iOS, Mac Catalyst, WASM

Platform / Operating System Version

Azure DevOps hosted agents and container images

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status
    New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions