Skip to content

Commit 4f37759

Browse files
Use explicit theory with runtime support check
1 parent 2115d36 commit 4f37759

3 files changed

Lines changed: 85 additions & 38 deletions

File tree

src/ImageSharp.Drawing.WebGPU/WebGPUDrawingBackend.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,24 @@ private enum PreparedBrushType : uint
7575
Recolor = 8,
7676
}
7777

78+
/// <summary>
79+
/// Gets a value indicating whether WebGPU is available on the current system.
80+
/// This probes the runtime by attempting to acquire an adapter and device.
81+
/// </summary>
82+
/// <returns><see langword="true"/> when WebGPU is functional; otherwise <see langword="false"/>.</returns>
83+
public static bool IsSupported()
84+
{
85+
try
86+
{
87+
using WebGPURuntime.Lease lease = WebGPURuntime.Acquire();
88+
return WebGPURuntime.TryGetOrCreateDevice(out _, out _, out _);
89+
}
90+
catch
91+
{
92+
return false;
93+
}
94+
}
95+
7896
/// <summary>
7997
/// Gets the testing-only diagnostic counter for total coverage preparation requests.
8098
/// </summary>

tests/ImageSharp.Drawing.Tests/Processing/Backends/WebGPUDrawingBackendTests.cs

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
33

4-
#if !ENV_CI_BAK
5-
// WebGPU is failing in our CI environment in Ubuntu with
6-
// WebGPU adapter request failed with status 'Unavailable'
7-
// It's also failing in Windows CI with "Test host process crashed : Fatal error.0xC0000005"
8-
// TODO: Ask the Silk.NET team for help.
94
using System.Numerics;
105
using SixLabors.Fonts;
116
using SixLabors.ImageSharp.Drawing.Processing;
127
using SixLabors.ImageSharp.Drawing.Processing.Backends;
8+
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities.Attributes;
139
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison;
1410
using SixLabors.ImageSharp.Memory;
1511
using SixLabors.ImageSharp.PixelFormats;
@@ -35,7 +31,7 @@ public class WebGPUDrawingBackendTests
3531
{ PixelColorBlendingMode.Normal, PixelAlphaCompositionMode.Clear }
3632
};
3733

38-
[Theory]
34+
[WebGPUTheory]
3935
[WithSolidFilledImages(512, 512, "White", PixelTypes.Rgba32)]
4036
public void FillPath_WithWebGPUCoverageBackend_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
4137
where TPixel : unmanaged, IPixel<TPixel>
@@ -89,7 +85,7 @@ public void FillPath_WithWebGPUCoverageBackend_MatchesDefaultOutput<TPixel>(Test
8985
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 1F);
9086
}
9187

92-
[Theory]
88+
[WebGPUTheory]
9389
[WithSolidFilledImages(512, 512, "White", PixelTypes.Rgba32)]
9490
public void FillPath_AliasedWithThreshold_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
9591
where TPixel : unmanaged, IPixel<TPixel>
@@ -129,7 +125,7 @@ public void FillPath_AliasedWithThreshold_MatchesDefaultOutput<TPixel>(TestImage
129125
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 1F);
130126
}
131127

132-
[Theory]
128+
[WebGPUTheory]
133129
[WithBasicTestPatternImages(384, 256, PixelTypes.Rgba32)]
134130
public void FillPath_WithImageBrush_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
135131
where TPixel : unmanaged, IPixel<TPixel>
@@ -190,7 +186,7 @@ void DrawAction(DrawingCanvas<TPixel> canvas)
190186
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 1F);
191187
}
192188

193-
[Theory]
189+
[WebGPUTheory]
194190
[WithSolidFilledImages(256, 256, "White", PixelTypes.Rgba32)]
195191
public void FillPath_WithNonZeroNestedContours_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
196192
where TPixel : unmanaged, IPixel<TPixel>
@@ -270,7 +266,7 @@ public void FillPath_WithNonZeroNestedContours_MatchesDefaultOutput<TPixel>(Test
270266
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.5F);
271267
}
272268

273-
[Theory]
269+
[WebGPUTheory]
274270
[WithBasicTestPatternImages(nameof(GraphicsOptionsModePairs), 384, 256, PixelTypes.Rgba32)]
275271
public void FillPath_WithGraphicsOptionsModes_SolidBrush_MatchesDefaultOutput<TPixel>(
276272
TestImageProvider<TPixel> provider,
@@ -325,7 +321,7 @@ public void FillPath_WithGraphicsOptionsModes_SolidBrush_MatchesDefaultOutput<TP
325321
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.1F);
326322
}
327323

328-
[Theory]
324+
[WebGPUTheory]
329325
[WithBasicTestPatternImages(nameof(GraphicsOptionsModePairs), 384, 256, PixelTypes.Rgba32)]
330326
public void FillPath_WithGraphicsOptionsModes_ImageBrush_MatchesDefaultOutput<TPixel>(
331327
TestImageProvider<TPixel> provider,
@@ -381,7 +377,7 @@ public void FillPath_WithGraphicsOptionsModes_ImageBrush_MatchesDefaultOutput<TP
381377
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.1F);
382378
}
383379

384-
[Theory]
380+
[WebGPUTheory]
385381
[WithSolidFilledImages(1200, 280, "White", PixelTypes.Rgba32)]
386382
public void DrawText_WithWebGPUCoverageBackend_RendersAndReleasesPreparedCoverage<TPixel>(TestImageProvider<TPixel> provider)
387383
where TPixel : unmanaged, IPixel<TPixel>
@@ -443,7 +439,7 @@ public void DrawText_WithWebGPUCoverageBackend_RendersAndReleasesPreparedCoverag
443439
AssertBackendTripletSimilarityInRegion(defaultImage, cpuRegionImage, nativeSurfaceImage, textRegion, 0.009F);
444440
}
445441

446-
[Theory]
442+
[WebGPUTheory]
447443
[WithSolidFilledImages(512, 512, "White", PixelTypes.Rgba32)]
448444
public void FillPath_WithWebGPUCoverageBackend_NativeSurface_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
449445
where TPixel : unmanaged, IPixel<TPixel>
@@ -487,7 +483,7 @@ void DrawAction(DrawingCanvas<TPixel> canvas)
487483
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.5F);
488484
}
489485

490-
[Theory]
486+
[WebGPUTheory]
491487
[WithSolidFilledImages(512, 512, "White", PixelTypes.Rgba32)]
492488
public void FillPath_WithWebGPUCoverageBackend_NativeSurfaceSubregion_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
493489
where TPixel : unmanaged, IPixel<TPixel>
@@ -533,7 +529,7 @@ void DrawAction(DrawingCanvas<TPixel> canvas)
533529
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.5F);
534530
}
535531

536-
[Theory]
532+
[WebGPUTheory]
537533
[WithBlankImage(220, 160, PixelTypes.Rgba32)]
538534
public void Process_WithWebGPUBackend_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
539535
where TPixel : unmanaged, IPixel<TPixel>
@@ -573,7 +569,7 @@ void DrawAction(DrawingCanvas<TPixel> canvas)
573569
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.0516F);
574570
}
575571

576-
[Theory]
572+
[WebGPUTheory]
577573
[WithBasicTestPatternImages(420, 220, PixelTypes.Rgba32)]
578574
public void DrawText_WithRepeatedGlyphs_UsesCoverageCache<TPixel>(TestImageProvider<TPixel> provider)
579575
where TPixel : unmanaged, IPixel<TPixel>
@@ -630,7 +626,7 @@ public void DrawText_WithRepeatedGlyphs_UsesCoverageCache<TPixel>(TestImageProvi
630626
AssertGpuPathWhenRequired(nativeSurfaceBackend);
631627
}
632628

633-
[Theory]
629+
[WebGPUTheory]
634630
[WithBlankImage(1200, 280, PixelTypes.Rgba32)]
635631
public void DrawText_WithRepeatedGlyphs_AfterClear_UsesBlendFastPath<TPixel>(TestImageProvider<TPixel> provider)
636632
where TPixel : unmanaged, IPixel<TPixel>
@@ -1032,7 +1028,7 @@ private static void AssertGpuPathWhenRequired(WebGPUDrawingBackend backend)
10321028
backend.TestingFallbackCompositeCoverageCallCount);
10331029
}
10341030

1035-
[Theory]
1031+
[WebGPUTheory]
10361032
[WithSolidFilledImages(400, 300, "White", PixelTypes.Rgba32)]
10371033
public void DrawPath_Stroke_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
10381034
where TPixel : unmanaged, IPixel<TPixel>
@@ -1084,7 +1080,7 @@ public void DrawPath_Stroke_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixe
10841080
LineJoin.Round
10851081
};
10861082

1087-
[Theory]
1083+
[WebGPUTheory]
10881084
[WithSolidFilledImages(400, 300, "White", PixelTypes.Rgba32, LineJoin.Miter)]
10891085
[WithSolidFilledImages(400, 300, "White", PixelTypes.Rgba32, LineJoin.MiterRevert)]
10901086
[WithSolidFilledImages(400, 300, "White", PixelTypes.Rgba32, LineJoin.MiterRound)]
@@ -1138,7 +1134,7 @@ public void DrawPath_Stroke_LineJoin_MatchesDefaultOutput<TPixel>(TestImageProvi
11381134
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.01F);
11391135
}
11401136

1141-
[Theory]
1137+
[WebGPUTheory]
11421138
[WithSolidFilledImages(400, 300, "White", PixelTypes.Rgba32, LineCap.Butt)]
11431139
[WithSolidFilledImages(400, 300, "White", PixelTypes.Rgba32, LineCap.Square)]
11441140
[WithSolidFilledImages(400, 300, "White", PixelTypes.Rgba32, LineCap.Round)]
@@ -1188,7 +1184,7 @@ public void DrawPath_Stroke_LineCap_MatchesDefaultOutput<TPixel>(TestImageProvid
11881184
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.01F);
11891185
}
11901186

1191-
[Theory]
1187+
[WebGPUTheory]
11921188
[WithSolidFilledImages(512, 512, "White", PixelTypes.Rgba32)]
11931189
public void FillPath_MultipleSeparatePaths_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
11941190
where TPixel : unmanaged, IPixel<TPixel>
@@ -1236,7 +1232,7 @@ void DrawAction(DrawingCanvas<TPixel> canvas)
12361232
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 1F);
12371233
}
12381234

1239-
[Theory]
1235+
[WebGPUTheory]
12401236
[WithSolidFilledImages(256, 256, "White", PixelTypes.Rgba32)]
12411237
public void FillPath_EvenOddRule_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
12421238
where TPixel : unmanaged, IPixel<TPixel>
@@ -1305,7 +1301,7 @@ public void FillPath_EvenOddRule_MatchesDefaultOutput<TPixel>(TestImageProvider<
13051301
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.5F);
13061302
}
13071303

1308-
[Theory]
1304+
[WebGPUTheory]
13091305
[WithSolidFilledImages(800, 600, "White", PixelTypes.Rgba32)]
13101306
public void FillPath_LargeTileCount_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
13111307
where TPixel : unmanaged, IPixel<TPixel>
@@ -1345,7 +1341,7 @@ public void FillPath_LargeTileCount_MatchesDefaultOutput<TPixel>(TestImageProvid
13451341
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 1F);
13461342
}
13471343

1348-
[Theory]
1344+
[WebGPUTheory]
13491345
[WithSolidFilledImages(300, 200, "White", PixelTypes.Rgba32)]
13501346
public void MultipleFlushes_OnSameBackend_ProduceCorrectResults<TPixel>(TestImageProvider<TPixel> provider)
13511347
where TPixel : unmanaged, IPixel<TPixel>
@@ -1460,7 +1456,7 @@ public void MultipleFlushes_OnSameBackend_ProduceCorrectResults<TPixel>(TestImag
14601456
}
14611457
}
14621458

