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-public → mono-SkiaSharp).
Platform / Operating System
Windows, macOS, Linux, iOS, Mac Catalyst, WASM
Platform / Operating System Version
Azure DevOps hosted agents and container images
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
ganesh-glganesh-glWGL_ARB_*extensions, soWglContextcannot come upganesh-glganesh-glganesh-glganesh-glganesh-glganesh-glganesh-metal,graphite-metalganesh-metal,graphite-metalganesh-metal,graphite-metalMac2GPU family Skia requiresgraphite-dawnnavigator.gpu.requestAdapter()returns null — the DeviceRunners CLI'swasm testlaunches a headless browser with no WebGPU and exposes no browser-argument passthroughgraphite-dawnWhat still works
Not everything is opted out — these are genuinely covered and must stay green:
rasteron all 13 legsganesh-vulkan+graphite-vulkanon Windows, Linux, Android (including software lavapipe on Linux and SwiftShader on Windows)ganesh-direct3dandganesh-vulkan-sharpvkon WindowsWork items
1. Linux OpenGL — #4590. Put every class calling
SKTest.CreateGlContext()into one xUnit collection so GLX contexts are never created concurrently, mirroringGpuRenderingCollection(visual) andVulkanGpuRenderingCollection(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-dist-win) works — verified correct per-arch PE headers and the required WGL extensions present.opengl32.dll+libgallium_wgl.dllwould go intoSystem32/SysWOW64exactly as the Vulkan loader already does inscripts/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.Nativedoes not work — every published version ships 32-bit binaries inruntimes/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.shnow pins):requestAdapter()--disable-gpu(CI-like)--enable-unsafe-webgpu --use-webgpu-adapter=swiftshader--disable-gpuThe 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: truedoes 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:
ganesh-gl.linux— nothing; blocked on (1)graphite-metal.maccatalyst— nothing; blocked on (4)graphite-dawn.*— nothing on any platform; blocked on (5)graphite-metal.ios— 4 of 5 scenes (GradientBlendmissing, see [BUG] Metal is unusable on every CI host: macOS agent hangs on shutdown, Catalyst reports no GPU family, simulator cannot compile Graphite's gradient pipeline #4555)Definition of done
scripts/azure-templates-stages-test.ymlcontains noSKIASHARP_TEST_SKIP_GPUentries, andGpuPolicy.RequiredOnis 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-public→mono-SkiaSharp).Platform / Operating System
Windows, macOS, Linux, iOS, Mac Catalyst, WASM
Platform / Operating System Version
Azure DevOps hosted agents and container images