Interpreter: Fix intrinsics when called with vector types

Change-Id: I0296ff5a68b934f6bc7152a66f57ef045fc94daf
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/272721
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Osman 2020-02-21 17:00:43 -05:00 committed by Skia Commit-Bot
parent 7f5e3c7e43
commit dc2a97774b
3 changed files with 34 additions and 13 deletions

View File

@ -14,13 +14,16 @@ ByteCodeGenerator::ByteCodeGenerator(const Program* program, ErrorReporter* erro
: INHERITED(program, errors, nullptr)
, fOutput(output)
, fIntrinsics {
// "Normal" intrinsics are all $genType f($genType), mapped to a single instruction
{ "cos", ByteCode::Instruction::kCos },
{ "dot", SpecialIntrinsic::kDot },
{ "inverse", SpecialIntrinsic::kInverse },
{ "print", ByteCode::Instruction::kPrint },
{ "sin", ByteCode::Instruction::kSin },
{ "sqrt", ByteCode::Instruction::kSqrt },
{ "tan", ByteCode::Instruction::kTan },
// Special intrinsics have other signatures, or non-standard code-gen
{ "dot", SpecialIntrinsic::kDot },
{ "inverse", SpecialIntrinsic::kInverse },
{ "print", SpecialIntrinsic::kPrint },
} {}
int ByteCodeGenerator::SlotCount(const Type& type) {
@ -956,20 +959,33 @@ void ByteCodeGenerator::writeIntrinsicCall(const FunctionCall& c, Intrinsic intr
this->write(arg);
break;
}
case SpecialIntrinsic::kPrint: {
SkASSERT(c.fArguments.size() == 1);
SkASSERT(SlotCount(c.fArguments[0]->fType) == 1);
ByteCode::Register arg = this->next(1);
this->writeExpression(*c.fArguments[0], arg);
this->write(ByteCode::Instruction::kPrint);
this->write(arg);
break;
}
}
} else {
int count = SlotCount(c.fType);
std::vector<ByteCode::Register> argRegs;
for (const auto& expr : c.fArguments) {
ByteCode::Register reg = this->next(SlotCount(expr->fType));
SkASSERT(SlotCount(expr->fType) == count);
ByteCode::Register reg = this->next(count);
this->writeExpression(*expr, reg);
argRegs.push_back(reg);
}
this->write(intrinsic.fValue.fInstruction);
if (c.fType.fName != "void") {
this->write(result);
}
for (ByteCode::Register arg : argRegs) {
this->write(arg);
for (int i = 0; i < count; ++i) {
this->write(intrinsic.fValue.fInstruction);
if (c.fType.fName != "void") {
this->write(result + i);
}
for (ByteCode::Register arg : argRegs) {
this->write(arg + i);
}
}
}
}

View File

@ -63,6 +63,7 @@ private:
enum class SpecialIntrinsic {
kDot,
kInverse,
kPrint,
};
struct Intrinsic {

View File

@ -916,9 +916,13 @@ DEF_TEST(SkSLInterpreterOutParams, r) {
DEF_TEST(SkSLInterpreterMathFunctions, r) {
float value[4], expected[4];
value[0] = 0.0f; expected[0] = 0.0f;
test(r, "float main(float x) { return sin(x); }", value, expected);
test(r, "float main(float x) { return tan(x); }", value, expected);
value[0] = 0.0f; value[1] = SK_FloatPI / 2;
expected[0] = 0.0f; expected[1] = 1.0f;
test(r, "float2 main(float2 x) { return sin(x); }", value, expected);
value[0] = 0.0f; value[1] = SK_FloatPI / 4;
expected[0] = 0.0f; expected[1] = 1.0f;
test(r, "float2 main(float2 x) { return tan(x); }", value, expected);
value[0] = 0.0f; expected[0] = 1.0f;
test(r, "float main(float x) { return cos(x); }", value, expected);