Enable comparison of arrays of different precision types.
GLSL allows an array of `lowp float` to be compared against `highp
float` seamlessly because the types are considered to be the same. SkSL,
however, treats these as different types, so we need to coerce the types
to allow this comparison to work.
In other words, these comparisons can cause an array to be implicitly
casted. The expression `myHalf2Array == float[2](a, b)` should be
allowed when narrowing conversions are enabled. To allow this to work,
we need a dedicated IR node representing this type coercion.
We now allow implicit coercion of array types when the array's component
types would be implicitly coercible, and have a new IR node representing
that implicit conversion.
This CL fixes array comparisons, but array assignment needs additional
fixes. It currently results in:
"type mismatch: '=' cannot operate on (types)".
Bug: skia:12248
Change-Id: I99062486c081f748f65be4b36a3a52e95b559812
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/436571
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/sksl/codegen/SkSLGLSLCodeGenerator.cpp b/src/sksl/codegen/SkSLGLSLCodeGenerator.cpp
index ddbfa62..155029b 100644
--- a/src/sksl/codegen/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/codegen/SkSLGLSLCodeGenerator.cpp
@@ -10,6 +10,7 @@
#include <memory>
#include "src/sksl/SkSLCompiler.h"
+#include "src/sksl/ir/SkSLConstructorArrayCast.h"
#include "src/sksl/ir/SkSLExpressionStatement.h"
#include "src/sksl/ir/SkSLExtension.h"
#include "src/sksl/ir/SkSLIndexExpression.h"
@@ -163,6 +164,9 @@
this->writeConstructorDiagonalMatrix(expr.as<ConstructorDiagonalMatrix>(),
parentPrecedence);
break;
+ case Expression::Kind::kConstructorArrayCast:
+ this->writeExpression(*expr.as<ConstructorArrayCast>().argument(), parentPrecedence);
+ break;
case Expression::Kind::kConstructorArray:
case Expression::Kind::kConstructorCompound:
case Expression::Kind::kConstructorMatrixResize:
diff --git a/src/sksl/codegen/SkSLMetalCodeGenerator.cpp b/src/sksl/codegen/SkSLMetalCodeGenerator.cpp
index c6d24e0..6584457 100644
--- a/src/sksl/codegen/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/codegen/SkSLMetalCodeGenerator.cpp
@@ -11,6 +11,7 @@
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/SkSLMemoryLayout.h"
#include "src/sksl/ir/SkSLConstructorArray.h"
+#include "src/sksl/ir/SkSLConstructorArrayCast.h"
#include "src/sksl/ir/SkSLConstructorCompoundCast.h"
#include "src/sksl/ir/SkSLConstructorDiagonalMatrix.h"
#include "src/sksl/ir/SkSLConstructorMatrixResize.h"
@@ -125,6 +126,9 @@
case Expression::Kind::kConstructorStruct:
this->writeAnyConstructor(expr.asAnyConstructor(), "{", "}", parentPrecedence);
break;
+ case Expression::Kind::kConstructorArrayCast:
+ this->writeExpression(*expr.as<ConstructorArrayCast>().argument(), parentPrecedence);
+ break;
case Expression::Kind::kConstructorCompound:
this->writeConstructorCompound(expr.as<ConstructorCompound>(), parentPrecedence);
break;
@@ -1338,8 +1342,8 @@
auto [iter, wasInserted] = fHelpers.insert("ArrayEquality []");
if (wasInserted) {
fExtraFunctions.writeText(R"(
-template <typename T, size_t N>
-bool operator==(thread const array<T, N>& left, thread const array<T, N>& right) {
+template <typename T1, typename T2, size_t N>
+bool operator==(thread const array<T1, N>& left, thread const array<T2, N>& right) {
for (size_t index = 0; index < N; ++index) {
if (!(left[index] == right[index])) {
return false;
@@ -1348,8 +1352,8 @@
return true;
}
-template <typename T, size_t N>
-bool operator!=(thread const array<T, N>& left, thread const array<T, N>& right) {
+template <typename T1, typename T2, size_t N>
+bool operator!=(thread const array<T1, N>& left, thread const array<T2, N>& right) {
return !(left == right);
}
)");
@@ -2403,6 +2407,7 @@
case Expression::Kind::kConstructorCompound:
case Expression::Kind::kConstructorCompoundCast:
case Expression::Kind::kConstructorArray:
+ case Expression::Kind::kConstructorArrayCast:
case Expression::Kind::kConstructorDiagonalMatrix:
case Expression::Kind::kConstructorScalarCast:
case Expression::Kind::kConstructorSplat:
diff --git a/src/sksl/codegen/SkSLPipelineStageCodeGenerator.cpp b/src/sksl/codegen/SkSLPipelineStageCodeGenerator.cpp
index 3c1b2c2..69ca39f 100644
--- a/src/sksl/codegen/SkSLPipelineStageCodeGenerator.cpp
+++ b/src/sksl/codegen/SkSLPipelineStageCodeGenerator.cpp
@@ -14,6 +14,7 @@
#include "src/sksl/SkSLStringStream.h"
#include "src/sksl/ir/SkSLBinaryExpression.h"
#include "src/sksl/ir/SkSLConstructor.h"
+#include "src/sksl/ir/SkSLConstructorArrayCast.h"
#include "src/sksl/ir/SkSLDoStatement.h"
#include "src/sksl/ir/SkSLExpressionStatement.h"
#include "src/sksl/ir/SkSLFieldAccess.h"
@@ -438,6 +439,9 @@
case Expression::Kind::kIntLiteral:
this->write(expr.description());
break;
+ case Expression::Kind::kConstructorArrayCast:
+ this->writeExpression(*expr.as<ConstructorArrayCast>().argument(), parentPrecedence);
+ break;
case Expression::Kind::kConstructorArray:
case Expression::Kind::kConstructorCompound:
case Expression::Kind::kConstructorCompoundCast:
diff --git a/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp b/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp
index 2a0a5ce..161689a 100644
--- a/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp
+++ b/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp
@@ -14,6 +14,7 @@
#include "src/sksl/SkSLOperators.h"
#include "src/sksl/dsl/priv/DSLWriter.h"
#include "src/sksl/ir/SkSLBlock.h"
+#include "src/sksl/ir/SkSLConstructorArrayCast.h"
#include "src/sksl/ir/SkSLExpressionStatement.h"
#include "src/sksl/ir/SkSLExtension.h"
#include "src/sksl/ir/SkSLField.h"
@@ -721,6 +722,8 @@
return this->writeBinaryExpression(expr.as<BinaryExpression>(), out);
case Expression::Kind::kBoolLiteral:
return this->writeBoolLiteral(expr.as<BoolLiteral>());
+ case Expression::Kind::kConstructorArrayCast:
+ return this->writeExpression(*expr.as<ConstructorArrayCast>().argument(), out);
case Expression::Kind::kConstructorArray:
case Expression::Kind::kConstructorStruct:
return this->writeCompositeConstructor(expr.asAnyConstructor(), out);
diff --git a/src/sksl/codegen/SkSLVMCodeGenerator.cpp b/src/sksl/codegen/SkSLVMCodeGenerator.cpp
index c2a5ea2..b9e2333 100644
--- a/src/sksl/codegen/SkSLVMCodeGenerator.cpp
+++ b/src/sksl/codegen/SkSLVMCodeGenerator.cpp
@@ -19,6 +19,7 @@
#include "src/sksl/ir/SkSLBreakStatement.h"
#include "src/sksl/ir/SkSLConstructor.h"
#include "src/sksl/ir/SkSLConstructorArray.h"
+#include "src/sksl/ir/SkSLConstructorArrayCast.h"
#include "src/sksl/ir/SkSLConstructorDiagonalMatrix.h"
#include "src/sksl/ir/SkSLConstructorMatrixResize.h"
#include "src/sksl/ir/SkSLConstructorSplat.h"
@@ -1339,6 +1340,8 @@
case Expression::Kind::kConstructorCompound:
case Expression::Kind::kConstructorStruct:
return this->writeAggregationConstructor(e.asAnyConstructor());
+ case Expression::Kind::kConstructorArrayCast:
+ return this->writeExpression(*e.as<ConstructorArrayCast>().argument());
case Expression::Kind::kConstructorDiagonalMatrix:
return this->writeConstructorDiagonalMatrix(e.as<ConstructorDiagonalMatrix>());
case Expression::Kind::kConstructorMatrixResize: