SkSL: Add test for scalar versions of geometric intrinsics
Fix code generation for Metal and Vulkan with geometric
intrinsics that have scalar versions in GLSL/SkSL, but no
native support in MSL/SPIR-V.
Change-Id: Id4538a00172e0d233ad9d5ed8d33db6436b83208
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/338276
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp
index 50548c4..af2b4bc 100644
--- a/src/sksl/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/SkSLMetalCodeGenerator.cpp
@@ -32,8 +32,12 @@
void MetalCodeGenerator::setupIntrinsics() {
#define METAL(x) std::make_pair(kMetal_IntrinsicKind, k ## x ## _MetalIntrinsic)
#define SPECIAL(x) std::make_pair(kSpecial_IntrinsicKind, k ## x ## _SpecialIntrinsic)
- fIntrinsicMap[String("sample")] = SPECIAL(Texture);
+ fIntrinsicMap[String("distance")] = SPECIAL(Distance);
+ fIntrinsicMap[String("dot")] = SPECIAL(Dot);
+ fIntrinsicMap[String("length")] = SPECIAL(Length);
fIntrinsicMap[String("mod")] = SPECIAL(Mod);
+ fIntrinsicMap[String("normalize")] = SPECIAL(Normalize);
+ fIntrinsicMap[String("sample")] = SPECIAL(Texture);
fIntrinsicMap[String("equal")] = METAL(Equal);
fIntrinsicMap[String("notEqual")] = METAL(NotEqual);
fIntrinsicMap[String("lessThan")] = METAL(LessThan);
@@ -405,6 +409,51 @@
this->write(", " + tmpX + " - " + tmpY + " * floor(" + tmpX + " / " + tmpY + "))");
break;
}
+ // GLSL declares scalar versions of most geometric intrinsics, but these don't exist in MSL
+ case kDistance_SpecialIntrinsic: {
+ if (arguments[0]->type().columns() == 1) {
+ this->write("abs(");
+ this->writeExpression(*arguments[0], kAdditive_Precedence);
+ this->write(" - ");
+ this->writeExpression(*arguments[1], kAdditive_Precedence);
+ this->write(")");
+ } else {
+ this->write("distance(");
+ this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->write(", ");
+ this->writeExpression(*arguments[1], kSequence_Precedence);
+ this->write(")");
+ }
+ break;
+ }
+ case kDot_SpecialIntrinsic: {
+ if (arguments[0]->type().columns() == 1) {
+ this->write("(");
+ this->writeExpression(*arguments[0], kMultiplicative_Precedence);
+ this->write(" * ");
+ this->writeExpression(*arguments[1], kMultiplicative_Precedence);
+ this->write(")");
+ } else {
+ this->write("dot(");
+ this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->write(", ");
+ this->writeExpression(*arguments[1], kSequence_Precedence);
+ this->write(")");
+ }
+ break;
+ }
+ case kLength_SpecialIntrinsic: {
+ this->write(arguments[0]->type().columns() == 1 ? "abs(" : "length(");
+ this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->write(")");
+ break;
+ }
+ case kNormalize_SpecialIntrinsic: {
+ this->write(arguments[0]->type().columns() == 1 ? "sign(" : "normalize(");
+ this->writeExpression(*arguments[0], kSequence_Precedence);
+ this->write(")");
+ break;
+ }
default:
ABORT("unsupported special intrinsic kind");
}