Move RecursiveComparison tests to run on GPU
These all require the GPU to generate NaN values. We don't have a static way of checking that in caps. Instead, added a probing function to decide if the GPU will generate them, and a flag to indicate which tests require that behavior. Change-Id: I9411969b042684ac583a9eb4e9b1aacf2525cc22 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/549099 Reviewed-by: John Stiles <johnstiles@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
d3d09d660c
commit
55f9ee1e35
@ -63,6 +63,11 @@ namespace SkSLTestFlags {
|
||||
|
||||
/** SkQP tests will be run in Android/Fuchsia conformance tests with no driver workarounds. */
|
||||
static constexpr int SkQP = 1 << 4;
|
||||
|
||||
/** UsesNaN tests rely on NaN values, so they are only expected to pass on GPUs that generate
|
||||
* them (which is not a requirement, even with ES3).
|
||||
*/
|
||||
static constexpr int UsesNaN = 1 << 5;
|
||||
}
|
||||
|
||||
static constexpr bool is_cpu(int flags) {
|
||||
@ -103,6 +108,74 @@ static void set_uniform_array(SkRuntimeShaderBuilder* builder, const char* name,
|
||||
}
|
||||
}
|
||||
|
||||
static SkBitmap bitmap_from_shader(skiatest::Reporter* r,
|
||||
SkSurface* surface,
|
||||
sk_sp<SkRuntimeEffect> effect) {
|
||||
static constexpr float kArray[5] = {1, 2, 3, 4, 5};
|
||||
|
||||
SkRuntimeShaderBuilder builder(effect);
|
||||
set_uniform(&builder, "colorBlack", SkV4{0, 0, 0, 1});
|
||||
set_uniform(&builder, "colorRed", SkV4{1, 0, 0, 1});
|
||||
set_uniform(&builder, "colorGreen", SkV4{0, 1, 0, 1});
|
||||
set_uniform(&builder, "colorBlue", SkV4{0, 0, 1, 1});
|
||||
set_uniform(&builder, "colorWhite", SkV4{1, 1, 1, 1});
|
||||
set_uniform(&builder, "testInputs", SkV4{-1.25, 0, 0.75, 2.25});
|
||||
set_uniform(&builder, "unknownInput", 1.0f);
|
||||
set_uniform(&builder, "testMatrix2x2", std::array<float,4>{1, 2,
|
||||
3, 4});
|
||||
set_uniform(&builder, "testMatrix3x3", std::array<float,9>{1, 2, 3,
|
||||
4, 5, 6,
|
||||
7, 8, 9});
|
||||
set_uniform(&builder, "testMatrix4x4", std::array<float,16>{1, 2, 3, 4,
|
||||
5, 6, 7, 8,
|
||||
9, 10, 11, 12,
|
||||
13, 14, 15, 16});
|
||||
set_uniform_array(&builder, "testArray", SkMakeSpan(kArray));
|
||||
|
||||
sk_sp<SkShader> shader = builder.makeShader();
|
||||
if (!shader) {
|
||||
return SkBitmap{};
|
||||
}
|
||||
|
||||
surface->getCanvas()->clear(SK_ColorBLACK);
|
||||
|
||||
SkPaint paintShader;
|
||||
paintShader.setShader(shader);
|
||||
surface->getCanvas()->drawRect(SkRect::MakeWH(kWidth, kHeight), paintShader);
|
||||
|
||||
SkBitmap bitmap;
|
||||
REPORTER_ASSERT(r, bitmap.tryAllocPixels(surface->imageInfo()));
|
||||
REPORTER_ASSERT(r, surface->readPixels(bitmap, /*srcX=*/0, /*srcY=*/0));
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
static bool gpu_generates_nan(skiatest::Reporter* r, GrDirectContext* ctx) {
|
||||
// If we don't have infinity support, we definitely won't generate NaNs
|
||||
if (!ctx->priv().caps()->shaderCaps()->fInfinitySupport) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto effect = SkRuntimeEffect::MakeForShader(SkString(R"(
|
||||
#version 300
|
||||
uniform half4 colorGreen, colorRed;
|
||||
|
||||
half4 main(float2 xy) {
|
||||
return isnan(colorGreen.r / colorGreen.b) ? colorGreen : colorRed;
|
||||
}
|
||||
)")).effect;
|
||||
REPORTER_ASSERT(r, effect);
|
||||
|
||||
const SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
|
||||
sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info));
|
||||
|
||||
SkBitmap bitmap = bitmap_from_shader(r, surface.get(), effect);
|
||||
REPORTER_ASSERT(r, !bitmap.empty());
|
||||
|
||||
SkColor color = bitmap.getColor(0, 0);
|
||||
REPORTER_ASSERT(r, color == SK_ColorGREEN || color == SK_ColorRED);
|
||||
return color == SK_ColorGREEN;
|
||||
}
|
||||
|
||||
static SkString load_source(skiatest::Reporter* r,
|
||||
const char* testFile,
|
||||
const char* permutationSuffix) {
|
||||
@ -130,50 +203,18 @@ static void test_one_permutation(skiatest::Reporter* r,
|
||||
return;
|
||||
}
|
||||
|
||||
static constexpr float kArray[5] = {1, 2, 3, 4, 5};
|
||||
|
||||
SkRuntimeShaderBuilder builder(result.effect);
|
||||
set_uniform(&builder, "colorBlack", SkV4{0, 0, 0, 1});
|
||||
set_uniform(&builder, "colorRed", SkV4{1, 0, 0, 1});
|
||||
set_uniform(&builder, "colorGreen", SkV4{0, 1, 0, 1});
|
||||
set_uniform(&builder, "colorBlue", SkV4{0, 0, 1, 1});
|
||||
set_uniform(&builder, "colorWhite", SkV4{1, 1, 1, 1});
|
||||
set_uniform(&builder, "testInputs", SkV4{-1.25, 0, 0.75, 2.25});
|
||||
set_uniform(&builder, "unknownInput", 1.0f);
|
||||
set_uniform(&builder, "testMatrix2x2", std::array<float,4>{1, 2,
|
||||
3, 4});
|
||||
set_uniform(&builder, "testMatrix3x3", std::array<float,9>{1, 2, 3,
|
||||
4, 5, 6,
|
||||
7, 8, 9});
|
||||
set_uniform(&builder, "testMatrix4x4", std::array<float,16>{1, 2, 3, 4,
|
||||
5, 6, 7, 8,
|
||||
9, 10, 11, 12,
|
||||
13, 14, 15, 16});
|
||||
set_uniform_array(&builder, "testArray", SkMakeSpan(kArray));
|
||||
|
||||
sk_sp<SkShader> shader = builder.makeShader();
|
||||
if (!shader) {
|
||||
SkBitmap bitmap = bitmap_from_shader(r, surface, result.effect);
|
||||
if (bitmap.empty()) {
|
||||
ERRORF(r, "%s%s: Unable to build shader", testFile, permutationSuffix);
|
||||
return;
|
||||
}
|
||||
|
||||
surface->getCanvas()->clear(SK_ColorBLACK);
|
||||
|
||||
SkPaint paintShader;
|
||||
paintShader.setShader(shader);
|
||||
surface->getCanvas()->drawRect(SkRect::MakeWH(kWidth, kHeight), paintShader);
|
||||
|
||||
SkBitmap bitmap;
|
||||
REPORTER_ASSERT(r, bitmap.tryAllocPixels(surface->imageInfo()));
|
||||
REPORTER_ASSERT(r, surface->readPixels(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes(),
|
||||
/*srcX=*/0, /*srcY=*/0));
|
||||
|
||||
bool success = true;
|
||||
SkColor color[kHeight][kWidth];
|
||||
for (int y = 0; y < kHeight; ++y) {
|
||||
for (int x = 0; x < kWidth; ++x) {
|
||||
color[y][x] = bitmap.getColor(x, y);
|
||||
if (color[y][x] != SkColorSetARGB(0xFF, 0x00, 0xFF, 0x00)) {
|
||||
if (color[y][x] != SK_ColorGREEN) {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
@ -239,6 +280,14 @@ static void test_gpu(skiatest::Reporter* r, GrDirectContext* ctx, const char* te
|
||||
if (!shouldRunGPU && !shouldRunGPU_ES3) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is a test that requires the GPU to generate NaN values, check for that first.
|
||||
if (flags & SkSLTestFlags::UsesNaN) {
|
||||
if (!gpu_generates_nan(r, ctx)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a GPU-backed surface.
|
||||
const SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
|
||||
sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info));
|
||||
@ -435,14 +484,10 @@ SKSL_TEST(CPU + GPU + SkQP, LoopInt, "runtime/LoopInt.rt
|
||||
SKSL_TEST(CPU + GPU + SkQP, QualifierOrder, "runtime/QualifierOrder.rts")
|
||||
SKSL_TEST(CPU + GPU + SkQP, PrecisionQualifiers, "runtime/PrecisionQualifiers.rts")
|
||||
|
||||
// These tests specifically rely the behavior of NaN values, but some older GPUs do not reliably
|
||||
// implement full IEEE support (skia:12977). They also rely on equality operators on array types
|
||||
// which are not available in GLSL ES 1.00. Therefore these tests are restricted to run on CPU and
|
||||
// with "strict ES2 mode" disabled.
|
||||
SKSL_TEST(CPU_ES3, RecursiveComparison_Arrays, "runtime/RecursiveComparison_Arrays.rts")
|
||||
SKSL_TEST(CPU_ES3, RecursiveComparison_Structs, "runtime/RecursiveComparison_Structs.rts")
|
||||
SKSL_TEST(CPU_ES3, RecursiveComparison_Types, "runtime/RecursiveComparison_Types.rts")
|
||||
SKSL_TEST(CPU_ES3, RecursiveComparison_Vectors, "runtime/RecursiveComparison_Vectors.rts")
|
||||
SKSL_TEST(GPU_ES3 + UsesNaN, RecursiveComparison_Arrays, "runtime/RecursiveComparison_Arrays.rts")
|
||||
SKSL_TEST(GPU_ES3 + UsesNaN, RecursiveComparison_Structs, "runtime/RecursiveComparison_Structs.rts")
|
||||
SKSL_TEST(GPU_ES3 + UsesNaN, RecursiveComparison_Types, "runtime/RecursiveComparison_Types.rts")
|
||||
SKSL_TEST(GPU_ES3 + UsesNaN, RecursiveComparison_Vectors, "runtime/RecursiveComparison_Vectors.rts")
|
||||
|
||||
SKSL_TEST(GPU_ES3, ArrayCast, "shared/ArrayCast.sksl")
|
||||
SKSL_TEST(GPU_ES3, ArrayComparison, "shared/ArrayComparison.sksl")
|
||||
|
Loading…
Reference in New Issue
Block a user