Revert "Revert "Complete rewrite of the SkSL interpreter""
This reverts commit 99c54f0290bbd55fba5394a6e4344205d2244063.
Change-Id: I010ac4fdb6c5b6bfbdf63f4dcac5dbf962b0ad9c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/266205
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/tests/SkSLInterpreterTest.cpp b/tests/SkSLInterpreterTest.cpp
index 8251269..1cb8a63 100644
--- a/tests/SkSLInterpreterTest.cpp
+++ b/tests/SkSLInterpreterTest.cpp
@@ -9,21 +9,13 @@
#include "src/sksl/SkSLByteCode.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/SkSLExternalValue.h"
+#include "src/sksl/SkSLInterpreter.h"
#include "src/utils/SkJSON.h"
#include "tests/Test.h"
-static bool nearly_equal(const float a[], const float b[], int count) {
- for (int i = 0; i < count; ++i) {
- if (!SkScalarNearlyEqual(a[i], b[i])) {
- return false;
- }
- }
- return true;
-}
-
void test(skiatest::Reporter* r, const char* src, float* in, float* expected,
- bool exactCompare = true) {
+ bool exactCompare = false) {
SkSL::Compiler compiler;
SkSL::Program::Settings settings;
std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
@@ -39,30 +31,17 @@
return;
}
const SkSL::ByteCodeFunction* main = byteCode->getFunction("main");
- int returnCount = main->getReturnCount();
- std::unique_ptr<float[]> out = std::unique_ptr<float[]>(new float[returnCount]);
- SkAssertResult(byteCode->run(main, in, main->getParameterCount(), out.get(), returnCount,
- nullptr, 0));
- bool valid = exactCompare ? !memcmp(out.get(), expected, sizeof(float) * returnCount)
- : nearly_equal(out.get(), expected, returnCount);
- if (!valid) {
- printf("for program: %s\n", src);
- printf(" expected (");
- const char* separator = "";
- for (int i = 0; i < returnCount; ++i) {
- printf("%s%f", separator, expected[i]);
- separator = ", ";
+ SkSL::Interpreter<1> interpreter(std::move(byteCode));
+ SkSL::ByteCode::Vector<1>* result;
+ bool success = interpreter.run(main, (SkSL::ByteCode::Vector<1>*) in, &result);
+ REPORTER_ASSERT(r, success);
+ for (int i = 0; i < main->getReturnSlotCount(); ++i) {
+ if (exactCompare) {
+ REPORTER_ASSERT(r, result[i].fInt[0] == ((int32_t*) expected)[i]);
+ } else {
+ REPORTER_ASSERT(r, SkScalarNearlyZero(result[i].fFloat[0] - expected[i]));
}
- printf("), but received (");
- separator = "";
- for (int i = 0; i < returnCount; ++i) {
- printf("%s%f", separator, out.get()[i]);
- separator = ", ";
- }
- printf(")\n");
- main->disassemble();
}
- REPORTER_ASSERT(r, valid);
} else {
printf("%s\n%s", src, compiler.errorText().c_str());
}
@@ -83,7 +62,8 @@
return;
}
- const SkSL::ByteCodeFunction* main = byteCode->getFunction("main");
+ const SkSL::ByteCodeFunction* main1 = byteCode->getFunction("main");
+ SkSL::Interpreter<1> interpreter1(std::move(byteCode));
// Test on four different vectors (with varying orderings to get divergent control flow)
const float input[16] = { 1, 2, 3, 4,
@@ -97,9 +77,16 @@
// First run in scalar mode to determine the expected output
for (int i = 0; i < 4; ++i) {
- SkAssertResult(byteCode->run(main, out_s + i * 4, 4, nullptr, 0, nullptr, 0));
+ SkAssertResult(interpreter1.run(main1, (SkSL::ByteCode::Vector<1>*) (out_s + i * 4),
+ nullptr));
}
+ byteCode = compiler.toByteCode(*program);
+ SkASSERT(compiler.errorCount() == 0);
+
+ const SkSL::ByteCodeFunction* main4 = byteCode->getFunction("main");
+ SkSL::Interpreter<4> interpreter4(std::move(byteCode));
+
// Need to transpose input vectors for striped execution
auto transpose = [](float* v) {
for (int r = 0; r < 4; ++r)
@@ -112,7 +99,7 @@
float* args[] = { out_v, out_v + 4, out_v + 8, out_v + 12 };
// Now run in parallel and compare results
- SkAssertResult(byteCode->runStriped(main, 4, args, 4, nullptr, 0, nullptr, 0));
+ SkAssertResult(interpreter4.runStriped(main4, 4, (float**) args));
// Transpose striped outputs back
transpose(out_v);
@@ -125,7 +112,7 @@
out_v[4*i + 0], out_v[4*i + 1], out_v[4*i + 2], out_v[4*i + 3],
out_s[4*i + 0], out_s[4*i + 1], out_s[4*i + 2], out_s[4*i + 3]);
}
- main->disassemble();
+ main4->disassemble();
REPORT_FAILURE(r, "VecInterpreter mismatch", SkString());
}
}
@@ -147,20 +134,26 @@
return;
}
const SkSL::ByteCodeFunction* main = byteCode->getFunction("main");
- float inoutColor[4] = { inR, inG, inB, inA };
- SkAssertResult(byteCode->run(main, inoutColor, 4, nullptr, 0, nullptr, 0));
- if (inoutColor[0] != expectedR || inoutColor[1] != expectedG ||
- inoutColor[2] != expectedB || inoutColor[3] != expectedA) {
+ SkSL::ByteCode::Vector<1> inoutColor[4];
+ inoutColor[0].fFloat[0] = inR;
+ inoutColor[1].fFloat[0] = inG;
+ inoutColor[2].fFloat[0] = inB;
+ inoutColor[3].fFloat[0] = inA;
+ SkSL::Interpreter<1> interpreter(std::move(byteCode));
+ bool success = interpreter.run(main, inoutColor, nullptr);
+ REPORTER_ASSERT(r, success);
+ if (inoutColor[0].fFloat[0] != expectedR || inoutColor[1].fFloat[0] != expectedG ||
+ inoutColor[2].fFloat[0] != expectedB || inoutColor[3].fFloat[0] != expectedA) {
printf("for program: %s\n", src);
printf(" expected (%f, %f, %f, %f), but received (%f, %f, %f, %f)\n", expectedR,
- expectedG, expectedB, expectedA, inoutColor[0], inoutColor[1], inoutColor[2],
- inoutColor[3]);
+ expectedG, expectedB, expectedA, inoutColor[0].fFloat[0],
+ inoutColor[1].fFloat[0], inoutColor[2].fFloat[0], inoutColor[3].fFloat[0]);
main->disassemble();
}
- REPORTER_ASSERT(r, inoutColor[0] == expectedR);
- REPORTER_ASSERT(r, inoutColor[1] == expectedG);
- REPORTER_ASSERT(r, inoutColor[2] == expectedB);
- REPORTER_ASSERT(r, inoutColor[3] == expectedA);
+ REPORTER_ASSERT(r, inoutColor[0].fFloat[0] == expectedR);
+ REPORTER_ASSERT(r, inoutColor[1].fFloat[0] == expectedG);
+ REPORTER_ASSERT(r, inoutColor[2].fFloat[0] == expectedB);
+ REPORTER_ASSERT(r, inoutColor[3].fFloat[0] == expectedA);
} else {
printf("%s\n%s", src, compiler.errorText().c_str());
}
@@ -177,6 +170,10 @@
0.5, 1, 1.5, 2);
test(r, "void main(inout half4 color) { color.r = int(color.r) + int(color.g); }", 1, 3, 0, 0,
4, 3, 0, 0);
+ test(r, "void main(inout half4 color) { color.rg = color.r + color.gb; }", 1, 2, 3, 4,
+ 3, 4, 3, 4);
+ test(r, "void main(inout half4 color) { color.rg = color.rg + color.b; }", 1, 2, 3, 4,
+ 4, 5, 3, 4);
}
DEF_TEST(SkSLInterpreterSubtract, r) {
@@ -189,6 +186,10 @@
test(r, "void main(inout half4 color) { color = -color; }", 4, 3, 2, 1, -4, -3, -2, -1);
test(r, "void main(inout half4 color) { color.r = int(color.r) - int(color.g); }", 3, 1, 0, 0,
2, 1, 0, 0);
+ test(r, "void main(inout half4 color) { color.rg = color.r - color.gb; }", 1, 2, 3, 4,
+ -1, -2, 3, 4);
+ test(r, "void main(inout half4 color) { color.rg = color.rg - color.b; }", 1, 2, 3, 4,
+ -2, -1, 3, 4);
}
DEF_TEST(SkSLInterpreterMultiply, r) {
@@ -200,6 +201,10 @@
16, 9, 4, 1);
test(r, "void main(inout half4 color) { color.r = int(color.r) * int(color.g); }", 3, -2, 0, 0,
-6, -2, 0, 0);
+ test(r, "void main(inout half4 color) { color.rg = color.r * color.gb; }", 5, 2, 3, 4,
+ 10, 15, 3, 4);
+ test(r, "void main(inout half4 color) { color.rg = color.rg * color.b; }", 1, 2, 3, 4,
+ 3, 6, 3, 4);
}
DEF_TEST(SkSLInterpreterDivide, r) {
@@ -211,6 +216,10 @@
1, 1, 1, 1);
test(r, "void main(inout half4 color) { color.r = int(color.r) / int(color.g); }", 8, -2, 0, 0,
-4, -2, 0, 0);
+ test(r, "void main(inout half4 color) { color.rg = color.r / color.gb; }", 12, 2, 3, 4,
+ 6, 4, 3, 4);
+ test(r, "void main(inout half4 color) { color.rg = color.rg / color.b; }", 6, 3, 3, 4,
+ 2, 1, 3, 4);
}
DEF_TEST(SkSLInterpreterRemainder, r) {
@@ -222,6 +231,14 @@
2, 3, 0, 0);
test(r, "void main(inout half4 color) { color.rg = half2(int2(int(color.r), int(color.g)) % "
"int(color.b)); }", 8, 10, 6, 0, 2, 4, 6, 0);
+ test(r, "void main(inout half4 color) { color.rg = color.r + color.gb; }", 1, 2, 3, 4,
+ 3, 4, 3, 4);
+ test(r, "void main(inout half4 color) { color.rg = color.rg + color.b; }", 1, 2, 3, 4,
+ 4, 5, 3, 4);
+ test(r, "void main(inout half4 color) { color.rg = color.r % color.gb; }", 10, 2, 3, 4,
+ 0, 1, 3, 4);
+ test(r, "void main(inout half4 color) { color.rg = color.rg % color.b; }", 6, 3, 4, 4,
+ 2, 3, 4, 4);
}
DEF_TEST(SkSLInterpreterAnd, r) {
@@ -278,7 +295,7 @@
unsigned out;
out = 0x00000088;
- test(r, "int main(int x) { return x << 3; }", (float*)&in, (float*)&out);
+ test(r, "int main(int x) { return x << 3; }", (float*)&in, (float*)&out);
out = 0xF0000002;
test(r, "int main(int x) { return x >> 3; }", (float*)&in, (float*)&out);
@@ -418,8 +435,8 @@
input[1].f = -5.0f;
expected[0].s = 3;
expected[1].s = -5;
- test(r, "int main(float x) { return int (x); }", (float*)input, (float*)expected);
- test(r, "int2 main(float2 x) { return int2(x); }", (float*)input, (float*)expected);
+ test(r, "int main(float x) { return int (x); }", (float*)input, (float*)expected, true);
+ test(r, "int2 main(float2 x) { return int2(x); }", (float*)input, (float*)expected, true);
input[0].s = 3;
expected[0].f = 3.0f;
@@ -474,11 +491,15 @@
test(r, "void main(inout half4 color) { if (color.rg == color.ba) color.a = 1; }",
1, 2, 1, 2, 1, 2, 1, 1);
test(r, "void main(inout half4 color) { if (color.rg == color.ba) color.a = 1; }",
+ 1, 2, 1, 3, 1, 2, 1, 3);
+ test(r, "void main(inout half4 color) { if (color.rg == color.ba) color.a = 1; }",
1, 2, 3, 2, 1, 2, 3, 2);
test(r, "void main(inout half4 color) { if (color.rg != color.ba) color.a = 1; }",
1, 2, 1, 2, 1, 2, 1, 2);
test(r, "void main(inout half4 color) { if (color.rg != color.ba) color.a = 1; }",
1, 2, 3, 2, 1, 2, 3, 1);
+ test(r, "void main(inout half4 color) { if (color.rg != color.ba) color.a = 1; }",
+ 1, 2, 1, 3, 1, 2, 1, 1);
}
DEF_TEST(SkSLInterpreterWhile, r) {
@@ -641,51 +662,67 @@
SkIRect gRects[4] = { { 1,2,3,4 }, { 5,6,7,8 }, { 9,10,11,12 }, { 13,14,15,16 } };
const float* fRects = (const float*)gRects;
+ SkSL::Interpreter<1> interpreter(std::move(byteCode));
+ auto geti = [](SkSL::Interpreter<1>::Vector* v) { return v->fInt[0]; };
+ auto getf = [](SkSL::Interpreter<1>::Vector* v) { return v->fFloat[0]; };
+
{
SkIRect in = SkIRect::MakeXYWH(10, 10, 20, 30);
- int out = 0;
- SkAssertResult(byteCode->run(rect_height, (float*)&in, 4, (float*)&out, 1, fRects, 16));
- REPORTER_ASSERT(r, out == 30);
+ SkSL::Interpreter<1>::Vector* out;
+ bool success = interpreter.run(rect_height, (SkSL::Interpreter<1>::Vector*) &in, &out);
+ REPORTER_ASSERT(r, success);
+ REPORTER_ASSERT(r, geti(out) == 30);
}
{
int in[2] = { 15, 25 };
- RectAndColor out;
- SkAssertResult(byteCode->run(make_blue_rect, (float*)in, 2, (float*)&out, 8, fRects, 16));
- REPORTER_ASSERT(r, out.fRect.width() == 15);
- REPORTER_ASSERT(r, out.fRect.height() == 25);
+ SkSL::Interpreter<1>::Vector* out;
+ bool success = interpreter.run(make_blue_rect, (SkSL::Interpreter<1>::Vector*) in, &out);
+ REPORTER_ASSERT(r, success);
+ RectAndColor result{ { geti(out), geti(out + 1), geti(out + 2), geti(out + 3) },
+ { getf(out + 4), getf(out + 5), getf(out + 6), getf(out + 7) } };
+ REPORTER_ASSERT(r, result.fRect.width() == 15);
+ REPORTER_ASSERT(r, result.fRect.height() == 25);
SkColor4f blue = { 0.0f, 1.0f, 0.0f, 1.0f };
- REPORTER_ASSERT(r, out.fColor == blue);
+ REPORTER_ASSERT(r, result.fColor == blue);
}
{
int in[15] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
- int out = 0;
- SkAssertResult(byteCode->run(median, (float*)in, 15, (float*)&out, 1, fRects, 16));
- REPORTER_ASSERT(r, out == 8);
+ SkSL::Interpreter<1>::Vector* out;
+ bool success = interpreter.run(median, (SkSL::Interpreter<1>::Vector*) in, &out);
+ REPORTER_ASSERT(r, success);
+ REPORTER_ASSERT(r, geti(out) == 8);
}
{
float in[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
- float out[8] = { 0 };
- SkAssertResult(byteCode->run(sums, in, 8, out, 8, fRects, 16));
+ SkSL::Interpreter<1>::Vector* out;
+ bool success = interpreter.run(sums, (SkSL::Interpreter<1>::Vector*) in, &out);
+ REPORTER_ASSERT(r, success);
for (int i = 0; i < 8; ++i) {
- REPORTER_ASSERT(r, out[i] == static_cast<float>((i + 1) * (i + 2) / 2));
+ REPORTER_ASSERT(r, getf(out + i) == static_cast<float>((i + 1) * (i + 2) / 2));
}
}
{
int in = 2;
- SkIRect out = SkIRect::MakeEmpty();
- SkAssertResult(byteCode->run(get_rect, (float*)&in, 1, (float*)&out, 4, fRects, 16));
- REPORTER_ASSERT(r, out == gRects[2]);
+ interpreter.setUniforms(fRects);
+ SkSL::Interpreter<1>::Vector* out;
+ bool success = interpreter.run(get_rect, (SkSL::Interpreter<1>::Vector*) &in, &out);
+ REPORTER_ASSERT(r, success);
+ REPORTER_ASSERT(r, geti(out) == gRects[2].fLeft);
+ REPORTER_ASSERT(r, geti(out + 1) == gRects[2].fTop);
+ REPORTER_ASSERT(r, geti(out + 2) == gRects[2].fRight);
+ REPORTER_ASSERT(r, geti(out + 3) == gRects[2].fBottom);
}
{
ManyRects in;
memset(&in, 0, sizeof(in));
in.fNumRects = 2;
- SkAssertResult(byteCode->run(fill_rects, (float*)&in, 33, nullptr, 0, fRects, 16));
+ bool success = interpreter.run(fill_rects, (SkSL::Interpreter<1>::Vector*) &in, nullptr);
+ REPORTER_ASSERT(r, success);
ManyRects expected;
memset(&expected, 0, sizeof(expected));
expected.fNumRects = 2;
@@ -718,9 +755,11 @@
auto byteCode = compiler.toByteCode(*program);
REPORTER_ASSERT(r, byteCode);
- auto fun = byteCode->getFunction("main");
- bool result = byteCode->run(fun, in, fun->getParameterCount(), nullptr, 0, nullptr, 0);
- REPORTER_ASSERT(r, !result);
+ auto main = byteCode->getFunction("main");
+ SkSL::Interpreter<1> interpreter(std::move(byteCode));
+ SkSL::ByteCode::Vector<1>* result;
+ bool success = interpreter.run(main, (SkSL::ByteCode::Vector<1>*) in, &result);
+ REPORTER_ASSERT(r, !success);
}
DEF_TEST(SkSLInterpreterRestrictFunctionCalls, r) {
@@ -786,16 +825,21 @@
REPORTER_ASSERT(r, dot3);
REPORTER_ASSERT(r, dot2);
- float out = 0.0f;
+ SkSL::Interpreter<1> interpreter(std::move(byteCode));
float in = 3.0f;
- SkAssertResult(byteCode->run(main, &in, 1, &out, 1, nullptr, 0));
- REPORTER_ASSERT(r, out = 6.0f);
- SkAssertResult(byteCode->run(dot3, &in, 1, &out, 1, nullptr, 0));
- REPORTER_ASSERT(r, out = 9.0f);
+ SkSL::Interpreter<1>::Vector* out;
+ bool success = interpreter.run(main, (SkSL::Interpreter<1>::Vector*) &in, &out);
+ REPORTER_ASSERT(r, success);
+ REPORTER_ASSERT(r, out->fFloat[0] = 6.0f);
- SkAssertResult(byteCode->run(dot2, &in, 1, &out, 1, nullptr, 0));
- REPORTER_ASSERT(r, out = -1.0f);
+ success = interpreter.run(dot3, (SkSL::Interpreter<1>::Vector*) &in, &out);
+ REPORTER_ASSERT(r, success);
+ REPORTER_ASSERT(r, out->fFloat[0] = 9.0f);
+
+ success = interpreter.run(dot2, (SkSL::Interpreter<1>::Vector*) &in, &out);
+ REPORTER_ASSERT(r, success);
+ REPORTER_ASSERT(r, out->fFloat[0] = -1.0f);
}
DEF_TEST(SkSLInterpreterOutParams, r) {
@@ -804,15 +848,18 @@
"void main(inout half4 color) { oneAlpha(color); }",
0, 0, 0, 0, 0, 0, 0, 1);
test(r,
- "half2 tricky(half x, half y, inout half2 color, half z) {"
+ "half2 tricky(half x, half y, inout half2 color, half z, out half w) {"
" color.xy = color.yx;"
+ " w = 47;"
" return half2(x + y, z);"
"}"
"void main(inout half4 color) {"
- " half2 t = tricky(1, 2, color.rb, 5);"
+ " half w;"
+ " half2 t = tricky(1, 2, color.rb, 5, w);"
+ " color.r += w;"
" color.ga = t;"
"}",
- 1, 2, 3, 4, 3, 3, 1, 5);
+ 1, 2, 3, 4, 50, 3, 1, 5);
}
DEF_TEST(SkSLInterpreterMathFunctions, r) {
@@ -1029,9 +1076,11 @@
return;
}
const SkSL::ByteCodeFunction* main = byteCode->getFunction("main");
- float out;
- SkAssertResult(byteCode->run(main, nullptr, 0, &out, 1, nullptr, 0));
- REPORTER_ASSERT(r, out == 66.0);
+ SkSL::Interpreter<1> interpreter(std::move(byteCode));
+ SkSL::ByteCode::Vector<1>* result;
+ bool success = interpreter.run(main, nullptr, &result);
+ REPORTER_ASSERT(r, success);
+ REPORTER_ASSERT(r, result->fFloat[0] == 66.0);
REPORTER_ASSERT(r, outValue == 152);
} else {
printf("%s\n%s", src, compiler.errorText().c_str());
@@ -1062,7 +1111,9 @@
return;
}
const SkSL::ByteCodeFunction* main = byteCode->getFunction("main");
- SkAssertResult(byteCode->run(main, nullptr, 0, nullptr, 0, nullptr, 0));
+ SkSL::Interpreter<1> interpreter(std::move(byteCode));
+ bool success = interpreter.run(main, nullptr, nullptr);
+ REPORTER_ASSERT(r, success);
REPORTER_ASSERT(r, value[0] == 2);
REPORTER_ASSERT(r, value[1] == 4);
REPORTER_ASSERT(r, value[2] == 6);
@@ -1127,9 +1178,11 @@
return;
}
const SkSL::ByteCodeFunction* main = byteCode->getFunction("main");
- float out;
- SkAssertResult(byteCode->run(main, nullptr, 0, &out, 1, nullptr, 0));
- REPORTER_ASSERT(r, out == 5.0);
+ SkSL::Interpreter<1> interpreter(std::move(byteCode));
+ SkSL::ByteCode::Vector<1>* result;
+ bool success = interpreter.run(main, nullptr, &result);
+ REPORTER_ASSERT(r, success);
+ REPORTER_ASSERT(r, result->fFloat[0] == 5.0);
} else {
printf("%s\n%s", src, compiler.errorText().c_str());
}
@@ -1142,32 +1195,23 @@
: INHERITED(name, *compiler.context().fFloat4_Type)
, fCompiler(compiler)
, fFunction(function) {}
-
bool canCall() const override {
return true;
}
-
int callParameterCount() const override {
return 1;
}
-
void getCallParameterTypes(const SkSL::Type** outTypes) const override {
outTypes[0] = fCompiler.context().fFloat4_Type.get();
}
-
void call(int /*unusedIndex*/, float* arguments, float* outReturn) override {
fFunction(arguments, outReturn);
}
-
private:
SkSL::Compiler& fCompiler;
-
void (*fFunction)(float[4], float[4]);
-
typedef SkSL::ExternalValue INHERITED;
};
-
-
DEF_TEST(SkSLInterpreterExternalValuesVectorCall, r) {
SkSL::Compiler compiler;
SkSL::Program::Settings settings;
@@ -1195,12 +1239,14 @@
return;
}
const SkSL::ByteCodeFunction* main = byteCode->getFunction("main");
- float out[4];
- SkAssertResult(byteCode->run(main, nullptr, 0, out, 4, nullptr, 0));
- REPORTER_ASSERT(r, out[0] == 1.0);
- REPORTER_ASSERT(r, out[1] == 2.0);
- REPORTER_ASSERT(r, out[2] == 3.0);
- REPORTER_ASSERT(r, out[3] == 4.0);
+ SkSL::Interpreter<1> interpreter(std::move(byteCode));
+ SkSL::ByteCode::Vector<1>* result;
+ bool success = interpreter.run(main, nullptr, &result);
+ REPORTER_ASSERT(r, success);
+ REPORTER_ASSERT(r, result[0].fFloat[0] == 1.0);
+ REPORTER_ASSERT(r, result[1].fFloat[0] == 2.0);
+ REPORTER_ASSERT(r, result[2].fFloat[0] == 3.0);
+ REPORTER_ASSERT(r, result[3].fFloat[0] == 4.0);
} else {
printf("%s\n%s", src, compiler.errorText().c_str());
}