aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Timothy Liang <timliang@google.com>2018-06-13 09:20:31 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-13 14:23:46 +0000
commitdc89f192c853df57c71c42407c193571c2e1008a (patch)
tree50c72d82bb1369b659a5fffe61bee8230236dbe7 /src
parent5f4b09d523a761a3a5c622bb01eeba47905da5f0 (diff)
consolidated writing fields logic and added more builtins for skslc msl backend
Bug: skia: Change-Id: I6cad948bc68194322f031926ab9a49186ec2302b Reviewed-on: https://skia-review.googlesource.com/134502 Reviewed-by: Ethan Nicholas <ethannicholas@google.com> Commit-Queue: Timothy Liang <timliang@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/sksl/SkSLMetalCodeGenerator.cpp85
-rw-r--r--src/sksl/SkSLMetalCodeGenerator.h5
2 files changed, 55 insertions, 35 deletions
diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp
index af2366e992..5a7ccb7c7f 100644
--- a/src/sksl/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/SkSLMetalCodeGenerator.cpp
@@ -80,14 +80,7 @@ void MetalCodeGenerator::writeType(const Type& type) {
fWrittenStructs.push_back(&type);
this->writeLine("struct " + type.name() + " {");
fIndentation++;
- for (const auto& f : type.fields()) {
- this->writeModifiers(f.fModifiers, false);
- // sizes (which must be static in structs) are part of the type name here
- this->writeType(*f.fType);
- this->write(" ");
- this->writeName(f.fName);
- this->writeLine(";");
- }
+ this->writeFields(type.fields(), type.fOffset);
fIndentation--;
this->write("}");
break;
@@ -317,6 +310,12 @@ void MetalCodeGenerator::writeVariableReference(const VariableReference& ref) {
case SK_FRAGCOORD_BUILTIN:
this->writeFragCoord();
break;
+ case SK_VERTEXID_BUILTIN:
+ this->write("sk_VertexID");
+ break;
+ case SK_INSTANCEID_BUILTIN:
+ this->write("sk_InstanceID");
+ break;
default:
if (Variable::kGlobal_Storage == ref.fVariable.fStorage) {
if (ref.fVariable.fModifiers.fFlags & Modifiers::kIn_Flag) {
@@ -574,6 +573,8 @@ void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) {
}
if (fProgram.fKind == Program::kFragment_Kind) {
this->write(", float4 _fragCoord [[position]]");
+ } else if (fProgram.fKind == Program::kVertex_Kind) {
+ this->write(", uint sk_VertexID [[vertex_id]], uint sk_InstanceID [[instance_id]]");
}
separator = ", ";
} else {
@@ -707,22 +708,50 @@ void MetalCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
if ("sk_PerVertex" == intf.fTypeName) {
return;
}
- MemoryLayout memoryLayout(MemoryLayout::k140_Standard);
- this->write("struct ");
this->writeModifiers(intf.fVariable.fModifiers, true);
+ this->write("struct ");
this->writeLine(intf.fTypeName + " {");
- fIndentation++;
const Type* structType = &intf.fVariable.fType;
fWrittenStructs.push_back(structType);
while (Type::kArray_Kind == structType->kind()) {
structType = &structType->componentType();
}
+ fIndentation++;
+ writeFields(structType->fields(), structType->fOffset, &intf);
+ if (fProgram.fKind == Program::kFragment_Kind) {
+ this->writeLine("float u_skRTHeight;");
+ }
+ fIndentation--;
+ this->write("}");
+ if (intf.fInstanceName.size()) {
+ this->write(" ");
+ this->write(intf.fInstanceName);
+ for (const auto& size : intf.fSizes) {
+ this->write("[");
+ if (size) {
+ this->writeExpression(*size, kTopLevel_Precedence);
+ }
+ this->write("]");
+ }
+ fInterfaceBlockNameMap[&intf] = intf.fInstanceName;
+ } else {
+ fInterfaceBlockNameMap[&intf] = "_anonInterface" + to_string(fAnonInterfaceCount++);
+ }
+ this->writeLine(";");
+}
+
+void MetalCodeGenerator::writeFields(const std::vector<Type::Field>& fields, int parentOffset,
+ const InterfaceBlock* parentIntf) {
+ MemoryLayout memoryLayout(MemoryLayout::k140_Standard);
int currentOffset = 0;
- for (const auto& field: structType->fields()) {
+ for (const auto& field: fields) {
int fieldOffset = field.fModifiers.fLayout.fOffset;
+ const Type* fieldType = field.fType;
if (fieldOffset != -1) {
if (currentOffset > fieldOffset) {
- ABORT("Original interface offsets are too close for MoltenVK");
+ fErrors.error(parentOffset,
+ "offset of field '" + field.fName + "' must be at least " +
+ to_string((int) currentOffset));
} else if (currentOffset < fieldOffset) {
this->write("char pad");
this->write(to_string(fPaddingCount++));
@@ -731,8 +760,13 @@ void MetalCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
this->writeLine("];");
currentOffset = fieldOffset;
}
+ int alignment = memoryLayout.alignment(*fieldType);
+ if (fieldOffset % alignment) {
+ fErrors.error(parentOffset,
+ "offset of field '" + field.fName + "' must be a multiple of " +
+ to_string((int) alignment));
+ }
}
- const Type* fieldType = field.fType;
if (fieldType->kind() == Type::kVector_Kind &&
fieldType->columns() == 3) {
// Pack all vec3 types so that their size in bytes will match what was expected in the
@@ -746,6 +780,7 @@ void MetalCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
sizes.push_back(fieldType->columns());
fieldType = &fieldType->componentType();
}
+ this->writeModifiers(field.fModifiers, false);
this->writeType(*fieldType);
this->write(" ");
this->writeName(field.fName);
@@ -757,28 +792,10 @@ void MetalCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
}
}
this->writeLine(";");
- fInterfaceBlockMap[&field] = &intf;
- }
- if (fProgram.fKind == Program::kFragment_Kind) {
- this->writeLine("float u_skRTHeight;");
- }
- fIndentation--;
- this->write("}");
- if (intf.fInstanceName.size()) {
- this->write(" ");
- this->write(intf.fInstanceName);
- for (const auto& size : intf.fSizes) {
- this->write("[");
- if (size) {
- this->writeExpression(*size, kTopLevel_Precedence);
- }
- this->write("]");
+ if (parentIntf) {
+ fInterfaceBlockMap[&field] = parentIntf;
}
- fInterfaceBlockNameMap[&intf] = intf.fInstanceName;
- } else {
- fInterfaceBlockNameMap[&intf] = "_anonInterface" + to_string(fAnonInterfaceCount++);
}
- this->writeLine(";");
}
void MetalCodeGenerator::writeVarInitializer(const Variable& var, const Expression& value) {
diff --git a/src/sksl/SkSLMetalCodeGenerator.h b/src/sksl/SkSLMetalCodeGenerator.h
index d5a8ca12fa..49a5bd6ed7 100644
--- a/src/sksl/SkSLMetalCodeGenerator.h
+++ b/src/sksl/SkSLMetalCodeGenerator.h
@@ -80,7 +80,7 @@ public:
MetalCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors,
OutputStream* out)
: INHERITED(program, errors, out)
- , fReservedWords({"atan2", "rsqrt", "dfdx", "dfdy"})
+ , fReservedWords({"atan2", "rsqrt", "dfdx", "dfdy", "vertex", "fragment"})
, fLineEnding("\n")
, fContext(*context) {
this->setupIntrinsics();
@@ -136,6 +136,9 @@ protected:
void writeInterfaceBlocks();
+ void writeFields(const std::vector<Type::Field>& fields, int parentOffset,
+ const InterfaceBlock* parentIntf = nullptr);
+
int size(const Type* type, bool isPacked) const;
int alignment(const Type* type, bool isPacked) const;