Interpreter: Fix vector/matrix equality and inequality
Need to compare all elements, then fold the result to a single bool. Change-Id: I0ebfaa9d518f29a782701246ada247cb55c01c2e Reviewed-on: https://skia-review.googlesource.com/c/skia/+/216607 Reviewed-by: Ethan Nicholas <ethannicholas@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
a86fc7a63b
commit
16e6fd53a1
@ -334,6 +334,8 @@ void ByteCodeGenerator::writeBinaryExpression(const BinaryExpression& b) {
|
|||||||
lvalue->store();
|
lvalue->store();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const Type& lType = b.fLeft->fType;
|
||||||
|
const Type& rType = b.fRight->fType;
|
||||||
Token::Kind op;
|
Token::Kind op;
|
||||||
std::unique_ptr<LValue> lvalue;
|
std::unique_ptr<LValue> lvalue;
|
||||||
if (is_assignment(b.fOperator)) {
|
if (is_assignment(b.fOperator)) {
|
||||||
@ -343,27 +345,31 @@ void ByteCodeGenerator::writeBinaryExpression(const BinaryExpression& b) {
|
|||||||
} else {
|
} else {
|
||||||
this->writeExpression(*b.fLeft);
|
this->writeExpression(*b.fLeft);
|
||||||
op = b.fOperator;
|
op = b.fOperator;
|
||||||
if (b.fLeft->fType.kind() == Type::kScalar_Kind &&
|
if (lType.kind() == Type::kScalar_Kind &&
|
||||||
b.fRight->fType.kind() == Type::kVector_Kind) {
|
(rType.kind() == Type::kVector_Kind || rType.kind() == Type::kMatrix_Kind)) {
|
||||||
for (int i = b.fRight->fType.columns(); i > 1; --i) {
|
for (int i = SlotCount(rType); i > 1; --i) {
|
||||||
this->write(ByteCodeInstruction::kDup);
|
this->write(ByteCodeInstruction::kDup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->writeExpression(*b.fRight);
|
this->writeExpression(*b.fRight);
|
||||||
if (b.fLeft->fType.kind() == Type::kVector_Kind &&
|
if ((lType.kind() == Type::kVector_Kind || lType.kind() == Type::kMatrix_Kind) &&
|
||||||
b.fRight->fType.kind() == Type::kScalar_Kind) {
|
rType.kind() == Type::kScalar_Kind) {
|
||||||
for (int i = b.fLeft->fType.columns(); i > 1; --i) {
|
for (int i = SlotCount(lType); i > 1; --i) {
|
||||||
this->write(ByteCodeInstruction::kDup);
|
this->write(ByteCodeInstruction::kDup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int count = SlotCount(b.fType);
|
int count = SkTMax(SlotCount(lType), SlotCount(rType));
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Token::Kind::EQEQ:
|
case Token::Kind::EQEQ:
|
||||||
this->writeTypedInstruction(b.fLeft->fType, ByteCodeInstruction::kCompareIEQ,
|
this->writeTypedInstruction(b.fLeft->fType, ByteCodeInstruction::kCompareIEQ,
|
||||||
ByteCodeInstruction::kCompareIEQ,
|
ByteCodeInstruction::kCompareIEQ,
|
||||||
ByteCodeInstruction::kCompareFEQ,
|
ByteCodeInstruction::kCompareFEQ,
|
||||||
count);
|
count);
|
||||||
|
// Collapse to a single bool
|
||||||
|
for (int i = count; i > 1; --i) {
|
||||||
|
this->write(ByteCodeInstruction::kAndB);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Token::Kind::GT:
|
case Token::Kind::GT:
|
||||||
this->writeTypedInstruction(b.fLeft->fType, ByteCodeInstruction::kCompareSGT,
|
this->writeTypedInstruction(b.fLeft->fType, ByteCodeInstruction::kCompareSGT,
|
||||||
@ -400,6 +406,10 @@ void ByteCodeGenerator::writeBinaryExpression(const BinaryExpression& b) {
|
|||||||
ByteCodeInstruction::kCompareINEQ,
|
ByteCodeInstruction::kCompareINEQ,
|
||||||
ByteCodeInstruction::kCompareFNEQ,
|
ByteCodeInstruction::kCompareFNEQ,
|
||||||
count);
|
count);
|
||||||
|
// Collapse to a single bool
|
||||||
|
for (int i = count; i > 1; --i) {
|
||||||
|
this->write(ByteCodeInstruction::kOrB);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Token::Kind::PERCENT:
|
case Token::Kind::PERCENT:
|
||||||
this->writeTypedInstruction(b.fLeft->fType, ByteCodeInstruction::kRemainderS,
|
this->writeTypedInstruction(b.fLeft->fType, ByteCodeInstruction::kRemainderS,
|
||||||
|
@ -96,8 +96,8 @@ static const uint8_t* disassemble_instruction(const uint8_t* ip) {
|
|||||||
switch ((ByteCodeInstruction) READ16()) {
|
switch ((ByteCodeInstruction) READ16()) {
|
||||||
VECTOR_DISASSEMBLE(kAddF, "addf")
|
VECTOR_DISASSEMBLE(kAddF, "addf")
|
||||||
VECTOR_DISASSEMBLE(kAddI, "addi")
|
VECTOR_DISASSEMBLE(kAddI, "addi")
|
||||||
case ByteCodeInstruction::kAndB: printf("andb"); break;
|
VECTOR_DISASSEMBLE(kAndB, "andb")
|
||||||
case ByteCodeInstruction::kAndI: printf("andi"); break;
|
VECTOR_DISASSEMBLE(kAndI, "andb")
|
||||||
case ByteCodeInstruction::kBranch: printf("branch %d", READ16()); break;
|
case ByteCodeInstruction::kBranch: printf("branch %d", READ16()); break;
|
||||||
case ByteCodeInstruction::kCall: printf("call %d", READ8()); break;
|
case ByteCodeInstruction::kCall: printf("call %d", READ8()); break;
|
||||||
case ByteCodeInstruction::kCallExternal: {
|
case ByteCodeInstruction::kCallExternal: {
|
||||||
@ -361,6 +361,7 @@ void Interpreter::innerRun(const ByteCodeFunction& f, Value* stack, Value* outRe
|
|||||||
switch (inst) {
|
switch (inst) {
|
||||||
VECTOR_BINARY_OP(kAddI, fSigned, +)
|
VECTOR_BINARY_OP(kAddI, fSigned, +)
|
||||||
VECTOR_BINARY_OP(kAddF, fFloat, +)
|
VECTOR_BINARY_OP(kAddF, fFloat, +)
|
||||||
|
VECTOR_BINARY_OP(kAndB, fBool, &&)
|
||||||
|
|
||||||
case ByteCodeInstruction::kBranch:
|
case ByteCodeInstruction::kBranch:
|
||||||
ip = code + READ16();
|
ip = code + READ16();
|
||||||
@ -597,6 +598,8 @@ void Interpreter::innerRun(const ByteCodeFunction& f, Value* stack, Value* outRe
|
|||||||
case ByteCodeInstruction::kNegateI : sp[ 0] = -sp [0].fSigned;
|
case ByteCodeInstruction::kNegateI : sp[ 0] = -sp [0].fSigned;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
VECTOR_BINARY_OP(kOrB, fBool, ||)
|
||||||
|
|
||||||
case ByteCodeInstruction::kPop4: POP();
|
case ByteCodeInstruction::kPop4: POP();
|
||||||
case ByteCodeInstruction::kPop3: POP();
|
case ByteCodeInstruction::kPop3: POP();
|
||||||
case ByteCodeInstruction::kPop2: POP();
|
case ByteCodeInstruction::kPop2: POP();
|
||||||
|
@ -284,6 +284,17 @@ DEF_TEST(SkSLInterpreterIf, r) {
|
|||||||
"color.a = 2; }", 2, -2, 0, 0, 2, -2, 0, 2);
|
"color.a = 2; }", 2, -2, 0, 0, 2, -2, 0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEF_TEST(SkSLInterpreterIfVector, r) {
|
||||||
|
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, 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);
|
||||||
|
}
|
||||||
|
|
||||||
DEF_TEST(SkSLInterpreterWhile, r) {
|
DEF_TEST(SkSLInterpreterWhile, r) {
|
||||||
test(r, "void main(inout half4 color) { while (color.r < 1) color.r += 0.25; }", 0, 0, 0, 0, 1,
|
test(r, "void main(inout half4 color) { while (color.r < 1) color.r += 0.25; }", 0, 0, 0, 0, 1,
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user