Add unit test for TraceHooks on compiled SkSL.

This verifies that compiled SkSL code generates a reasonable trace.

Change-Id: Ia81a694460eaac261dfb9287b64f0afec013f76c
Bug: skia:12614
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/473145
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
John Stiles 2021-11-18 10:47:10 -05:00 committed by SkCQ
parent a97bd9d4b2
commit acec7450ec

View File

@ -8,6 +8,7 @@
#include "include/core/SkM44.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/codegen/SkSLVMCodeGenerator.h"
#include "src/sksl/codegen/SkVMDebugInfo.h"
#include "src/sksl/ir/SkSLExternalFunction.h"
#include "src/utils/SkJSON.h"
@ -973,3 +974,97 @@ DEF_TEST(SkSLInterpreterExternalTable, r) {
REPORTER_ASSERT(r, out[2] == 2.0);
REPORTER_ASSERT(r, out[3] == 4.0);
}
DEF_TEST(SkSLInterpreterTrace, r) {
GrShaderCaps caps;
SkSL::Compiler compiler(&caps);
SkSL::Program::Settings settings;
settings.fOptimize = false;
constexpr const char kSrc[] =
R"(bool less_than(int left, int right) {
bool comparison = left < right;
return comparison;
}
int main() {
for (int loop = 10; loop <= 30; loop += 10) {
bool function_result = less_than(loop, 20);
}
return 40;
}
)";
skvm::Builder b;
std::unique_ptr<SkSL::Program> program = compiler.convertProgram(SkSL::ProgramKind::kGeneric,
SkSL::String(kSrc), settings);
REPORTER_ASSERT(r, program);
const SkSL::FunctionDefinition* main = SkSL::Program_GetFunction(*program, "main");
SkSL::SkVMDebugInfo debugInfo;
skvm::Coord zero = {b.splat(0.0f), b.splat(0.0f)};
debugInfo.setTraceCoord(zero);
SkSL::ProgramToSkVM(*program, *main, &b, &debugInfo, /*uniforms=*/{});
skvm::Program p = b.done();
REPORTER_ASSERT(r, p.nargs() == 1);
class TestTraceHook : public skvm::TraceHook {
public:
void line(int lineNum) override {
fTrace.appendf("line %d\n", lineNum);
}
void var(int slot, int32_t val) override {
fTrace.appendf("%s = %d\n", fDebugInfo->fSlotInfo[slot].name.c_str(), val);
}
void call(int fnIdx, bool enter) override {
fTrace.appendf("%s %s\n", enter ? "enter" : "exit",
fDebugInfo->fFuncInfo[fnIdx].name.c_str());
}
const SkSL::SkVMDebugInfo* fDebugInfo;
SkSL::String fTrace;
};
TestTraceHook hook;
hook.fDebugInfo = &debugInfo;
p.attachTraceHook(&hook);
int result;
p.eval(1, &result);
REPORTER_ASSERT(r, result == 40);
REPORTER_ASSERT(r, hook.fTrace ==
R"(enter int main()
line 7
loop = 10
line 8
enter bool less_than(int left, int right)
left = 10
right = 20
line 2
comparison = 1
line 3
exit bool less_than(int left, int right)
function_result = 1
line 7
loop = 20
line 8
enter bool less_than(int left, int right)
left = 20
line 2
comparison = 0
line 3
exit bool less_than(int left, int right)
function_result = 0
line 7
loop = 30
line 8
enter bool less_than(int left, int right)
left = 30
line 2
line 3
exit bool less_than(int left, int right)
line 7
line 10
exit int main()
)", "Trace output does not match expectation:\n%s\n", hook.fTrace.c_str());
}