aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/sksl/SkSLSPIRVCodeGenerator.cpp26
-rw-r--r--src/sksl/SkSLSPIRVCodeGenerator.h8
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);