aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/sksl
diff options
context:
space:
mode:
authorGravatar Timothy Liang <timliang@google.com>2018-06-05 09:58:07 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-05 15:20:58 +0000
commit7d63778a0a262a8728fd2507794d3a8d92e5fac5 (patch)
tree5d05fbcbabbf6b9249a8e07cf251aed42fdfd36f /src/sksl
parent1b7cd334f8d6de2e31396eb0d2a8ad3a99c1d221 (diff)
fixed interface/in/out struct for mvk integration and added a few missing builtins to skslc msl backend
Bug: skia: Change-Id: Id514dc6af64bb2a5eb71f2161ceba549a8a6836d Reviewed-on: https://skia-review.googlesource.com/131881 Reviewed-by: Ethan Nicholas <ethannicholas@google.com> Commit-Queue: Timothy Liang <timliang@google.com>
Diffstat (limited to 'src/sksl')
-rw-r--r--src/sksl/SkSLMetalCodeGenerator.cpp379
-rw-r--r--src/sksl/SkSLMetalCodeGenerator.h11
2 files changed, 327 insertions, 63 deletions
diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp
index 7140dbaa9c..b11667cfcb 100644
--- a/src/sksl/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/SkSLMetalCodeGenerator.cpp
@@ -14,19 +14,16 @@
#include "ir/SkSLModifiersDeclaration.h"
#include "ir/SkSLNop.h"
#include "ir/SkSLVariableReference.h"
+#include <fstream> // FIXME - remove streams when done inserting MSL code directly
+#include <sstream>
static const uint32_t MVKMagicNum = 0x19960412; // FIXME - remove when decoupled from MVK
namespace SkSL {
void MetalCodeGenerator::setupIntrinsics() {
-#define METAL(x) std::make_tuple(kMetal_IntrinsicKind, k ## x ## _MetalIntrinsic, \
- k ## x ## _MetalIntrinsic, k ## x ## _MetalIntrinsic, \
- k ## x ## _MetalIntrinsic)
-#define SPECIAL(x) std::make_tuple(kSpecial_IntrinsicKind, k ## x ## _SpecialIntrinsic, \
- k ## x ## _SpecialIntrinsic, k ## x ## _SpecialIntrinsic, \
- k ## x ## _SpecialIntrinsic)
-// FIXME - tuple probably doesn't need this many fields, will fix when all intrinsics written
+#define METAL(x) std::make_pair(kMetal_IntrinsicKind, k ## x ## _MetalIntrinsic)
+#define SPECIAL(x) std::make_pair(kSpecial_IntrinsicKind, k ## x ## _SpecialIntrinsic)
fIntrinsicMap[String("texture")] = SPECIAL(Texture);
fIntrinsicMap[String("lessThan")] = METAL(LessThan);
fIntrinsicMap[String("lessThanEqual")] = METAL(LessThanEqual);
@@ -96,10 +93,19 @@ void MetalCodeGenerator::writeType(const Type& type) {
this->write(to_string(type.columns()));
break;
case Type::kSampler_Kind:
- this->write("texture2d<half> "); //FIXME - support other texture types;
+ this->write("texture2d<float> "); //FIXME - support other texture types;
break;
default:
- this->write(type.name());
+ // FIXME - converted all half types to floats for MVK integration
+ if ((type.kind() == Type::kVector_Kind || type.kind() == Type::kMatrix_Kind) &&
+ type.componentType() == *fContext.fHalf_Type) {
+ this->writeType(fContext.fFloat_Type->toCompound(fContext, type.columns(),
+ type.rows()));
+ } else if (type == *fContext.fHalf_Type) {
+ this->writeType(*fContext.fFloat_Type);
+ } else {
+ this->write(type.name());
+ }
}
}
@@ -153,17 +159,11 @@ void MetalCodeGenerator::writeExpression(const Expression& expr, Precedence pare
}
void MetalCodeGenerator::writeIntrinsicCall(const FunctionCall& c) {
- auto intrinsic = fIntrinsicMap.find(c.fFunction.fName);
- ASSERT(intrinsic != fIntrinsicMap.end());
- int32_t intrinsicId = 0;
- if (c.fArguments.size() > 0) {
- if (std::get<0>(intrinsic->second) == kSpecial_IntrinsicKind) {
- intrinsicId = std::get<1>(intrinsic->second);
- }
- } else {
- intrinsicId = std::get<1>(intrinsic->second);
- }
- switch (std::get<0>(intrinsic->second)) {
+ auto i = fIntrinsicMap.find(c.fFunction.fName);
+ ASSERT(i != fIntrinsicMap.end());
+ Intrinsic intrinsic = i->second;
+ int32_t intrinsicId = intrinsic.second;
+ switch (intrinsic.first) {
case kSpecial_IntrinsicKind:
return this->writeSpecialIntrinsic(c, (SpecialIntrinsic) intrinsicId);
break;
@@ -204,6 +204,10 @@ void MetalCodeGenerator::writeFunctionCall(const FunctionCall& c) {
this->write("rsqrt");
} else if (c.fFunction.fBuiltin && "mod" == c.fFunction.fName) {
this->write("fmod");
+ } else if (c.fFunction.fBuiltin && "dFdx" == c.fFunction.fName) {
+ this->write("dfdx");
+ } else if (c.fFunction.fBuiltin && "dFdy" == c.fFunction.fName) {
+ this->write("dfdy");
} else {
this->write(c.fFunction.fName);
}
@@ -289,13 +293,13 @@ void MetalCodeGenerator::writeConstructor(const Constructor& c) {
}
void MetalCodeGenerator::writeFragCoord() {
- this->write("_in.position");
+ this->write("float4(_fragCoord.x, _anonInterface0.u_skRTHeight - _fragCoord.y, 0.0, 1.0)");
}
void MetalCodeGenerator::writeVariableReference(const VariableReference& ref) {
switch (ref.fVariable.fModifiers.fLayout.fBuiltin) {
case SK_FRAGCOLOR_BUILTIN:
- this->write("sk_FragColor");
+ this->write("_out->sk_FragColor");
break;
case SK_FRAGCOORD_BUILTIN:
this->writeFragCoord();
@@ -313,6 +317,13 @@ void MetalCodeGenerator::writeVariableReference(const VariableReference& ref) {
this->write("_globals->");
}
}
+ // FIXME - probably going to eventually have a map of renamed functions and
+ // use it to detect conflicts with variable names.
+ if (ref.fVariable.fName == "dfdx") {
+ this->write("dFdx");
+ } else if (ref.fVariable.fName == "dfdy") {
+ this->write("dFdy");
+ }
this->write(ref.fVariable.fName);
}
}
@@ -325,11 +336,12 @@ void MetalCodeGenerator::writeIndexExpression(const IndexExpression& expr) {
}
void MetalCodeGenerator::writeFieldAccess(const FieldAccess& f) {
+ const Type::Field* field = &f.fBase->fType.fields()[f.fFieldIndex];
if (FieldAccess::kDefault_OwnerKind == f.fOwnerKind) {
this->writeExpression(*f.fBase, kPostfix_Precedence);
this->write(".");
}
- switch (f.fBase->fType.fields()[f.fFieldIndex].fModifiers.fLayout.fBuiltin) {
+ switch (field->fModifiers.fLayout.fBuiltin) {
case SK_CLIPDISTANCE_BUILTIN:
this->write("gl_ClipDistance");
break;
@@ -337,12 +349,16 @@ void MetalCodeGenerator::writeFieldAccess(const FieldAccess& f) {
this->write("_out->position");
break;
default:
- if (FieldAccess::kAnonymousInterfaceBlock_OwnerKind == f.fOwnerKind) {
- this->write(fInterfaceBlockNameMap[
- fInterfaceBlockMap[&f.fBase->fType.fields()[f.fFieldIndex]]]);
- this->write(".");
+ if (field->fName == "sk_PointSize") {
+ this->write("_out->sk_PointSize");
+ } else {
+ if (FieldAccess::kAnonymousInterfaceBlock_OwnerKind == f.fOwnerKind) {
+ this->write("_globals->");
+ this->write(fInterfaceBlockNameMap[fInterfaceBlockMap[field]]);
+ this->write("->");
+ }
+ this->write(field->fName);
}
- this->write(f.fBase->fType.fields()[f.fFieldIndex].fName);
}
}
@@ -497,7 +513,7 @@ void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) {
if ("main" == f.fDeclaration.fName) {
switch (fProgram.fKind) {
case Program::kFragment_Kind:
- this->write("fragment half4 main0"); // FIXME - named main0 for MVK integration
+ this->write("fragment Outputs main0"); // FIXME - named main0 for MVK integration
break;
case Program::kVertex_Kind:
this->write("vertex Outputs main0");
@@ -519,7 +535,7 @@ void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) {
for (const auto& stmt: decls.fVars) {
VarDeclaration& var = (VarDeclaration&) *stmt;
if (var.fVar->fType.kind() == Type::kSampler_Kind) {
- this->write(", texture2d<half> "); // FIXME - support other texture types
+ this->write(", texture2d<float> "); // FIXME - support other texture types
this->write(var.fVar->fName);
this->write("[[texture(");
this->write(to_string(var.fVar->fModifiers.fLayout.fBinding));
@@ -542,10 +558,17 @@ void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) {
this->write("& " );
this->write(fInterfaceBlockNameMap[&intf]);
this->write(" [[buffer(");
- this->write(to_string(intf.fVariable.fModifiers.fLayout.fBinding));
+ this->write(to_string(intf.fVariable.fModifiers.fLayout.fSet));
this->write(")]]");
}
}
+ if (fInterfaceBlockNameMap.empty()) {
+ // FIXME - used for MVK integration
+ this->write(", constant sksl_synthetic_uniforms& _anonInterface0 [[buffer(0)]]");
+ }
+ if (fProgram.fKind == Program::kFragment_Kind) {
+ this->write(", float4 _fragCoord [[position]]");
+ }
separator = ", ";
} else {
this->writeType(f.fDeclaration.fReturnType);
@@ -601,6 +624,14 @@ void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) {
if (fNeedsGlobalStructInit) {
this->writeLine(" Globals globalStruct;");
this->writeLine(" thread Globals* _globals = &globalStruct;");
+ for (const auto& intf: fInterfaceBlockNameMap) {
+ const auto& intfName = intf.second;
+ this->write(" _globals->");
+ this->write(intfName);
+ this->write(" = &");
+ this->write(intfName);
+ this->write(";\n");
+ }
for (const auto& var: fInitNonConstGlobalVars) {
this->write(" _globals->");
this->write(var->fVar->fName);
@@ -623,17 +654,8 @@ void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) {
this->write(";\n");
}
}
- switch (fProgram.fKind) {
- case Program::kFragment_Kind:
- this->writeLine(" half4 sk_FragColor;");
- break;
- case Program::kVertex_Kind:
- this->writeLine(" Outputs _outputStruct;");
- this->writeLine(" thread Outputs* _out = &_outputStruct;");
- break;
- default:
- ASSERT(false);
- }
+ this->writeLine(" Outputs _outputStruct;");
+ this->writeLine(" thread Outputs* _out = &_outputStruct;");
}
fFunctionHeader = "";
OutputStream* oldOut = fOut;
@@ -644,7 +666,7 @@ void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) {
if ("main" == f.fDeclaration.fName) {
switch (fProgram.fKind) {
case Program::kFragment_Kind:
- this->writeLine("return sk_FragColor;");
+ this->writeLine("return *_out;");
break;
case Program::kVertex_Kind:
this->writeLine("_out->position.y = -_out->position.y;");
@@ -685,11 +707,49 @@ void MetalCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
while (Type::kArray_Kind == structType->kind()) {
structType = &structType->componentType();
}
- for (const auto& f : structType->fields()) {
- this->writeModifiers(f.fModifiers, false);
- this->writeType(*f.fType);
- this->writeLine(" " + f.fName + ";");
- fInterfaceBlockMap[&f] = &intf;
+ int currentOffset = 0;
+ // Pack half/float3 types and add char arrays for padding when needed to maintain alignment
+ for (const auto& field: structType->fields()) {
+ int fieldOffset = field.fModifiers.fLayout.fOffset;
+ if (fieldOffset != -1) {
+ if (currentOffset > fieldOffset) {
+ ABORT("Original interface offsets are too close for MoltenVK");
+ } else if (currentOffset < fieldOffset) {
+ this->write("char pad");
+ this->write(to_string(fPaddingCount++));
+ this->write("[");
+ this->write(to_string(fieldOffset - currentOffset));
+ this->writeLine("];");
+ currentOffset = fieldOffset;
+ }
+ }
+ const Type* fieldType = field.fType;
+ std::vector<int> sizes;
+ while (fieldType->kind() == Type::kArray_Kind) {
+ sizes.push_back(fieldType->columns());
+ fieldType = &fieldType->componentType();
+ }
+ bool isPacked = false;
+ if (fieldType->kind() == Type::kVector_Kind && fieldType->columns() == 3 &&
+ fieldOffset != -1) {
+ this->write(PACKED_PREFIX);
+ isPacked = true;
+ }
+ this->writeType(*fieldType);
+ this->write(" " + field.fName);
+ for (int s : sizes) {
+ if (s <= 0) {
+ this->write("[]");
+ } else {
+ this->write("[" + to_string(s) + "]");
+ }
+ }
+ this->writeLine(";");
+ fInterfaceBlockMap[&field] = &intf;
+ currentOffset += size(fieldType, isPacked);
+ }
+ if (fProgram.fKind == Program::kFragment_Kind) {
+ this->writeLine("float u_skRTHeight;");
}
fIndentation--;
this->write("}");
@@ -705,11 +765,97 @@ void MetalCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
}
fInterfaceBlockNameMap[&intf] = intf.fInstanceName;
} else {
- fInterfaceBlockNameMap[&intf] = "_AnonInterface" + to_string(fAnonInterfaceCount++);
+ fInterfaceBlockNameMap[&intf] = "_anonInterface" + to_string(fAnonInterfaceCount++);
}
this->writeLine(";");
}
+// FIXME - Update SkSLMemoryLayout.h to calculate size and alignment values below for MSL shaders.
+// Also, the below currently only handle cases needed for gm's
+int MetalCodeGenerator::size(const Type* type, bool isPacked) const {
+ if (type->kind() == Type::kArray_Kind && type->componentType().kind() == Type::kScalar_Kind) {
+ return type->columns() * 4;
+ }
+ if ((type->kind() == Type::kVector_Kind || type->kind() == Type::kMatrix_Kind) &&
+ type->componentType() == *fContext.fHalf_Type) {
+ type = &fContext.fFloat_Type->toCompound(fContext, type->columns(),type->rows());
+ } else if (type == fContext.fHalf_Type.get()) {
+ type = fContext.fFloat_Type.get();
+ }
+ if (isPacked) {
+ if (type == fContext.fFloat_Type.get()) {
+ return 4;
+ } else if (type == fContext.fFloat2_Type.get()) {
+ return 8;
+ } else if (type == fContext.fFloat3_Type.get()) {
+ return 12;
+ } else if (type == fContext.fFloat4_Type.get()) {
+ return 16;
+ }
+ } else {
+ if (type == fContext.fFloat_Type.get()) {
+ return 4;
+ } else if (type == fContext.fFloat2_Type.get()) {
+ return 8;
+ } else if (type == fContext.fFloat3_Type.get()) {
+ return 16;
+ } else if (type == fContext.fFloat4_Type.get()) {
+ return 16;
+ } else if (type == fContext.fFloat2x2_Type.get()) {
+ return 16;
+ } else if (type == fContext.fFloat2x3_Type.get()) {
+ return 32;
+ } else if (type == fContext.fFloat2x4_Type.get()) {
+ return 32;
+ } else if (type == fContext.fFloat3x2_Type.get()) {
+ return 24;
+ } else if (type == fContext.fFloat3x3_Type.get()) {
+ return 48;
+ } else if (type == fContext.fFloat3x4_Type.get()) {
+ return 48;
+ } else if (type == fContext.fFloat4x2_Type.get()) {
+ return 32;
+ } else if (type == fContext.fFloat4x3_Type.get()) {
+ return 64;
+ } else if (type == fContext.fFloat4x4_Type.get()) {
+ return 64;
+ }
+ }
+
+ ABORT("Unsupported type for size: %s", String(type->fName).c_str());
+}
+
+int MetalCodeGenerator::alignment(const Type* type, bool isPacked) const {
+ if ((type->kind() == Type::kVector_Kind || type->kind() == Type::kMatrix_Kind) &&
+ type->componentType() == *fContext.fHalf_Type) {
+ type = &fContext.fFloat_Type->toCompound(fContext, type->columns(),type->rows());
+ } else if (type == fContext.fHalf_Type.get()) {
+ type = fContext.fFloat_Type.get();
+ }
+ if (isPacked) {
+ if (type == fContext.fFloat_Type.get()) {
+ return 4;
+ } else if (type == fContext.fFloat2_Type.get()) {
+ return 4;
+ } else if (type == fContext.fFloat3_Type.get()) {
+ return 4;
+ } else if (type == fContext.fFloat4_Type.get()) {
+ return 4;
+ }
+ } else {
+ if (type == fContext.fFloat_Type.get()) {
+ return 4;
+ } else if (type == fContext.fFloat2_Type.get()) {
+ return 8;
+ } else if (type == fContext.fFloat3_Type.get()) {
+ return 16;
+ } else if (type == fContext.fFloat4_Type.get()) {
+ return 16;
+ }
+ }
+ ABORT("Unsupported type for alignment: %s", String(type->fName).c_str());
+}
+
void MetalCodeGenerator::writeVarInitializer(const Variable& var, const Expression& value) {
this->writeExpression(value, kTopLevel_Precedence);
}
@@ -730,6 +876,13 @@ void MetalCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool
this->write(" ");
wroteType = true;
}
+ // FIXME - probably going to eventually have a map of all renamed functions and
+ // use it to detect conflicts with variable names.
+ if (var.fVar->fName == "dfdx") {
+ this->write("dFdx");
+ } else if (var.fVar->fName == "dfdy") {
+ this->write("dFdy");
+ }
this->write(var.fVar->fName);
for (const auto& size : var.fSizes) {
this->write("[");
@@ -943,9 +1096,6 @@ void MetalCodeGenerator::writeUniformStruct() {
void MetalCodeGenerator::writeInputStruct() {
this->write("struct Inputs {\n");
- if (Program::kFragment_Kind == fProgram.fKind) {
- this->write(" float4 position [[position]];\n");
- }
for (const auto& e : fProgram) {
if (ProgramElement::kVar_Kind == e.fKind) {
VarDeclarations& decls = (VarDeclarations&) e;
@@ -962,8 +1112,13 @@ void MetalCodeGenerator::writeInputStruct() {
VarDeclaration& var = (VarDeclaration&) *stmt;
this->write(var.fVar->fName);
if (-1 != var.fVar->fModifiers.fLayout.fLocation) {
- this->write(" [[attribute(" +
- to_string(var.fVar->fModifiers.fLayout.fLocation) + ")]]");
+ if (fProgram.fKind == Program::kVertex_Kind) {
+ this->write(" [[attribute(" +
+ to_string(var.fVar->fModifiers.fLayout.fLocation) + ")]]");
+ } else if (fProgram.fKind == Program::kFragment_Kind) {
+ this->write(" [[user(locn" +
+ to_string(var.fVar->fModifiers.fLayout.fLocation) + ")]]");
+ }
}
}
this->write(";\n");
@@ -975,7 +1130,11 @@ void MetalCodeGenerator::writeInputStruct() {
void MetalCodeGenerator::writeOutputStruct() {
this->write("struct Outputs {\n");
- this->write(" float4 position [[position]];\n");
+ if (fProgram.fKind == Program::kVertex_Kind) {
+ this->write(" float4 position [[position]];\n");
+ } else if (fProgram.fKind == Program::kFragment_Kind) {
+ this->write(" float4 sk_FragColor [[color(0), index(0)]];\n");
+ }
for (const auto& e : fProgram) {
if (ProgramElement::kVar_Kind == e.fKind) {
VarDeclarations& decls = (VarDeclarations&) e;
@@ -991,15 +1150,58 @@ void MetalCodeGenerator::writeOutputStruct() {
for (const auto& stmt : decls.fVars) {
VarDeclaration& var = (VarDeclaration&) *stmt;
this->write(var.fVar->fName);
+ if (fProgram.fKind == Program::kVertex_Kind) {
+ this->write(" [[user(locn" +
+ to_string(var.fVar->fModifiers.fLayout.fLocation) + ")]]");
+ } else if (fProgram.fKind == Program::kFragment_Kind) {
+ this->write(" [[color(" +
+ to_string(var.fVar->fModifiers.fLayout.fLocation) +
+ "), index(" +
+ to_string(var.fVar->fModifiers.fLayout.fIndex) + ")]]");
+ }
}
this->write(";\n");
}
}
- } this->write("};\n");
+ }
+ if (fProgram.fKind == Program::kVertex_Kind) {
+ this->write(" float sk_PointSize;\n");
+ }
+ this->write("};\n");
+}
+
+void MetalCodeGenerator::writeInterfaceBlocks() {
+ bool wroteInterfaceBlock = false;
+ for (const auto& e : fProgram) {
+ if (ProgramElement::kInterfaceBlock_Kind == e.fKind) {
+ this->writeInterfaceBlock((InterfaceBlock&) e);
+ wroteInterfaceBlock = true;
+ }
+ }
+ if (!wroteInterfaceBlock && (fProgram.fKind == Program::kFragment_Kind)) {
+ // FIXME - below struct needed for mvk integration
+ this->writeLine("struct sksl_synthetic_uniforms {");
+ this->writeLine(" float u_skRTHeight;");
+ this->writeLine("};");
+ }
}
void MetalCodeGenerator::writeGlobalStruct() {
bool wroteStructDecl = false;
+ for (const auto& intf : fInterfaceBlockNameMap) {
+ if (!wroteStructDecl) {
+ this->write("struct Globals {\n");
+ wroteStructDecl = true;
+ }
+ fNeedsGlobalStructInit = true;
+ const auto& intfType = intf.first;
+ const auto& intfName = intf.second;
+ this->write(" constant ");
+ this->write(intfType->fTypeName);
+ this->write("* ");
+ this->write(intfName);
+ this->write(";\n");
+ }
for (const auto& e : fProgram) {
if (ProgramElement::kVar_Kind == e.fKind) {
VarDeclarations& decls = (VarDeclarations&) e;
@@ -1059,7 +1261,7 @@ void MetalCodeGenerator::writeProgramElement(const ProgramElement& e) {
break;
}
case ProgramElement::kInterfaceBlock_Kind:
- this->writeInterfaceBlock((InterfaceBlock&) e);
+ // handled in writeInterfaceBlocks, do nothing
break;
case ProgramElement::kFunction_Kind:
this->writeFunction((FunctionDefinition&) e);
@@ -1092,8 +1294,13 @@ MetalCodeGenerator::Requirements MetalCodeGenerator::requirements(const Expressi
}
return result;
}
- case Expression::kFieldAccess_Kind:
+ case Expression::kFieldAccess_Kind: {
+ const FieldAccess& f = (const FieldAccess&) e;
+ if (FieldAccess::kAnonymousInterfaceBlock_OwnerKind == f.fOwnerKind) {
+ return kGlobals_Requirement;
+ }
return this->requirements(*((const FieldAccess&) e).fBase);
+ }
case Expression::kSwizzle_Kind:
return this->requirements(*((const Swizzle&) e).fBase);
case Expression::kBinary_Kind: {
@@ -1146,6 +1353,22 @@ MetalCodeGenerator::Requirements MetalCodeGenerator::requirements(const Statemen
}
return result;
}
+ case Statement::kVarDeclaration_Kind: {
+ Requirements result = kNo_Requirements;
+ const VarDeclaration& var = (const VarDeclaration&) s;
+ if (var.fValue) {
+ result = this->requirements(*var.fValue);
+ }
+ return result;
+ }
+ case Statement::kVarDeclarations_Kind: {
+ Requirements result = kNo_Requirements;
+ const VarDeclarations& decls = *((const VarDeclarationsStatement&) s).fDeclaration;
+ for (const auto& stmt : decls.fVars) {
+ result |= this->requirements(*stmt);
+ }
+ return result;
+ }
case Statement::kExpression_Kind:
return this->requirements(*((const ExpressionStatement&) s).fExpression);
case Statement::kReturn_Kind: {
@@ -1213,7 +1436,12 @@ MetalCodeGenerator::Requirements MetalCodeGenerator::requirements(const Function
return found->second;
}
-bool MetalCodeGenerator::generateCode() {
+bool MetalCodeGenerator::generateCode() { // FIXME - use this one when done with inserting MSL
+ return false;
+}
+
+// FIXME - temporarily using this while inserting MSL
+bool MetalCodeGenerator::generateCode(int shaderNum) {
OutputStream* rawOut = fOut;
fOut = &fHeader;
fOut->write((const char*) &MVKMagicNum, sizeof(MVKMagicNum)); // FIXME - for MVK integration
@@ -1221,9 +1449,8 @@ bool MetalCodeGenerator::generateCode() {
this->writeHeader();
this->writeUniformStruct();
this->writeInputStruct();
- if (Program::kVertex_Kind == fProgram.fKind) {
- this->writeOutputStruct();
- }
+ this->writeOutputStruct();
+ this->writeInterfaceBlocks();
this->writeGlobalStruct();
StringStream body;
fOut = &body;
@@ -1236,6 +1463,34 @@ bool MetalCodeGenerator::generateCode() {
write_stringstream(body, *rawOut);
this->write("\0"); // FIXME - for MVK integration
return true;
+
+ // FIXME - remove when done inserting MSL
+ // OutputStream* rawOut = fOut;
+ // fOut = &fHeader;
+ // // fOut->write((const char*) &MVKMagicNum, sizeof(MVKMagicNum)); // FIXME - for MVK integration
+ // // fProgramKind = fProgram.fKind;
+ // // this->writeHeader();
+ // // this->writeUniformStruct();
+ // // this->writeInputStruct();
+ // // this->writeOutputStruct();
+ // // this->writeGlobalStruct();
+ // (void) MVKMagicNum;
+ // StringStream body;
+ // fOut = &body;
+ // // for (const auto& e : fProgram) {
+ // // this->writeProgramElement(e);
+ // // }
+ // std::ifstream mvkin("/Users/timliang/MVKShaders/mvk" + std::to_string(shaderNum) + ".metal");
+ // std::ostringstream contents;
+ // contents << mvkin.rdbuf();
+ // mvkin.close();
+ // this->write(contents.str().c_str());
+ // fOut = rawOut;
+
+ // write_stringstream(fHeader, *rawOut);
+ // write_stringstream(body, *rawOut);
+ // this->write("\0"); // FIXME - for MVK integration
+ // return true;
}
}
diff --git a/src/sksl/SkSLMetalCodeGenerator.h b/src/sksl/SkSLMetalCodeGenerator.h
index 517f9f655b..3f0bc2862b 100644
--- a/src/sksl/SkSLMetalCodeGenerator.h
+++ b/src/sksl/SkSLMetalCodeGenerator.h
@@ -53,6 +53,7 @@ namespace SkSL {
class MetalCodeGenerator : public CodeGenerator {
public:
static constexpr const char* SAMPLER_SUFFIX = "Smplr";
+ static constexpr const char* PACKED_PREFIX = "packed_";
enum Precedence {
kParentheses_Precedence = 1,
@@ -83,6 +84,7 @@ public:
this->setupIntrinsics();
}
+ bool generateCode(int shaderNum); // FIXME - remove when done inserting MSL
bool generateCode() override;
protected:
@@ -129,6 +131,12 @@ protected:
void writeOutputStruct();
+ void writeInterfaceBlocks();
+
+ int size(const Type* type, bool isPacked) const;
+
+ int alignment(const Type* type, bool isPacked) const;
+
void writeGlobalStruct();
void writePrecisionModifier();
@@ -221,13 +229,14 @@ protected:
Requirements requirements(const Statement& e);
- typedef std::tuple<IntrinsicKind, int32_t, int32_t, int32_t, int32_t> Intrinsic;
+ typedef std::pair<IntrinsicKind, int32_t> Intrinsic;
std::unordered_map<String, Intrinsic> fIntrinsicMap;
std::vector<const VarDeclaration*> fInitNonConstGlobalVars;
std::vector<const Variable*> fTextures;
std::unordered_map<const Type::Field*, const InterfaceBlock*> fInterfaceBlockMap;
std::unordered_map<const InterfaceBlock*, String> fInterfaceBlockNameMap;
int fAnonInterfaceCount = 0;
+ int fPaddingCount = 0;
bool fNeedsGlobalStructInit = false;
const char* fLineEnding;
const Context& fContext;