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/GrDirectContext.h"
24 #include "include/private/SkSLProgramElement.h"
25 #include "include/private/SkSLProgramKind.h"
26 #include "include/private/base/SkTArray.h"
27 #include "include/sksl/DSLCore.h"
28 #include "include/sksl/SkSLVersion.h"
29 #include "src/base/SkArenaAlloc.h"
30 #include "src/core/SkRasterPipeline.h"
31 #include "src/core/SkRasterPipelineOpContexts.h"
32 #include "src/core/SkRasterPipelineOpList.h"
33 #include "src/core/SkRuntimeEffectPriv.h"
34 #include "src/gpu/ganesh/GrCaps.h"
35 #include "src/gpu/ganesh/GrDirectContextPriv.h"
36 #include "src/gpu/ganesh/GrShaderCaps.h"
37 #include "src/sksl/SkSLCompiler.h"
38 #include "src/sksl/SkSLProgramSettings.h"
39 #include "src/sksl/SkSLUtil.h"
40 #include "src/sksl/codegen/SkSLRasterPipelineBuilder.h"
41 #include "src/sksl/codegen/SkSLRasterPipelineCodeGenerator.h"
42 #include "src/sksl/ir/SkSLFunctionDeclaration.h"
43 #include "src/sksl/ir/SkSLProgram.h"
44 #include "src/sksl/tracing/SkRPDebugTrace.h"
45 #include "tests/CtsEnforcement.h"
46 #include "tests/Test.h"
47 #include "tools/Resources.h"
48 
49 #include <cstdint>
50 #include <memory>
51 #include <string>
52 #include <string_view>
53 #include <vector>
54 
55 // This debugging toggle enables extra logging in `test_raster_pipeline`.
56 //#define DUMP_RP_PROGRAMS 1
57 
58 struct GrContextOptions;
59 
60 static constexpr int kWidth = 2;
61 static constexpr int kHeight = 2;
62 
63 namespace SkSLTestFlags {
64     /** VM tests must pass on the SkVM backend. */
65     static constexpr int VM      = 1 << 0;
66 
67     /** RP tests must pass on SkRasterPipeline backend. */
68     static constexpr int RP      = 1 << 1;
69 
70     /** GPU tests must pass on all GPU backends. */
71     static constexpr int GPU     = 1 << 2;
72 
73     /** GPU_ES3 tests must pass on ES3-compatible GPUs when "enforce ES2 restrictions" is off. */
74     static constexpr int GPU_ES3 = 1 << 4;
75 
76     /**
77      * UsesNaN tests rely on NaN values, so they are only expected to pass on GPUs that generate
78      * them (which is not a requirement, even with ES3).
79      */
80     static constexpr int UsesNaN = 1 << 8;
81 }
82 
is_skvm(int flags)83 static constexpr bool is_skvm(int flags) {
84     return flags & SkSLTestFlags::VM;
85 }
86 
is_gpu(int flags)87 static constexpr bool is_gpu(int flags) {
88     return flags & (SkSLTestFlags::GPU | SkSLTestFlags::GPU_ES3);
89 }
90 
is_strict_es2(int flags)91 static constexpr bool is_strict_es2(int flags) {
92     return !(flags & (SkSLTestFlags::GPU_ES3 | SkSLTestFlags::RP));
93 }
94 
95 struct UniformData {
96     std::string_view    name;
97     SkSpan<const float> span;
98 };
99 
100 static constexpr float kUniformColorBlack[]    = {0.0f, 0.0f, 0.0f, 1.0f};
101 static constexpr float kUniformColorRed  []    = {1.0f, 0.0f, 0.0f, 1.0f};
102 static constexpr float kUniformColorGreen[]    = {0.0f, 1.0f, 0.0f, 1.0f};
103 static constexpr float kUniformColorBlue []    = {0.0f, 0.0f, 1.0f, 1.0f};
104 static constexpr float kUniformColorWhite[]    = {1.0f, 1.0f, 1.0f, 1.0f};
105 static constexpr float kUniformTestInputs[]    = {-1.25f, 0.0f, 0.75f, 2.25f};
106 static constexpr float kUniformUnknownInput[]  = {1.0f};
107 static constexpr float kUniformTestMatrix2x2[] = {1.0f, 2.0f,
108                                                   3.0f, 4.0f};
109 static constexpr float kUniformTestMatrix3x3[] = {1.0f, 2.0f, 3.0f,
110                                                   4.0f, 5.0f, 6.0f,
111                                                   7.0f, 8.0f, 9.0f};
112 static constexpr float kUniformTestMatrix4x4[] = {1.0f,  2.0f,  3.0f,  4.0f,
113                                                   5.0f,  6.0f,  7.0f,  8.0f,
114                                                   9.0f,  10.0f, 11.0f, 12.0f,
115                                                   13.0f, 14.0f, 15.0f, 16.0f};
116 static constexpr float kUniformTestArray[] = {1, 2, 3, 4, 5};
117 static constexpr float kUniformTestArrayNegative[] = {-1, -2, -3, -4, -5};
118 
119 static constexpr UniformData kUniformData[] = {
120         {"colorBlack", kUniformColorBlack},
121         {"colorRed", kUniformColorRed},
122         {"colorGreen", kUniformColorGreen},
123         {"colorBlue", kUniformColorBlue},
124         {"colorWhite", kUniformColorWhite},
125         {"testInputs", kUniformTestInputs},
126         {"unknownInput", kUniformUnknownInput},
127         {"testMatrix2x2", kUniformTestMatrix2x2},
128         {"testMatrix3x3", kUniformTestMatrix3x3},
129         {"testMatrix4x4", kUniformTestMatrix4x4},
130         {"testArray", kUniformTestArray},
131         {"testArrayNegative", kUniformTestArrayNegative},
132 };
133 
bitmap_from_shader(skiatest::Reporter * r,SkSurface * surface,sk_sp<SkRuntimeEffect> effect)134 static SkBitmap bitmap_from_shader(skiatest::Reporter* r,
135                                    SkSurface* surface,
136                                    sk_sp<SkRuntimeEffect> effect) {
137 
138     SkRuntimeShaderBuilder builder(effect);
139     for (const UniformData& data : kUniformData) {
140         SkRuntimeShaderBuilder::BuilderUniform uniform = builder.uniform(data.name);
141         if (uniform.fVar) {
142             uniform.set(data.span.data(), data.span.size());
143         }
144     }
145 
146     sk_sp<SkShader> shader = builder.makeShader();
147     if (!shader) {
148         return SkBitmap{};
149     }
150 
151     surface->getCanvas()->clear(SK_ColorBLACK);
152 
153     SkPaint paintShader;
154     paintShader.setShader(shader);
155     surface->getCanvas()->drawRect(SkRect::MakeWH(kWidth, kHeight), paintShader);
156 
157     SkBitmap bitmap;
158     REPORTER_ASSERT(r, bitmap.tryAllocPixels(surface->imageInfo()));
159     REPORTER_ASSERT(r, surface->readPixels(bitmap, /*srcX=*/0, /*srcY=*/0));
160     return bitmap;
161 }
162 
gpu_generates_nan(skiatest::Reporter * r,GrDirectContext * ctx)163 static bool gpu_generates_nan(skiatest::Reporter* r, GrDirectContext* ctx) {
164 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
165     // The Metal shader compiler (which is also used under-the-hood for some GL/GLES contexts on
166     // these platforms) enables fast-math by default. That prevents NaN-based tests from passing:
167     // https://developer.apple.com/documentation/metal/mtlcompileoptions/1515914-fastmathenabled
168     return false;
169 #else
170     // If we don't have infinity support, we definitely won't generate NaNs
171     if (!ctx->priv().caps()->shaderCaps()->fInfinitySupport) {
172         return false;
173     }
174 
175     auto effect = SkRuntimeEffect::MakeForShader(SkString(R"(
176         #version 300
177         uniform half4 colorGreen, colorRed;
178 
179         half4 main(float2 xy) {
180             return isnan(colorGreen.r / colorGreen.b) ? colorGreen : colorRed;
181         }
182     )")).effect;
183     REPORTER_ASSERT(r, effect);
184 
185     const SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
186     sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(ctx, skgpu::Budgeted::kNo, info));
187 
188     SkBitmap bitmap = bitmap_from_shader(r, surface.get(), effect);
189     REPORTER_ASSERT(r, !bitmap.empty());
190 
191     SkColor color = bitmap.getColor(0, 0);
192     REPORTER_ASSERT(r, color == SK_ColorGREEN || color == SK_ColorRED);
193     return color == SK_ColorGREEN;
194 #endif
195 }
196 
load_source(skiatest::Reporter * r,const char * testFile,const char * permutationSuffix)197 static SkString load_source(skiatest::Reporter* r,
198                             const char* testFile,
199                             const char* permutationSuffix) {
200     SkString resourcePath = SkStringPrintf("sksl/%s", testFile);
201     sk_sp<SkData> shaderData = GetResourceAsData(resourcePath.c_str());
202     if (!shaderData) {
203         ERRORF(r, "%s%s: Unable to load file", testFile, permutationSuffix);
204         return SkString("");
205     }
206     return SkString{reinterpret_cast<const char*>(shaderData->bytes()), shaderData->size()};
207 }
208 
test_one_permutation(skiatest::Reporter * r,SkSurface * surface,const char * testFile,const char * permutationSuffix,const SkRuntimeEffect::Options & options)209 static void test_one_permutation(skiatest::Reporter* r,
210                                  SkSurface* surface,
211                                  const char* testFile,
212                                  const char* permutationSuffix,
213                                  const SkRuntimeEffect::Options& options) {
214     SkString shaderString = load_source(r, testFile, permutationSuffix);
215     if (shaderString.isEmpty()) {
216         return;
217     }
218     SkRuntimeEffect::Result result = SkRuntimeEffect::MakeForShader(shaderString, options);
219     if (!result.effect) {
220         ERRORF(r, "%s%s: %s", testFile, permutationSuffix, result.errorText.c_str());
221         return;
222     }
223 
224     SkBitmap bitmap = bitmap_from_shader(r, surface, result.effect);
225     if (bitmap.empty()) {
226         ERRORF(r, "%s%s: Unable to build shader", testFile, permutationSuffix);
227         return;
228     }
229 
230     bool success = true;
231     SkColor color[kHeight][kWidth];
232     for (int y = 0; y < kHeight; ++y) {
233         for (int x = 0; x < kWidth; ++x) {
234             color[y][x] = bitmap.getColor(x, y);
235             if (color[y][x] != SK_ColorGREEN) {
236                 success = false;
237             }
238         }
239     }
240 
241     if (!success) {
242         static_assert(kWidth  == 2);
243         static_assert(kHeight == 2);
244         ERRORF(r, "Expected%s: solid green. Actual:\n"
245                   "RRGGBBAA RRGGBBAA\n"
246                   "%02X%02X%02X%02X %02X%02X%02X%02X\n"
247                   "%02X%02X%02X%02X %02X%02X%02X%02X",
248                   permutationSuffix,
249                   SkColorGetR(color[0][0]), SkColorGetG(color[0][0]),
250                   SkColorGetB(color[0][0]), SkColorGetA(color[0][0]),
251 
252                   SkColorGetR(color[0][1]), SkColorGetG(color[0][1]),
253                   SkColorGetB(color[0][1]), SkColorGetA(color[0][1]),
254 
255                   SkColorGetR(color[1][0]), SkColorGetG(color[1][0]),
256                   SkColorGetB(color[1][0]), SkColorGetA(color[1][0]),
257 
258                   SkColorGetR(color[1][1]), SkColorGetG(color[1][1]),
259                   SkColorGetB(color[1][1]), SkColorGetA(color[1][1]));
260     }
261 }
262 
test_permutations(skiatest::Reporter * r,SkSurface * surface,const char * testFile,bool strictES2)263 static void test_permutations(skiatest::Reporter* r,
264                               SkSurface* surface,
265                               const char* testFile,
266                               bool strictES2) {
267     SkRuntimeEffect::Options options =
268             strictES2 ? SkRuntimeEffect::Options{} : SkRuntimeEffectPriv::ES3Options();
269     options.forceUnoptimized = false;
270     test_one_permutation(r, surface, testFile, "", options);
271 
272     options.forceUnoptimized = true;
273     test_one_permutation(r, surface, testFile, " (Unoptimized)", options);
274 }
275 
test_skvm(skiatest::Reporter * r,const char * testFile,int flags)276 static void test_skvm(skiatest::Reporter* r, const char* testFile, int flags) {
277     SkASSERT(flags & SkSLTestFlags::VM);
278 
279     // Create a raster-backed surface.
280     const SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
281     sk_sp<SkSurface> surface(SkSurface::MakeRaster(info));
282 
283     test_permutations(r, surface.get(), testFile, /*strictES2=*/true);
284 }
285 
test_gpu(skiatest::Reporter * r,GrDirectContext * ctx,const char * testFile,int flags)286 static void test_gpu(skiatest::Reporter* r, GrDirectContext* ctx, const char* testFile, int flags) {
287     // If this is an ES3-only test on a GPU which doesn't support SkSL ES3, return immediately.
288     bool shouldRunGPU = (flags & SkSLTestFlags::GPU);
289     bool shouldRunGPU_ES3 =
290             (flags & SkSLTestFlags::GPU_ES3) &&
291             (ctx->priv().caps()->shaderCaps()->supportedSkSLVerion() >= SkSL::Version::k300);
292     if (!shouldRunGPU && !shouldRunGPU_ES3) {
293         return;
294     }
295 
296     // If this is a test that requires the GPU to generate NaN values, check for that first.
297     if (flags & SkSLTestFlags::UsesNaN) {
298         if (!gpu_generates_nan(r, ctx)) {
299             return;
300         }
301     }
302 
303     // Create a GPU-backed surface.
304     const SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
305     sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(ctx, skgpu::Budgeted::kNo, info));
306 
307     if (shouldRunGPU) {
308         test_permutations(r, surface.get(), testFile, /*strictES2=*/true);
309     }
310     if (shouldRunGPU_ES3) {
311         test_permutations(r, surface.get(), testFile, /*strictES2=*/false);
312     }
313 }
314 
test_clone(skiatest::Reporter * r,const char * testFile,int flags)315 static void test_clone(skiatest::Reporter* r, const char* testFile, int flags) {
316     SkString shaderString = load_source(r, testFile, "");
317     if (shaderString.isEmpty()) {
318         return;
319     }
320     SkSL::ProgramSettings settings;
321     settings.fAllowVarDeclarationCloneForTesting = true;
322     // TODO(skia:11209): Can we just put the correct #version in the source files that need this?
323     settings.fMaxVersionAllowed = is_strict_es2(flags) ? SkSL::Version::k100 : SkSL::Version::k300;
324     SkSL::Compiler compiler(SkSL::ShaderCapsFactory::Standalone());
325     std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
326             SkSL::ProgramKind::kRuntimeShader, shaderString.c_str(), settings);
327     if (!program) {
328         ERRORF(r, "%s", compiler.errorText().c_str());
329         return;
330     }
331     // Starting DSL allows us to get access to the ThreadContext::Settings
332     SkSL::dsl::Start(&compiler, SkSL::ProgramKind::kFragment, settings);
333     for (const std::unique_ptr<SkSL::ProgramElement>& element : program->fOwnedElements) {
334         std::string original = element->description();
335         std::string cloned = element->clone()->description();
336         REPORTER_ASSERT(r, original == cloned,
337                 "Mismatch after clone!\nOriginal: %s\nCloned: %s\n", original.c_str(),
338                 cloned.c_str());
339     }
340     SkSL::dsl::End();
341 }
342 
343 #if defined(DUMP_RP_PROGRAMS)
344 #include "src/core/SkStreamPriv.h"
345 #endif
346 
report_rp_pass(skiatest::Reporter * r,const char * testFile,int flags)347 static void report_rp_pass(skiatest::Reporter* r, const char* testFile, int flags) {
348     if (!(flags & SkSLTestFlags::RP)) {
349         ERRORF(r, "NEW: %s", testFile);
350     }
351 }
352 
report_rp_fail(skiatest::Reporter * r,const char * testFile,int flags,const char * reason)353 static void report_rp_fail(skiatest::Reporter* r,
354                            const char* testFile,
355                            int flags,
356                            const char* reason) {
357     if (flags & SkSLTestFlags::RP) {
358         ERRORF(r, "%s: %s", testFile, reason);
359     }
360 }
361 
test_raster_pipeline(skiatest::Reporter * r,const char * testFile,int flags)362 static void test_raster_pipeline(skiatest::Reporter* r, const char* testFile, int flags) {
363     SkString shaderString = load_source(r, testFile, "");
364     if (shaderString.isEmpty()) {
365         return;
366     }
367 
368     // In Raster Pipeline, we can compile and run test shaders directly, without involving a surface
369     // at all.
370     SkSL::Compiler compiler(SkSL::ShaderCapsFactory::Default());
371     SkSL::ProgramSettings settings;
372     settings.fMaxVersionAllowed = SkSL::Version::k300;
373     std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
374             SkSL::ProgramKind::kRuntimeShader, shaderString.c_str(), settings);
375     if (!program) {
376         ERRORF(r, "%s: Unexpected compilation error\n%s", testFile, compiler.errorText().c_str());
377         return;
378     }
379     const SkSL::FunctionDeclaration* main = program->getFunction("main");
380     if (!main) {
381         ERRORF(r, "%s: Program must have a 'main' function", testFile);
382         return;
383     }
384 
385     // Match up uniforms from the program against our list of test uniforms, and build up a data
386     // buffer of uniform floats. TODO: this approach doesn't work for complex types (arrays and
387     // structs), but the RP backend doesn't support those yet regardless.
388     std::unique_ptr<SkSL::UniformInfo> uniformInfo = program->getUniformInfo();
389     SkTArray<float> uniformValues;
390     for (const SkSL::UniformInfo::Uniform& programUniform : uniformInfo->fUniforms) {
391         bool foundMatch = false;
392         for (const UniformData& data : kUniformData) {
393             if (data.name == programUniform.fName) {
394                 SkASSERT((int)data.span.size() == programUniform.fColumns * programUniform.fRows);
395                 foundMatch = true;
396                 uniformValues.push_back_n(data.span.size(), data.span.data());
397                 break;
398             }
399         }
400         if (!foundMatch) {
401             report_rp_fail(r, testFile, flags, "unsupported uniform");
402             return;
403         }
404     }
405 
406     // Compile our program.
407     SkArenaAlloc alloc(/*firstHeapAllocation=*/1000);
408     SkRasterPipeline pipeline(&alloc);
409     SkSL::SkRPDebugTrace debugTrace;
410     std::unique_ptr<SkSL::RP::Program> rasterProg =
411             SkSL::MakeRasterPipelineProgram(*program,
412                                             *main->definition(),
413                                             &debugTrace);
414     if (!rasterProg) {
415         report_rp_fail(r, testFile, flags, "code is not supported");
416         return;
417     }
418 
419 #if defined(DUMP_RP_PROGRAMS)
420     // Dump the program instructions via SkDebugf.
421     SkDebugf("----- %s -----\n\n", testFile);
422     SkDebugfStream stream;
423     rasterProg->dump(&stream);
424     SkDebugf("\n-----\n\n");
425 #endif
426 
427     // Append the SkSL program to the raster pipeline.
428     pipeline.append_constant_color(&alloc, SkColors::kTransparent);
429     rasterProg->appendStages(&pipeline, &alloc, /*callbacks=*/nullptr, SkSpan(uniformValues));
430 
431     // Move the float values from RGBA into an 8888 memory buffer.
432     uint32_t out[SkRasterPipeline_kMaxStride_highp] = {};
433     SkRasterPipeline_MemoryCtx outCtx{/*pixels=*/out, /*stride=*/SkRasterPipeline_kMaxStride_highp};
434     pipeline.append(SkRasterPipelineOp::store_8888, &outCtx);
435     pipeline.run(0, 0, 1, 1);
436 
437     // Make sure the first pixel (exclusively) of `out` is green. If the program compiled
438     // successfully, we expect it to run without error, and will assert if it doesn't.
439     uint32_t expected = 0xFF00FF00;
440     if (out[0] != expected) {
441         ERRORF(r, "%s: Raster Pipeline failed. Expected solid green, got ARGB:%02X%02X%02X%02X",
442                   testFile,
443                   (out[0] >> 24) & 0xFF,
444                   (out[0] >> 16) & 0xFF,
445                   (out[0] >> 8) & 0xFF,
446                   out[0] & 0xFF);
447         return;
448     }
449 
450     // Success!
451     report_rp_pass(r, testFile, flags);
452 }
453 
454 #undef DUMP_RP_PROGRAMS
455 #undef REPORT_RP_PASS_FAIL
456 
457 #define SKSL_TEST(flags, ctsEnforcement, name, path)                                         \
458     DEF_CONDITIONAL_TEST(SkSL##name##_CPU, r, is_skvm(flags)) { test_skvm(r, path, flags); } \
459     DEF_CONDITIONAL_GANESH_TEST_FOR_RENDERING_CONTEXTS(                                      \
460             SkSL##name##_GPU, r, ctxInfo, is_gpu(flags), ctsEnforcement) {                   \
461         test_gpu(r, ctxInfo.directContext(), path, flags);                                   \
462     }                                                                                        \
463     DEF_TEST(SkSL##name##_Clone, r) { test_clone(r, path, flags); }                          \
464     DEF_TEST(SkSL##name##_RP, r) { test_raster_pipeline(r, path, flags); }
465 
466 /**
467  * Test flags:
468  * - CPU:     this test should pass on the CPU backend
469  * - GPU:     this test should pass on the Ganesh GPU backends
470  * - GPU_ES3: this test should pass on an ES3-compatible GPU when "enforce ES2 restrictions" is off
471  *
472  * CtsEnforcement:
473  *   Android CTS (go/wtf/cts) enforces that devices must pass this test at the given API level.
474  *   CTS and Android SkQP builds should only run tests on devices greater than the provided API
475  *   level, but other test binaries (dm/fm) should run every test, regardless of this value.
476  */
477 
478 // clang-format off
479 
480 using namespace SkSLTestFlags;
481 
482 constexpr auto kApiLevel_T = CtsEnforcement::kApiLevel_T;
483 constexpr auto kNever = CtsEnforcement::kNever;
484 constexpr auto kNextRelease = CtsEnforcement::kNextRelease;
485 
486 SKSL_TEST(RP + VM + GPU, kApiLevel_T, ArraySizeFolding,                "folding/ArraySizeFolding.rts")
487 SKSL_TEST(RP + VM + GPU, kApiLevel_T, AssignmentOps,                   "folding/AssignmentOps.rts")
488 SKSL_TEST(RP + VM + GPU, kApiLevel_T, BoolFolding,                     "folding/BoolFolding.rts")
489 SKSL_TEST(RP + VM + GPU, kApiLevel_T, CastFolding,                     "folding/CastFolding.rts")
490 SKSL_TEST(RP + VM + GPU, kApiLevel_T, IntFoldingES2,                   "folding/IntFoldingES2.rts")
491 SKSL_TEST(RP + GPU_ES3,  kNever,      IntFoldingES3,                   "folding/IntFoldingES3.sksl")
492 SKSL_TEST(RP + VM + GPU, kApiLevel_T, FloatFolding,                    "folding/FloatFolding.rts")
493 SKSL_TEST(RP + VM + GPU, kApiLevel_T, MatrixFoldingES2,                "folding/MatrixFoldingES2.rts")
494 SKSL_TEST(RP + GPU_ES3,  kNever,      MatrixFoldingES3,                "folding/MatrixFoldingES3.sksl")
495 SKSL_TEST(RP + VM + GPU, kNextRelease, MatrixNoOpFolding,               "folding/MatrixNoOpFolding.rts")
496 SKSL_TEST(RP + VM + GPU, kNextRelease, MatrixScalarNoOpFolding,         "folding/MatrixScalarNoOpFolding.rts")
497 SKSL_TEST(RP + VM + GPU, kNextRelease, MatrixVectorNoOpFolding,         "folding/MatrixVectorNoOpFolding.rts")
498 SKSL_TEST(RP + VM + GPU, kApiLevel_T, Negation,                        "folding/Negation.rts")
499 // TODO(skia:13035): This test fails on Nvidia GPUs on OpenGL but passes Vulkan. Re-enable the test
500 // on Vulkan when granular GPU backend selection is supported.
501 SKSL_TEST(RP + VM,       kApiLevel_T, PreserveSideEffects,             "folding/PreserveSideEffects.rts")
502 SKSL_TEST(RP + VM + GPU, kApiLevel_T, SelfAssignment,                  "folding/SelfAssignment.rts")
503 SKSL_TEST(RP + VM + GPU, kApiLevel_T, ShortCircuitBoolFolding,         "folding/ShortCircuitBoolFolding.rts")
504 SKSL_TEST(RP + VM + GPU, kNextRelease, StructFieldFolding,              "folding/StructFieldFolding.rts")
505 SKSL_TEST(RP + VM + GPU, kNextRelease, StructFieldNoFolding,            "folding/StructFieldNoFolding.rts")
506 SKSL_TEST(RP + VM + GPU, kApiLevel_T, SwitchCaseFolding,               "folding/SwitchCaseFolding.rts")
507 SKSL_TEST(RP + VM + GPU, kApiLevel_T, SwizzleFolding,                  "folding/SwizzleFolding.rts")
508 SKSL_TEST(RP + VM + GPU, kNextRelease, TernaryFolding,                  "folding/TernaryFolding.rts")
509 SKSL_TEST(RP + VM + GPU, kApiLevel_T, VectorScalarFolding,             "folding/VectorScalarFolding.rts")
510 SKSL_TEST(RP + VM + GPU, kApiLevel_T, VectorVectorFolding,             "folding/VectorVectorFolding.rts")
511 
512 SKSL_TEST(RP + GPU_ES3,  kNever,      DoWhileBodyMustBeInlinedIntoAScope,               "inliner/DoWhileBodyMustBeInlinedIntoAScope.sksl")
513 SKSL_TEST(RP + GPU_ES3,  kNever,      DoWhileTestCannotBeInlined,                       "inliner/DoWhileTestCannotBeInlined.sksl")
514 SKSL_TEST(RP + VM + GPU, kApiLevel_T, ForBodyMustBeInlinedIntoAScope,                   "inliner/ForBodyMustBeInlinedIntoAScope.sksl")
515 SKSL_TEST(RP + GPU_ES3,  kNever,      ForInitializerExpressionsCanBeInlined,            "inliner/ForInitializerExpressionsCanBeInlined.sksl")
516 SKSL_TEST(RP + VM + GPU, kApiLevel_T, ForWithoutReturnInsideCanBeInlined,               "inliner/ForWithoutReturnInsideCanBeInlined.sksl")
517 SKSL_TEST(RP + VM + GPU, kApiLevel_T, ForWithReturnInsideCannotBeInlined,               "inliner/ForWithReturnInsideCannotBeInlined.sksl")
518 SKSL_TEST(RP + VM + GPU, kApiLevel_T, IfBodyMustBeInlinedIntoAScope,                    "inliner/IfBodyMustBeInlinedIntoAScope.sksl")
519 SKSL_TEST(RP + VM + GPU, kApiLevel_T, IfElseBodyMustBeInlinedIntoAScope,                "inliner/IfElseBodyMustBeInlinedIntoAScope.sksl")
520 SKSL_TEST(RP + VM + GPU, kApiLevel_T, IfElseChainWithReturnsCanBeInlined,               "inliner/IfElseChainWithReturnsCanBeInlined.sksl")
521 SKSL_TEST(RP + VM + GPU, kApiLevel_T, IfTestCanBeInlined,                               "inliner/IfTestCanBeInlined.sksl")
522 SKSL_TEST(RP + VM + GPU, kApiLevel_T, IfWithReturnsCanBeInlined,                        "inliner/IfWithReturnsCanBeInlined.sksl")
523 SKSL_TEST(RP + VM + GPU, kApiLevel_T, InlineKeywordOverridesThreshold,                  "inliner/InlineKeywordOverridesThreshold.sksl")
524 SKSL_TEST(RP + VM + GPU, kApiLevel_T, InlinerAvoidsVariableNameOverlap,                 "inliner/InlinerAvoidsVariableNameOverlap.sksl")
525 SKSL_TEST(RP + VM + GPU, kApiLevel_T, InlinerElidesTempVarForReturnsInsideBlock,        "inliner/InlinerElidesTempVarForReturnsInsideBlock.sksl")
526 SKSL_TEST(RP + VM + GPU, kApiLevel_T, InlinerUsesTempVarForMultipleReturns,             "inliner/InlinerUsesTempVarForMultipleReturns.sksl")
527 SKSL_TEST(RP + VM + GPU, kApiLevel_T, InlinerUsesTempVarForReturnsInsideBlockWithVar,   "inliner/InlinerUsesTempVarForReturnsInsideBlockWithVar.sksl")
528 SKSL_TEST(RP + VM + GPU, kApiLevel_T, InlineThreshold,                                  "inliner/InlineThreshold.sksl")
529 SKSL_TEST(RP + GPU_ES3,  kNextRelease, InlineUnscopedVariable,                           "inliner/InlineUnscopedVariable.sksl")
530 SKSL_TEST(RP + VM + GPU, kApiLevel_T, InlineWithModifiedArgument,                       "inliner/InlineWithModifiedArgument.sksl")
531 SKSL_TEST(RP + VM + GPU, kApiLevel_T, InlineWithNestedBigCalls,                         "inliner/InlineWithNestedBigCalls.sksl")
532 SKSL_TEST(RP + VM + GPU, kApiLevel_T, InlineWithUnmodifiedArgument,                     "inliner/InlineWithUnmodifiedArgument.sksl")
533 SKSL_TEST(RP + VM + GPU, kApiLevel_T, InlineWithUnnecessaryBlocks,                      "inliner/InlineWithUnnecessaryBlocks.sksl")
534 SKSL_TEST(RP + VM + GPU, kApiLevel_T, NoInline,                                         "inliner/NoInline.sksl")
535 SKSL_TEST(RP + VM + GPU, kApiLevel_T, ShortCircuitEvaluationsCannotInlineRightHandSide, "inliner/ShortCircuitEvaluationsCannotInlineRightHandSide.sksl")
536 SKSL_TEST(RP + GPU_ES3,  kNever,      StaticSwitchInline,                               "inliner/StaticSwitch.sksl")
537 SKSL_TEST(RP + VM + GPU, kApiLevel_T, StructsCanBeInlinedSafely,                        "inliner/StructsCanBeInlinedSafely.sksl")
538 SKSL_TEST(RP + VM + GPU, kApiLevel_T, SwizzleCanBeInlinedDirectly,                      "inliner/SwizzleCanBeInlinedDirectly.sksl")
539 SKSL_TEST(RP + VM + GPU, kApiLevel_T, TernaryResultsCannotBeInlined,                    "inliner/TernaryResultsCannotBeInlined.sksl")
540 SKSL_TEST(RP + VM + GPU, kApiLevel_T, TernaryTestCanBeInlined,                          "inliner/TernaryTestCanBeInlined.sksl")
541 SKSL_TEST(RP + VM + GPU, kApiLevel_T, TrivialArgumentsInlineDirectly,                   "inliner/TrivialArgumentsInlineDirectly.sksl")
542 SKSL_TEST(GPU_ES3,       kNever,      TrivialArgumentsInlineDirectlyES3,                "inliner/TrivialArgumentsInlineDirectlyES3.sksl")
543 SKSL_TEST(RP + GPU_ES3,  kNever,      WhileBodyMustBeInlinedIntoAScope,                 "inliner/WhileBodyMustBeInlinedIntoAScope.sksl")
544 SKSL_TEST(RP + GPU_ES3,  kNever,      WhileTestCannotBeInlined,                         "inliner/WhileTestCannotBeInlined.sksl")
545 
546 SKSL_TEST(RP + VM + GPU, kApiLevel_T, IntrinsicAbsFloat,               "intrinsics/AbsFloat.sksl")
547 SKSL_TEST(RP + GPU_ES3,  kNever,      IntrinsicAbsInt,                 "intrinsics/AbsInt.sksl")
548 SKSL_TEST(RP + VM + GPU, kNever,      IntrinsicAny,                    "intrinsics/Any.sksl")
549 SKSL_TEST(RP + VM + GPU, kNever,      IntrinsicAll,                    "intrinsics/All.sksl")
550 SKSL_TEST(RP + VM + GPU, kApiLevel_T, IntrinsicCeil,                   "intrinsics/Ceil.sksl")
551 SKSL_TEST(RP + GPU_ES3,  kNever,      IntrinsicClampInt,               "intrinsics/ClampInt.sksl")
552 SKSL_TEST(RP + GPU_ES3,  kNever,      IntrinsicClampUInt,              "intrinsics/ClampUInt.sksl")
553 SKSL_TEST(RP + VM + GPU, kApiLevel_T, IntrinsicClampFloat,             "intrinsics/ClampFloat.sksl")
554 SKSL_TEST(RP + VM + GPU, kNever,      IntrinsicCross,                  "intrinsics/Cross.sksl")
555 SKSL_TEST(RP + VM + GPU, kNever,      IntrinsicDegrees,                "intrinsics/Degrees.sksl")
556 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicDeterminant,            "intrinsics/Determinant.sksl")
557 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicDFdx,                   "intrinsics/DFdx.sksl")
558 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicDFdy,                   "intrinsics/DFdy.sksl")
559 SKSL_TEST(RP + VM + GPU, kNever,      IntrinsicDot,                    "intrinsics/Dot.sksl")
560 SKSL_TEST(RP + VM + GPU, kNever,      IntrinsicFract,                  "intrinsics/Fract.sksl")
561 SKSL_TEST(RP + GPU_ES3,  kNever,      IntrinsicFloatBitsToInt,         "intrinsics/FloatBitsToInt.sksl")
562 SKSL_TEST(RP + GPU_ES3,  kNever,      IntrinsicFloatBitsToUint,        "intrinsics/FloatBitsToUint.sksl")
563 SKSL_TEST(RP + VM + GPU, kNever,      IntrinsicFloor,                  "intrinsics/Floor.sksl")
564 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicFwidth,                 "intrinsics/Fwidth.sksl")
565 SKSL_TEST(RP + GPU_ES3,  kNever,      IntrinsicIntBitsToFloat,         "intrinsics/IntBitsToFloat.sksl")
566 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicIsInf,                  "intrinsics/IsInf.sksl")
567 SKSL_TEST(RP + VM + GPU, kNever,      IntrinsicLength,                 "intrinsics/Length.sksl")
568 SKSL_TEST(RP + VM + GPU, kApiLevel_T, IntrinsicMatrixCompMultES2,      "intrinsics/MatrixCompMultES2.sksl")
569 SKSL_TEST(RP + GPU_ES3,  kNever,      IntrinsicMatrixCompMultES3,      "intrinsics/MatrixCompMultES3.sksl")
570 SKSL_TEST(RP + VM + GPU, kApiLevel_T, IntrinsicMaxFloat,               "intrinsics/MaxFloat.sksl")
571 SKSL_TEST(RP + GPU_ES3,  kNever,      IntrinsicMaxInt,                 "intrinsics/MaxInt.sksl")
572 SKSL_TEST(RP + GPU_ES3,  kNever,      IntrinsicMaxUint,                "intrinsics/MaxUint.sksl")
573 SKSL_TEST(RP + VM + GPU, kApiLevel_T, IntrinsicMinFloat,               "intrinsics/MinFloat.sksl")
574 SKSL_TEST(RP + GPU_ES3,  kNever,      IntrinsicMinInt,                 "intrinsics/MinInt.sksl")
575 SKSL_TEST(RP + GPU_ES3,  kNever,      IntrinsicMinUint,                "intrinsics/MinUint.sksl")
576 SKSL_TEST(RP + VM + GPU, kApiLevel_T, IntrinsicMixFloatES2,            "intrinsics/MixFloatES2.sksl")
577 SKSL_TEST(RP + GPU_ES3,  kNever,      IntrinsicMixFloatES3,            "intrinsics/MixFloatES3.sksl")
578 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicModf,                   "intrinsics/Modf.sksl")
579 SKSL_TEST(RP + VM + GPU, kNever,      IntrinsicNot,                    "intrinsics/Not.sksl")
580 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicOuterProduct,           "intrinsics/OuterProduct.sksl")
581 // Fails on Mac OpenGL + Radeon 5300M (skia:12434)
582 // SKSL_TEST(GPU_ES3,    kNever,      IntrinsicPackUnorm2x16,          "intrinsics/PackUnorm2x16.sksl")
583 SKSL_TEST(RP + VM + GPU, kNever,      IntrinsicRadians,                "intrinsics/Radians.sksl")
584 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicRound,                  "intrinsics/Round.sksl")
585 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicRoundEven,              "intrinsics/RoundEven.sksl")
586 SKSL_TEST(RP + VM + GPU, kNever,      IntrinsicSaturate,               "intrinsics/Saturate.sksl")
587 SKSL_TEST(RP + VM + GPU, kApiLevel_T, IntrinsicSignFloat,              "intrinsics/SignFloat.sksl")
588 SKSL_TEST(RP + GPU_ES3,  kNever,      IntrinsicSignInt,                "intrinsics/SignInt.sksl")
589 SKSL_TEST(RP + VM + GPU, kNever,      IntrinsicSqrt,                   "intrinsics/Sqrt.sksl")
590 SKSL_TEST(RP + VM + GPU, kApiLevel_T, IntrinsicStep,                   "intrinsics/Step.sksl")
591 SKSL_TEST(GPU_ES3,       kNever,      IntrinsicTrunc,                  "intrinsics/Trunc.sksl")
592 SKSL_TEST(RP + GPU_ES3,  kNever,      IntrinsicTranspose,              "intrinsics/Transpose.sksl")
593 SKSL_TEST(RP + GPU_ES3,  kNever,      IntrinsicUintBitsToFloat,        "intrinsics/UintBitsToFloat.sksl")
594 
595 SKSL_TEST(GPU_ES3,       kNever,      ArrayNarrowingConversions,       "runtime/ArrayNarrowingConversions.rts")
596 SKSL_TEST(RP + GPU_ES3,  kNever,      Commutative,                     "runtime/Commutative.rts")
597 SKSL_TEST(RP + VM + GPU, kApiLevel_T, LoopFloat,                       "runtime/LoopFloat.rts")
598 SKSL_TEST(RP + VM + GPU, kApiLevel_T, LoopInt,                         "runtime/LoopInt.rts")
599 SKSL_TEST(RP + VM + GPU, kNextRelease, Ossfuzz52603,                    "runtime/Ossfuzz52603.rts")
600 SKSL_TEST(RP + VM + GPU, kApiLevel_T, QualifierOrder,                  "runtime/QualifierOrder.rts")
601 SKSL_TEST(RP + VM + GPU, kApiLevel_T, PrecisionQualifiers,             "runtime/PrecisionQualifiers.rts")
602 
603 SKSL_TEST(RP + GPU_ES3 + UsesNaN, kNever, RecursiveComparison_Arrays,  "runtime/RecursiveComparison_Arrays.rts")
604 SKSL_TEST(RP + GPU_ES3 + UsesNaN, kNever, RecursiveComparison_Structs, "runtime/RecursiveComparison_Structs.rts")
605 SKSL_TEST(RP + GPU_ES3 + UsesNaN, kNever, RecursiveComparison_Types,   "runtime/RecursiveComparison_Types.rts")
606 SKSL_TEST(RP + GPU_ES3 + UsesNaN, kNever, RecursiveComparison_Vectors, "runtime/RecursiveComparison_Vectors.rts")
607 
608 SKSL_TEST(GPU_ES3,           kNever,      ArrayCast,                       "shared/ArrayCast.sksl")
609 SKSL_TEST(GPU_ES3,           kNever,      ArrayComparison,                 "shared/ArrayComparison.sksl")
610 SKSL_TEST(GPU_ES3,           kNever,      ArrayConstructors,               "shared/ArrayConstructors.sksl")
611 SKSL_TEST(RP + VM + GPU_ES3, kNever,      ArrayFollowedByScalar,           "shared/ArrayFollowedByScalar.sksl")
612 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, ArrayTypes,                      "shared/ArrayTypes.sksl")
613 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, Assignment,                      "shared/Assignment.sksl")
614 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, CastsRoundTowardZero,            "shared/CastsRoundTowardZero.sksl")
615 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, CommaMixedTypes,                 "shared/CommaMixedTypes.sksl")
616 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, CommaSideEffects,                "shared/CommaSideEffects.sksl")
617 SKSL_TEST(RP + VM + GPU,     kNextRelease, CompileTimeConstantVariables,    "shared/CompileTimeConstantVariables.sksl")
618 SKSL_TEST(GPU_ES3,           kNever,      ConstantCompositeAccessViaConstantIndex, "shared/ConstantCompositeAccessViaConstantIndex.sksl")
619 SKSL_TEST(GPU_ES3,           kNever,      ConstantCompositeAccessViaDynamicIndex,  "shared/ConstantCompositeAccessViaDynamicIndex.sksl")
620 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, ConstantIf,                      "shared/ConstantIf.sksl")
621 SKSL_TEST(RP + GPU_ES3,      kNever,      ConstArray,                      "shared/ConstArray.sksl")
622 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, ConstVariableComparison,         "shared/ConstVariableComparison.sksl")
623 SKSL_TEST(RP + VM + GPU,     kNever,      DeadGlobals,                     "shared/DeadGlobals.sksl")
624 SKSL_TEST(RP + GPU_ES3,      kNever,      DeadLoopVariable,                "shared/DeadLoopVariable.sksl")
625 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, DeadIfStatement,                 "shared/DeadIfStatement.sksl")
626 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, DeadReturn,                      "shared/DeadReturn.sksl")
627 // TODO(skia:12012): some Radeons crash when compiling this code; disable them.
628 SKSL_TEST(RP /* +GPU_ES3 */, kNever,      SkSLDeadReturnES3,               "shared/DeadReturnES3.sksl")
629 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, DeadStripFunctions,              "shared/DeadStripFunctions.sksl")
630 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, DependentInitializers,           "shared/DependentInitializers.sksl")
631 SKSL_TEST(RP + VM + GPU,     kNextRelease, DoubleNegation,                  "shared/DoubleNegation.sksl")
632 SKSL_TEST(RP + GPU_ES3,      kNever,      DoWhileControlFlow,              "shared/DoWhileControlFlow.sksl")
633 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, EmptyBlocksES2,                  "shared/EmptyBlocksES2.sksl")
634 SKSL_TEST(RP + GPU_ES3,      kNever,      EmptyBlocksES3,                  "shared/EmptyBlocksES3.sksl")
635 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, ForLoopControlFlow,              "shared/ForLoopControlFlow.sksl")
636 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, FunctionAnonymousParameters,     "shared/FunctionAnonymousParameters.sksl")
637 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, FunctionArgTypeMatch,            "shared/FunctionArgTypeMatch.sksl")
638 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, FunctionReturnTypeMatch,         "shared/FunctionReturnTypeMatch.sksl")
639 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, Functions,                       "shared/Functions.sksl")
640 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, FunctionPrototype,               "shared/FunctionPrototype.sksl")
641 SKSL_TEST(VM + GPU,          kApiLevel_T, GeometricIntrinsics,             "shared/GeometricIntrinsics.sksl")
642 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, HelloWorld,                      "shared/HelloWorld.sksl")
643 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, Hex,                             "shared/Hex.sksl")
644 SKSL_TEST(RP + GPU_ES3,      kNever,      HexUnsigned,                     "shared/HexUnsigned.sksl")
645 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, InoutParameters,                 "shared/InoutParameters.sksl")
646 SKSL_TEST(RP + VM + GPU,     kNextRelease, InoutParamsAreDistinct,          "shared/InoutParamsAreDistinct.sksl")
647 SKSL_TEST(RP + GPU_ES3,      kNextRelease, IntegerDivisionES3,              "shared/IntegerDivisionES3.sksl")
648 SKSL_TEST(RP + VM + GPU,     kNextRelease,LogicalAndShortCircuit,          "shared/LogicalAndShortCircuit.sksl")
649 SKSL_TEST(RP + VM + GPU,     kNextRelease,LogicalOrShortCircuit,           "shared/LogicalOrShortCircuit.sksl")
650 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, Matrices,                        "shared/Matrices.sksl")
651 SKSL_TEST(RP + GPU_ES3,      kNever,      MatricesNonsquare,               "shared/MatricesNonsquare.sksl")
652 // TODO(skia:12443) The MatrixConstructors tests actually don't work on MANY devices. The GLSL SkQP
653 // suite does a terrible job of enforcing this rule. We still test the ES2 variant on CPU.
654 SKSL_TEST(RP + VM,           kNever,      MatrixConstructorsES2,           "shared/MatrixConstructorsES2.sksl")
655 SKSL_TEST(RP,                kNever,      MatrixConstructorsES3,           "shared/MatrixConstructorsES3.sksl")
656 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, MatrixEquality,                  "shared/MatrixEquality.sksl")
657 SKSL_TEST(RP + VM + GPU,     kNextRelease,MatrixOpEqualsES2,               "shared/MatrixOpEqualsES2.sksl")
658 SKSL_TEST(RP + GPU_ES3,      kNextRelease,MatrixOpEqualsES3,               "shared/MatrixOpEqualsES3.sksl")
659 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, MatrixScalarMath,                "shared/MatrixScalarMath.sksl")
660 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, MatrixToVectorCast,              "shared/MatrixToVectorCast.sksl")
661 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, MultipleAssignments,             "shared/MultipleAssignments.sksl")
662 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, NumberCasts,                     "shared/NumberCasts.sksl")
663 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, OperatorsES2,                    "shared/OperatorsES2.sksl")
664 SKSL_TEST(GPU_ES3,           kNever,      OperatorsES3,                    "shared/OperatorsES3.sksl")
665 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, Ossfuzz36852,                    "shared/Ossfuzz36852.sksl")
666 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, OutParams,                       "shared/OutParams.sksl")
667 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, OutParamsAreDistinct,            "shared/OutParamsAreDistinct.sksl")
668 SKSL_TEST(RP + VM + GPU,     kNextRelease, OutParamsAreDistinctFromGlobal,  "shared/OutParamsAreDistinctFromGlobal.sksl")
669 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, OutParamsTricky,                 "shared/OutParamsTricky.sksl")
670 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, ResizeMatrix,                    "shared/ResizeMatrix.sksl")
671 SKSL_TEST(RP + GPU_ES3,      kNever,      ResizeMatrixNonsquare,           "shared/ResizeMatrixNonsquare.sksl")
672 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, ReturnsValueOnEveryPathES2,      "shared/ReturnsValueOnEveryPathES2.sksl")
673 SKSL_TEST(RP + GPU_ES3,      kNever,      ReturnsValueOnEveryPathES3,      "shared/ReturnsValueOnEveryPathES3.sksl")
674 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, ScalarConversionConstructorsES2, "shared/ScalarConversionConstructorsES2.sksl")
675 SKSL_TEST(RP + GPU_ES3,      kNever,      ScalarConversionConstructorsES3, "shared/ScalarConversionConstructorsES3.sksl")
676 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, ScopedSymbol,                    "shared/ScopedSymbol.sksl")
677 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, StackingVectorCasts,             "shared/StackingVectorCasts.sksl")
678 SKSL_TEST(RP + VM + GPU_ES3, kNever,      StaticSwitch,                    "shared/StaticSwitch.sksl")
679 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, StructArrayFollowedByScalar,     "shared/StructArrayFollowedByScalar.sksl")
680 // TODO(skia:13920): StructComparison currently exposes a bug in SPIR-V codegen.
681 // SKSL_TEST(RP /* +GPU_ES3 */, kNever,      StructComparison,                "shared/StructComparison.sksl")
682 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, StructsInFunctions,              "shared/StructsInFunctions.sksl")
683 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, Switch,                          "shared/Switch.sksl")
684 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, SwitchDefaultOnly,               "shared/SwitchDefaultOnly.sksl")
685 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, SwitchWithFallthrough,           "shared/SwitchWithFallthrough.sksl")
686 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, SwitchWithLoops,                 "shared/SwitchWithLoops.sksl")
687 SKSL_TEST(RP + GPU_ES3,      kNever,      SwitchWithLoopsES3,              "shared/SwitchWithLoopsES3.sksl")
688 SKSL_TEST(RP + VM + GPU,     kNever,      SwizzleAsLValue,                 "shared/SwizzleAsLValue.sksl")
689 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, SwizzleBoolConstants,            "shared/SwizzleBoolConstants.sksl")
690 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, SwizzleByConstantIndex,          "shared/SwizzleByConstantIndex.sksl")
691 SKSL_TEST(GPU_ES3,           kNever,      SwizzleByIndex,                  "shared/SwizzleByIndex.sksl")
692 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, SwizzleConstants,                "shared/SwizzleConstants.sksl")
693 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, SwizzleLTRB,                     "shared/SwizzleLTRB.sksl")
694 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, SwizzleOpt,                      "shared/SwizzleOpt.sksl")
695 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, SwizzleScalar,                   "shared/SwizzleScalar.sksl")
696 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, SwizzleScalarBool,               "shared/SwizzleScalarBool.sksl")
697 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, SwizzleScalarInt,                "shared/SwizzleScalarInt.sksl")
698 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, TernaryAsLValueEntirelyFoldable, "shared/TernaryAsLValueEntirelyFoldable.sksl")
699 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, TernaryAsLValueFoldableTest,     "shared/TernaryAsLValueFoldableTest.sksl")
700 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, TernaryExpression,               "shared/TernaryExpression.sksl")
701 SKSL_TEST(RP + VM + GPU,     kNextRelease,TernarySideEffects,              "shared/TernarySideEffects.sksl")
702 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, UnaryPositiveNegative,           "shared/UnaryPositiveNegative.sksl")
703 SKSL_TEST(VM + GPU,          kApiLevel_T, UniformArray,                    "shared/UniformArray.sksl")
704 SKSL_TEST(RP + VM + GPU,     kNextRelease, UniformMatrixResize,             "shared/UniformMatrixResize.sksl")
705 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, UnusedVariables,                 "shared/UnusedVariables.sksl")
706 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, VectorConstructors,              "shared/VectorConstructors.sksl")
707 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, VectorToMatrixCast,              "shared/VectorToMatrixCast.sksl")
708 SKSL_TEST(RP + VM + GPU,     kApiLevel_T, VectorScalarMath,                "shared/VectorScalarMath.sksl")
709 SKSL_TEST(RP + GPU_ES3,      kNever,      WhileLoopControlFlow,            "shared/WhileLoopControlFlow.sksl")
710