Loosen ES3 restrictions in Runtime Effects for debugging.
This CL adds a RuntimeEffect option flag which skips over the various
`strictES2Mode` checks sprinkled throughout IR generation.
Runtime Effects still won't allow a lot of ES3 things (the Pipeline
stage will reject unsupported statement types, SkVM doesn't support most
non-ES2 constructs, etc). However, this change will give us the ability
to test many more features involving arrays and structs that previously
were off-limits due to ES2 restrictions, and will shore up some
legitimate gaps in our testing. This is a useful starting point to allow
for improved test coverage.
Change-Id: I4a5bc43914e65fc7e59f1cecb76a0ec5a7f05f2f
Bug: skia:11209
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/402157
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/tests/SkRuntimeEffectTest.cpp b/tests/SkRuntimeEffectTest.cpp
index 77f66b7..a6ba883 100644
--- a/tests/SkRuntimeEffectTest.cpp
+++ b/tests/SkRuntimeEffectTest.cpp
@@ -75,11 +75,23 @@
"unknown identifier 'sk_Caps'");
}
+DEF_TEST(SkRuntimeEffectCanDisableES2Restrictions, r) {
+ auto test_valid_es3 = [](skiatest::Reporter* r, const char* sksl) {
+ SkRuntimeEffect::Options opt;
+ opt.enforceES2Restrictions = false;
+ auto [effect, errorText] = SkRuntimeEffect::MakeForShader(SkString(sksl), opt);
+ REPORTER_ASSERT(r, effect, "%s", errorText.c_str());
+ };
+
+ test_invalid_effect(r, "float f[2] = float[2](0, 1);" EMPTY_MAIN, "construction of array type");
+ test_valid_es3 (r, "float f[2] = float[2](0, 1);" EMPTY_MAIN);
+}
+
DEF_TEST(SkRuntimeEffectForColorFilter, r) {
// Tests that the color filter factory rejects or accepts certain SkSL constructs
auto test_valid = [r](const char* sksl) {
auto [effect, errorText] = SkRuntimeEffect::MakeForColorFilter(SkString(sksl));
- REPORTER_ASSERT(r, effect, errorText.c_str());
+ REPORTER_ASSERT(r, effect, "%s", errorText.c_str());
};
auto test_invalid = [r](const char* sksl, const char* expected) {
@@ -131,7 +143,7 @@
// Tests that the shader factory rejects or accepts certain SkSL constructs
auto test_valid = [r](const char* sksl) {
auto [effect, errorText] = SkRuntimeEffect::MakeForShader(SkString(sksl));
- REPORTER_ASSERT(r, effect, errorText.c_str());
+ REPORTER_ASSERT(r, effect, "%s", errorText.c_str());
};
auto test_invalid = [r](const char* sksl, const char* expected) {
diff --git a/tests/SkSLTest.cpp b/tests/SkSLTest.cpp
index 20b3a44..20bcff5 100644
--- a/tests/SkSLTest.cpp
+++ b/tests/SkSLTest.cpp
@@ -19,6 +19,8 @@
#include "include/effects/SkRuntimeEffect.h"
#include "include/private/SkSLDefines.h" // for kDefaultInlineThreshold
#include "include/utils/SkRandom.h"
+#include "src/gpu/GrCaps.h"
+#include "src/gpu/GrDirectContextPriv.h"
#include "tests/Test.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"
@@ -92,8 +94,12 @@
SkColorGetA(color), SkColorGetR(color), SkColorGetG(color), SkColorGetB(color));
}
-static void test_permutations(skiatest::Reporter* r, SkSurface* surface, const char* testFile) {
+static void test_permutations(skiatest::Reporter* r,
+ SkSurface* surface,
+ const char* testFile,
+ bool worksInES2) {
SkRuntimeEffect::Options options;
+ options.enforceES2Restrictions = worksInES2;
options.forceNoInline = false;
test_one_permutation(r, surface, testFile, "", options);
@@ -105,14 +111,28 @@
const SkImageInfo info = SkImageInfo::MakeN32Premul(kRect.width(), kRect.height());
sk_sp<SkSurface> surface(SkSurface::MakeRaster(info));
- test_permutations(r, surface.get(), testFile);
+ test_permutations(r, surface.get(), testFile, /*worksInES2=*/true);
}
static void test_gpu(skiatest::Reporter* r, GrDirectContext* ctx, const char* testFile) {
const SkImageInfo info = SkImageInfo::MakeN32Premul(kRect.width(), kRect.height());
sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info));
- test_permutations(r, surface.get(), testFile);
+ test_permutations(r, surface.get(), testFile, /*worksInES2=*/true);
+}
+
+static void test_es3(skiatest::Reporter* r, GrDirectContext* ctx, const char* testFile) {
+ // We don't have an ES2 caps bit, so we check for integer support and derivatives support.
+ // Our ES2 bots should return false for these.
+ if (!ctx->priv().caps()->shaderCaps()->shaderDerivativeSupport() ||
+ !ctx->priv().caps()->shaderCaps()->integerSupport()) {
+ return;
+ }
+ // ES3-only tests never run on the CPU, because SkVM lacks support for many non-ES2 features.
+ const SkImageInfo info = SkImageInfo::MakeN32Premul(kRect.width(), kRect.height());
+ sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info));
+
+ test_permutations(r, surface.get(), testFile, /*worksInES2=*/false);
}
#define SKSL_TEST_CPU(name, path) \
@@ -123,11 +143,16 @@
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(name ## _GPU, r, ctxInfo) { \
test_gpu(r, ctxInfo.directContext(), path); \
}
+#define SKSL_TEST_ES3(name, path) \
+ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(name ## _GPU, r, ctxInfo) { \
+ test_es3(r, ctxInfo.directContext(), path); \
+ }
#define SKSL_TEST(name, path) SKSL_TEST_CPU(name, path) SKSL_TEST_GPU(name, path)
SKSL_TEST(SkSLAssignmentOps, "folding/AssignmentOps.sksl")
SKSL_TEST(SkSLBoolFolding, "folding/BoolFolding.sksl")
SKSL_TEST(SkSLIntFoldingES2, "folding/IntFoldingES2.sksl")
+SKSL_TEST_ES3(SkSLIntFoldingES3, "folding/IntFoldingES3.sksl")
SKSL_TEST(SkSLFloatFolding, "folding/FloatFolding.sksl")
// skbug.com/11919: Fails on Nexus5/7, and Intel GPUs
SKSL_TEST_CPU(SkSLMatrixFoldingES2, "folding/MatrixFoldingES2.sksl")
@@ -137,6 +162,8 @@
SKSL_TEST(SkSLVectorVectorFolding, "folding/VectorVectorFolding.sksl")
SKSL_TEST(SkSLForBodyMustBeInlinedIntoAScope, "inliner/ForBodyMustBeInlinedIntoAScope.sksl")
+SKSL_TEST_ES3(SkSLForInitializerExpressionsCanBeInlined,
+ "inliner/ForInitializerExpressionsCanBeInlined.sksl")
SKSL_TEST(SkSLForWithoutReturnInsideCanBeInlined, "inliner/ForWithoutReturnInsideCanBeInlined.sksl")
SKSL_TEST(SkSLForWithReturnInsideCannotBeInlined, "inliner/ForWithReturnInsideCannotBeInlined.sksl")
SKSL_TEST(SkSLIfBodyMustBeInlinedIntoAScope, "inliner/IfBodyMustBeInlinedIntoAScope.sksl")
@@ -167,6 +194,9 @@
SKSL_TEST(SkSLTernaryResultsCannotBeInlined, "inliner/TernaryResultsCannotBeInlined.sksl")
SKSL_TEST(SkSLTernaryTestCanBeInlined, "inliner/TernaryTestCanBeInlined.sksl")
SKSL_TEST(SkSLTrivialArgumentsInlineDirectly, "inliner/TrivialArgumentsInlineDirectly.sksl")
+SKSL_TEST_ES3(SkSLWhileBodyMustBeInlinedIntoAScope,
+ "inliner/WhileBodyMustBeInlinedIntoAScope.sksl")
+SKSL_TEST_ES3(SkSLWhileTestCannotBeInlined, "inliner/WhileTestCannotBeInlined.sksl")
// TODO(skia:11052): SPIR-V does not yet honor `out` param semantics correctly
SKSL_TEST_CPU(SkSLInlinerHonorsGLSLOutParamSemantics,
@@ -244,17 +274,12 @@
/*
TODO(skia:11209): enable these tests when Runtime Effects have support for ES3
-SKSL_TEST(SkSLIntFoldingES3, "folding/IntFoldingES3.sksl")
SKSL_TEST(SkSLMatrixFoldingES3, "folding/MatrixFoldingES3.sksl")
SKSL_TEST(SkSLDoWhileBodyMustBeInlinedIntoAScope, "inliner/DoWhileBodyMustBeInlinedIntoAScope.sksl")
SKSL_TEST(SkSLDoWhileTestCannotBeInlined, "inliner/DoWhileTestCannotBeInlined.sksl")
-SKSL_TEST(SkSLEnumsCanBeInlinedSafely, "inliner/EnumsCanBeInlinedSafely.sksl")
-SKSL_TEST(SkSLForInitializerExpressionsCanBeInlined,
- "inliner/ForInitializerExpressionsCanBeInlined.sksl")
+SKSL_TEST(SkSLEnumsCanBeInlinedSafely, "inliner/EnumsCanBeInlinedSafely.sksl")
SKSL_TEST(SkSLStaticSwitch, "inliner/StaticSwitch.sksl")
-SKSL_TEST(SkSLWhileBodyMustBeInlinedIntoAScope, "inliner/WhileBodyMustBeInlinedIntoAScope.sksl")
-SKSL_TEST(SkSLWhileTestCannotBeInlined, "inliner/WhileTestCannotBeInlined.sksl")
SKSL_TEST(SkSLIntrinsicAbsInt, "intrinsics/AbsInt.sksl")
SKSL_TEST(SkSLIntrinsicClampInt, "intrinsics/ClampInt.sksl")
diff --git a/tests/sksl/inliner/ForInitializerExpressionsCanBeInlined.glsl b/tests/sksl/inliner/ForInitializerExpressionsCanBeInlined.glsl
index 29c2e35..52339f3 100644
--- a/tests/sksl/inliner/ForInitializerExpressionsCanBeInlined.glsl
+++ b/tests/sksl/inliner/ForInitializerExpressionsCanBeInlined.glsl
@@ -8,7 +8,7 @@
return v + vec4(0.125);
}
vec4 main() {
- for (sk_FragColor = vec4(0.0625);shouldLoop_bh4(sk_FragColor); sk_FragColor = grow_h4h4(sk_FragColor)) {
+ for (vec4 color = vec4(0.0625);shouldLoop_bh4(color); color = grow_h4h4(color)) {
}
return colorGreen;
}