xref: /aosp_15_r20/external/skia/tests/SkSLTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2021 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "include/core/SkBitmap.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkColor.h"
11 #include "include/core/SkData.h"
12 #include "include/core/SkImageInfo.h"
13 #include "include/core/SkPaint.h"
14 #include "include/core/SkRect.h"
15 #include "include/core/SkRefCnt.h"
16 #include "include/core/SkShader.h"
17 #include "include/core/SkSpan.h"
18 #include "include/core/SkString.h"
19 #include "include/core/SkSurface.h"
20 #include "include/core/SkTypes.h"
21 #include "include/effects/SkRuntimeEffect.h"
22 #include "include/gpu/GpuTypes.h"
23 #include "include/gpu/ganesh/GrDirectContext.h"
24 #include "include/gpu/ganesh/SkSurfaceGanesh.h"
25 #include "include/private/base/SkTArray.h"
26 #include "include/sksl/SkSLVersion.h"
27 #include "src/base/SkArenaAlloc.h"
28 #include "src/base/SkEnumBitMask.h"
29 #include "src/base/SkNoDestructor.h"
30 #include "src/base/SkStringView.h"
31 #include "src/core/SkRasterPipeline.h"
32 #include "src/core/SkRasterPipelineOpContexts.h"
33 #include "src/core/SkRasterPipelineOpList.h"
34 #include "src/core/SkRuntimeEffectPriv.h"
35 #include "src/gpu/ganesh/GrCaps.h"
36 #include "src/gpu/ganesh/GrDirectContextPriv.h"
37 #include "src/gpu/ganesh/GrShaderCaps.h"
38 #include "src/sksl/SkSLCompiler.h"
39 #include "src/sksl/SkSLProgramKind.h"
40 #include "src/sksl/SkSLProgramSettings.h"
41 #include "src/sksl/SkSLUtil.h"
42 #include "src/sksl/analysis/SkSLProgramVisitor.h"
43 #include "src/sksl/codegen/SkSLRasterPipelineBuilder.h"
44 #include "src/sksl/codegen/SkSLRasterPipelineCodeGenerator.h"
45 #include "src/sksl/ir/SkSLFunctionDeclaration.h"
46 #include "src/sksl/ir/SkSLModifierFlags.h"
47 #include "src/sksl/ir/SkSLProgram.h"
48 #include "src/sksl/ir/SkSLProgramElement.h"
49 #include "src/sksl/ir/SkSLStatement.h"
50 #include "src/sksl/ir/SkSLType.h"
51 #include "src/sksl/ir/SkSLVarDeclarations.h"
52 #include "src/sksl/ir/SkSLVariable.h"
53 #include "src/sksl/tracing/SkSLDebugTracePriv.h"
54 #include "tests/CtsEnforcement.h"
55 #include "tests/Test.h"
56 #include "tools/Resources.h"
57 
58 #include <algorithm>
59 #include <cstddef>
60 #include <cstdint>
61 #include <memory>
62 #include <regex>
63 #include <string>
64 #include <string_view>
65 #include <vector>
66 
67 #if defined(SK_GRAPHITE)
68 #include "include/gpu/graphite/Context.h"
69 #include "include/gpu/graphite/ContextOptions.h"
70 #include "include/gpu/graphite/Recorder.h"
71 #include "include/gpu/graphite/Surface.h"
72 #include "src/gpu/graphite/Caps.h"
73 #include "src/gpu/graphite/ContextPriv.h"
74 #include "tools/graphite/GraphiteTestContext.h"
75 #if defined(SK_DAWN)
76 #include "src/gpu/graphite/dawn/DawnCaps.h"
77 #endif
78 #endif
79 
80 using namespace skia_private;
81 
82 namespace SkSL { class Context; }
83 struct GrContextOptions;
84 
85 static constexpr int kWidth = 2;
86 static constexpr int kHeight = 2;
87 
88 enum class SkSLTestFlag : int {
89     /** `CPU` tests must pass when painted to a CPU-backed surface via SkRuntimeEffect. */
90     CPU     = 1 << 0,
91 
92     /**
93      * `ES3` tests must pass when executed directly on the CPU via the SkRasterPipeline backend.
94      * They aren't compatible with SkRuntimeEffect, since they use non-ES2 features.
95      */
96     ES3     = 1 << 1,
97 
98     /** `GPU` tests must pass when painted to a GPU-backed surface via SkRuntimeEffect. */
99     GPU     = 1 << 2,
100 
101     /** `GPU_ES3` tests must pass on ES3-compatible GPUs when "enforce ES2 restrictions" is off. */
102     GPU_ES3 = 1 << 3,
103 
104     /**
105      * `UsesNaN` tests rely on NaN values, so they are only expected to pass on GPUs that generate
106      * them (which is not a requirement, even with ES3).
107      */
108     UsesNaN = 1 << 4,
109 
110     /**
111      * `Priv` tests rely on `AllowPrivateAccess` support in the runtime effect.
112      */
113     Priv    = 1 << 5,
114 };
115 
116 using SkSLTestFlags = SkEnumBitMask<SkSLTestFlag>;
117 
is_cpu(SkSLTestFlags flags)118 static constexpr bool is_cpu(SkSLTestFlags flags) {
119     return SkToBool(flags & SkSLTestFlag::CPU);
120 }
121 
is_gpu(SkSLTestFlags flags)122 static constexpr bool is_gpu(SkSLTestFlags flags) {
123     return (flags & SkSLTestFlag::GPU) || (flags & SkSLTestFlag::GPU_ES3);
124 }
125 
is_strict_es2(SkSLTestFlags flags)126 static constexpr bool is_strict_es2(SkSLTestFlags flags) {
127     return !(flags & SkSLTestFlag::GPU_ES3) && !(flags & SkSLTestFlag::ES3);
128 }
129 
130 struct UniformData {
131     std::string_view    name;
132     SkSpan<const float> span;
133 };
134 
135 static constexpr float kUniformColorBlack[]    = {0.0f, 0.0f, 0.0f, 1.0f};
136 static constexpr float kUniformColorRed  []    = {1.0f, 0.0f, 0.0f, 1.0f};
137 static constexpr float kUniformColorGreen[]    = {0.0f, 1.0f, 0.0f, 1.0f};
138 static constexpr float kUniformColorBlue []    = {0.0f, 0.0f, 1.0f, 1.0f};
139 static constexpr float kUniformColorWhite[]    = {1.0f, 1.0f, 1.0f, 1.0f};
140 static constexpr float kUniformTestInputs[]    = {-1.25f, 0.0f, 0.75f, 2.25f};
141 static constexpr float kUniformUnknownInput[]  = {1.0f};
142 static constexpr float kUniformTestMatrix2x2[] = {1.0f, 2.0f,
143                                                   3.0f, 4.0f};
144 static constexpr float kUniformTestMatrix3x3[] = {1.0f, 2.0f, 3.0f,
145                                                   4.0f, 5.0f, 6.0f,
146                                                   7.0f, 8.0f, 9.0f};
147 static constexpr float kUniformTestMatrix4x4[] = {1.0f,  2.0f,  3.0f,  4.0f,
148                                                   5.0f,  6.0f,  7.0f,  8.0f,
149                                                   9.0f,  10.0f, 11.0f, 12.0f,
150                                                   13.0f, 14.0f, 15.0f, 16.0f};
151 static constexpr float kUniformTestArray[] = {1, 2, 3, 4, 5};
152 static constexpr float kUniformTestArrayNegative[] = {-1, -2, -3, -4, -5};
153 
154 static constexpr UniformData kUniformData[] = {
155         {"colorBlack", kUniformColorBlack},
156         {"colorRed", kUniformColorRed},
157         {"colorGreen", kUniformColorGreen},
158         {"colorBlue", kUniformColorBlue},
159         {"colorWhite", kUniformColorWhite},
160         {"testInputs", kUniformTestInputs},
161         {"unknownInput", kUniformUnknownInput},
162         {"testMatrix2x2", kUniformTestMatrix2x2},
163         {"testMatrix3x3", kUniformTestMatrix3x3},
164         {"testMatrix4x4", kUniformTestMatrix4x4},
165         {"testArray", kUniformTestArray},
166         {"testArrayNegative", kUniformTestArrayNegative},
167 };
168 
bitmap_from_shader(skiatest::Reporter * r,SkSurface * surface,sk_sp<SkRuntimeEffect> effect)169 static SkBitmap bitmap_from_shader(skiatest::Reporter* r,
170                                    SkSurface* surface,
171                                    sk_sp<SkRuntimeEffect> effect) {
172     SkRuntimeShaderBuilder builder(effect);
173     for (const UniformData& data : kUniformData) {
174         SkRuntimeShaderBuilder::BuilderUniform uniform = builder.uniform(data.name);
175         if (uniform.fVar) {
176             uniform.set(data.span.data(), data.span.size());
177         }
178     }
179 
180     if (SkRuntimeShaderBuilder::BuilderChild green = builder.child("shaderGreen"); green.fChild) {
181         green = SkShaders::Color(SK_ColorGREEN);
182     }
183 
184     if (SkRuntimeShaderBuilder::BuilderChild red = builder.child("shaderRed"); red.fChild) {
185         red = SkShaders::Color(SK_ColorRED);
186     }
187 
188     sk_sp<SkShader> shader = builder.makeShader();
189     if (!shader) {
190         return SkBitmap{};
191     }
192 
193     surface->getCanvas()->clear(SK_ColorBLACK);
194 
195     SkPaint paintShader;
196     paintShader.setShader(shader);
197     surface->getCanvas()->drawRect(SkRect::MakeWH(kWidth, kHeight), paintShader);
198 
199     SkBitmap bitmap;
200     REPORTER_ASSERT(r, bitmap.tryAllocPixels(surface->imageInfo()));
201     REPORTER_ASSERT(r, surface->readPixels(bitmap, /*srcX=*/0, /*srcY=*/0));
202     return bitmap;
203 }
204 
gpu_generates_nan(skiatest::Reporter * r,GrDirectContext * ctx)205 static bool gpu_generates_nan(skiatest::Reporter* r, GrDirectContext* ctx) {
206 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
207     // The Metal shader compiler (which is also used under-the-hood for some GL/GLES contexts on
208     // these platforms) enables fast-math by default. That prevents NaN-based tests from passing:
209     // https://developer.apple.com/documentation/metal/mtlcompileoptions/1515914-fastmathenabled
210     return false;
211 #else
212     // If we don't have infinity support, we definitely won't generate NaNs
213     if (!ctx->priv().caps()->shaderCaps()->fInfinitySupport) {
214         return false;
215     }
216 
217     auto effect = SkRuntimeEffect::MakeForShader(SkString(R"(
218         #version 300
219         uniform half4 colorGreen, colorRed;
220 
221         half4 main(float2 xy) {
222             return isnan(colorGreen.r / colorGreen.b) ? colorGreen : colorRed;
223         }
224     )")).effect;
225     REPORTER_ASSERT(r, effect);
226 
227     const SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
228     sk_sp<SkSurface> surface(SkSurfaces::RenderTarget(ctx, skgpu::Budgeted::kNo, info));
229 
230     SkBitmap bitmap = bitmap_from_shader(r, surface.get(), effect);
231     REPORTER_ASSERT(r, !bitmap.empty());
232 
233     SkColor color = bitmap.getColor(0, 0);
234     REPORTER_ASSERT(r, color == SK_ColorGREEN || color == SK_ColorRED);
235     return color == SK_ColorGREEN;
236 #endif
237 }
238 
load_source(skiatest::Reporter * r,const char * testFile,const char * permutationSuffix)239 static SkString load_source(skiatest::Reporter* r,
240                             const char* testFile,
241                             const char* permutationSuffix) {
242     SkString resourcePath = SkStringPrintf("sksl/%s", testFile);
243     sk_sp<SkData> shaderData = GetResourceAsData(resourcePath.c_str());
244     if (!shaderData) {
245         ERRORF(r, "%s%s: Unable to load file", testFile, permutationSuffix);
246         return SkString("");
247     }
248     return SkString{reinterpret_cast<const char*>(shaderData->bytes()), shaderData->size()};
249 }
250 
failure_is_expected(std::string_view deviceName,std::string_view backendAPI,std::string_view name,skiatest::TestType testType)251 static bool failure_is_expected(std::string_view deviceName,    // "Geforce RTX4090"
252                                 std::string_view backendAPI,    // "OpenGL"
253                                 std::string_view name,          // "MatrixToVectorCast"
254                                 skiatest::TestType testType) {  // skiatest::TestType::kGraphite
255     enum TestTypeMatcher { CPU, Ganesh, Graphite, GPU /* either Ganesh or Graphite */ };
256 
257     struct TestDisable {
258         std::optional<std::regex> deviceName;
259         std::optional<std::string_view> backendAPI;
260         std::optional<TestTypeMatcher> testTypeMatcher;
261         std::optional<bool> platform;
262     };
263 
264     using TestDisableMap = THashMap<std::string_view, std::vector<TestDisable>>;
265 
266     // TODO(b/40044139): migrate test-disable list from dm_flags into this map
267     static SkNoDestructor<TestDisableMap> testDisableMap{[] {
268         #define ADRENO "Adreno \\(TM\\) "
269         #define NVIDIA "(Tegra|Quadro|RTX|GTX) "
270 
271         TestDisableMap disables;
272         constexpr std::nullopt_t _ = std::nullopt;
273         using regex = std::regex;
274 
275 #if defined(SK_BUILD_FOR_UNIX)
276         constexpr bool kLinux = true;
277 #else
278         constexpr bool kLinux = false;
279 #endif
280 #if defined(SK_BUILD_FOR_MAC)
281         constexpr bool kMac = true;
282 #else
283         constexpr bool kMac = false;
284 #endif
285 #if defined(SK_BUILD_FOR_IOS)
286         constexpr bool kiOS = true;
287 #else
288         constexpr bool kiOS = false;
289 #endif
290 #if defined(SK_BUILD_FOR_WIN)
291         constexpr bool kWindows = true;
292 #else
293         constexpr bool kWindows = false;
294 #endif
295 #if defined(SK_BUILD_FOR_ANDROID)
296         constexpr bool kAndroid = true;
297 #else
298         constexpr bool kAndroid = false;
299 #endif
300 
301         // - Apple --------------------------------------------------------------------------------
302         // MacOS/iOS do not handle short-circuit evaluation properly in OpenGL (chromium:307751)
303         for (const char* test : {"LogicalAndShortCircuit",
304                                  "LogicalOrShortCircuit"}) {
305             disables[test].push_back({_, "OpenGL", GPU, kMac || kiOS});
306         }
307 
308         // ANGLE has a handful of Mac-specific bugs.
309         for (const char* test : {"MatrixScalarNoOpFolding",         // anglebug.com/7525
310                                  "MatrixScalarMath",                // anglebug.com/7525
311                                  "SwizzleIndexStore",               // Apple bug FB12055941
312                                  "OutParamsAreDistinctFromGlobal",  // anglebug.com/7145
313                                  "IntrinsicMixFloatES3"}) {         // anglebug.com/7245
314             disables[test].push_back({_, "ANGLE", GPU, kMac});
315         }
316 
317         // Switch fallthrough has some issues on iOS.
318         for (const char* test : {"SwitchWithFallthrough",
319                                  "SwitchWithFallthroughGroups"}) {
320             disables[test].push_back({_, "OpenGL", GPU, kiOS});
321         }
322 
323         // - ARM ----------------------------------------------------------------------------------
324         // Mali 400 is a very old driver its share of quirks, particularly in relation to matrices.
325         for (const char* test : {"Matrices",                // b/40043539
326                                  "MatrixNoOpFolding",
327                                  "MatrixScalarMath",        // b/40043764
328                                  "MatrixSwizzleStore",
329                                  "MatrixScalarNoOpFolding", // b/40044644
330                                  "UnaryPositiveNegative",
331                                  "Cross"}) {
332             disables[test].push_back({regex("Mali-400"), _, GPU, _});
333         }
334 
335         // - Nvidia -------------------------------------------------------------------------------
336         // Tegra3 has several issues, but the inability to break from a for loop is a common theme.
337         for (const char* test : {"Switch",                            // b/40043561
338                                  "SwitchDefaultOnly",                 //  "      "
339                                  "SwitchWithFallthrough",             //  "      "
340                                  "SwitchWithFallthroughAndVarDecls",  //  "      "
341                                  "SwitchWithFallthroughGroups",       //  "      "
342                                  "SwitchWithLoops",                   //  "      "
343                                  "SwitchCaseFolding",                 //  "      "
344                                  "LoopFloat",                         //  "      "
345                                  "LoopInt",                           //  "      "
346                                  "MatrixScalarNoOpFolding",           // b/40044644
347                                  "MatrixScalarMath",                  // b/40043764
348                                  "MatrixFoldingES2",                  // b/40043017
349                                  "MatrixEquality",                    // b/40043017
350                                  "IntrinsicFract",
351                                  "ModifiedStructParametersCannotBeInlined"}) {
352             disables[test].push_back({regex("Tegra 3"), _, GPU, _});
353         }
354 
355         // Various Nvidia GPUs generate errors when assembling weird matrices, and erroneously
356         // constant-fold expressions with side-effects in constructors when compiling GLSL.
357         for (const char* test : {"MatrixConstructorsES2",    // b/40043524
358                                  "MatrixConstructorsES3",    // b/40043524
359                                  "MatrixScalarNoOpFolding",  // b/40044644
360                                  "PreserveSideEffects",      // b/40044140
361                                  "StructFieldNoFolding"}) {  // b/40044479
362             disables[test].push_back({regex(NVIDIA), "OpenGL", _, _});
363             disables[test].push_back({regex(NVIDIA), "ANGLE GL", _, _});
364         }
365 
366         disables["IntrinsicMixFloatES3"].push_back({regex("RTX "), "Vulkan", _, kWindows});
367 
368         // The Golo features P400s with older and buggier drivers than usual.
369         for (const char* test : {"PreserveSideEffects",  // b/40044140
370                                  "CommaSideEffects"}) {
371             disables[test].push_back({regex("Quadro P400"), _, _, kLinux});
372         }
373 
374         // b/318725123
375         for (const char* test : {"UniformArray",
376                                  "TemporaryIndexLookup",
377                                  "MatrixIndexLookup"}) {
378             disables[test].push_back({regex("Quadro P400"), "Dawn Vulkan", Graphite, kWindows});
379         }
380 
381         // - PowerVR ------------------------------------------------------------------------------
382         for (const char* test : {"OutParamsAreDistinct",              // b/40044222
383                                  "OutParamsAreDistinctFromGlobal"}) {
384             disables[test].push_back({regex("PowerVR Rogue GE8300"), _, GPU, _});
385         }
386 
387         // - Radeon -------------------------------------------------------------------------------
388         for (const char* test : {"DeadReturnES3",              // b/301326132
389                                  "IntrinsicAll",               // b/40045114
390                                  "MatrixConstructorsES3",      // b/40043524
391                                  "MatrixScalarNoOpFolding",    // b/40044644
392                                  "StructIndexStore",           // b/40045236
393                                  "SwizzleIndexLookup",         // b/40045254
394                                  "SwizzleIndexStore"}) {       // b/40045254
395             disables[test].push_back({regex("Radeon.*(R9|HD)"), "OpenGL", GPU, _});
396             disables[test].push_back({regex("Radeon.*(R9|HD)"), "ANGLE GL", GPU, _});
397         }
398 
399         // The Radeon Vega 6 doesn't return zero for the derivative of a uniform.
400         for (const char* test : {"IntrinsicDFdy",
401                                  "IntrinsicDFdx",
402                                  "IntrinsicFwidth"}) {
403             disables[test].push_back({regex("AMD RADV RENOIR"), _, GPU, _});
404         }
405 
406         // - Adreno -------------------------------------------------------------------------------
407         // Disable broken tests on Android with Adreno GPUs (b/40043413, b/40045254)
408         for (const char* test : {"ArrayCast",
409                                  "ArrayComparison",
410                                  "CommaSideEffects",
411                                  "IntrinsicMixFloatES2",
412                                  "IntrinsicClampFloat",
413                                  "SwitchWithFallthrough",
414                                  "SwitchWithFallthroughGroups",
415                                  "SwizzleIndexLookup",
416                                  "SwizzleIndexStore"}) {
417             disables[test].push_back({regex(ADRENO "[3456]"), _, _, kAndroid});
418         }
419         for (const char* test : {"SwitchWithFallthroughGroups",
420                                  "SwizzleIndexLookup",
421                                  "SwizzleIndexStore"}) {
422             disables[test].push_back({regex(ADRENO "[7]"), _, _, kAndroid});
423         }
424 
425         // Older Adreno 5/6xx drivers report a pipeline error or silently fail when handling inouts.
426         for (const char* test : {"VoidInSequenceExpressions",  // b/295217166
427                                  "InoutParameters",            // b/40043966
428                                  "OutParams",
429                                  "OutParamsDoubleSwizzle",
430                                  "OutParamsNoInline",
431                                  "OutParamsFunctionCallInArgument"}) {
432             disables[test].push_back({regex(ADRENO "[56]"), "Vulkan", _, kAndroid});
433         }
434 
435         for (const char* test : {"MatrixToVectorCast",     // b/40043288
436                                  "StructsInFunctions"}) {  // b/40043024
437             disables[test].push_back({regex(ADRENO "[345]"), "OpenGL", _, kAndroid});
438         }
439 
440         // Constructing a matrix from vectors and scalars can be surprisingly finicky (b/40043539)
441         for (const char* test : {"Matrices",
442                                  "MatrixNoOpFolding"}) {
443             disables[test].push_back({regex(ADRENO "3"), "OpenGL", _, kAndroid});
444         }
445 
446         // Adreno 600 doesn't handle isinf() in OpenGL correctly. (b/40043464)
447         disables["IntrinsicIsInf"].push_back({regex(ADRENO "6"), "OpenGL", _, kAndroid});
448 
449         // Older Adreno drivers crash when presented with an empty block (b/40044390)
450         disables["EmptyBlocksES3"].push_back({regex(ADRENO "(540|630)"), _, _, kAndroid});
451 
452         // Adrenos alias out-params to globals improperly (b/40044222)
453         disables["OutParamsAreDistinctFromGlobal"].push_back({regex(ADRENO "[3456]"), "OpenGL",
454                                                               _, kAndroid});
455         // Adreno generates the wrong result for this test. (b/40044477)
456         disables["StructFieldFolding"].push_back({regex(ADRENO "[56]"), "OpenGL",
457                                                         _, kAndroid});
458 
459         // b/318726662
460         for (const char* test : {"PrefixExpressionsES2",
461                                  "MatrixToVectorCast",
462                                  "MatrixConstructorsES2"}) {
463             disables[test].push_back({regex(ADRENO "620"), "Vulkan", Graphite, kAndroid});
464         }
465 
466         // - Intel --------------------------------------------------------------------------------
467         // Disable various tests on Intel.
468         // Intrinsic floor() on Intel + ANGLE + DirectX is broken (anglebug.com/5588)
469         disables["IntrinsicFloor"].push_back({regex("Intel.*(Iris|HD)"), "ANGLE D3D", _, _});
470 
471         // Intrinsic not() and mix() are broken on Intel GPUs in Metal. (b/40045105)
472         for (const char* test : {"IntrinsicNot",
473                                  "IntrinsicMixFloatES3"}) {
474             disables[test].push_back({regex("Intel.*(Iris|6000)"), "Metal", _, kMac});
475         }
476 
477         // Swizzled-index store is broken across many Intel GPUs. (b/40045254)
478         disables["SwizzleIndexStore"].push_back({regex("Intel"), "OpenGL", _, kMac});
479         disables["SwizzleIndexStore"].push_back({regex("Intel.*Iris"), _, _, kWindows});
480 
481         // vec4(mat2) conversions can lead to a crash on Intel + ANGLE (b/40043275)
482         for (const char* test : {"VectorToMatrixCast",
483                                  "VectorScalarMath",
484                                  "TrivialArgumentsInlineDirectly"}) {
485             disables[test].push_back({regex("Intel"), "ANGLE", _, kWindows});
486         }
487 
488         for (const char* test : {"MatrixFoldingES2",
489                                  "MatrixEquality",
490                                  "TemporaryIndexLookup",  // b/40045228
491                                  "SwizzleIndexLookup"}) { // b/40045254
492             disables[test].push_back({regex("Intel.*(Iris|4400)"), "OpenGL", _, kWindows});
493             disables[test].push_back({regex("Intel.*(Iris|4400)"), "ANGLE",  _, kWindows});
494         }
495 
496         for (const char* test : {"ReturnsValueOnEveryPathES3",      // b/40043548
497                                  "OutParamsAreDistinctFromGlobal",  // b/40044222
498                                  "StructFieldFolding"}) {           // b/40044477
499             disables[test].push_back({regex("Intel"), "OpenGL", _, kWindows});
500             disables[test].push_back({regex("Intel"), "ANGLE GL", _, kWindows});
501         }
502 
503         for (const char* test : {"SwitchDefaultOnly",               // b/40043548
504                                  "ReturnsValueOnEveryPathES3"}) {   // b/40045205
505             disables[test].push_back({regex("Intel"), "Vulkan", _, kLinux});
506         }
507 
508         for (const char* test : {"SwitchDefaultOnly"}) {
509             disables[test].push_back({regex("Intel"), "ANGLE", _, kWindows});
510         }
511 
512         for (const char* test : {"SwizzleAsLValueES3"}) {  // https://anglebug.com/8260
513             disables[test].push_back({regex("Intel"), _, _, kWindows});
514             disables[test].push_back({_, "ANGLE", _, kWindows});
515         }
516 
517         // Some Intel GPUs don't return zero for the derivative of a uniform.
518         for (const char* test : {"IntrinsicDFdy",
519                                  "IntrinsicDFdx",
520                                  "IntrinsicFwidth"}) {
521             disables[test].push_back({regex("Intel"), _, GPU, _});
522         }
523 
524         disables["LoopFloat"].push_back({regex("Intel.*(Iris|6000)"), _, _, kMac});  // b/40043507
525 
526         #undef ADRENO
527         #undef NVIDIA
528 
529         return disables;
530     }()};
531 
532     if (const std::vector<TestDisable>* testDisables = testDisableMap->find(name)) {
533         for (const TestDisable& d : *testDisables) {
534             if (d.platform.has_value() && !*d.platform) {
535                 continue;  // disable applies to a different platform
536             }
537             if (d.backendAPI.has_value() && !skstd::contains(backendAPI, *d.backendAPI)) {
538                 continue;  // disable applies to a different backend API
539             }
540             if (d.deviceName.has_value() &&
541                 !std::regex_search(deviceName.begin(), deviceName.end(), *d.deviceName)) {
542                 continue;  // disable applies to a different device
543             }
544             if (d.testTypeMatcher == CPU && testType != skiatest::TestType::kCPU) {
545                 continue;  // disable only applies to CPU
546             }
547             if (d.testTypeMatcher == Ganesh && testType != skiatest::TestType::kGanesh) {
548                 continue;  // disable only applies to Ganesh
549             }
550             if (d.testTypeMatcher == Graphite && testType != skiatest::TestType::kGraphite) {
551                 continue;  // disable only applies to Graphites
552             }
553             if (d.testTypeMatcher == GPU && testType == skiatest::TestType::kCPU) {
554                 continue;  // disable only applies to GPU
555             }
556             // This test was disabled.
557             return true;
558         }
559     }
560 
561     // This test was not in our disable list.
562     return false;
563 }
564 
test_one_permutation(skiatest::Reporter * r,std::string_view deviceName,std::string_view backendAPI,SkSurface * surface,const char * name,const char * testFile,skiatest::TestType testType,const char * permutationSuffix,const SkRuntimeEffect::Options & options)565 static void test_one_permutation(skiatest::Reporter* r,
566                                  std::string_view deviceName,
567                                  std::string_view backendAPI,
568                                  SkSurface* surface,
569                                  const char* name,
570                                  const char* testFile,
571                                  skiatest::TestType testType,
572                                  const char* permutationSuffix,
573                                  const SkRuntimeEffect::Options& options) {
574     SkString shaderString = load_source(r, testFile, permutationSuffix);
575     if (shaderString.isEmpty()) {
576         return;
577     }
578     SkRuntimeEffect::Result result = SkRuntimeEffect::MakeForShader(shaderString, options);
579     if (!result.effect) {
580         ERRORF(r, "%s%s: %s", testFile, permutationSuffix, result.errorText.c_str());
581         return;
582     }
583     if (failure_is_expected(deviceName, backendAPI, name, testType)) {
584         // Some driver bugs can be catastrophic (e.g. crashing dm entirely), so we don't even try to
585         // run a shader if we expect that it might fail.
586         SkDebugf("%s: skipped %.*s%s\n", testFile, (int)backendAPI.size(), backendAPI.data(),
587                                          permutationSuffix);
588         return;
589     }
590 
591     SkBitmap bitmap = bitmap_from_shader(r, surface, result.effect);
592     if (bitmap.empty()) {
593         ERRORF(r, "%s%s: Unable to build shader", testFile, permutationSuffix);
594         return;
595     }
596 
597     bool success = true;
598     SkColor color[kHeight][kWidth];
599     for (int y = 0; y < kHeight; ++y) {
600         for (int x = 0; x < kWidth; ++x) {
601             color[y][x] = bitmap.getColor(x, y);
602             if (color[y][x] != SK_ColorGREEN) {
603                 success = false;
604             }
605         }
606     }
607 
608     if (!success) {
609         static_assert(kWidth  == 2);
610         static_assert(kHeight == 2);
611 
612         SkString message = SkStringPrintf("Expected%s: solid green. Actual output from %.*s using "
613                                           "%.*s:\n"
614                                           "RRGGBBAA RRGGBBAA\n"
615                                           "%02X%02X%02X%02X %02X%02X%02X%02X\n"
616                                           "%02X%02X%02X%02X %02X%02X%02X%02X",
617                                           permutationSuffix,
618                                           (int)deviceName.size(), deviceName.data(),
619                                           (int)backendAPI.size(), backendAPI.data(),
620 
621                                           SkColorGetR(color[0][0]), SkColorGetG(color[0][0]),
622                                           SkColorGetB(color[0][0]), SkColorGetA(color[0][0]),
623 
624                                           SkColorGetR(color[0][1]), SkColorGetG(color[0][1]),
625                                           SkColorGetB(color[0][1]), SkColorGetA(color[0][1]),
626 
627                                           SkColorGetR(color[1][0]), SkColorGetG(color[1][0]),
628                                           SkColorGetB(color[1][0]), SkColorGetA(color[1][0]),
629 
630                                           SkColorGetR(color[1][1]), SkColorGetG(color[1][1]),
631                                           SkColorGetB(color[1][1]), SkColorGetA(color[1][1]));
632 
633         ERRORF(r, "%s", message.c_str());
634     }
635 }
636 
test_permutations(skiatest::Reporter * r,std::string_view deviceName,std::string_view backendAPI,SkSurface * surface,const char * name,const char * testFile,skiatest::TestType testType,bool strictES2,bool privateAccess)637 static void test_permutations(skiatest::Reporter* r,
638                               std::string_view deviceName,
639                               std::string_view backendAPI,
640                               SkSurface* surface,
641                               const char* name,
642                               const char* testFile,
643                               skiatest::TestType testType,
644                               bool strictES2,
645                               bool privateAccess) {
646     SkRuntimeEffect::Options options = strictES2 ? SkRuntimeEffect::Options{}
647                                                  : SkRuntimeEffectPriv::ES3Options();
648     if (privateAccess) {
649         SkRuntimeEffectPriv::AllowPrivateAccess(&options);
650     }
651     options.forceUnoptimized = false;
652     test_one_permutation(r, deviceName, backendAPI, surface, name, testFile, testType, "", options);
653 
654     options.forceUnoptimized = true;
655     test_one_permutation(r, deviceName, backendAPI, surface, name, testFile, testType,
656                          " (Unoptimized)", options);
657 }
658 
test_cpu(skiatest::Reporter * r,const char * name,const char * testFile,SkSLTestFlags flags)659 static void test_cpu(skiatest::Reporter* r,
660                      const char* name,
661                      const char* testFile,
662                      SkSLTestFlags flags) {
663     SkASSERT(flags & SkSLTestFlag::CPU);
664 
665     // Create a raster-backed surface.
666     const SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
667     sk_sp<SkSurface> surface(SkSurfaces::Raster(info));
668     bool privateAccess = bool(flags & SkSLTestFlag::Priv);
669 
670     test_permutations(r, "CPU", "SkRP", surface.get(), name, testFile,
671                       skiatest::TestType::kCPU, /*strictES2=*/true, privateAccess);
672 }
673 
674 #if defined(SK_GANESH)
test_ganesh(skiatest::Reporter * r,const sk_gpu_test::ContextInfo & ctxInfo,const char * name,const char * testFile,SkSLTestFlags flags)675 static void test_ganesh(skiatest::Reporter* r,
676                         const sk_gpu_test::ContextInfo& ctxInfo,
677                         const char* name,
678                         const char* testFile,
679                         SkSLTestFlags flags) {
680     GrDirectContext *ctx = ctxInfo.directContext();
681 
682     // If this is an ES3-only test on a GPU which doesn't support SkSL ES3, return immediately.
683     bool shouldRunGPU = SkToBool(flags & SkSLTestFlag::GPU);
684     bool shouldRunGPU_ES3 =
685             (flags & SkSLTestFlag::GPU_ES3) &&
686             (ctx->priv().caps()->shaderCaps()->supportedSkSLVerion() >= SkSL::Version::k300);
687     if (!shouldRunGPU && !shouldRunGPU_ES3) {
688         return;
689     }
690 
691     // If this is a test that requires the GPU to generate NaN values, check for that first.
692     if (flags & SkSLTestFlag::UsesNaN) {
693         if (!gpu_generates_nan(r, ctx)) {
694             return;
695         }
696     }
697 
698     // Create a GPU-backed Ganesh surface.
699     const SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
700     sk_sp<SkSurface> surface(SkSurfaces::RenderTarget(ctx, skgpu::Budgeted::kNo, info));
701     std::string_view deviceName = ctx->priv().caps()->deviceName();
702     std::string_view backendAPI = skgpu::ContextTypeName(ctxInfo.type());
703     bool privateAccess = bool(flags & SkSLTestFlag::Priv);
704 
705     if (shouldRunGPU) {
706         test_permutations(r, deviceName, backendAPI, surface.get(), name, testFile,
707                           skiatest::TestType::kGanesh, /*strictES2=*/true, privateAccess);
708     }
709     if (shouldRunGPU_ES3) {
710         test_permutations(r, deviceName, backendAPI, surface.get(), name, testFile,
711                           skiatest::TestType::kGanesh, /*strictES2=*/false, privateAccess);
712     }
713 }
714 #endif
715 
716 #if defined(SK_GRAPHITE)
717 // Note: SKSL_TEST sets CTS enforcement API level to max(kApiLevel_V, ctsEnforcement) for Graphite.
test_graphite(skiatest::Reporter * r,skgpu::graphite::Context * ctx,skiatest::graphite::GraphiteTestContext * testCtx,const char * name,const char * testFile,SkSLTestFlags flags)718 static void test_graphite(skiatest::Reporter* r,
719                           skgpu::graphite::Context* ctx,
720                           skiatest::graphite::GraphiteTestContext* testCtx,
721                           const char* name,
722                           const char* testFile,
723                           SkSLTestFlags flags) {
724     // If this is an ES3-only test on a GPU which doesn't support SkSL ES3, return immediately.
725     bool shouldRunGPU = SkToBool(flags & SkSLTestFlag::GPU);
726     bool shouldRunGPU_ES3 =
727             (flags & SkSLTestFlag::GPU_ES3) &&
728             (ctx->priv().caps()->shaderCaps()->supportedSkSLVerion() >= SkSL::Version::k300);
729     if (!shouldRunGPU && !shouldRunGPU_ES3) {
730         return;
731     }
732 
733 #if defined(SK_DAWN)
734     if (ctx->backend() == skgpu::BackendApi::kDawn) {
735         // If this is a test that requires the GPU to generate NaN values, we don't run it in Dawn.
736         // (WGSL/Dawn does not support infinity or NaN even if the GPU natively does.)
737         if (flags & SkSLTestFlag::UsesNaN) {
738             return;
739         }
740     }
741 #endif
742 
743     // Create a GPU-backed Graphite surface.
744     std::unique_ptr<skgpu::graphite::Recorder> recorder = ctx->makeRecorder();
745 
746     const SkImageInfo info = SkImageInfo::Make({kWidth, kHeight},
747                                                 kRGBA_8888_SkColorType,
748                                                 kPremul_SkAlphaType);
749     sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(recorder.get(), info);
750     std::string_view deviceName = ctx->priv().caps()->deviceName();
751     std::string_view backendAPI = skgpu::ContextTypeName(testCtx->contextType());
752     bool privateAccess = bool(flags & SkSLTestFlag::Priv);
753 
754     if (shouldRunGPU) {
755         test_permutations(r, deviceName, backendAPI, surface.get(), name, testFile,
756                           skiatest::TestType::kGraphite, /*strictES2=*/true, privateAccess);
757     }
758     if (shouldRunGPU_ES3) {
759         test_permutations(r, deviceName, backendAPI, surface.get(), name, testFile,
760                           skiatest::TestType::kGraphite, /*strictES2=*/false, privateAccess);
761     }
762 }
763 #endif
764 
test_clone(skiatest::Reporter * r,const char * testFile,SkSLTestFlags flags)765 static void test_clone(skiatest::Reporter* r, const char* testFile, SkSLTestFlags flags) {
766     SkString shaderString = load_source(r, testFile, "");
767     if (shaderString.isEmpty()) {
768         return;
769     }
770     SkSL::ProgramSettings settings;
771     // TODO(skia:11209): Can we just put the correct #version in the source files that need this?
772     settings.fMaxVersionAllowed = is_strict_es2(flags) ? SkSL::Version::k100 : SkSL::Version::k300;
773     SkSL::ProgramKind kind = bool(flags & SkSLTestFlag::Priv)
774                                      ? SkSL::ProgramKind::kPrivateRuntimeShader
775                                      : SkSL::ProgramKind::kRuntimeShader;
776     SkSL::Compiler compiler;
777     std::unique_ptr<SkSL::Program> program = compiler.convertProgram(kind, shaderString.c_str(),
778                                                                      settings);
779     if (!program) {
780         ERRORF(r, "%s", compiler.errorText().c_str());
781         return;
782     }
783 
784     // Clone every expression in the program, and ensure that its clone generates the same
785     // description as the original.
786     class CloneVisitor : public SkSL::ProgramVisitor {
787     public:
788         CloneVisitor(skiatest::Reporter* r) : fReporter(r) {}
789 
790         bool visitExpression(const SkSL::Expression& expr) override {
791             std::string original = expr.description();
792             std::string cloned = expr.clone()->description();
793             REPORTER_ASSERT(fReporter, original == cloned,
794                             "Mismatch after clone!\nOriginal: %s\nCloned: %s\n",
795                             original.c_str(), cloned.c_str());
796 
797             return INHERITED::visitExpression(expr);
798         }
799 
800         skiatest::Reporter* fReporter;
801 
802         using INHERITED = ProgramVisitor;
803     };
804 
805     CloneVisitor{r}.visit(*program);
806 }
807 
report_rp_pass(skiatest::Reporter * r,const char * testFile,SkSLTestFlags flags)808 static void report_rp_pass(skiatest::Reporter* r, const char* testFile, SkSLTestFlags flags) {
809     if (!(flags & SkSLTestFlag::CPU) && !(flags & SkSLTestFlag::ES3)) {
810         ERRORF(r, "NEW: %s", testFile);
811     }
812 }
813 
report_rp_fail(skiatest::Reporter * r,const char * testFile,SkSLTestFlags flags,const char * reason)814 static void report_rp_fail(skiatest::Reporter* r,
815                            const char* testFile,
816                            SkSLTestFlags flags,
817                            const char* reason) {
818     if ((flags & SkSLTestFlag::CPU) || (flags & SkSLTestFlag::ES3)) {
819         ERRORF(r, "%s: %s", testFile, reason);
820     }
821 }
822 
test_raster_pipeline(skiatest::Reporter * r,const char * testFile,SkSLTestFlags flags)823 static void test_raster_pipeline(skiatest::Reporter* r,
824                                  const char* testFile,
825                                  SkSLTestFlags flags) {
826     SkString shaderString = load_source(r, testFile, "");
827     if (shaderString.isEmpty()) {
828         return;
829     }
830 
831     // In Raster Pipeline, we can compile and run test shaders directly, without involving a surface
832     // at all.
833     SkSL::Compiler compiler;
834     SkSL::ProgramSettings settings;
835     settings.fMaxVersionAllowed = SkSL::Version::k300;
836     SkSL::ProgramKind kind = bool(flags & SkSLTestFlag::Priv)
837                                      ? SkSL::ProgramKind::kPrivateRuntimeShader
838                                      : SkSL::ProgramKind::kRuntimeShader;
839     std::unique_ptr<SkSL::Program> program = compiler.convertProgram(kind, shaderString.c_str(),
840                                                                      settings);
841     if (!program) {
842         ERRORF(r, "%s: Unexpected compilation error\n%s", testFile, compiler.errorText().c_str());
843         return;
844     }
845     const SkSL::FunctionDeclaration* main = program->getFunction("main");
846     if (!main) {
847         ERRORF(r, "%s: Program must have a 'main' function", testFile);
848         return;
849     }
850 
851     // Match up uniforms from the program against our list of test uniforms, and build up a data
852     // buffer of uniform floats.
853     size_t offset = 0;
854     TArray<SkRuntimeEffect::Uniform> uniforms;
855     TArray<std::string_view> childEffects;
856     const SkSL::Context& ctx(compiler.context());
857 
858     for (const SkSL::ProgramElement* elem : program->elements()) {
859         // Variables (uniform, etc.)
860         if (elem->is<SkSL::GlobalVarDeclaration>()) {
861             const SkSL::GlobalVarDeclaration& global = elem->as<SkSL::GlobalVarDeclaration>();
862             const SkSL::VarDeclaration& varDecl = global.declaration()->as<SkSL::VarDeclaration>();
863             const SkSL::Variable& var = *varDecl.var();
864 
865             // Keep track of child effects.
866             if (var.type().isEffectChild()) {
867                 childEffects.push_back(var.name());
868                 continue;
869             }
870             // 'uniform' variables
871             if (var.modifierFlags().isUniform()) {
872                 uniforms.push_back(SkRuntimeEffectPriv::VarAsUniform(var, ctx, &offset));
873             }
874         }
875     }
876 
877     TArray<float> uniformValues;
878     for (const SkRuntimeEffect::Uniform& programUniform : uniforms) {
879         bool foundMatch = false;
880         for (const UniformData& data : kUniformData) {
881             if (data.name == programUniform.name) {
882                 SkASSERT(data.span.size() * sizeof(float) == programUniform.sizeInBytes());
883                 foundMatch = true;
884                 uniformValues.push_back_n(data.span.size(), data.span.data());
885                 break;
886             }
887         }
888         if (!foundMatch) {
889             report_rp_fail(r, testFile, flags, "unsupported uniform");
890             return;
891         }
892     }
893 
894     // Compile our program.
895     SkArenaAlloc alloc(/*firstHeapAllocation=*/1000);
896     SkRasterPipeline pipeline(&alloc);
897     SkSL::DebugTracePriv debugTrace;
898     std::unique_ptr<SkSL::RP::Program> rasterProg =
899             SkSL::MakeRasterPipelineProgram(*program,
900                                             *main->definition(),
901                                             &debugTrace);
902     if (!rasterProg) {
903         report_rp_fail(r, testFile, flags, "code is not supported");
904         return;
905     }
906 
907     // Create callbacks which implement `shaderGreen` and `shaderRed` shaders. Fortunately, these
908     // are trivial to implement directly in Raster Pipeline.
909     struct RPCallbacks : public SkSL::RP::Callbacks {
910         RPCallbacks(SkRasterPipeline* p, SkArenaAlloc* a, const TArray<std::string_view>* c)
911                 : fPipeline(p)
912                 , fAlloc(a)
913                 , fChildEffects(c) {}
914 
915         bool appendShader(int index) override {
916             if (fChildEffects->at(index) == "shaderGreen") {
917                 static constexpr float kColorGreen[4] = {0.0f, 1.0f, 0.0f, 1.0f};
918                 fPipeline->appendConstantColor(fAlloc, kColorGreen);
919                 return true;
920             }
921             if (fChildEffects->at(index) == "shaderRed") {
922                 static constexpr float kColorRed[4] = {1.0f, 0.0f, 0.0f, 1.0f};
923                 fPipeline->appendConstantColor(fAlloc, kColorRed);
924                 return true;
925             }
926             SK_ABORT("unrecognized RP effect");
927         }
928 
929         bool appendColorFilter(int index) override { SK_ABORT("unsupported RP callback"); }
930         bool appendBlender(int index) override { SK_ABORT("unsupported RP callback"); }
931         void toLinearSrgb(const void* color) override { SK_ABORT("unsupported RP callback"); }
932         void fromLinearSrgb(const void* color) override { SK_ABORT("unsupported RP callback"); }
933 
934         SkRasterPipeline* fPipeline = nullptr;
935         SkArenaAlloc* fAlloc = nullptr;
936         const TArray<std::string_view>* fChildEffects;
937     };
938 
939     RPCallbacks callbacks{&pipeline, &alloc, &childEffects};
940 
941     // Append the SkSL program to the raster pipeline.
942     pipeline.appendConstantColor(&alloc, SkColors::kTransparent);
943     rasterProg->appendStages(&pipeline, &alloc, &callbacks, SkSpan(uniformValues));
944 
945     // Move the float values from RGBA into an 8888 memory buffer.
946     uint32_t out[SkRasterPipeline_kMaxStride_highp] = {};
947     SkRasterPipeline_MemoryCtx outCtx{/*pixels=*/out, /*stride=*/SkRasterPipeline_kMaxStride_highp};
948     pipeline.append(SkRasterPipelineOp::store_8888, &outCtx);
949     pipeline.run(0, 0, 1, 1);
950 
951     // Make sure the first pixel (exclusively) of `out` is green. If the program compiled
952     // successfully, we expect it to run without error, and will assert if it doesn't.
953     uint32_t expected = 0xFF00FF00;
954     if (out[0] != expected) {
955         ERRORF(r, "%s: Raster Pipeline failed. Expected solid green, got ARGB:%02X%02X%02X%02X",
956                   testFile,
957                   (out[0] >> 24) & 0xFF,
958                   (out[0] >> 16) & 0xFF,
959                   (out[0] >> 8) & 0xFF,
960                   out[0] & 0xFF);
961         return;
962     }
963 
964     // Success!
965     report_rp_pass(r, testFile, flags);
966 }
967 
968 #if defined(SK_GANESH)
969 #define DEF_GANESH_SKSL_TEST(flags, ctsEnforcement, name, path) \
970     DEF_CONDITIONAL_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkSL##name##_Ganesh, \
971                                                        r,                   \
972                                                        ctxInfo,             \
973                                                        is_gpu(flags),       \
974                                                        ctsEnforcement) {    \
975         test_ganesh(r, ctxInfo, #name, path, flags);                        \
976     }
977 #else
978 #define DEF_GANESH_SKSL_TEST(flags, ctsEnforcement, name, path) /* Ganesh is disabled */
979 #endif
980 
981 #if defined(SK_GRAPHITE)
is_native_context_or_dawn(skgpu::ContextType type)982 static bool is_native_context_or_dawn(skgpu::ContextType type) {
983     return skgpu::IsNativeBackend(type) || skgpu::IsDawnBackend(type);
984 }
985 
986 #define DEF_GRAPHITE_SKSL_TEST(flags, ctsEnforcement, name, path)         \
987     DEF_CONDITIONAL_GRAPHITE_TEST_FOR_CONTEXTS(SkSL##name##_Graphite,     \
988                                                is_native_context_or_dawn, \
989                                                r,                         \
990                                                context,                   \
991                                                testContext,               \
992                                                /*opt_filter=*/nullptr,    \
993                                                is_gpu(flags),             \
994                                                ctsEnforcement) {          \
995         test_graphite(r, context, testContext, #name, path, flags);       \
996     }
997 #else
998 #define DEF_GRAPHITE_SKSL_TEST(flags, ctsEnforcement, name, path) /* Graphite is disabled */
999 #endif
1000 
1001 #define SKSL_TEST(flags, ctsEnforcement, name, path)                                              \
1002     DEF_CONDITIONAL_TEST(SkSL##name##_CPU, r, is_cpu(flags)) { test_cpu(r, #name, path, flags); } \
1003     DEF_TEST(SkSL##name##_RP, r) { test_raster_pipeline(r, path, flags); }                        \
1004     DEF_TEST(SkSL##name##_Clone, r) { test_clone(r, path, flags); }                               \
1005     DEF_GANESH_SKSL_TEST(flags, ctsEnforcement, name, path)                                       \
1006     DEF_GRAPHITE_SKSL_TEST(flags, std::max(kApiLevel_V, ctsEnforcement), name, path)
1007 
1008 /**
1009  * Test flags:
1010  * - CPU:     this test should pass on the CPU backend
1011  * - GPU:     this test should pass on the Ganesh GPU backends
1012  * - GPU_ES3: this test should pass on an ES3-compatible GPU when "enforce ES2 restrictions" is off
1013  *
1014  * CtsEnforcement:
1015  *   Android CTS (go/wtf/cts) enforces that devices must pass this test at the given API level.
1016  *   CTS and Android SkQP builds should only run tests on devices greater than the provided API
1017  *   level, but other test binaries (dm/fm) should run every test, regardless of this value.
1018  */
1019 
1020 // clang-format off
1021 
1022 constexpr SkSLTestFlags CPU = SkSLTestFlag::CPU;
1023 constexpr SkSLTestFlags ES3 = SkSLTestFlag::ES3;
1024 constexpr SkSLTestFlags GPU = SkSLTestFlag::GPU;
1025 constexpr SkSLTestFlags GPU_ES3 = SkSLTestFlag::GPU_ES3;
1026 constexpr SkSLTestFlags UsesNaN = SkSLTestFlag::UsesNaN;
1027 constexpr SkSLTestFlags Priv = SkSLTestFlag::Priv;
1028 constexpr auto kApiLevel_T = CtsEnforcement::kApiLevel_T;
1029 constexpr auto kApiLevel_U = CtsEnforcement::kApiLevel_U;
1030 [[maybe_unused]] constexpr auto kApiLevel_V = CtsEnforcement::kApiLevel_V;
1031 constexpr auto kNever = CtsEnforcement::kNever;
1032 [[maybe_unused]] constexpr auto kNextRelease = CtsEnforcement::kNextRelease;
1033 
1034 SKSL_TEST(ES3 | GPU_ES3, kApiLevel_T, ArrayFolding,                    "folding/ArrayFolding.sksl")
1035 SKSL_TEST(CPU | GPU,     kApiLevel_T, ArraySizeFolding,                "folding/ArraySizeFolding.rts")
1036 SKSL_TEST(CPU | GPU,     kApiLevel_T, AssignmentOps,                   "folding/AssignmentOps.rts")
1037 SKSL_TEST(CPU | GPU,     kApiLevel_T, BoolFolding,                     "folding/BoolFolding.rts")
1038 SKSL_TEST(CPU | GPU,     kApiLevel_T, CastFolding,                     "folding/CastFolding.rts")
1039 SKSL_TEST(CPU | GPU,     kApiLevel_T, IntFoldingES2,                   "folding/IntFoldingES2.rts")
1040 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntFoldingES3,                   "folding/IntFoldingES3.sksl")
1041 SKSL_TEST(CPU | GPU,     kApiLevel_T, FloatFolding,                    "folding/FloatFolding.rts")
1042 SKSL_TEST(CPU | GPU,     kApiLevel_V, LogicalNot,                      "folding/LogicalNot.rts")
1043 SKSL_TEST(CPU | GPU,     kApiLevel_T, MatrixFoldingES2,                "folding/MatrixFoldingES2.rts")
1044 SKSL_TEST(ES3 | GPU_ES3, kNever,      MatrixFoldingES3,                "folding/MatrixFoldingES3.sksl")
1045 SKSL_TEST(CPU | GPU,     kApiLevel_U, MatrixNoOpFolding,               "folding/MatrixNoOpFolding.rts")
1046 SKSL_TEST(CPU | GPU,     kApiLevel_U, MatrixScalarNoOpFolding,         "folding/MatrixScalarNoOpFolding.rts")
1047 SKSL_TEST(CPU | GPU,     kApiLevel_U, MatrixVectorNoOpFolding,         "folding/MatrixVectorNoOpFolding.rts")
1048 SKSL_TEST(CPU | GPU,     kApiLevel_T, Negation,                        "folding/Negation.rts")
1049 SKSL_TEST(CPU | GPU,     kApiLevel_T, PreserveSideEffects,             "folding/PreserveSideEffects.rts")
1050 SKSL_TEST(CPU | GPU,     kApiLevel_T, SelfAssignment,                  "folding/SelfAssignment.rts")
1051 SKSL_TEST(CPU | GPU,     kApiLevel_T, ShortCircuitBoolFolding,         "folding/ShortCircuitBoolFolding.rts")
1052 SKSL_TEST(CPU | GPU,     kApiLevel_U, StructFieldFolding,              "folding/StructFieldFolding.rts")
1053 SKSL_TEST(CPU | GPU,     kApiLevel_U, StructFieldNoFolding,            "folding/StructFieldNoFolding.rts")
1054 SKSL_TEST(CPU | GPU,     kApiLevel_T, SwitchCaseFolding,               "folding/SwitchCaseFolding.rts")
1055 SKSL_TEST(CPU | GPU,     kApiLevel_T, SwizzleFolding,                  "folding/SwizzleFolding.rts")
1056 SKSL_TEST(CPU | GPU,     kApiLevel_U, TernaryFolding,                  "folding/TernaryFolding.rts")
1057 SKSL_TEST(CPU | GPU,     kApiLevel_T, VectorScalarFolding,             "folding/VectorScalarFolding.rts")
1058 SKSL_TEST(CPU | GPU,     kApiLevel_T, VectorVectorFolding,             "folding/VectorVectorFolding.rts")
1059 
1060 SKSL_TEST(CPU | GPU,     kApiLevel_V, CommaExpressionsAllowInlining,                    "inliner/CommaExpressionsAllowInlining.sksl")
1061 SKSL_TEST(ES3 | GPU_ES3, kNever,      DoWhileBodyMustBeInlinedIntoAScope,               "inliner/DoWhileBodyMustBeInlinedIntoAScope.sksl")
1062 SKSL_TEST(ES3 | GPU_ES3, kNever,      DoWhileTestCannotBeInlined,                       "inliner/DoWhileTestCannotBeInlined.sksl")
1063 SKSL_TEST(CPU | GPU,     kApiLevel_T, ForBodyMustBeInlinedIntoAScope,                   "inliner/ForBodyMustBeInlinedIntoAScope.sksl")
1064 SKSL_TEST(ES3 | GPU_ES3, kNever,      ForInitializerExpressionsCanBeInlined,            "inliner/ForInitializerExpressionsCanBeInlined.sksl")
1065 SKSL_TEST(CPU | GPU,     kApiLevel_T, ForWithoutReturnInsideCanBeInlined,               "inliner/ForWithoutReturnInsideCanBeInlined.sksl")
1066 SKSL_TEST(CPU | GPU,     kApiLevel_T, ForWithReturnInsideCannotBeInlined,               "inliner/ForWithReturnInsideCannotBeInlined.sksl")
1067 SKSL_TEST(CPU | GPU,     kApiLevel_T, IfBodyMustBeInlinedIntoAScope,                    "inliner/IfBodyMustBeInlinedIntoAScope.sksl")
1068 SKSL_TEST(CPU | GPU,     kApiLevel_T, IfElseBodyMustBeInlinedIntoAScope,                "inliner/IfElseBodyMustBeInlinedIntoAScope.sksl")
1069 SKSL_TEST(CPU | GPU,     kApiLevel_T, IfElseChainWithReturnsCanBeInlined,               "inliner/IfElseChainWithReturnsCanBeInlined.sksl")
1070 SKSL_TEST(CPU | GPU,     kApiLevel_T, IfTestCanBeInlined,                               "inliner/IfTestCanBeInlined.sksl")
1071 SKSL_TEST(CPU | GPU,     kApiLevel_T, IfWithReturnsCanBeInlined,                        "inliner/IfWithReturnsCanBeInlined.sksl")
1072 SKSL_TEST(CPU | GPU,     kApiLevel_T, InlineKeywordOverridesThreshold,                  "inliner/InlineKeywordOverridesThreshold.sksl")
1073 SKSL_TEST(CPU | GPU,     kApiLevel_T, InlinerAvoidsVariableNameOverlap,                 "inliner/InlinerAvoidsVariableNameOverlap.sksl")
1074 SKSL_TEST(CPU | GPU,     kApiLevel_T, InlinerElidesTempVarForReturnsInsideBlock,        "inliner/InlinerElidesTempVarForReturnsInsideBlock.sksl")
1075 SKSL_TEST(CPU | GPU,     kApiLevel_T, InlinerUsesTempVarForMultipleReturns,             "inliner/InlinerUsesTempVarForMultipleReturns.sksl")
1076 SKSL_TEST(CPU | GPU,     kApiLevel_T, InlinerUsesTempVarForReturnsInsideBlockWithVar,   "inliner/InlinerUsesTempVarForReturnsInsideBlockWithVar.sksl")
1077 SKSL_TEST(CPU | GPU,     kApiLevel_T, InlineThreshold,                                  "inliner/InlineThreshold.sksl")
1078 SKSL_TEST(ES3 | GPU_ES3, kApiLevel_U, InlineUnscopedVariable,                           "inliner/InlineUnscopedVariable.sksl")
1079 SKSL_TEST(CPU | GPU,     kApiLevel_T, InlineWithModifiedArgument,                       "inliner/InlineWithModifiedArgument.sksl")
1080 SKSL_TEST(CPU | GPU,     kApiLevel_T, InlineWithNestedBigCalls,                         "inliner/InlineWithNestedBigCalls.sksl")
1081 SKSL_TEST(CPU | GPU,     kApiLevel_T, InlineWithUnmodifiedArgument,                     "inliner/InlineWithUnmodifiedArgument.sksl")
1082 SKSL_TEST(CPU | GPU,     kApiLevel_T, InlineWithUnnecessaryBlocks,                      "inliner/InlineWithUnnecessaryBlocks.sksl")
1083 SKSL_TEST(CPU | GPU,     kApiLevel_V, IntrinsicNameCollision,                           "inliner/IntrinsicNameCollision.sksl")
1084 SKSL_TEST(CPU | GPU,     kApiLevel_V, ModifiedArrayParametersCannotBeInlined,           "inliner/ModifiedArrayParametersCannotBeInlined.sksl")
1085 SKSL_TEST(CPU | GPU,     kApiLevel_V, ModifiedStructParametersCannotBeInlined,          "inliner/ModifiedStructParametersCannotBeInlined.sksl")
1086 SKSL_TEST(CPU | GPU,     kApiLevel_T, NoInline,                                         "inliner/NoInline.sksl")
1087 SKSL_TEST(CPU | GPU,     kApiLevel_T, ShortCircuitEvaluationsCannotInlineRightHandSide, "inliner/ShortCircuitEvaluationsCannotInlineRightHandSide.sksl")
1088 SKSL_TEST(ES3 | GPU_ES3, kNever,      StaticSwitchInline,                               "inliner/StaticSwitch.sksl")
1089 SKSL_TEST(CPU | GPU,     kApiLevel_T, StructsCanBeInlinedSafely,                        "inliner/StructsCanBeInlinedSafely.sksl")
1090 SKSL_TEST(CPU | GPU,     kApiLevel_T, SwizzleCanBeInlinedDirectly,                      "inliner/SwizzleCanBeInlinedDirectly.sksl")
1091 SKSL_TEST(CPU | GPU,     kApiLevel_T, TernaryResultsCannotBeInlined,                    "inliner/TernaryResultsCannotBeInlined.sksl")
1092 SKSL_TEST(CPU | GPU,     kApiLevel_T, TernaryTestCanBeInlined,                          "inliner/TernaryTestCanBeInlined.sksl")
1093 SKSL_TEST(CPU | GPU,     kApiLevel_T, TrivialArgumentsInlineDirectly,                   "inliner/TrivialArgumentsInlineDirectly.sksl")
1094 SKSL_TEST(ES3 | GPU_ES3, kNever,      TrivialArgumentsInlineDirectlyES3,                "inliner/TrivialArgumentsInlineDirectlyES3.sksl")
1095 SKSL_TEST(CPU | GPU,     kApiLevel_V, TypeShadowing,                                    "inliner/TypeShadowing.sksl")
1096 SKSL_TEST(ES3 | GPU_ES3, kNever,      WhileBodyMustBeInlinedIntoAScope,                 "inliner/WhileBodyMustBeInlinedIntoAScope.sksl")
1097 SKSL_TEST(ES3 | GPU_ES3, kNever,      WhileTestCannotBeInlined,                         "inliner/WhileTestCannotBeInlined.sksl")
1098 
1099 SKSL_TEST(CPU | GPU,     kApiLevel_T, IntrinsicAbsFloat,               "intrinsics/AbsFloat.sksl")
1100 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntrinsicAbsInt,                 "intrinsics/AbsInt.sksl")
1101 SKSL_TEST(CPU | GPU,     kNever,      IntrinsicAny,                    "intrinsics/Any.sksl")
1102 SKSL_TEST(CPU | GPU,     kNever,      IntrinsicAll,                    "intrinsics/All.sksl")
1103 SKSL_TEST(CPU | GPU,     kApiLevel_T, IntrinsicCeil,                   "intrinsics/Ceil.sksl")
1104 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntrinsicClampInt,               "intrinsics/ClampInt.sksl")
1105 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntrinsicClampUInt,              "intrinsics/ClampUInt.sksl")
1106 SKSL_TEST(CPU | GPU,     kApiLevel_T, IntrinsicClampFloat,             "intrinsics/ClampFloat.sksl")
1107 SKSL_TEST(CPU | GPU,     kNever,      IntrinsicCross,                  "intrinsics/Cross.sksl")
1108 SKSL_TEST(CPU | GPU,     kNever,      IntrinsicDegrees,                "intrinsics/Degrees.sksl")
1109 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicDeterminant,            "intrinsics/Determinant.sksl")
1110 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicDFdx,                   "intrinsics/DFdx.sksl")
1111 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicDFdy,                   "intrinsics/DFdy.sksl")
1112 SKSL_TEST(CPU | GPU,     kNever,      IntrinsicDot,                    "intrinsics/Dot.sksl")
1113 SKSL_TEST(CPU | GPU,     kNever,      IntrinsicFract,                  "intrinsics/Fract.sksl")
1114 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntrinsicFloatBitsToInt,         "intrinsics/FloatBitsToInt.sksl")
1115 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntrinsicFloatBitsToUint,        "intrinsics/FloatBitsToUint.sksl")
1116 SKSL_TEST(CPU | GPU,     kNever,      IntrinsicFloor,                  "intrinsics/Floor.sksl")
1117 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicFwidth,                 "intrinsics/Fwidth.sksl")
1118 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntrinsicIntBitsToFloat,         "intrinsics/IntBitsToFloat.sksl")
1119 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicIsInf,                  "intrinsics/IsInf.sksl")
1120 SKSL_TEST(CPU | GPU,     kNever,      IntrinsicLength,                 "intrinsics/Length.sksl")
1121 SKSL_TEST(CPU | GPU,     kApiLevel_T, IntrinsicMatrixCompMultES2,      "intrinsics/MatrixCompMultES2.sksl")
1122 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntrinsicMatrixCompMultES3,      "intrinsics/MatrixCompMultES3.sksl")
1123 SKSL_TEST(CPU | GPU,     kApiLevel_T, IntrinsicMaxFloat,               "intrinsics/MaxFloat.sksl")
1124 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntrinsicMaxInt,                 "intrinsics/MaxInt.sksl")
1125 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntrinsicMaxUint,                "intrinsics/MaxUint.sksl")
1126 SKSL_TEST(CPU | GPU,     kApiLevel_T, IntrinsicMinFloat,               "intrinsics/MinFloat.sksl")
1127 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntrinsicMinInt,                 "intrinsics/MinInt.sksl")
1128 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntrinsicMinUint,                "intrinsics/MinUint.sksl")
1129 SKSL_TEST(CPU | GPU,     kApiLevel_T, IntrinsicMixFloatES2,            "intrinsics/MixFloatES2.sksl")
1130 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntrinsicMixFloatES3,            "intrinsics/MixFloatES3.sksl")
1131 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicModf,                   "intrinsics/Modf.sksl")
1132 SKSL_TEST(CPU | GPU,     kNever,      IntrinsicNot,                    "intrinsics/Not.sksl")
1133 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicOuterProduct,           "intrinsics/OuterProduct.sksl")
1134 SKSL_TEST(CPU | GPU,     kNever,      IntrinsicRadians,                "intrinsics/Radians.sksl")
1135 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicRound,                  "intrinsics/Round.sksl")
1136 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicRoundEven,              "intrinsics/RoundEven.sksl")
1137 SKSL_TEST(CPU | GPU,     kNever,      IntrinsicSaturate,               "intrinsics/Saturate.sksl")
1138 SKSL_TEST(CPU | GPU,     kApiLevel_T, IntrinsicSignFloat,              "intrinsics/SignFloat.sksl")
1139 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntrinsicSignInt,                "intrinsics/SignInt.sksl")
1140 SKSL_TEST(CPU | GPU,     kNever,      IntrinsicSqrt,                   "intrinsics/Sqrt.sksl")
1141 SKSL_TEST(CPU | GPU,     kApiLevel_T, IntrinsicStep,                   "intrinsics/Step.sksl")
1142 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntrinsicTrunc,                  "intrinsics/Trunc.sksl")
1143 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntrinsicTranspose,              "intrinsics/Transpose.sksl")
1144 SKSL_TEST(ES3 | GPU_ES3, kNever,      IntrinsicUintBitsToFloat,        "intrinsics/UintBitsToFloat.sksl")
1145 
1146 SKSL_TEST(ES3 | GPU_ES3, kNever,      ArrayNarrowingConversions,       "runtime/ArrayNarrowingConversions.rts")
1147 SKSL_TEST(CPU | GPU,     kNextRelease,ChildEffectSimple,               "runtime/ChildEffectSimple.rts")
1148 SKSL_TEST(CPU | GPU|Priv,kNextRelease,ChildEffectSpecializationFanOut, "runtime/ChildEffectSpecializationFanOut.privrts")
1149 SKSL_TEST(ES3 | GPU_ES3, kNever,      Commutative,                     "runtime/Commutative.rts")
1150 SKSL_TEST(CPU,           kNever,      DivideByZero,                    "runtime/DivideByZero.rts")
1151 SKSL_TEST(CPU | GPU,     kApiLevel_V, FunctionParameterAliasingFirst,  "runtime/FunctionParameterAliasingFirst.rts")
1152 SKSL_TEST(CPU | GPU,     kApiLevel_V, FunctionParameterAliasingSecond, "runtime/FunctionParameterAliasingSecond.rts")
1153 SKSL_TEST(CPU | GPU,     kApiLevel_V, IfElseBinding,                   "runtime/IfElseBinding.rts")
1154 SKSL_TEST(CPU | GPU,     kApiLevel_V, IncrementDisambiguation,         "runtime/IncrementDisambiguation.rts")
1155 SKSL_TEST(CPU | GPU,     kApiLevel_T, LoopFloat,                       "runtime/LoopFloat.rts")
1156 SKSL_TEST(CPU | GPU,     kApiLevel_T, LoopInt,                         "runtime/LoopInt.rts")
1157 SKSL_TEST(CPU | GPU,     kApiLevel_U, Ossfuzz52603,                    "runtime/Ossfuzz52603.rts")
1158 SKSL_TEST(CPU | GPU,     kApiLevel_T, QualifierOrder,                  "runtime/QualifierOrder.rts")
1159 SKSL_TEST(CPU | GPU,     kApiLevel_T, PrecisionQualifiers,             "runtime/PrecisionQualifiers.rts")
1160 SKSL_TEST(CPU | GPU,     kNextRelease,SharedFunctions,                 "runtime/SharedFunctions.rts")
1161 
1162 SKSL_TEST(ES3 | GPU_ES3 | UsesNaN, kNever, RecursiveComparison_Arrays,  "runtime/RecursiveComparison_Arrays.rts")
1163 SKSL_TEST(ES3 | GPU_ES3 | UsesNaN, kNever, RecursiveComparison_Structs, "runtime/RecursiveComparison_Structs.rts")
1164 SKSL_TEST(ES3 | GPU_ES3 | UsesNaN, kNever, RecursiveComparison_Types,   "runtime/RecursiveComparison_Types.rts")
1165 SKSL_TEST(ES3 | GPU_ES3 | UsesNaN, kNever, RecursiveComparison_Vectors, "runtime/RecursiveComparison_Vectors.rts")
1166 
1167 SKSL_TEST(ES3 | GPU_ES3, kNever,      ArrayCast,                       "shared/ArrayCast.sksl")
1168 SKSL_TEST(ES3 | GPU_ES3, kNever,      ArrayComparison,                 "shared/ArrayComparison.sksl")
1169 SKSL_TEST(ES3 | GPU_ES3, kNever,      ArrayConstructors,               "shared/ArrayConstructors.sksl")
1170 SKSL_TEST(CPU | GPU,     kApiLevel_V, ArrayFollowedByScalar,           "shared/ArrayFollowedByScalar.sksl")
1171 SKSL_TEST(CPU | GPU,     kApiLevel_T, ArrayTypes,                      "shared/ArrayTypes.sksl")
1172 SKSL_TEST(CPU | GPU,     kApiLevel_T, Assignment,                      "shared/Assignment.sksl")
1173 SKSL_TEST(CPU | GPU,     kApiLevel_T, CastsRoundTowardZero,            "shared/CastsRoundTowardZero.sksl")
1174 SKSL_TEST(CPU | GPU,     kApiLevel_T, CommaMixedTypes,                 "shared/CommaMixedTypes.sksl")
1175 SKSL_TEST(CPU | GPU,     kApiLevel_T, CommaSideEffects,                "shared/CommaSideEffects.sksl")
1176 SKSL_TEST(CPU | GPU,     kApiLevel_U, CompileTimeConstantVariables,    "shared/CompileTimeConstantVariables.sksl")
1177 SKSL_TEST(ES3 | GPU_ES3, kNever,      ConstantCompositeAccessViaConstantIndex, "shared/ConstantCompositeAccessViaConstantIndex.sksl")
1178 SKSL_TEST(ES3 | GPU_ES3, kNever,      ConstantCompositeAccessViaDynamicIndex,  "shared/ConstantCompositeAccessViaDynamicIndex.sksl")
1179 SKSL_TEST(CPU | GPU,     kApiLevel_T, ConstantIf,                      "shared/ConstantIf.sksl")
1180 SKSL_TEST(ES3 | GPU_ES3, kNever,      ConstArray,                      "shared/ConstArray.sksl")
1181 SKSL_TEST(CPU | GPU,     kApiLevel_T, ConstVariableComparison,         "shared/ConstVariableComparison.sksl")
1182 SKSL_TEST(CPU | GPU,     kNever,      DeadGlobals,                     "shared/DeadGlobals.sksl")
1183 SKSL_TEST(ES3 | GPU_ES3, kNever,      DeadLoopVariable,                "shared/DeadLoopVariable.sksl")
1184 SKSL_TEST(CPU | GPU,     kApiLevel_T, DeadIfStatement,                 "shared/DeadIfStatement.sksl")
1185 SKSL_TEST(CPU | GPU,     kApiLevel_T, DeadReturn,                      "shared/DeadReturn.sksl")
1186 SKSL_TEST(ES3 | GPU_ES3, kNever,      DeadReturnES3,                   "shared/DeadReturnES3.sksl")
1187 SKSL_TEST(CPU | GPU,     kApiLevel_T, DeadStripFunctions,              "shared/DeadStripFunctions.sksl")
1188 SKSL_TEST(CPU | GPU,     kApiLevel_T, DependentInitializers,           "shared/DependentInitializers.sksl")
1189 SKSL_TEST(CPU | GPU,     kApiLevel_U, DoubleNegation,                  "shared/DoubleNegation.sksl")
1190 SKSL_TEST(ES3 | GPU_ES3, kNever,      DoWhileControlFlow,              "shared/DoWhileControlFlow.sksl")
1191 SKSL_TEST(CPU | GPU,     kApiLevel_T, EmptyBlocksES2,                  "shared/EmptyBlocksES2.sksl")
1192 SKSL_TEST(ES3 | GPU_ES3, kNever,      EmptyBlocksES3,                  "shared/EmptyBlocksES3.sksl")
1193 SKSL_TEST(CPU | GPU,     kApiLevel_T, ForLoopControlFlow,              "shared/ForLoopControlFlow.sksl")
1194 SKSL_TEST(ES3 | GPU_ES3, kNever,      ForLoopMultipleInitES3,          "shared/ForLoopMultipleInitES3.sksl")
1195 SKSL_TEST(CPU | GPU,     kApiLevel_V, ForLoopShadowing,                "shared/ForLoopShadowing.sksl")
1196 SKSL_TEST(CPU | GPU,     kApiLevel_T, FunctionAnonymousParameters,     "shared/FunctionAnonymousParameters.sksl")
1197 SKSL_TEST(CPU | GPU,     kApiLevel_T, FunctionArgTypeMatch,            "shared/FunctionArgTypeMatch.sksl")
1198 SKSL_TEST(CPU | GPU,     kApiLevel_T, FunctionReturnTypeMatch,         "shared/FunctionReturnTypeMatch.sksl")
1199 SKSL_TEST(CPU | GPU,     kApiLevel_T, Functions,                       "shared/Functions.sksl")
1200 SKSL_TEST(CPU | GPU,     kApiLevel_T, FunctionPrototype,               "shared/FunctionPrototype.sksl")
1201 SKSL_TEST(CPU | GPU,     kApiLevel_T, GeometricIntrinsics,             "shared/GeometricIntrinsics.sksl")
1202 SKSL_TEST(CPU | GPU,     kApiLevel_T, HelloWorld,                      "shared/HelloWorld.sksl")
1203 SKSL_TEST(CPU | GPU,     kApiLevel_T, Hex,                             "shared/Hex.sksl")
1204 SKSL_TEST(ES3 | GPU_ES3, kNever,      HexUnsigned,                     "shared/HexUnsigned.sksl")
1205 SKSL_TEST(CPU | GPU,     kApiLevel_V, IfStatement,                     "shared/IfStatement.sksl")
1206 SKSL_TEST(CPU | GPU,     kApiLevel_T, InoutParameters,                 "shared/InoutParameters.sksl")
1207 SKSL_TEST(CPU | GPU,     kApiLevel_U, InoutParamsAreDistinct,          "shared/InoutParamsAreDistinct.sksl")
1208 SKSL_TEST(ES3 | GPU_ES3, kApiLevel_U, IntegerDivisionES3,              "shared/IntegerDivisionES3.sksl")
1209 SKSL_TEST(CPU | GPU,     kApiLevel_U, LogicalAndShortCircuit,          "shared/LogicalAndShortCircuit.sksl")
1210 SKSL_TEST(CPU | GPU,     kApiLevel_U, LogicalOrShortCircuit,           "shared/LogicalOrShortCircuit.sksl")
1211 SKSL_TEST(CPU | GPU,     kApiLevel_T, Matrices,                        "shared/Matrices.sksl")
1212 SKSL_TEST(ES3 | GPU_ES3, kNever,      MatricesNonsquare,               "shared/MatricesNonsquare.sksl")
1213 SKSL_TEST(CPU | GPU,     kNever,      MatrixConstructorsES2,           "shared/MatrixConstructorsES2.sksl")
1214 SKSL_TEST(ES3 | GPU_ES3, kNever,      MatrixConstructorsES3,           "shared/MatrixConstructorsES3.sksl")
1215 SKSL_TEST(CPU | GPU,     kApiLevel_T, MatrixEquality,                  "shared/MatrixEquality.sksl")
1216 SKSL_TEST(CPU | GPU,     kApiLevel_V, MatrixIndexLookup,               "shared/MatrixIndexLookup.sksl")
1217 SKSL_TEST(CPU | GPU,     kApiLevel_V, MatrixIndexStore,                "shared/MatrixIndexStore.sksl")
1218 SKSL_TEST(CPU | GPU,     kApiLevel_U, MatrixOpEqualsES2,               "shared/MatrixOpEqualsES2.sksl")
1219 SKSL_TEST(ES3 | GPU_ES3, kApiLevel_U, MatrixOpEqualsES3,               "shared/MatrixOpEqualsES3.sksl")
1220 SKSL_TEST(CPU | GPU,     kApiLevel_T, MatrixScalarMath,                "shared/MatrixScalarMath.sksl")
1221 SKSL_TEST(CPU | GPU,     kApiLevel_V, MatrixSwizzleStore,              "shared/MatrixSwizzleStore.sksl")
1222 SKSL_TEST(CPU | GPU,     kApiLevel_T, MatrixToVectorCast,              "shared/MatrixToVectorCast.sksl")
1223 SKSL_TEST(CPU | GPU,     kApiLevel_T, MultipleAssignments,             "shared/MultipleAssignments.sksl")
1224 SKSL_TEST(CPU | GPU,     kApiLevel_T, NumberCasts,                     "shared/NumberCasts.sksl")
1225 SKSL_TEST(CPU | GPU,     kApiLevel_V, NestedComparisonIntrinsics,      "shared/NestedComparisonIntrinsics.sksl")
1226 SKSL_TEST(CPU | GPU,     kApiLevel_T, OperatorsES2,                    "shared/OperatorsES2.sksl")
1227 SKSL_TEST(GPU_ES3,       kNever,      OperatorsES3,                    "shared/OperatorsES3.sksl")
1228 SKSL_TEST(CPU | GPU,     kApiLevel_T, Ossfuzz36852,                    "shared/Ossfuzz36852.sksl")
1229 SKSL_TEST(CPU | GPU,     kApiLevel_T, OutParams,                       "shared/OutParams.sksl")
1230 SKSL_TEST(CPU | GPU,     kApiLevel_T, OutParamsAreDistinct,            "shared/OutParamsAreDistinct.sksl")
1231 SKSL_TEST(CPU | GPU,     kApiLevel_U, OutParamsAreDistinctFromGlobal,  "shared/OutParamsAreDistinctFromGlobal.sksl")
1232 SKSL_TEST(ES3 | GPU_ES3, kNever,      OutParamsFunctionCallInArgument, "shared/OutParamsFunctionCallInArgument.sksl")
1233 SKSL_TEST(CPU | GPU,     kApiLevel_T, OutParamsDoubleSwizzle,          "shared/OutParamsDoubleSwizzle.sksl")
1234 SKSL_TEST(CPU | GPU,     kApiLevel_V, PostfixExpressions,              "shared/PostfixExpressions.sksl")
1235 SKSL_TEST(CPU | GPU,     kApiLevel_V, PrefixExpressionsES2,            "shared/PrefixExpressionsES2.sksl")
1236 SKSL_TEST(ES3 | GPU_ES3, kNever,      PrefixExpressionsES3,            "shared/PrefixExpressionsES3.sksl")
1237 SKSL_TEST(CPU | GPU,     kNextRelease,ReservedInGLSLButAllowedInSkSL,  "shared/ReservedInGLSLButAllowedInSkSL.sksl")
1238 SKSL_TEST(CPU | GPU,     kApiLevel_T, ResizeMatrix,                    "shared/ResizeMatrix.sksl")
1239 SKSL_TEST(ES3 | GPU_ES3, kNever,      ResizeMatrixNonsquare,           "shared/ResizeMatrixNonsquare.sksl")
1240 SKSL_TEST(CPU | GPU,     kApiLevel_T, ReturnsValueOnEveryPathES2,      "shared/ReturnsValueOnEveryPathES2.sksl")
1241 SKSL_TEST(ES3 | GPU_ES3, kNever,      ReturnsValueOnEveryPathES3,      "shared/ReturnsValueOnEveryPathES3.sksl")
1242 SKSL_TEST(CPU | GPU,     kApiLevel_T, ScalarConversionConstructorsES2, "shared/ScalarConversionConstructorsES2.sksl")
1243 SKSL_TEST(ES3 | GPU_ES3, kNever,      ScalarConversionConstructorsES3, "shared/ScalarConversionConstructorsES3.sksl")
1244 SKSL_TEST(CPU | GPU,     kApiLevel_T, ScopedSymbol,                    "shared/ScopedSymbol.sksl")
1245 SKSL_TEST(CPU | GPU,     kApiLevel_T, StackingVectorCasts,             "shared/StackingVectorCasts.sksl")
1246 SKSL_TEST(CPU | GPU_ES3, kNever,      StaticSwitch,                    "shared/StaticSwitch.sksl")
1247 SKSL_TEST(CPU | GPU,     kApiLevel_T, StructArrayFollowedByScalar,     "shared/StructArrayFollowedByScalar.sksl")
1248 SKSL_TEST(CPU | GPU,     kApiLevel_V, StructIndexLookup,               "shared/StructIndexLookup.sksl")
1249 SKSL_TEST(CPU | GPU,     kApiLevel_V, StructIndexStore,                "shared/StructIndexStore.sksl")
1250 // TODO(skia:13920): StructComparison currently exposes a bug in SPIR-V codegen.
1251 SKSL_TEST(ES3,           kNextRelease,StructComparison,                "shared/StructComparison.sksl")
1252 SKSL_TEST(CPU | GPU,     kApiLevel_T, StructsInFunctions,              "shared/StructsInFunctions.sksl")
1253 SKSL_TEST(CPU | GPU,     kApiLevel_T, Switch,                          "shared/Switch.sksl")
1254 SKSL_TEST(CPU | GPU,     kApiLevel_T, SwitchDefaultOnly,               "shared/SwitchDefaultOnly.sksl")
1255 SKSL_TEST(CPU | GPU,     kApiLevel_T, SwitchWithFallthrough,           "shared/SwitchWithFallthrough.sksl")
1256 SKSL_TEST(CPU | GPU,     kApiLevel_T, SwitchWithFallthroughAndVarDecls,"shared/SwitchWithFallthroughAndVarDecls.sksl")
1257 SKSL_TEST(CPU | GPU,     kApiLevel_V, SwitchWithFallthroughGroups,     "shared/SwitchWithFallthroughGroups.sksl")
1258 SKSL_TEST(CPU | GPU,     kApiLevel_T, SwitchWithLoops,                 "shared/SwitchWithLoops.sksl")
1259 SKSL_TEST(ES3 | GPU_ES3, kNever,      SwitchWithLoopsES3,              "shared/SwitchWithLoopsES3.sksl")
1260 SKSL_TEST(CPU | GPU,     kNever,      SwizzleAsLValue,                 "shared/SwizzleAsLValue.sksl")
1261 SKSL_TEST(ES3 | GPU_ES3, kNever,      SwizzleAsLValueES3,              "shared/SwizzleAsLValueES3.sksl")
1262 SKSL_TEST(CPU | GPU,     kApiLevel_T, SwizzleBoolConstants,            "shared/SwizzleBoolConstants.sksl")
1263 SKSL_TEST(CPU | GPU,     kApiLevel_T, SwizzleByConstantIndex,          "shared/SwizzleByConstantIndex.sksl")
1264 SKSL_TEST(ES3 | GPU_ES3, kNever,      SwizzleByIndex,                  "shared/SwizzleByIndex.sksl")
1265 SKSL_TEST(CPU | GPU,     kApiLevel_T, SwizzleConstants,                "shared/SwizzleConstants.sksl")
1266 SKSL_TEST(CPU | GPU,     kApiLevel_V, SwizzleIndexLookup,              "shared/SwizzleIndexLookup.sksl")
1267 SKSL_TEST(CPU | GPU,     kApiLevel_V, SwizzleIndexStore,               "shared/SwizzleIndexStore.sksl")
1268 SKSL_TEST(CPU | GPU,     kApiLevel_T, SwizzleLTRB,                     "shared/SwizzleLTRB.sksl")
1269 SKSL_TEST(CPU | GPU,     kApiLevel_T, SwizzleOpt,                      "shared/SwizzleOpt.sksl")
1270 SKSL_TEST(CPU | GPU,     kApiLevel_T, SwizzleScalar,                   "shared/SwizzleScalar.sksl")
1271 SKSL_TEST(CPU | GPU,     kApiLevel_T, SwizzleScalarBool,               "shared/SwizzleScalarBool.sksl")
1272 SKSL_TEST(CPU | GPU,     kApiLevel_T, SwizzleScalarInt,                "shared/SwizzleScalarInt.sksl")
1273 SKSL_TEST(CPU | GPU,     kApiLevel_V, TemporaryIndexLookup,            "shared/TemporaryIndexLookup.sksl")
1274 SKSL_TEST(CPU | GPU,     kApiLevel_T, TernaryAsLValueEntirelyFoldable, "shared/TernaryAsLValueEntirelyFoldable.sksl")
1275 SKSL_TEST(CPU | GPU,     kApiLevel_T, TernaryAsLValueFoldableTest,     "shared/TernaryAsLValueFoldableTest.sksl")
1276 SKSL_TEST(CPU | GPU,     kApiLevel_V, TernaryComplexNesting,           "shared/TernaryComplexNesting.sksl")
1277 SKSL_TEST(CPU | GPU,     kApiLevel_T, TernaryExpression,               "shared/TernaryExpression.sksl")
1278 SKSL_TEST(CPU | GPU,     kApiLevel_V, TernaryNesting,                  "shared/TernaryNesting.sksl")
1279 SKSL_TEST(CPU | GPU,     kApiLevel_V, TernaryOneZeroOptimization,      "shared/TernaryOneZeroOptimization.sksl")
1280 SKSL_TEST(CPU | GPU,     kApiLevel_U, TernarySideEffects,              "shared/TernarySideEffects.sksl")
1281 SKSL_TEST(CPU | GPU,     kApiLevel_T, UnaryPositiveNegative,           "shared/UnaryPositiveNegative.sksl")
1282 SKSL_TEST(CPU | GPU,     kApiLevel_T, UniformArray,                    "shared/UniformArray.sksl")
1283 SKSL_TEST(CPU | GPU,     kApiLevel_U, UniformMatrixResize,             "shared/UniformMatrixResize.sksl")
1284 SKSL_TEST(CPU | GPU,     kApiLevel_T, UnusedVariables,                 "shared/UnusedVariables.sksl")
1285 SKSL_TEST(CPU | GPU,     kApiLevel_T, VectorConstructors,              "shared/VectorConstructors.sksl")
1286 SKSL_TEST(CPU | GPU,     kApiLevel_T, VectorToMatrixCast,              "shared/VectorToMatrixCast.sksl")
1287 SKSL_TEST(CPU | GPU,     kApiLevel_T, VectorScalarMath,                "shared/VectorScalarMath.sksl")
1288 SKSL_TEST(ES3 | GPU_ES3, kNever,      WhileLoopControlFlow,            "shared/WhileLoopControlFlow.sksl")
1289 
1290 SKSL_TEST(CPU | GPU,     kApiLevel_V, VoidInSequenceExpressions,       "workarounds/VoidInSequenceExpressions.sksl")
1291