Reland "Improve support for arrays in Metal."
This reverts commit 38df4c8470ab3db7455005ab0c3599a95c791d2b.
Reason for revert: updated ArrayTypes test for ES2 compatibility
Original change's description:
> Revert "Improve support for arrays in Metal."
>
> This reverts commit dd904af5666b4746d4b9af5c1f03b47ac3ec73b2.
>
> Reason for revert: breaks ANGLE
>
> Original change's description:
> > Improve support for arrays in Metal.
> >
> > Arrays in Metal now use the `array<T, N>` type instead of the C-style
> > `T[N]` type. This gives them semantics much more in line with GLSL,
> > so they can be initialized and assigned like GLSL arrays.
> >
> > This allows the ArrayTypes and Assignment tests to pass, so they have
> > been added to our dm SkSL tests. (ArrayConstructors also passes, but
> > is not ES2-compliant so it is not enabled.)
> >
> > Change-Id: Id1028311963084befd0e044e11e223af6a064dda
> > Bug: skia:10761, skia:10760, skia:11022, skia:10939
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/365699
> > Commit-Queue: John Stiles <johnstiles@google.com>
> > Auto-Submit: John Stiles <johnstiles@google.com>
> > Reviewed-by: Brian Osman <brianosman@google.com>
>
> TBR=brianosman@google.com,ethannicholas@google.com,johnstiles@google.com
>
> Change-Id: If6a18dea7d6a45fa7836e9129bf81c2e536f07e3
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:10761
> Bug: skia:10760
> Bug: skia:11022
> Bug: skia:10939
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/365976
> Reviewed-by: John Stiles <johnstiles@google.com>
> Commit-Queue: John Stiles <johnstiles@google.com>
TBR=brianosman@google.com,ethannicholas@google.com,johnstiles@google.com
Bug: skia:10761
Bug: skia:10760
Bug: skia:11022
Bug: skia:10939
Change-Id: Ia1c4917f5d3c41162d282b3093814d861707ad30
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/366144
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp
index 908f9df..37d8d20 100644
--- a/src/sksl/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/SkSLMetalCodeGenerator.cpp
@@ -109,15 +109,24 @@
String MetalCodeGenerator::typeName(const Type& type) {
switch (type.typeKind()) {
+ case Type::TypeKind::kArray:
+ SkASSERTF(type.columns() > 0, "invalid array size: %s", type.description().c_str());
+ return String::printf("array<%s, %d>",
+ this->typeName(type.componentType()).c_str(), type.columns());
+
case Type::TypeKind::kVector:
return this->typeName(type.componentType()) + to_string(type.columns());
+
case Type::TypeKind::kMatrix:
return this->typeName(type.componentType()) + to_string(type.columns()) + "x" +
to_string(type.rows());
+
case Type::TypeKind::kSampler:
return "texture2d<float>"; // FIXME - support other texture types
+
case Type::TypeKind::kEnum:
return "int";
+
default:
if (type == *fContext.fTypes.fHalf) {
// FIXME - Currently only supporting floats in MSL to avoid type coercion issues.
@@ -141,36 +150,8 @@
this->writeLine("};");
}
-// Flags an error if an array type is found. Meant to be used in places where an array type might
-// appear in the SkSL/IR, but can't be represented by Metal.
-void MetalCodeGenerator::disallowArrayTypes(const Type& type, int offset) {
- if (type.isArray()) {
- fErrors.error(offset, "Metal does not support array types in this context");
- }
-}
-
-// Writes the base type, stripping array suffixes. e.g. `float[2]` will output `float`.
-// Call `writeArrayDimensions` to write the type's accompanying array sizes.
-void MetalCodeGenerator::writeBaseType(const Type& type) {
- switch (type.typeKind()) {
- case Type::TypeKind::kArray:
- this->writeBaseType(type.componentType());
- break;
- default:
- this->write(this->typeName(type));
- break;
- }
-}
-
-// Writes the array suffix of a type, if one exists. e.g. `float[2][4]` will output `[2][4]`.
-void MetalCodeGenerator::writeArrayDimensions(const Type& type) {
- if (type.isArray()) {
- this->write("[");
- if (type.columns() != Type::kUnsizedArray) {
- this->write(to_string(type.columns()));
- }
- this->write("]");
- }
+void MetalCodeGenerator::writeType(const Type& type) {
+ this->write(this->typeName(type));
}
void MetalCodeGenerator::writeExpression(const Expression& expr, Precedence parentPrecedence) {
@@ -242,7 +223,7 @@
// `outVars` is non-null; in those places, we take the type of the VariableReference.
//
// float _skOutParamHelper0_originalFuncName(float _var0, float _var1, float& outParam) {
- this->writeBaseType(call.type());
+ this->writeType(call.type());
this->write(" ");
this->write(name);
this->write("(");
@@ -259,7 +240,7 @@
this->writeModifiers(param->modifiers(), /*globalContext=*/false);
const Type* type = outVars[index] ? &outVars[index]->type() : &arguments[index]->type();
- this->writeBaseType(*type);
+ this->writeType(*type);
if (param->modifiers().fFlags & Modifiers::kOut_Flag) {
this->write("&");
@@ -273,7 +254,6 @@
this->write(" _var");
this->write(to_string(index));
}
- this->writeArrayDimensions(*type);
}
this->writeLine(") {");
@@ -283,7 +263,7 @@
continue;
}
// float3 _var2[ = outParam.zyx];
- this->writeBaseType(arguments[index]->type());
+ this->writeType(arguments[index]->type());
this->write(" _var");
this->write(to_string(index));
@@ -301,7 +281,7 @@
// [int _skResult = ] myFunction(inputs, outputs, _globals, _var0, _var1, _var2, _var3);
bool hasResult = (call.type().name() != "void");
if (hasResult) {
- this->writeBaseType(call.type());
+ this->writeType(call.type());
this->write(" _skResult = ");
}
@@ -1082,9 +1062,8 @@
}
// Explicitly invoke the constructor, passing in the necessary arguments.
- this->writeBaseType(constructorType);
- this->disallowArrayTypes(constructorType, c.fOffset);
- this->write("(");
+ this->writeType(constructorType);
+ this->write(constructorType.isArray() ? "{" : "(");
const char* separator = "";
int scalarCount = 0;
for (const std::unique_ptr<Expression>& arg : c.arguments()) {
@@ -1095,7 +1074,7 @@
argType.columns() < constructorType.rows()) {
// Merge scalars and smaller vectors together.
if (!scalarCount) {
- this->writeBaseType(constructorType.componentType());
+ this->writeType(constructorType.componentType());
this->write(to_string(constructorType.rows()));
this->write("(");
}
@@ -1107,7 +1086,7 @@
scalarCount = 0;
}
}
- this->write(")");
+ this->write(constructorType.isArray() ? "}" : ")");
}
void MetalCodeGenerator::writeFragCoord() {
@@ -1500,7 +1479,7 @@
continue;
}
this->write(", constant ");
- this->writeBaseType(intf.variable().type());
+ this->writeType(intf.variable().type());
this->write("& " );
this->write(fInterfaceBlockNameMap[&intf]);
this->write(" [[buffer(");
@@ -1520,8 +1499,7 @@
}
separator = ", ";
} else {
- this->writeBaseType(f.returnType());
- this->disallowArrayTypes(f.returnType(), f.fOffset);
+ this->writeType(f.returnType());
this->write(" ");
this->writeName(f.name());
this->write("(");
@@ -1532,13 +1510,12 @@
separator = ", ";
this->writeModifiers(param->modifiers(), /*globalContext=*/false);
const Type* type = ¶m->type();
- this->writeBaseType(*type);
+ this->writeType(*type);
if (param->modifiers().fFlags & Modifiers::kOut_Flag) {
this->write("&");
}
this->write(" ");
this->writeName(param->name());
- this->writeArrayDimensions(*type);
}
this->write(")");
return true;
@@ -1698,10 +1675,9 @@
}
currentOffset += fieldSize;
this->writeModifiers(field.fModifiers, /*globalContext=*/false);
- this->writeBaseType(*fieldType);
+ this->writeType(*fieldType);
this->write(" ");
this->writeName(field.fName);
- this->writeArrayDimensions(*fieldType);
this->writeLine(";");
if (parentIntf) {
fInterfaceBlockMap[&field] = parentIntf;
@@ -1720,25 +1696,17 @@
this->write(name);
}
-void MetalCodeGenerator::writeVarDeclaration(const VarDeclaration& var, bool global) {
- if (global && !(var.var().modifiers().fFlags & Modifiers::kConst_Flag)) {
+void MetalCodeGenerator::writeVarDeclaration(const VarDeclaration& varDecl, bool global) {
+ if (global && !(varDecl.var().modifiers().fFlags & Modifiers::kConst_Flag)) {
return;
}
- this->writeModifiers(var.var().modifiers(), global);
- this->writeBaseType(var.baseType());
- this->disallowArrayTypes(var.baseType(), var.fOffset);
+ this->writeModifiers(varDecl.var().modifiers(), global);
+ this->writeType(varDecl.var().type());
this->write(" ");
- this->writeName(var.var().name());
- if (var.arraySize() > 0) {
- this->write("[");
- this->write(to_string(var.arraySize()));
- this->write("]");
- } else if (var.arraySize() == Type::kUnsizedArray){
- this->write("[]");
- }
- if (var.value()) {
+ this->writeName(varDecl.var().name());
+ if (varDecl.value()) {
this->write(" = ");
- this->writeVarInitializer(var.var(), *var.value());
+ this->writeVarInitializer(varDecl.var(), *varDecl.value());
}
this->write(";");
}
@@ -1940,10 +1908,9 @@
"the same 'layout(set=...)'");
}
this->write(" ");
- this->writeBaseType(var.type());
+ this->writeType(var.type());
this->write(" ");
this->writeName(var.name());
- this->writeArrayDimensions(var.type());
this->write(";\n");
}
}
@@ -1962,10 +1929,9 @@
if (var.modifiers().fFlags & Modifiers::kIn_Flag &&
-1 == var.modifiers().fLayout.fBuiltin) {
this->write(" ");
- this->writeBaseType(var.type());
+ this->writeType(var.type());
this->write(" ");
this->writeName(var.name());
- this->writeArrayDimensions(var.type());
if (-1 != var.modifiers().fLayout.fLocation) {
if (fProgram.fKind == Program::kVertex_Kind) {
this->write(" [[attribute(" +
@@ -1996,10 +1962,9 @@
if (var.modifiers().fFlags & Modifiers::kOut_Flag &&
-1 == var.modifiers().fLayout.fBuiltin) {
this->write(" ");
- this->writeBaseType(var.type());
+ this->writeType(var.type());
this->write(" ");
this->writeName(var.name());
- this->writeArrayDimensions(var.type());
int location = var.modifiers().fLayout.fLocation;
if (location < 0) {
@@ -2088,10 +2053,9 @@
void visitTexture(const Type& type, const String& name) override {
this->addElement();
fCodeGen->write(" ");
- fCodeGen->writeBaseType(type);
+ fCodeGen->writeType(type);
fCodeGen->write(" ");
fCodeGen->writeName(name);
- fCodeGen->writeArrayDimensions(type);
fCodeGen->write(";\n");
}
void visitSampler(const Type&, const String& name) override {
@@ -2103,10 +2067,9 @@
void visitVariable(const Variable& var, const Expression* value) override {
this->addElement();
fCodeGen->write(" ");
- fCodeGen->writeBaseType(var.type());
+ fCodeGen->writeType(var.type());
fCodeGen->write(" ");
fCodeGen->writeName(var.name());
- fCodeGen->writeArrayDimensions(var.type());
fCodeGen->write(";\n");
}
void addElement() {