1463-
[Theory]
1459+
[WebGPUTheory]
14641460
[WithSolidFilledImages(256, 256, "White", PixelTypes.Rgba32)]
14651461
public void FillPath_WithLinearGradientBrush_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
14661462
where TPixel : unmanaged, IPixel<TPixel>
@@ -1506,7 +1502,7 @@ public void FillPath_WithLinearGradientBrush_MatchesDefaultOutput<TPixel>(TestIm
15061502
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.005F);
15071503
}
15081504

1509-
[Theory]
1505+
[WebGPUTheory]
15101506
[WithSolidFilledImages(256, 256, "White", PixelTypes.Rgba32)]
15111507
public void FillPath_WithLinearGradientBrush_Repeat_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
15121508
where TPixel : unmanaged, IPixel<TPixel>
@@ -1551,7 +1547,7 @@ public void FillPath_WithLinearGradientBrush_Repeat_MatchesDefaultOutput<TPixel>
15511547
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.005F);
15521548
}
15531549

1554-
[Theory]
1550+
[WebGPUTheory]
15551551
[WithSolidFilledImages(256, 256, "White", PixelTypes.Rgba32)]
15561552
public void FillPath_WithRadialGradientBrush_SingleCircle_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
15571553
where TPixel : unmanaged, IPixel<TPixel>
@@ -1596,7 +1592,7 @@ public void FillPath_WithRadialGradientBrush_SingleCircle_MatchesDefaultOutput<T
15961592
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.005F);
15971593
}
15981594

1599-
[Theory]
1595+
[WebGPUTheory]
16001596
[WithSolidFilledImages(256, 256, "White", PixelTypes.Rgba32)]
16011597
public void FillPath_WithRadialGradientBrush_TwoCircle_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
16021598
where TPixel : unmanaged, IPixel<TPixel>
@@ -1643,7 +1639,7 @@ public void FillPath_WithRadialGradientBrush_TwoCircle_MatchesDefaultOutput<TPix
16431639
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.005F);
16441640
}
16451641

1646-
[Theory]
1642+
[WebGPUTheory]
16471643
[WithSolidFilledImages(256, 256, "White", PixelTypes.Rgba32)]
16481644
public void FillPath_WithEllipticGradientBrush_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
16491645
where TPixel : unmanaged, IPixel<TPixel>
@@ -1689,7 +1685,7 @@ public void FillPath_WithEllipticGradientBrush_MatchesDefaultOutput<TPixel>(Test
16891685
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.005F);
16901686
}
16911687

1692-
[Theory]
1688+
[WebGPUTheory]
16931689
[WithSolidFilledImages(256, 256, "White", PixelTypes.Rgba32)]
16941690
public void FillPath_WithSweepGradientBrush_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
16951691
where TPixel : unmanaged, IPixel<TPixel>
@@ -1737,7 +1733,7 @@ public void FillPath_WithSweepGradientBrush_MatchesDefaultOutput<TPixel>(TestIma
17371733
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.005F);
17381734
}
17391735

1740-
[Theory]
1736+
[WebGPUTheory]
17411737
[WithSolidFilledImages(256, 256, "White", PixelTypes.Rgba32)]
17421738
public void FillPath_WithSweepGradientBrush_PartialArc_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
17431739
where TPixel : unmanaged, IPixel<TPixel>
@@ -1783,7 +1779,7 @@ public void FillPath_WithSweepGradientBrush_PartialArc_MatchesDefaultOutput<TPix
17831779
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.005F);
17841780
}
17851781

1786-
[Theory]
1782+
[WebGPUTheory]
17871783
[WithSolidFilledImages(256, 256, "White", PixelTypes.Rgba32)]
17881784
public void FillPath_WithPatternBrush_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
17891785
where TPixel : unmanaged, IPixel<TPixel>
@@ -1823,7 +1819,7 @@ public void FillPath_WithPatternBrush_MatchesDefaultOutput<TPixel>(TestImageProv
18231819
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.005F);
18241820
}
18251821

1826-
[Theory]
1822+
[WebGPUTheory]
18271823
[WithSolidFilledImages(256, 256, "White", PixelTypes.Rgba32)]
18281824
public void FillPath_WithPatternBrush_Diagonal_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
18291825
where TPixel : unmanaged, IPixel<TPixel>
@@ -1863,7 +1859,7 @@ public void FillPath_WithPatternBrush_Diagonal_MatchesDefaultOutput<TPixel>(Test
18631859
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.005F);
18641860
}
18651861

1866-
[Theory]
1862+
[WebGPUTheory]
18671863
[WithSolidFilledImages(256, 256, "Red", PixelTypes.Rgba32)]
18681864
public void FillPath_WithRecolorBrush_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
18691865
where TPixel : unmanaged, IPixel<TPixel>
@@ -1903,7 +1899,7 @@ public void FillPath_WithRecolorBrush_MatchesDefaultOutput<TPixel>(TestImageProv
19031899
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.005F);
19041900
}
19051901

1906-
[Theory]
1902+
[WebGPUTheory]
19071903
[WithSolidFilledImages(256, 256, "White", PixelTypes.Rgba32)]
19081904
public void FillPath_WithLinearGradientBrush_ThreePoint_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
19091905
where TPixel : unmanaged, IPixel<TPixel>
@@ -1949,7 +1945,7 @@ public void FillPath_WithLinearGradientBrush_ThreePoint_MatchesDefaultOutput<TPi
19491945
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.005F);
19501946
}
19511947

1952-
[Theory]
1948+
[WebGPUTheory]
19531949
[WithSolidFilledImages(256, 256, "White", PixelTypes.Rgba32)]
19541950
public void FillPath_WithEllipticGradientBrush_Reflect_MatchesDefaultOutput<TPixel>(TestImageProvider<TPixel> provider)
19551951
where TPixel : unmanaged, IPixel<TPixel>
@@ -1996,7 +1992,7 @@ public void FillPath_WithEllipticGradientBrush_Reflect_MatchesDefaultOutput<TPix
19961992
AssertBackendTripletSimilarity(defaultImage, cpuRegionImage, nativeSurfaceImage, 0.005F);
19971993
}
19981994

1999-
[Theory]
1995+
[WebGPUTheory]
20001996
[WithSolidFilledImages(500, 400, "Black", PixelTypes.Rgba32)]
20011997
public void CanApplyPerspectiveTransform_StarWarsCrawl<TPixel>(TestImageProvider<TPixel> provider)
20021998
where TPixel : unmanaged, IPixel<TPixel>
@@ -2234,4 +2230,3 @@ private static Buffer2DRegion<TPixel> GetFrameRegion<TPixel>(Image<TPixel> image
22342230
where TPixel : unmanaged, IPixel<TPixel>
22352231
=> new(image.Frames.RootFrame.PixelBuffer, image.Bounds);
22362232
}
2237-
#endif
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
using SixLabors.ImageSharp.Drawing.Processing.Backends;
5+
6+
namespace SixLabors.ImageSharp.Drawing.Tests.TestUtilities.Attributes;
7+
8+
/// <summary>
9+
/// A <see cref="FactAttribute"/> that skips when WebGPU is not available on the current system.
10+
/// </summary>
11+
public class WebGPUFactAttribute : FactAttribute
12+
{
13+
public WebGPUFactAttribute()
14+
{
15+
if (!WebGPUDrawingBackend.IsSupported())
16+
{
17+
this.Skip = "WebGPU is not available on this system.";
18+
}
19+
}
20+
}
21+
22+
/// <summary>
23+
/// A <see cref="TheoryAttribute"/> that skips when WebGPU is not available on the current system.
24+
/// </summary>
25+
public class WebGPUTheoryAttribute : TheoryAttribute
26+
{
27+
public WebGPUTheoryAttribute()
28+
{
29+
if (!WebGPUDrawingBackend.IsSupported())
30+
{
31+
this.Skip = "WebGPU is not available on this system.";
32+
}
33+
}
34+
}

0 commit comments

Comments
 (0)