diff options
author | Timothy Liang <timliang@google.com> | 2018-06-13 09:20:31 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-06-13 14:23:46 +0000 |
commit | dc89f192c853df57c71c42407c193571c2e1008a (patch) | |
tree | 50c72d82bb1369b659a5fffe61bee8230236dbe7 /src/sksl | |
parent | 5f4b09d523a761a3a5c622bb01eeba47905da5f0 (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/sksl')
-rw-r--r-- | src/sksl/SkSLMetalCodeGenerator.cpp | 85 | ||||
-rw-r--r-- | src/sksl/SkSLMetalCodeGenerator.h | 5 |
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; |