diff options
-rw-r--r-- | src/sksl/SkSLSPIRVCodeGenerator.cpp | 26 | ||||
-rw-r--r-- | src/sksl/SkSLSPIRVCodeGenerator.h | 8 |
2 files changed, 28 insertions, 6 deletions
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp index feb66a60f4..2da63da3e4 100644 --- a/src/sksl/SkSLSPIRVCodeGenerator.cpp +++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp @@ -1989,6 +1989,15 @@ bool is_assignment(Token::Kind op) { } } +SpvId SPIRVCodeGenerator::foldToBool(SpvId id, const Type& operandType, SkWStream& out) { + if (operandType.kind() == Type::kVector_Kind) { + SpvId result = this->nextId(); + this->writeInstruction(SpvOpAll, this->getType(*fContext.fBool_Type), result, id, out); + return result; + } + return id; +} + SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, SkWStream& out) { // handle cases where we don't necessarily evaluate both LHS and RHS switch (b.fOperator) { @@ -2089,15 +2098,20 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, SkWSt ASSERT(*operandType == b.fRight->fType); } switch (b.fOperator) { - case Token::EQEQ: + case Token::EQEQ: { ASSERT(resultType == *fContext.fBool_Type); - return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFOrdEqual, - SpvOpIEqual, SpvOpIEqual, SpvOpLogicalEqual, out); + return this->foldToBool(this->writeBinaryOperation(resultType, *operandType, lhs, rhs, + SpvOpFOrdEqual, SpvOpIEqual, + SpvOpIEqual, SpvOpLogicalEqual, out), + *operandType, out); + } case Token::NEQ: ASSERT(resultType == *fContext.fBool_Type); - return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFOrdNotEqual, - SpvOpINotEqual, SpvOpINotEqual, SpvOpLogicalNotEqual, - out); + return this->foldToBool(this->writeBinaryOperation(resultType, *operandType, lhs, rhs, + SpvOpFOrdNotEqual, SpvOpINotEqual, + SpvOpINotEqual, SpvOpLogicalNotEqual, + out), + *operandType, out); case Token::GT: ASSERT(resultType == *fContext.fBool_Type); return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, diff --git a/src/sksl/SkSLSPIRVCodeGenerator.h b/src/sksl/SkSLSPIRVCodeGenerator.h index fad7e31d80..1cdc653c85 100644 --- a/src/sksl/SkSLSPIRVCodeGenerator.h +++ b/src/sksl/SkSLSPIRVCodeGenerator.h @@ -172,6 +172,14 @@ private: SpvId writeSwizzle(const Swizzle& swizzle, SkWStream& out); + /** + * Folds the potentially-vector result of a logical operation down to a single bool. If + * operandType is a vector type, assumes that the intermediate result in id is a bvec of the + * same dimensions, and applys all() to it to fold it down to a single bool value. Otherwise, + * returns the original id value. + */ + SpvId foldToBool(SpvId id, const Type& operandType, SkWStream& out); + SpvId writeBinaryOperation(const Type& resultType, const Type& operandType, SpvId lhs, SpvId rhs, SpvOp_ ifFloat, SpvOp_ ifInt, SpvOp_ ifUInt, SpvOp_ ifBool, SkWStream& out); |