aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/sksl
diff options
context:
space:
mode:
authorGravatar ethannicholas <ethannicholas@google.com>2016-08-03 12:43:36 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-08-03 12:43:36 -0700
commitf789b3893579b773bb4d7be6c2c65311500b53bb (patch)
treeffb4c1c5775ba6379a9e504534171a67fa1803c5 /src/sksl
parente57b8c9a790253df1e2f0663bf63f8d6e04227d1 (diff)
added initial GLSL support to skslc
Diffstat (limited to 'src/sksl')
-rw-r--r--src/sksl/SkSLCodeGenerator.h6
-rw-r--r--src/sksl/SkSLCompiler.cpp29
-rw-r--r--src/sksl/SkSLCompiler.h13
-rw-r--r--src/sksl/SkSLGLSLCodeGenerator.cpp479
-rw-r--r--src/sksl/SkSLGLSLCodeGenerator.h177
-rw-r--r--src/sksl/SkSLIRGenerator.cpp80
-rw-r--r--src/sksl/SkSLParser.cpp33
-rw-r--r--src/sksl/SkSLSPIRVCodeGenerator.cpp82
-rw-r--r--src/sksl/SkSLSPIRVCodeGenerator.h76
-rw-r--r--src/sksl/SkSLToken.h6
-rw-r--r--src/sksl/SkSLUtil.h7
-rw-r--r--src/sksl/ast/SkSLASTLayout.h10
-rw-r--r--src/sksl/ast/SkSLASTModifiers.h24
-rw-r--r--src/sksl/ast/SkSLASTNode.h2
-rw-r--r--src/sksl/ir/SkSLBoolLiteral.h2
-rw-r--r--src/sksl/ir/SkSLFieldAccess.h14
-rw-r--r--src/sksl/ir/SkSLFloatLiteral.h2
-rw-r--r--src/sksl/ir/SkSLFunctionReference.h4
-rw-r--r--src/sksl/ir/SkSLIntLiteral.h2
-rw-r--r--src/sksl/ir/SkSLLayout.h25
-rw-r--r--src/sksl/ir/SkSLModifiers.h28
-rw-r--r--src/sksl/ir/SkSLTypeReference.h4
-rw-r--r--src/sksl/ir/SkSLUnresolvedFunction.h6
-rw-r--r--src/sksl/ir/SkSLVarDeclaration.h10
-rw-r--r--src/sksl/ir/SkSLVariable.h2
-rw-r--r--src/sksl/lex.sksl.c614
-rw-r--r--src/sksl/sksl.flex4
27 files changed, 1286 insertions, 455 deletions
diff --git a/src/sksl/SkSLCodeGenerator.h b/src/sksl/SkSLCodeGenerator.h
index cd50cc88fc..7fa8c1931a 100644
--- a/src/sksl/SkSLCodeGenerator.h
+++ b/src/sksl/SkSLCodeGenerator.h
@@ -20,9 +20,9 @@ namespace SkSL {
*/
class CodeGenerator {
public:
- virtual ~CodeGenerator() {}
-
- virtual void generateCode(Program& program, std::ostream& out) = 0;
+ virtual ~CodeGenerator() {}
+
+ virtual void generateCode(const Program& program, std::ostream& out) = 0;
};
} // namespace
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index 0d65b107ec..f55150c134 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -67,14 +67,17 @@ Compiler::Compiler()
ADD_TYPE(BVec3);
ADD_TYPE(BVec4);
ADD_TYPE(Mat2x2);
+ types->addWithoutOwnership("mat2x2", fContext.fMat2x2_Type.get());
ADD_TYPE(Mat2x3);
ADD_TYPE(Mat2x4);
ADD_TYPE(Mat3x2);
ADD_TYPE(Mat3x3);
+ types->addWithoutOwnership("mat3x3", fContext.fMat3x3_Type.get());
ADD_TYPE(Mat3x4);
ADD_TYPE(Mat4x2);
ADD_TYPE(Mat4x3);
ADD_TYPE(Mat4x4);
+ types->addWithoutOwnership("mat4x4", fContext.fMat4x4_Type.get());
ADD_TYPE(GenType);
ADD_TYPE(GenDType);
ADD_TYPE(GenIType);
@@ -223,8 +226,7 @@ void Compiler::writeErrorCount() {
}
}
-#include <fstream>
-bool Compiler::toSPIRV(Program::Kind kind, std::string text, std::ostream& out) {
+bool Compiler::toSPIRV(Program::Kind kind, const std::string& text, std::ostream& out) {
auto program = this->convertProgram(kind, text);
if (fErrorCount == 0) {
SkSL::SPIRVCodeGenerator cg(&fContext);
@@ -234,13 +236,34 @@ bool Compiler::toSPIRV(Program::Kind kind, std::string text, std::ostream& out)
return fErrorCount == 0;
}
-bool Compiler::toSPIRV(Program::Kind kind, std::string text, std::string* out) {
+bool Compiler::toSPIRV(Program::Kind kind, const std::string& text, std::string* out) {
std::stringstream buffer;
bool result = this->toSPIRV(kind, text, buffer);
if (result) {
*out = buffer.str();
}
+ return result;
+}
+
+bool Compiler::toGLSL(Program::Kind kind, const std::string& text, GLCaps caps,
+ std::ostream& out) {
+ auto program = this->convertProgram(kind, text);
+ if (fErrorCount == 0) {
+ SkSL::GLSLCodeGenerator cg(&fContext, caps);
+ cg.generateCode(*program.get(), out);
+ ASSERT(!out.rdstate());
+ }
return fErrorCount == 0;
}
+bool Compiler::toGLSL(Program::Kind kind, const std::string& text, GLCaps caps,
+ std::string* out) {
+ std::stringstream buffer;
+ bool result = this->toGLSL(kind, text, caps, buffer);
+ if (result) {
+ *out = buffer.str();
+ }
+ return result;
+}
+
} // namespace
diff --git a/src/sksl/SkSLCompiler.h b/src/sksl/SkSLCompiler.h
index e63d5f4ed8..9cd1eac3f9 100644
--- a/src/sksl/SkSLCompiler.h
+++ b/src/sksl/SkSLCompiler.h
@@ -13,6 +13,7 @@
#include "ir/SkSLSymbolTable.h"
#include "SkSLContext.h"
#include "SkSLErrorReporter.h"
+#include "SkSLGLSLCodeGenerator.h"
namespace SkSL {
@@ -32,9 +33,13 @@ public:
std::unique_ptr<Program> convertProgram(Program::Kind kind, std::string text);
- bool toSPIRV(Program::Kind kind, std::string text, std::ostream& out);
-
- bool toSPIRV(Program::Kind kind, std::string text, std::string* out);
+ bool toSPIRV(Program::Kind kind, const std::string& text, std::ostream& out);
+
+ bool toSPIRV(Program::Kind kind, const std::string& text, std::string* out);
+
+ bool toGLSL(Program::Kind kind, const std::string& text, GLCaps caps, std::ostream& out);
+
+ bool toGLSL(Program::Kind kind, const std::string& text, GLCaps caps, std::string* out);
void error(Position position, std::string msg) override;
@@ -45,7 +50,7 @@ public:
private:
void internalConvertProgram(std::string text,
- std::vector<std::unique_ptr<ProgramElement>>* result);
+ std::vector<std::unique_ptr<ProgramElement>>* result);
std::shared_ptr<SymbolTable> fTypes;
IRGenerator* fIRGenerator;
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
new file mode 100644
index 0000000000..8e69a2f052
--- /dev/null
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -0,0 +1,479 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkSLGLSLCodeGenerator.h"
+
+#include "string.h"
+
+#include "GLSL.std.450.h"
+
+#include "ir/SkSLExpressionStatement.h"
+#include "ir/SkSLExtension.h"
+#include "ir/SkSLIndexExpression.h"
+#include "ir/SkSLVariableReference.h"
+
+namespace SkSL {
+
+void GLSLCodeGenerator::write(const char* s) {
+ if (s[0] == 0) {
+ return;
+ }
+ if (fAtLineStart) {
+ for (int i = 0; i < fIndentation; i++) {
+ *fOut << " ";
+ }
+ }
+ *fOut << s;
+ fAtLineStart = false;
+}
+
+void GLSLCodeGenerator::writeLine(const char* s) {
+ this->write(s);
+ *fOut << "\n";
+ fAtLineStart = true;
+}
+
+void GLSLCodeGenerator::write(const std::string& s) {
+ this->write(s.c_str());
+}
+
+void GLSLCodeGenerator::writeLine(const std::string& s) {
+ this->writeLine(s.c_str());
+}
+
+void GLSLCodeGenerator::writeLine() {
+ this->writeLine("");
+}
+
+void GLSLCodeGenerator::writeExtension(const Extension& ext) {
+ this->writeLine("#extension " + ext.fName + " : enable");
+}
+
+void GLSLCodeGenerator::writeType(const Type& type) {
+ if (type.kind() == Type::kStruct_Kind) {
+ for (const Type* search : fWrittenStructs) {
+ if (*search == type) {
+ // already written
+ this->write(type.name());
+ return;
+ }
+ }
+ fWrittenStructs.push_back(&type);
+ this->writeLine("struct " + type.name() + " {");
+ fIndentation++;
+ for (const auto& f : type.fields()) {
+ this->writeModifiers(f.fModifiers);
+ // sizes (which must be static in structs) are part of the type name here
+ this->writeType(f.fType);
+ this->writeLine(" " + f.fName + ";");
+ }
+ fIndentation--;
+ this->writeLine("}");
+ } else {
+ this->write(type.name());
+ }
+}
+
+void GLSLCodeGenerator::writeExpression(const Expression& expr, Precedence parentPrecedence) {
+ switch (expr.fKind) {
+ case Expression::kBinary_Kind:
+ this->writeBinaryExpression((BinaryExpression&) expr, parentPrecedence);
+ break;
+ case Expression::kBoolLiteral_Kind:
+ this->writeBoolLiteral((BoolLiteral&) expr);
+ break;
+ case Expression::kConstructor_Kind:
+ this->writeConstructor((Constructor&) expr);
+ break;
+ case Expression::kIntLiteral_Kind:
+ this->writeIntLiteral((IntLiteral&) expr);
+ break;
+ case Expression::kFieldAccess_Kind:
+ this->writeFieldAccess(((FieldAccess&) expr));
+ break;
+ case Expression::kFloatLiteral_Kind:
+ this->writeFloatLiteral(((FloatLiteral&) expr));
+ break;
+ case Expression::kFunctionCall_Kind:
+ this->writeFunctionCall((FunctionCall&) expr);
+ break;
+ case Expression::kPrefix_Kind:
+ this->writePrefixExpression((PrefixExpression&) expr, parentPrecedence);
+ break;
+ case Expression::kPostfix_Kind:
+ this->writePostfixExpression((PostfixExpression&) expr, parentPrecedence);
+ break;
+ case Expression::kSwizzle_Kind:
+ this->writeSwizzle((Swizzle&) expr);
+ break;
+ case Expression::kVariableReference_Kind:
+ this->writeVariableReference((VariableReference&) expr);
+ break;
+ case Expression::kTernary_Kind:
+ this->writeTernaryExpression((TernaryExpression&) expr, parentPrecedence);
+ break;
+ case Expression::kIndex_Kind:
+ this->writeIndexExpression((IndexExpression&) expr);
+ break;
+ default:
+ ABORT("unsupported expression: %s", expr.description().c_str());
+ }
+}
+
+void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) {
+ this->write(c.fFunction.fName + "(");
+ const char* separator = "";
+ for (const auto& arg : c.fArguments) {
+ this->write(separator);
+ separator = ", ";
+ this->writeExpression(*arg, kSequence_Precedence);
+ }
+ this->write(")");
+}
+
+void GLSLCodeGenerator::writeConstructor(const Constructor& c) {
+ this->write(c.fType.name() + "(");
+ const char* separator = "";
+ for (const auto& arg : c.fArguments) {
+ this->write(separator);
+ separator = ", ";
+ this->writeExpression(*arg, kSequence_Precedence);
+ }
+ this->write(")");
+}
+
+void GLSLCodeGenerator::writeVariableReference(const VariableReference& ref) {
+ this->write(ref.fVariable.fName);
+}
+
+void GLSLCodeGenerator::writeIndexExpression(const IndexExpression& expr) {
+ this->writeExpression(*expr.fBase, kPostfix_Precedence);
+ this->write("[");
+ this->writeExpression(*expr.fIndex, kTopLevel_Precedence);
+ this->write("]");
+}
+
+void GLSLCodeGenerator::writeFieldAccess(const FieldAccess& f) {
+ if (f.fOwnerKind == FieldAccess::kDefault_OwnerKind) {
+ this->writeExpression(*f.fBase, kPostfix_Precedence);
+ this->write(".");
+ }
+ this->write(f.fBase->fType.fields()[f.fFieldIndex].fName);
+}
+
+void GLSLCodeGenerator::writeSwizzle(const Swizzle& swizzle) {
+ this->writeExpression(*swizzle.fBase, kPostfix_Precedence);
+ this->write(".");
+ for (int c : swizzle.fComponents) {
+ this->write(&("x\0y\0z\0w\0"[c * 2]));
+ }
+}
+
+static GLSLCodeGenerator::Precedence get_binary_precedence(Token::Kind op) {
+ switch (op) {
+ case Token::STAR: // fall through
+ case Token::SLASH: // fall through
+ case Token::PERCENT: return GLSLCodeGenerator::kMultiplicative_Precedence;
+ case Token::PLUS: // fall through
+ case Token::MINUS: return GLSLCodeGenerator::kAdditive_Precedence;
+ case Token::SHL: // fall through
+ case Token::SHR: return GLSLCodeGenerator::kShift_Precedence;
+ case Token::LT: // fall through
+ case Token::GT: // fall through
+ case Token::LTEQ: // fall through
+ case Token::GTEQ: return GLSLCodeGenerator::kRelational_Precedence;
+ case Token::EQEQ: // fall through
+ case Token::NEQ: return GLSLCodeGenerator::kEquality_Precedence;
+ case Token::BITWISEAND: return GLSLCodeGenerator::kBitwiseAnd_Precedence;
+ case Token::BITWISEXOR: return GLSLCodeGenerator::kBitwiseXor_Precedence;
+ case Token::BITWISEOR: return GLSLCodeGenerator::kBitwiseOr_Precedence;
+ case Token::LOGICALAND: return GLSLCodeGenerator::kLogicalAnd_Precedence;
+ case Token::LOGICALXOR: return GLSLCodeGenerator::kLogicalXor_Precedence;
+ case Token::LOGICALOR: return GLSLCodeGenerator::kLogicalOr_Precedence;
+ case Token::EQ: // fall through
+ case Token::PLUSEQ: // fall through
+ case Token::MINUSEQ: // fall through
+ case Token::STAREQ: // fall through
+ case Token::SLASHEQ: // fall through
+ case Token::PERCENTEQ: // fall through
+ case Token::SHLEQ: // fall through
+ case Token::SHREQ: // fall through
+ case Token::LOGICALANDEQ: // fall through
+ case Token::LOGICALXOREQ: // fall through
+ case Token::LOGICALOREQ: // fall through
+ case Token::BITWISEANDEQ: // fall through
+ case Token::BITWISEXOREQ: // fall through
+ case Token::BITWISEOREQ: return GLSLCodeGenerator::kAssignment_Precedence;
+ default: ABORT("unsupported binary operator");
+ }
+}
+
+void GLSLCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
+ Precedence parentPrecedence) {
+ Precedence precedence = get_binary_precedence(b.fOperator);
+ if (precedence >= parentPrecedence) {
+ this->write("(");
+ }
+ this->writeExpression(*b.fLeft, precedence);
+ this->write(" " + Token::OperatorName(b.fOperator) + " ");
+ this->writeExpression(*b.fRight, precedence);
+ if (precedence >= parentPrecedence) {
+ this->write(")");
+ }
+}
+
+void GLSLCodeGenerator::writeTernaryExpression(const TernaryExpression& t,
+ Precedence parentPrecedence) {
+ if (kTernary_Precedence >= parentPrecedence) {
+ this->write("(");
+ }
+ this->writeExpression(*t.fTest, kTernary_Precedence);
+ this->write(" ? ");
+ this->writeExpression(*t.fIfTrue, kTernary_Precedence);
+ this->write(" : ");
+ this->writeExpression(*t.fIfFalse, kTernary_Precedence);
+ if (kTernary_Precedence >= parentPrecedence) {
+ this->write(")");
+ }
+}
+
+void GLSLCodeGenerator::writePrefixExpression(const PrefixExpression& p,
+ Precedence parentPrecedence) {
+ if (kPrefix_Precedence >= parentPrecedence) {
+ this->write("(");
+ }
+ this->write(Token::OperatorName(p.fOperator));
+ this->writeExpression(*p.fOperand, kPrefix_Precedence);
+ if (kPrefix_Precedence >= parentPrecedence) {
+ this->write(")");
+ }
+}
+
+void GLSLCodeGenerator::writePostfixExpression(const PostfixExpression& p,
+ Precedence parentPrecedence) {
+ if (kPostfix_Precedence >= parentPrecedence) {
+ this->write("(");
+ }
+ this->writeExpression(*p.fOperand, kPostfix_Precedence);
+ this->write(Token::OperatorName(p.fOperator));
+ if (kPostfix_Precedence >= parentPrecedence) {
+ this->write(")");
+ }
+}
+
+void GLSLCodeGenerator::writeBoolLiteral(const BoolLiteral& b) {
+ this->write(b.fValue ? "true" : "false");
+}
+
+void GLSLCodeGenerator::writeIntLiteral(const IntLiteral& i) {
+ this->write(to_string(i.fValue));
+}
+
+void GLSLCodeGenerator::writeFloatLiteral(const FloatLiteral& f) {
+ this->write(to_string(f.fValue));
+}
+
+void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) {
+ this->writeType(f.fDeclaration.fReturnType);
+ this->write(" " + f.fDeclaration.fName + "(");
+ const char* separator = "";
+ for (const auto& param : f.fDeclaration.fParameters) {
+ this->write(separator);
+ separator = ", ";
+ this->writeModifiers(param->fModifiers);
+ this->writeType(param->fType);
+ this->write(" " + param->fName);
+ }
+ this->write(") ");
+ this->writeBlock(*f.fBody);
+ this->writeLine();
+}
+
+void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers) {
+ this->write(modifiers.description());
+}
+
+void GLSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
+ if (intf.fVariable.fName == "gl_PerVertex") {
+ return;
+ }
+ this->writeModifiers(intf.fVariable.fModifiers);
+ this->writeLine(intf.fVariable.fType.name() + " {");
+ fIndentation++;
+ for (const auto& f : intf.fVariable.fType.fields()) {
+ this->writeModifiers(f.fModifiers);
+ this->writeType(f.fType);
+ this->writeLine(" " + f.fName + ";");
+ }
+ fIndentation--;
+ this->writeLine("};");
+}
+
+void GLSLCodeGenerator::writeVarDeclaration(const VarDeclaration& decl) {
+ ASSERT(decl.fVars.size() > 0);
+ this->writeModifiers(decl.fVars[0]->fModifiers);
+ this->writeType(decl.fBaseType);
+ std::string separator = " ";
+ for (size_t i = 0; i < decl.fVars.size(); i++) {
+ ASSERT(decl.fVars[i]->fModifiers == decl.fVars[0]->fModifiers);
+ this->write(separator);
+ separator = ", ";
+ this->write(decl.fVars[i]->fName);
+ for (const auto& size : decl.fSizes[i]) {
+ this->write("[");
+ this->writeExpression(*size, kTopLevel_Precedence);
+ this->write("]");
+ }
+ if (decl.fValues[i]) {
+ this->write(" = ");
+ this->writeExpression(*decl.fValues[i], kTopLevel_Precedence);
+ }
+ }
+ this->write(";");
+}
+
+void GLSLCodeGenerator::writeStatement(const Statement& s) {
+ switch (s.fKind) {
+ case Statement::kBlock_Kind:
+ this->writeBlock((Block&) s);
+ break;
+ case Statement::kExpression_Kind:
+ this->writeExpression(*((ExpressionStatement&) s).fExpression, kTopLevel_Precedence);
+ this->write(";");
+ break;
+ case Statement::kReturn_Kind:
+ this->writeReturnStatement((ReturnStatement&) s);
+ break;
+ case Statement::kVarDeclaration_Kind:
+ this->writeVarDeclaration(*((VarDeclarationStatement&) s).fDeclaration);
+ break;
+ case Statement::kIf_Kind:
+ this->writeIfStatement((IfStatement&) s);
+ break;
+ case Statement::kFor_Kind:
+ this->writeForStatement((ForStatement&) s);
+ break;
+ case Statement::kWhile_Kind:
+ this->writeWhileStatement((WhileStatement&) s);
+ break;
+ case Statement::kDo_Kind:
+ this->writeDoStatement((DoStatement&) s);
+ break;
+ case Statement::kBreak_Kind:
+ this->write("break;");
+ break;
+ case Statement::kContinue_Kind:
+ this->write("continue;");
+ break;
+ case Statement::kDiscard_Kind:
+ this->write("discard;");
+ break;
+ default:
+ ABORT("unsupported statement: %s", s.description().c_str());
+ }
+}
+
+void GLSLCodeGenerator::writeBlock(const Block& b) {
+ this->writeLine("{");
+ fIndentation++;
+ for (const auto& s : b.fStatements) {
+ this->writeStatement(*s);
+ this->writeLine();
+ }
+ fIndentation--;
+ this->write("}");
+}
+
+void GLSLCodeGenerator::writeIfStatement(const IfStatement& stmt) {
+ this->write("if (");
+ this->writeExpression(*stmt.fTest, kTopLevel_Precedence);
+ this->write(") ");
+ this->writeStatement(*stmt.fIfTrue);
+ if (stmt.fIfFalse) {
+ this->write(" else ");
+ this->writeStatement(*stmt.fIfFalse);
+ }
+}
+
+void GLSLCodeGenerator::writeForStatement(const ForStatement& f) {
+ this->write("for (");
+ if (f.fInitializer) {
+ this->writeStatement(*f.fInitializer);
+ } else {
+ this->write("; ");
+ }
+ if (f.fTest) {
+ this->writeExpression(*f.fTest, kTopLevel_Precedence);
+ }
+ this->write("; ");
+ if (f.fNext) {
+ this->writeExpression(*f.fNext, kTopLevel_Precedence);
+ }
+ this->write(") ");
+ this->writeStatement(*f.fStatement);
+}
+
+void GLSLCodeGenerator::writeWhileStatement(const WhileStatement& w) {
+ this->write("while (");
+ this->writeExpression(*w.fTest, kTopLevel_Precedence);
+ this->write(") ");
+ this->writeStatement(*w.fStatement);
+}
+
+void GLSLCodeGenerator::writeDoStatement(const DoStatement& d) {
+ this->write("do ");
+ this->writeStatement(*d.fStatement);
+ this->write(" while (");
+ this->writeExpression(*d.fTest, kTopLevel_Precedence);
+ this->write(");");
+}
+
+void GLSLCodeGenerator::writeReturnStatement(const ReturnStatement& r) {
+ this->write("return");
+ if (r.fExpression) {
+ this->write(" ");
+ this->writeExpression(*r.fExpression, kTopLevel_Precedence);
+ }
+ this->write(";");
+}
+
+void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out) {
+ ASSERT(fOut == nullptr);
+ fOut = &out;
+ this->write("#version " + to_string(fCaps.fVersion));
+ if (fCaps.fStandard == GLCaps::kGLES_Standard) {
+ this->write(" es");
+ }
+ this->writeLine();
+ for (const auto& e : program.fElements) {
+ switch (e->fKind) {
+ case ProgramElement::kExtension_Kind:
+ this->writeExtension((Extension&) *e);
+ break;
+ case ProgramElement::kVar_Kind: {
+ VarDeclaration& decl = (VarDeclaration&) *e;
+ if (decl.fVars.size() > 0 && decl.fVars[0]->fModifiers.fLayout.fBuiltin == -1) {
+ this->writeVarDeclaration(decl);
+ this->writeLine();
+ }
+ break;
+ }
+ case ProgramElement::kInterfaceBlock_Kind:
+ this->writeInterfaceBlock((InterfaceBlock&) *e);
+ break;
+ case ProgramElement::kFunction_Kind:
+ this->writeFunction((FunctionDefinition&) *e);
+ break;
+ default:
+ printf("%s\n", e->description().c_str());
+ ABORT("unsupported program element");
+ }
+ }
+ fOut = nullptr;
+}
+
+}
diff --git a/src/sksl/SkSLGLSLCodeGenerator.h b/src/sksl/SkSLGLSLCodeGenerator.h
new file mode 100644
index 0000000000..76512e06a6
--- /dev/null
+++ b/src/sksl/SkSLGLSLCodeGenerator.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SKSL_GLSLCODEGENERATOR
+#define SKSL_GLSLCODEGENERATOR
+
+#include <stack>
+#include <tuple>
+#include <unordered_map>
+
+#include "SkSLCodeGenerator.h"
+#include "ir/SkSLBinaryExpression.h"
+#include "ir/SkSLBoolLiteral.h"
+#include "ir/SkSLConstructor.h"
+#include "ir/SkSLDoStatement.h"
+#include "ir/SkSLExtension.h"
+#include "ir/SkSLFloatLiteral.h"
+#include "ir/SkSLIfStatement.h"
+#include "ir/SkSLIndexExpression.h"
+#include "ir/SkSLInterfaceBlock.h"
+#include "ir/SkSLIntLiteral.h"
+#include "ir/SkSLFieldAccess.h"
+#include "ir/SkSLForStatement.h"
+#include "ir/SkSLFunctionCall.h"
+#include "ir/SkSLFunctionDeclaration.h"
+#include "ir/SkSLFunctionDefinition.h"
+#include "ir/SkSLPrefixExpression.h"
+#include "ir/SkSLPostfixExpression.h"
+#include "ir/SkSLProgramElement.h"
+#include "ir/SkSLReturnStatement.h"
+#include "ir/SkSLStatement.h"
+#include "ir/SkSLSwizzle.h"
+#include "ir/SkSLTernaryExpression.h"
+#include "ir/SkSLVarDeclaration.h"
+#include "ir/SkSLVarDeclarationStatement.h"
+#include "ir/SkSLVariableReference.h"
+#include "ir/SkSLWhileStatement.h"
+
+namespace SkSL {
+
+#define kLast_Capability SpvCapabilityMultiViewport
+
+struct GLCaps {
+ int fVersion;
+ enum {
+ kGL_Standard,
+ kGLES_Standard
+ } fStandard;
+};
+
+/**
+ * Converts a Program into GLSL code.
+ */
+class GLSLCodeGenerator : public CodeGenerator {
+public:
+ enum Precedence {
+ kParentheses_Precedence = 1,
+ kPostfix_Precedence = 2,
+ kPrefix_Precedence = 3,
+ kMultiplicative_Precedence = 4,
+ kAdditive_Precedence = 5,
+ kShift_Precedence = 6,
+ kRelational_Precedence = 7,
+ kEquality_Precedence = 8,
+ kBitwiseAnd_Precedence = 9,
+ kBitwiseXor_Precedence = 10,
+ kBitwiseOr_Precedence = 11,
+ kLogicalAnd_Precedence = 12,
+ kLogicalXor_Precedence = 13,
+ kLogicalOr_Precedence = 14,
+ kTernary_Precedence = 15,
+ kAssignment_Precedence = 16,
+ kSequence_Precedence = 17,
+ kTopLevel_Precedence = 18
+ };
+
+ GLSLCodeGenerator(const Context* context, GLCaps caps)
+ : fContext(*context)
+ , fCaps(caps)
+ , fIndentation(0)
+ , fAtLineStart(true) {}
+
+ void generateCode(const Program& program, std::ostream& out) override;
+
+private:
+ void write(const char* s);
+
+ void writeLine();
+
+ void writeLine(const char* s);
+
+ void write(const std::string& s);
+
+ void writeLine(const std::string& s);
+
+ void writeType(const Type& type);
+
+ void writeExtension(const Extension& ext);
+
+ void writeInterfaceBlock(const InterfaceBlock& intf);
+
+ void writeFunctionStart(const FunctionDeclaration& f);
+
+ void writeFunctionDeclaration(const FunctionDeclaration& f);
+
+ void writeFunction(const FunctionDefinition& f);
+
+ void writeLayout(const Layout& layout);
+
+ void writeModifiers(const Modifiers& modifiers);
+
+ void writeGlobalVars(const VarDeclaration& vs);
+
+ void writeVarDeclaration(const VarDeclaration& decl);
+
+ void writeVariableReference(const VariableReference& ref);
+
+ void writeExpression(const Expression& expr, Precedence parentPrecedence);
+
+ void writeIntrinsicCall(const FunctionCall& c);
+
+ void writeFunctionCall(const FunctionCall& c);
+
+ void writeConstructor(const Constructor& c);
+
+ void writeFieldAccess(const FieldAccess& f);
+
+ void writeSwizzle(const Swizzle& swizzle);
+
+ void writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence);
+
+ void writeTernaryExpression(const TernaryExpression& t, Precedence parentPrecedence);
+
+ void writeIndexExpression(const IndexExpression& expr);
+
+ void writePrefixExpression(const PrefixExpression& p, Precedence parentPrecedence);
+
+ void writePostfixExpression(const PostfixExpression& p, Precedence parentPrecedence);
+
+ void writeBoolLiteral(const BoolLiteral& b);
+
+ void writeIntLiteral(const IntLiteral& i);
+
+ void writeFloatLiteral(const FloatLiteral& f);
+
+ void writeStatement(const Statement& s);
+
+ void writeBlock(const Block& b);
+
+ void writeIfStatement(const IfStatement& stmt);
+
+ void writeForStatement(const ForStatement& f);
+
+ void writeWhileStatement(const WhileStatement& w);
+
+ void writeDoStatement(const DoStatement& d);
+
+ void writeReturnStatement(const ReturnStatement& r);
+
+ const Context& fContext;
+ const GLCaps fCaps;
+ std::ostream* fOut;
+ int fIndentation;
+ bool fAtLineStart;
+ // Keeps track of which struct types we have written. Given that we are unlikely to ever write
+ // more than one or two structs per shader, a simple linear search will be faster than anything
+ // fancier.
+ std::vector<const Type*> fWrittenStructs;
+};
+
+}
+
+#endif
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index f250c4bb0c..db033d63b9 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -182,7 +182,6 @@ std::unique_ptr<VarDeclaration> IRGenerator::convertVarDeclaration(const ASTVarD
currentVarSizes.push_back(nullptr);
}
}
- sizes.push_back(std::move(currentVarSizes));
auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifiers, decl.fNames[i],
*type, storage));
std::unique_ptr<Expression> value;
@@ -193,12 +192,22 @@ std::unique_ptr<VarDeclaration> IRGenerator::convertVarDeclaration(const ASTVarD
}
value = this->coerce(std::move(value), *type);
}
- variables.push_back(var.get());
- fSymbolTable->add(decl.fNames[i], std::move(var));
- values.push_back(std::move(value));
+ if ("gl_FragCoord" == decl.fNames[i] && (*fSymbolTable)[decl.fNames[i]]) {
+ // already defined, just update the modifiers
+ Variable* old = (Variable*) (*fSymbolTable)[decl.fNames[i]];
+ old->fModifiers = var->fModifiers;
+ } else {
+ variables.push_back(var.get());
+ fSymbolTable->add(decl.fNames[i], std::move(var));
+ values.push_back(std::move(value));
+ sizes.push_back(std::move(currentVarSizes));
+ }
}
- return std::unique_ptr<VarDeclaration>(new VarDeclaration(decl.fPosition, std::move(variables),
- std::move(sizes), std::move(values)));
+ return std::unique_ptr<VarDeclaration>(new VarDeclaration(decl.fPosition,
+ baseType,
+ std::move(variables),
+ std::move(sizes),
+ std::move(values)));
}
std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) {
@@ -573,8 +582,10 @@ std::unique_ptr<Expression> IRGenerator::convertIdentifier(const ASTIdentifier&
case Symbol::kField_Kind: {
const Field* field = (const Field*) result;
VariableReference* base = new VariableReference(identifier.fPosition, field->fOwner);
- return std::unique_ptr<Expression>(new FieldAccess(std::unique_ptr<Expression>(base),
- field->fFieldIndex));
+ return std::unique_ptr<Expression>(new FieldAccess(
+ std::unique_ptr<Expression>(base),
+ field->fFieldIndex,
+ FieldAccess::kAnonymousInterfaceBlock_OwnerKind));
}
case Symbol::kType_Kind: {
const Type* t = (const Type*) result;
@@ -616,6 +627,12 @@ std::unique_ptr<Expression> IRGenerator::coerce(std::unique_ptr<Expression> expr
type.description().c_str());
}
+static bool is_matrix_multiply(const Type& left, const Type& right) {
+ if (left.kind() == Type::kMatrix_Kind) {
+ return right.kind() == Type::kMatrix_Kind || right.kind() == Type::kVector_Kind;
+ }
+ return left.kind() == Type::kVector_Kind && right.kind() == Type::kMatrix_Kind;
+}
/**
* Determines the operand and result types of a binary expression. Returns true if the expression is
* legal, false otherwise. If false, the values of the out parameters are undefined.
@@ -651,18 +668,41 @@ static bool determine_binary_type(const Context& context,
right.canCoerceTo(*context.fBool_Type);
case Token::STAR: // fall through
case Token::STAREQ:
- // FIXME need to handle non-square matrices
- if (left.kind() == Type::kMatrix_Kind && right.kind() == Type::kVector_Kind) {
- *outLeftType = &left;
- *outRightType = &right;
- *outResultType = &right;
- return left.rows() == right.columns();
- }
- if (left.kind() == Type::kVector_Kind && right.kind() == Type::kMatrix_Kind) {
- *outLeftType = &left;
- *outRightType = &right;
- *outResultType = &left;
- return left.columns() == right.columns();
+ if (is_matrix_multiply(left, right)) {
+ // determine final component type
+ if (determine_binary_type(context, Token::STAR, left.componentType(),
+ right.componentType(), outLeftType, outRightType,
+ outResultType, false)) {
+ *outLeftType = &(*outResultType)->toCompound(context, left.columns(),
+ left.rows());;
+ *outRightType = &(*outResultType)->toCompound(context, right.columns(),
+ right.rows());;
+ int leftColumns = left.columns();
+ int leftRows = left.rows();
+ int rightColumns;
+ int rightRows;
+ if (right.kind() == Type::kVector_Kind) {
+ // matrix * vector treats the vector as a column vector, so we need to
+ // transpose it
+ rightColumns = right.rows();
+ rightRows = right.columns();
+ ASSERT(rightColumns == 1);
+ } else {
+ rightColumns = right.columns();
+ rightRows = right.rows();
+ }
+ if (rightColumns > 1) {
+ *outResultType = &(*outResultType)->toCompound(context, rightColumns,
+ leftRows);
+ } else {
+ // result was a column vector, transpose it back to a row
+ *outResultType = &(*outResultType)->toCompound(context, leftRows,
+ rightColumns);
+ }
+ return leftColumns == rightRows;
+ } else {
+ return false;
+ }
}
// fall through
default:
diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp
index edff0c67d1..d6acc7d8a8 100644
--- a/src/sksl/SkSLParser.cpp
+++ b/src/sksl/SkSLParser.cpp
@@ -14,11 +14,26 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunneeded-internal-declaration"
#pragma clang diagnostic ignored "-Wnull-conversion"
+#pragma clang diagnostic ignored "-Wsign-compare"
+#endif
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsign-compare"
+#endif
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4018)
#endif
#include "lex.sksl.c"
#ifdef __clang__
#pragma clang diagnostic pop
#endif
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
#undef register
#include "ast/SkSLASTBinaryExpression.h"
@@ -471,10 +486,11 @@ ASTLayout Parser::layout() {
int index = -1;
int set = -1;
int builtin = -1;
+ bool originUpperLeft = false;
if (this->peek().fKind == Token::LAYOUT) {
this->nextToken();
if (!this->expect(Token::LPAREN, "'('")) {
- return ASTLayout(location, binding, index, set, builtin);
+ return ASTLayout(location, binding, index, set, builtin, originUpperLeft);
}
for (;;) {
Token t = this->nextToken();
@@ -488,6 +504,8 @@ ASTLayout Parser::layout() {
set = this->layoutInt();
} else if (t.fText == "builtin") {
builtin = this->layoutInt();
+ } else if (t.fText == "origin_upper_left") {
+ originUpperLeft = true;
} else {
this->error(t.fPosition, ("'" + t.fText +
"' is not a valid layout qualifier").c_str());
@@ -501,11 +519,10 @@ ASTLayout Parser::layout() {
}
}
}
- return ASTLayout(location, binding, index, set, builtin);
+ return ASTLayout(location, binding, index, set, builtin, originUpperLeft);
}
-/* layout? (UNIFORM | CONST | IN | OUT | INOUT | LOWP |
- MEDIUMP | HIGHP)* */
+/* layout? (UNIFORM | CONST | IN | OUT | INOUT | LOWP | MEDIUMP | HIGHP | FLAT | NOPERSPECTIVE)* */
ASTModifiers Parser::modifiers() {
ASTLayout layout = this->layout();
int flags = 0;
@@ -545,6 +562,14 @@ ASTModifiers Parser::modifiers() {
this->nextToken();
flags |= ASTModifiers::kHighp_Flag;
break;
+ case Token::FLAT:
+ this->nextToken();
+ flags |= ASTModifiers::kFlat_Flag;
+ break;
+ case Token::NOPERSPECTIVE:
+ this->nextToken();
+ flags |= ASTModifiers::kNoPerspective_Flag;
+ break;
default:
return ASTModifiers(layout, flags);
}
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp
index 2771e0291b..8a38cf7028 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.cpp
+++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp
@@ -1151,7 +1151,7 @@ SpvId SPIRVCodeGenerator::getPointerType(const Type& type,
return entry->second;
}
-SpvId SPIRVCodeGenerator::writeExpression(Expression& expr, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeExpression(const Expression& expr, std::ostream& out) {
switch (expr.fKind) {
case Expression::kBinary_Kind:
return this->writeBinaryExpression((BinaryExpression&) expr, out);
@@ -1185,7 +1185,7 @@ SpvId SPIRVCodeGenerator::writeExpression(Expression& expr, std::ostream& out) {
return -1;
}
-SpvId SPIRVCodeGenerator::writeIntrinsicCall(FunctionCall& c, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeIntrinsicCall(const FunctionCall& c, std::ostream& out) {
auto intrinsic = fIntrinsicMap.find(c.fFunction.fName);
ASSERT(intrinsic != fIntrinsicMap.end());
const Type& type = c.fArguments[0]->fType;
@@ -1240,7 +1240,7 @@ SpvId SPIRVCodeGenerator::writeIntrinsicCall(FunctionCall& c, std::ostream& out)
}
}
-SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(FunctionCall& c, SpecialIntrinsic kind,
+SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIntrinsic kind,
std::ostream& out) {
SpvId result = this->nextId();
switch (kind) {
@@ -1305,7 +1305,7 @@ SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(FunctionCall& c, SpecialIntrinsi
return result;
}
-SpvId SPIRVCodeGenerator::writeFunctionCall(FunctionCall& c, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeFunctionCall(const FunctionCall& c, std::ostream& out) {
const auto& entry = fFunctionMap.find(&c.fFunction);
if (entry == fFunctionMap.end()) {
return this->writeIntrinsicCall(c, out);
@@ -1366,7 +1366,7 @@ SpvId SPIRVCodeGenerator::writeFunctionCall(FunctionCall& c, std::ostream& out)
return result;
}
-SpvId SPIRVCodeGenerator::writeConstantVector(Constructor& c) {
+SpvId SPIRVCodeGenerator::writeConstantVector(const Constructor& c) {
ASSERT(c.fType.kind() == Type::kVector_Kind && c.isConstant());
SpvId result = this->nextId();
std::vector<SpvId> arguments;
@@ -1394,7 +1394,7 @@ SpvId SPIRVCodeGenerator::writeConstantVector(Constructor& c) {
return result;
}
-SpvId SPIRVCodeGenerator::writeFloatConstructor(Constructor& c, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeFloatConstructor(const Constructor& c, std::ostream& out) {
ASSERT(c.fType == *fContext.fFloat_Type);
ASSERT(c.fArguments.size() == 1);
ASSERT(c.fArguments[0]->fType.isNumber());
@@ -1412,7 +1412,7 @@ SpvId SPIRVCodeGenerator::writeFloatConstructor(Constructor& c, std::ostream& ou
return result;
}
-SpvId SPIRVCodeGenerator::writeIntConstructor(Constructor& c, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeIntConstructor(const Constructor& c, std::ostream& out) {
ASSERT(c.fType == *fContext.fInt_Type);
ASSERT(c.fArguments.size() == 1);
ASSERT(c.fArguments[0]->fType.isNumber());
@@ -1430,7 +1430,7 @@ SpvId SPIRVCodeGenerator::writeIntConstructor(Constructor& c, std::ostream& out)
return result;
}
-SpvId SPIRVCodeGenerator::writeMatrixConstructor(Constructor& c, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, std::ostream& out) {
ASSERT(c.fType.kind() == Type::kMatrix_Kind);
// go ahead and write the arguments so we don't try to write new instructions in the middle of
// an instruction
@@ -1502,7 +1502,7 @@ SpvId SPIRVCodeGenerator::writeMatrixConstructor(Constructor& c, std::ostream& o
return result;
}
-SpvId SPIRVCodeGenerator::writeVectorConstructor(Constructor& c, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeVectorConstructor(const Constructor& c, std::ostream& out) {
ASSERT(c.fType.kind() == Type::kVector_Kind);
if (c.isConstant()) {
return this->writeConstantVector(c);
@@ -1532,7 +1532,7 @@ SpvId SPIRVCodeGenerator::writeVectorConstructor(Constructor& c, std::ostream& o
return result;
}
-SpvId SPIRVCodeGenerator::writeConstructor(Constructor& c, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeConstructor(const Constructor& c, std::ostream& out) {
if (c.fType == *fContext.fFloat_Type) {
return this->writeFloatConstructor(c, out);
} else if (c.fType == *fContext.fInt_Type) {
@@ -1560,7 +1560,7 @@ SpvStorageClass_ get_storage_class(const Modifiers& modifiers) {
}
}
-SpvStorageClass_ get_storage_class(Expression& expr) {
+SpvStorageClass_ get_storage_class(const Expression& expr) {
switch (expr.fKind) {
case Expression::kVariableReference_Kind:
return get_storage_class(((VariableReference&) expr).fVariable.fModifiers);
@@ -1573,7 +1573,7 @@ SpvStorageClass_ get_storage_class(Expression& expr) {
}
}
-std::vector<SpvId> SPIRVCodeGenerator::getAccessChain(Expression& expr, std::ostream& out) {
+std::vector<SpvId> SPIRVCodeGenerator::getAccessChain(const Expression& expr, std::ostream& out) {
std::vector<SpvId> chain;
switch (expr.fKind) {
case Expression::kIndex_Kind: {
@@ -1697,7 +1697,7 @@ private:
const Type& fSwizzleType;
};
-std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(Expression& expr,
+std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const Expression& expr,
std::ostream& out) {
switch (expr.fKind) {
case Expression::kVariableReference_Kind: {
@@ -1771,7 +1771,7 @@ std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(Expres
}
}
-SpvId SPIRVCodeGenerator::writeVariableReference(VariableReference& ref, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, std::ostream& out) {
auto entry = fVariableMap.find(&ref.fVariable);
ASSERT(entry != fVariableMap.end());
SpvId var = entry->second;
@@ -1780,15 +1780,15 @@ SpvId SPIRVCodeGenerator::writeVariableReference(VariableReference& ref, std::os
return result;
}
-SpvId SPIRVCodeGenerator::writeIndexExpression(IndexExpression& expr, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeIndexExpression(const IndexExpression& expr, std::ostream& out) {
return getLValue(expr, out)->load(out);
}
-SpvId SPIRVCodeGenerator::writeFieldAccess(FieldAccess& f, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeFieldAccess(const FieldAccess& f, std::ostream& out) {
return getLValue(f, out)->load(out);
}
-SpvId SPIRVCodeGenerator::writeSwizzle(Swizzle& swizzle, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeSwizzle(const Swizzle& swizzle, std::ostream& out) {
SpvId base = this->writeExpression(*swizzle.fBase, out);
SpvId result = this->nextId();
size_t count = swizzle.fComponents.size();
@@ -1849,7 +1849,7 @@ bool is_assignment(Token::Kind op) {
}
}
-SpvId SPIRVCodeGenerator::writeBinaryExpression(BinaryExpression& b, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, std::ostream& out) {
// handle cases where we don't necessarily evaluate both LHS and RHS
switch (b.fOperator) {
case Token::EQ: {
@@ -2041,7 +2041,7 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(BinaryExpression& b, std::ostrea
}
}
-SpvId SPIRVCodeGenerator::writeLogicalAnd(BinaryExpression& a, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeLogicalAnd(const BinaryExpression& a, std::ostream& out) {
ASSERT(a.fOperator == Token::LOGICALAND);
BoolLiteral falseLiteral(fContext, Position(), false);
SpvId falseConstant = this->writeBoolLiteral(falseLiteral);
@@ -2062,7 +2062,7 @@ SpvId SPIRVCodeGenerator::writeLogicalAnd(BinaryExpression& a, std::ostream& out
return result;
}
-SpvId SPIRVCodeGenerator::writeLogicalOr(BinaryExpression& o, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeLogicalOr(const BinaryExpression& o, std::ostream& out) {
ASSERT(o.fOperator == Token::LOGICALOR);
BoolLiteral trueLiteral(fContext, Position(), true);
SpvId trueConstant = this->writeBoolLiteral(trueLiteral);
@@ -2083,7 +2083,7 @@ SpvId SPIRVCodeGenerator::writeLogicalOr(BinaryExpression& o, std::ostream& out)
return result;
}
-SpvId SPIRVCodeGenerator::writeTernaryExpression(TernaryExpression& t, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeTernaryExpression(const TernaryExpression& t, std::ostream& out) {
SpvId test = this->writeExpression(*t.fTest, out);
if (t.fIfTrue->isConstant() && t.fIfFalse->isConstant()) {
// both true and false are constants, can just use OpSelect
@@ -2127,7 +2127,7 @@ std::unique_ptr<Expression> create_literal_1(const Context& context, const Type&
}
}
-SpvId SPIRVCodeGenerator::writePrefixExpression(PrefixExpression& p, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writePrefixExpression(const PrefixExpression& p, std::ostream& out) {
if (p.fOperator == Token::MINUS) {
SpvId result = this->nextId();
SpvId typeId = this->getType(p.fType);
@@ -2174,7 +2174,7 @@ SpvId SPIRVCodeGenerator::writePrefixExpression(PrefixExpression& p, std::ostrea
}
}
-SpvId SPIRVCodeGenerator::writePostfixExpression(PostfixExpression& p, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writePostfixExpression(const PostfixExpression& p, std::ostream& out) {
std::unique_ptr<LValue> lv = this->getLValue(*p.fOperand, out);
SpvId result = lv->load(out);
SpvId one = this->writeExpression(*create_literal_1(fContext, p.fType), out);
@@ -2196,7 +2196,7 @@ SpvId SPIRVCodeGenerator::writePostfixExpression(PostfixExpression& p, std::ostr
}
}
-SpvId SPIRVCodeGenerator::writeBoolLiteral(BoolLiteral& b) {
+SpvId SPIRVCodeGenerator::writeBoolLiteral(const BoolLiteral& b) {
if (b.fValue) {
if (fBoolTrue == 0) {
fBoolTrue = this->nextId();
@@ -2214,7 +2214,7 @@ SpvId SPIRVCodeGenerator::writeBoolLiteral(BoolLiteral& b) {
}
}
-SpvId SPIRVCodeGenerator::writeIntLiteral(IntLiteral& i) {
+SpvId SPIRVCodeGenerator::writeIntLiteral(const IntLiteral& i) {
if (i.fType == *fContext.fInt_Type) {
auto entry = fIntConstants.find(i.fValue);
if (entry == fIntConstants.end()) {
@@ -2239,7 +2239,7 @@ SpvId SPIRVCodeGenerator::writeIntLiteral(IntLiteral& i) {
}
}
-SpvId SPIRVCodeGenerator::writeFloatLiteral(FloatLiteral& f) {
+SpvId SPIRVCodeGenerator::writeFloatLiteral(const FloatLiteral& f) {
if (f.fType == *fContext.fFloat_Type) {
float value = (float) f.fValue;
auto entry = fFloatConstants.find(value);
@@ -2350,7 +2350,7 @@ void SPIRVCodeGenerator::writeLayout(const Layout& layout, SpvId target, int mem
}
}
-SpvId SPIRVCodeGenerator::writeInterfaceBlock(InterfaceBlock& intf) {
+SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
SpvId type = this->getType(intf.fVariable.fType);
SpvId result = this->nextId();
this->writeInstruction(SpvOpDecorate, type, SpvDecorationBlock, fDecorationBuffer);
@@ -2363,7 +2363,7 @@ SpvId SPIRVCodeGenerator::writeInterfaceBlock(InterfaceBlock& intf) {
return result;
}
-void SPIRVCodeGenerator::writeGlobalVars(VarDeclaration& decl, std::ostream& out) {
+void SPIRVCodeGenerator::writeGlobalVars(const VarDeclaration& decl, std::ostream& out) {
for (size_t i = 0; i < decl.fVars.size(); i++) {
if (!decl.fVars[i]->fIsReadFrom && !decl.fVars[i]->fIsWrittenTo &&
!(decl.fVars[i]->fModifiers.fFlags & (Modifiers::kIn_Flag |
@@ -2399,17 +2399,17 @@ void SPIRVCodeGenerator::writeGlobalVars(VarDeclaration& decl, std::ostream& out
(SpvId) decl.fVars[i]->fType.stride(), fDecorationBuffer);
}
if (decl.fValues[i]) {
- ASSERT(!fCurrentBlock);
- fCurrentBlock = -1;
+ ASSERT(!fCurrentBlock);
+ fCurrentBlock = -1;
SpvId value = this->writeExpression(*decl.fValues[i], fGlobalInitializersBuffer);
this->writeInstruction(SpvOpStore, id, value, fGlobalInitializersBuffer);
- fCurrentBlock = 0;
+ fCurrentBlock = 0;
}
this->writeLayout(decl.fVars[i]->fModifiers.fLayout, id);
}
}
-void SPIRVCodeGenerator::writeVarDeclaration(VarDeclaration& decl, std::ostream& out) {
+void SPIRVCodeGenerator::writeVarDeclaration(const VarDeclaration& decl, std::ostream& out) {
for (size_t i = 0; i < decl.fVars.size(); i++) {
SpvId id = this->nextId();
fVariableMap[decl.fVars[i]] = id;
@@ -2423,7 +2423,7 @@ void SPIRVCodeGenerator::writeVarDeclaration(VarDeclaration& decl, std::ostream&
}
}
-void SPIRVCodeGenerator::writeStatement(Statement& s, std::ostream& out) {
+void SPIRVCodeGenerator::writeStatement(const Statement& s, std::ostream& out) {
switch (s.fKind) {
case Statement::kBlock_Kind:
this->writeBlock((Block&) s, out);
@@ -2457,13 +2457,13 @@ void SPIRVCodeGenerator::writeStatement(Statement& s, std::ostream& out) {
}
}
-void SPIRVCodeGenerator::writeBlock(Block& b, std::ostream& out) {
+void SPIRVCodeGenerator::writeBlock(const Block& b, std::ostream& out) {
for (size_t i = 0; i < b.fStatements.size(); i++) {
this->writeStatement(*b.fStatements[i], out);
}
}
-void SPIRVCodeGenerator::writeIfStatement(IfStatement& stmt, std::ostream& out) {
+void SPIRVCodeGenerator::writeIfStatement(const IfStatement& stmt, std::ostream& out) {
SpvId test = this->writeExpression(*stmt.fTest, out);
SpvId ifTrue = this->nextId();
SpvId ifFalse = this->nextId();
@@ -2494,7 +2494,7 @@ void SPIRVCodeGenerator::writeIfStatement(IfStatement& stmt, std::ostream& out)
}
}
-void SPIRVCodeGenerator::writeForStatement(ForStatement& f, std::ostream& out) {
+void SPIRVCodeGenerator::writeForStatement(const ForStatement& f, std::ostream& out) {
if (f.fInitializer) {
this->writeStatement(*f.fInitializer, out);
}
@@ -2508,7 +2508,7 @@ void SPIRVCodeGenerator::writeForStatement(ForStatement& f, std::ostream& out) {
this->writeInstruction(SpvOpBranch, header, out);
this->writeLabel(header, out);
this->writeInstruction(SpvOpLoopMerge, end, next, SpvLoopControlMaskNone, out);
- this->writeInstruction(SpvOpBranch, start, out);
+ this->writeInstruction(SpvOpBranch, start, out);
this->writeLabel(start, out);
SpvId test = this->writeExpression(*f.fTest, out);
this->writeInstruction(SpvOpBranchConditional, test, body, end, out);
@@ -2527,7 +2527,7 @@ void SPIRVCodeGenerator::writeForStatement(ForStatement& f, std::ostream& out) {
fContinueTarget.pop();
}
-void SPIRVCodeGenerator::writeReturnStatement(ReturnStatement& r, std::ostream& out) {
+void SPIRVCodeGenerator::writeReturnStatement(const ReturnStatement& r, std::ostream& out) {
if (r.fExpression) {
this->writeInstruction(SpvOpReturnValue, this->writeExpression(*r.fExpression, out),
out);
@@ -2536,7 +2536,7 @@ void SPIRVCodeGenerator::writeReturnStatement(ReturnStatement& r, std::ostream&
}
}
-void SPIRVCodeGenerator::writeInstructions(Program& program, std::ostream& out) {
+void SPIRVCodeGenerator::writeInstructions(const Program& program, std::ostream& out) {
fGLSLExtendedInstructions = this->nextId();
std::stringstream body;
std::vector<SpvId> interfaceVars;
@@ -2569,7 +2569,7 @@ void SPIRVCodeGenerator::writeInstructions(Program& program, std::ostream& out)
}
const FunctionDeclaration* main = nullptr;
for (auto entry : fFunctionMap) {
- if (entry.first->fName == "main") {
+ if (entry.first->fName == "main") {
main = entry.first;
}
}
@@ -2621,7 +2621,7 @@ void SPIRVCodeGenerator::writeInstructions(Program& program, std::ostream& out)
out << body.str();
}
-void SPIRVCodeGenerator::generateCode(Program& program, std::ostream& out) {
+void SPIRVCodeGenerator::generateCode(const Program& program, std::ostream& out) {
this->writeWord(SpvMagicNumber, out);
this->writeWord(SpvVersion, out);
this->writeWord(SKSL_MAGIC, out);
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.h b/src/sksl/SkSLSPIRVCodeGenerator.h
index a20ad9f40b..caae20114d 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.h
+++ b/src/sksl/SkSLSPIRVCodeGenerator.h
@@ -71,7 +71,7 @@ public:
this->setupIntrinsics();
}
- void generateCode(Program& program, std::ostream& out) override;
+ void generateCode(const Program& program, std::ostream& out) override;
private:
enum IntrinsicKind {
@@ -97,7 +97,7 @@ private:
SpvId getPointerType(const Type& type, SpvStorageClass_ storageClass);
- std::vector<SpvId> getAccessChain(Expression& expr, std::ostream& out);
+ std::vector<SpvId> getAccessChain(const Expression& expr, std::ostream& out);
void writeLayout(const Layout& layout, SpvId target);
@@ -105,9 +105,9 @@ private:
void writeStruct(const Type& type, SpvId resultId);
- void writeProgramElement(ProgramElement& pe, std::ostream& out);
+ void writeProgramElement(const ProgramElement& pe, std::ostream& out);
- SpvId writeInterfaceBlock(InterfaceBlock& intf);
+ SpvId writeInterfaceBlock(const InterfaceBlock& intf);
SpvId writeFunctionStart(const FunctionDeclaration& f, std::ostream& out);
@@ -115,78 +115,78 @@ private:
SpvId writeFunction(const FunctionDefinition& f, std::ostream& out);
- void writeGlobalVars(VarDeclaration& v, std::ostream& out);
+ void writeGlobalVars(const VarDeclaration& v, std::ostream& out);
- void writeVarDeclaration(VarDeclaration& decl, std::ostream& out);
+ void writeVarDeclaration(const VarDeclaration& decl, std::ostream& out);
- SpvId writeVariableReference(VariableReference& ref, std::ostream& out);
+ SpvId writeVariableReference(const VariableReference& ref, std::ostream& out);
- std::unique_ptr<LValue> getLValue(Expression& value, std::ostream& out);
+ std::unique_ptr<LValue> getLValue(const Expression& value, std::ostream& out);
- SpvId writeExpression(Expression& expr, std::ostream& out);
+ SpvId writeExpression(const Expression& expr, std::ostream& out);
- SpvId writeIntrinsicCall(FunctionCall& c, std::ostream& out);
+ SpvId writeIntrinsicCall(const FunctionCall& c, std::ostream& out);
- SpvId writeFunctionCall(FunctionCall& c, std::ostream& out);
+ SpvId writeFunctionCall(const FunctionCall& c, std::ostream& out);
- SpvId writeSpecialIntrinsic(FunctionCall& c, SpecialIntrinsic kind, std::ostream& out);
+ SpvId writeSpecialIntrinsic(const FunctionCall& c, SpecialIntrinsic kind, std::ostream& out);
- SpvId writeConstantVector(Constructor& c);
+ SpvId writeConstantVector(const Constructor& c);
- SpvId writeFloatConstructor(Constructor& c, std::ostream& out);
+ SpvId writeFloatConstructor(const Constructor& c, std::ostream& out);
- SpvId writeIntConstructor(Constructor& c, std::ostream& out);
+ SpvId writeIntConstructor(const Constructor& c, std::ostream& out);
- SpvId writeMatrixConstructor(Constructor& c, std::ostream& out);
+ SpvId writeMatrixConstructor(const Constructor& c, std::ostream& out);
- SpvId writeVectorConstructor(Constructor& c, std::ostream& out);
+ SpvId writeVectorConstructor(const Constructor& c, std::ostream& out);
- SpvId writeConstructor(Constructor& c, std::ostream& out);
+ SpvId writeConstructor(const Constructor& c, std::ostream& out);
- SpvId writeFieldAccess(FieldAccess& f, std::ostream& out);
+ SpvId writeFieldAccess(const FieldAccess& f, std::ostream& out);
- SpvId writeSwizzle(Swizzle& swizzle, std::ostream& out);
+ SpvId writeSwizzle(const Swizzle& swizzle, std::ostream& out);
SpvId writeBinaryOperation(const Type& resultType, const Type& operandType, SpvId lhs,
SpvId rhs, SpvOp_ ifFloat, SpvOp_ ifInt, SpvOp_ ifUInt,
SpvOp_ ifBool, std::ostream& out);
- SpvId writeBinaryOperation(BinaryExpression& expr, SpvOp_ ifFloat, SpvOp_ ifInt, SpvOp_ ifUInt,
- std::ostream& out);
+ SpvId writeBinaryOperation(const BinaryExpression& expr, SpvOp_ ifFloat, SpvOp_ ifInt,
+ SpvOp_ ifUInt, std::ostream& out);
- SpvId writeBinaryExpression(BinaryExpression& b, std::ostream& out);
+ SpvId writeBinaryExpression(const BinaryExpression& b, std::ostream& out);
- SpvId writeTernaryExpression(TernaryExpression& t, std::ostream& out);
+ SpvId writeTernaryExpression(const TernaryExpression& t, std::ostream& out);
- SpvId writeIndexExpression(IndexExpression& expr, std::ostream& out);
+ SpvId writeIndexExpression(const IndexExpression& expr, std::ostream& out);
- SpvId writeLogicalAnd(BinaryExpression& b, std::ostream& out);
+ SpvId writeLogicalAnd(const BinaryExpression& b, std::ostream& out);
- SpvId writeLogicalOr(BinaryExpression& o, std::ostream& out);
+ SpvId writeLogicalOr(const BinaryExpression& o, std::ostream& out);
- SpvId writePrefixExpression(PrefixExpression& p, std::ostream& out);
+ SpvId writePrefixExpression(const PrefixExpression& p, std::ostream& out);
- SpvId writePostfixExpression(PostfixExpression& p, std::ostream& out);
+ SpvId writePostfixExpression(const PostfixExpression& p, std::ostream& out);
- SpvId writeBoolLiteral(BoolLiteral& b);
+ SpvId writeBoolLiteral(const BoolLiteral& b);
- SpvId writeIntLiteral(IntLiteral& i);
+ SpvId writeIntLiteral(const IntLiteral& i);
- SpvId writeFloatLiteral(FloatLiteral& f);
+ SpvId writeFloatLiteral(const FloatLiteral& f);
- void writeStatement(Statement& s, std::ostream& out);
+ void writeStatement(const Statement& s, std::ostream& out);
- void writeBlock(Block& b, std::ostream& out);
+ void writeBlock(const Block& b, std::ostream& out);
- void writeIfStatement(IfStatement& stmt, std::ostream& out);
+ void writeIfStatement(const IfStatement& stmt, std::ostream& out);
- void writeForStatement(ForStatement& f, std::ostream& out);
+ void writeForStatement(const ForStatement& f, std::ostream& out);
- void writeReturnStatement(ReturnStatement& r, std::ostream& out);
+ void writeReturnStatement(const ReturnStatement& r, std::ostream& out);
void writeCapabilities(std::ostream& out);
- void writeInstructions(Program& program, std::ostream& out);
+ void writeInstructions(const Program& program, std::ostream& out);
void writeOpCode(SpvOp_ opCode, int length, std::ostream& out);
diff --git a/src/sksl/SkSLToken.h b/src/sksl/SkSLToken.h
index 538ae50a1a..29fa81e2e0 100644
--- a/src/sksl/SkSLToken.h
+++ b/src/sksl/SkSLToken.h
@@ -13,6 +13,10 @@
namespace SkSL {
+#undef IN
+#undef OUT
+#undef CONST
+
/**
* Represents a lexical analysis token. Token is generally only used during the parse process, but
* Token::Kind is also used to represent operator kinds.
@@ -89,6 +93,8 @@ struct Token {
MEDIUMP,
HIGHP,
UNIFORM,
+ FLAT,
+ NOPERSPECTIVE,
STRUCT,
LAYOUT,
DIRECTIVE,
diff --git a/src/sksl/SkSLUtil.h b/src/sksl/SkSLUtil.h
index 5536d93151..33611cde02 100644
--- a/src/sksl/SkSLUtil.h
+++ b/src/sksl/SkSLUtil.h
@@ -8,6 +8,7 @@
#ifndef SKSL_UTIL
#define SKSL_UTIL
+#include <iomanip>
#include <string>
#include <sstream>
#include "stdlib.h"
@@ -19,13 +20,9 @@ namespace SkSL {
// our own definitions of certain std:: functions, because they are not always present on Android
template <typename T> std::string to_string(T value) {
-#ifdef SK_BUILD_FOR_ANDROID
std::stringstream buffer;
- buffer << value;
+ buffer << std::setprecision(std::numeric_limits<T>::digits10) << value;
return buffer.str();
-#else
- return std::to_string(value);
-#endif
}
#if _MSC_VER
diff --git a/src/sksl/ast/SkSLASTLayout.h b/src/sksl/ast/SkSLASTLayout.h
index 487e6e9ecb..08d67531c3 100644
--- a/src/sksl/ast/SkSLASTLayout.h
+++ b/src/sksl/ast/SkSLASTLayout.h
@@ -20,12 +20,13 @@ namespace SkSL {
*/
struct ASTLayout : public ASTNode {
// For all parameters, a -1 means no value
- ASTLayout(int location, int binding, int index, int set, int builtin)
+ ASTLayout(int location, int binding, int index, int set, int builtin, bool originUpperLeft)
: fLocation(location)
, fBinding(binding)
, fIndex(index)
, fSet(set)
- , fBuiltin(builtin) {}
+ , fBuiltin(builtin)
+ , fOriginUpperLeft(originUpperLeft) {}
std::string description() const {
std::string result;
@@ -50,6 +51,10 @@ struct ASTLayout : public ASTNode {
result += separator + "builtin = " + to_string(fBuiltin);
separator = ", ";
}
+ if (fOriginUpperLeft) {
+ result += separator + "origin_upper_left";
+ separator = ", ";
+ }
if (result.length() > 0) {
result = "layout (" + result + ")";
}
@@ -61,6 +66,7 @@ struct ASTLayout : public ASTNode {
const int fIndex;
const int fSet;
const int fBuiltin;
+ const bool fOriginUpperLeft;
};
} // namespace
diff --git a/src/sksl/ast/SkSLASTModifiers.h b/src/sksl/ast/SkSLASTModifiers.h
index 6ef29aa72a..61d2e9f25d 100644
--- a/src/sksl/ast/SkSLASTModifiers.h
+++ b/src/sksl/ast/SkSLASTModifiers.h
@@ -18,14 +18,16 @@ namespace SkSL {
*/
struct ASTModifiers : public ASTNode {
enum Flag {
- kNo_Flag = 0,
- kConst_Flag = 1,
- kIn_Flag = 2,
- kOut_Flag = 4,
- kLowp_Flag = 8,
- kMediump_Flag = 16,
- kHighp_Flag = 32,
- kUniform_Flag = 64
+ kNo_Flag = 0,
+ kConst_Flag = 1,
+ kIn_Flag = 2,
+ kOut_Flag = 4,
+ kLowp_Flag = 8,
+ kMediump_Flag = 16,
+ kHighp_Flag = 32,
+ kUniform_Flag = 64,
+ kFlat_Flag = 128,
+ kNoPerspective_Flag = 256
};
ASTModifiers(ASTLayout layout, int flags)
@@ -49,6 +51,12 @@ struct ASTModifiers : public ASTNode {
if (fFlags & kHighp_Flag) {
result += "highp ";
}
+ if (fFlags & kFlat_Flag) {
+ result += "flat ";
+ }
+ if (fFlags & kNoPerspective_Flag) {
+ result += "noperspective ";
+ }
if ((fFlags & kIn_Flag) && (fFlags & kOut_Flag)) {
result += "inout ";
diff --git a/src/sksl/ast/SkSLASTNode.h b/src/sksl/ast/SkSLASTNode.h
index 26be769925..4305011fa5 100644
--- a/src/sksl/ast/SkSLASTNode.h
+++ b/src/sksl/ast/SkSLASTNode.h
@@ -19,7 +19,7 @@ namespace SkSL {
*/
struct ASTNode {
virtual ~ASTNode() {}
-
+
virtual std::string description() const = 0;
};
diff --git a/src/sksl/ir/SkSLBoolLiteral.h b/src/sksl/ir/SkSLBoolLiteral.h
index 8f55a69311..ba054e4181 100644
--- a/src/sksl/ir/SkSLBoolLiteral.h
+++ b/src/sksl/ir/SkSLBoolLiteral.h
@@ -26,7 +26,7 @@ struct BoolLiteral : public Expression {
}
bool isConstant() const override {
- return true;
+ return true;
}
const bool fValue;
diff --git a/src/sksl/ir/SkSLFieldAccess.h b/src/sksl/ir/SkSLFieldAccess.h
index f09c3a3447..bcdd7eea4f 100644
--- a/src/sksl/ir/SkSLFieldAccess.h
+++ b/src/sksl/ir/SkSLFieldAccess.h
@@ -17,10 +17,19 @@ namespace SkSL {
* An expression which extracts a field from a struct, as in 'foo.bar'.
*/
struct FieldAccess : public Expression {
- FieldAccess(std::unique_ptr<Expression> base, int fieldIndex)
+ enum OwnerKind {
+ kDefault_OwnerKind,
+ // this field access is to a field of an anonymous interface block (and thus, the field name
+ // is actually in global scope, so only the field name needs to be written in GLSL)
+ kAnonymousInterfaceBlock_OwnerKind
+ };
+
+ FieldAccess(std::unique_ptr<Expression> base, int fieldIndex,
+ OwnerKind ownerKind = kDefault_OwnerKind)
: INHERITED(base->fPosition, kFieldAccess_Kind, base->fType.fields()[fieldIndex].fType)
, fBase(std::move(base))
- , fFieldIndex(fieldIndex) {}
+ , fFieldIndex(fieldIndex)
+ , fOwnerKind(ownerKind) {}
virtual std::string description() const override {
return fBase->description() + "." + fBase->fType.fields()[fFieldIndex].fName;
@@ -28,6 +37,7 @@ struct FieldAccess : public Expression {
const std::unique_ptr<Expression> fBase;
const int fFieldIndex;
+ const OwnerKind fOwnerKind;
typedef Expression INHERITED;
};
diff --git a/src/sksl/ir/SkSLFloatLiteral.h b/src/sksl/ir/SkSLFloatLiteral.h
index d9c8b6538a..a8fcfcf644 100644
--- a/src/sksl/ir/SkSLFloatLiteral.h
+++ b/src/sksl/ir/SkSLFloatLiteral.h
@@ -26,7 +26,7 @@ struct FloatLiteral : public Expression {
}
bool isConstant() const override {
- return true;
+ return true;
}
const double fValue;
diff --git a/src/sksl/ir/SkSLFunctionReference.h b/src/sksl/ir/SkSLFunctionReference.h
index 5d97a5879f..f3f8fb71da 100644
--- a/src/sksl/ir/SkSLFunctionReference.h
+++ b/src/sksl/ir/SkSLFunctionReference.h
@@ -24,8 +24,8 @@ struct FunctionReference : public Expression {
, fFunctions(function) {}
virtual std::string description() const override {
- ASSERT(false);
- return "<function>";
+ ASSERT(false);
+ return "<function>";
}
const std::vector<const FunctionDeclaration*> fFunctions;
diff --git a/src/sksl/ir/SkSLIntLiteral.h b/src/sksl/ir/SkSLIntLiteral.h
index f2bf40b590..2bc565712e 100644
--- a/src/sksl/ir/SkSLIntLiteral.h
+++ b/src/sksl/ir/SkSLIntLiteral.h
@@ -27,7 +27,7 @@ struct IntLiteral : public Expression {
}
bool isConstant() const override {
- return true;
+ return true;
}
const int64_t fValue;
diff --git a/src/sksl/ir/SkSLLayout.h b/src/sksl/ir/SkSLLayout.h
index bab2f0e0db..d8dc98096f 100644
--- a/src/sksl/ir/SkSLLayout.h
+++ b/src/sksl/ir/SkSLLayout.h
@@ -21,14 +21,16 @@ struct Layout {
, fBinding(layout.fBinding)
, fIndex(layout.fIndex)
, fSet(layout.fSet)
- , fBuiltin(layout.fBuiltin) {}
+ , fBuiltin(layout.fBuiltin)
+ , fOriginUpperLeft(layout.fOriginUpperLeft) {}
- Layout(int location, int binding, int index, int set, int builtin)
+ Layout(int location, int binding, int index, int set, int builtin, bool originUpperLeft)
: fLocation(location)
, fBinding(binding)
, fIndex(index)
, fSet(set)
- , fBuiltin(builtin) {}
+ , fBuiltin(builtin)
+ , fOriginUpperLeft(originUpperLeft) {}
std::string description() const {
std::string result;
@@ -53,6 +55,10 @@ struct Layout {
result += separator + "builtin = " + to_string(fBuiltin);
separator = ", ";
}
+ if (fOriginUpperLeft) {
+ result += separator + "origin_upper_left";
+ separator = ", ";
+ }
if (result.length() > 0) {
result = "layout (" + result + ")";
}
@@ -71,11 +77,14 @@ struct Layout {
return !(*this == other);
}
- const int fLocation;
- const int fBinding;
- const int fIndex;
- const int fSet;
- const int fBuiltin;
+ // everything but builtin is in the GLSL spec; builtin comes from SPIR-V and identifies which
+ // particular builtin value this object represents.
+ int fLocation;
+ int fBinding;
+ int fIndex;
+ int fSet;
+ int fBuiltin;
+ bool fOriginUpperLeft;
};
} // namespace
diff --git a/src/sksl/ir/SkSLModifiers.h b/src/sksl/ir/SkSLModifiers.h
index d3b9c40ea1..f39e92959f 100644
--- a/src/sksl/ir/SkSLModifiers.h
+++ b/src/sksl/ir/SkSLModifiers.h
@@ -18,14 +18,16 @@ namespace SkSL {
*/
struct Modifiers {
enum Flag {
- kNo_Flag = ASTModifiers::kNo_Flag,
- kConst_Flag = ASTModifiers::kConst_Flag,
- kIn_Flag = ASTModifiers::kIn_Flag,
- kOut_Flag = ASTModifiers::kOut_Flag,
- kLowp_Flag = ASTModifiers::kLowp_Flag,
- kMediump_Flag = ASTModifiers::kMediump_Flag,
- kHighp_Flag = ASTModifiers::kHighp_Flag,
- kUniform_Flag = ASTModifiers::kUniform_Flag
+ kNo_Flag = ASTModifiers::kNo_Flag,
+ kConst_Flag = ASTModifiers::kConst_Flag,
+ kIn_Flag = ASTModifiers::kIn_Flag,
+ kOut_Flag = ASTModifiers::kOut_Flag,
+ kLowp_Flag = ASTModifiers::kLowp_Flag,
+ kMediump_Flag = ASTModifiers::kMediump_Flag,
+ kHighp_Flag = ASTModifiers::kHighp_Flag,
+ kUniform_Flag = ASTModifiers::kUniform_Flag,
+ kFlat_Flag = ASTModifiers::kFlat_Flag,
+ kNoPerspective_Flag = ASTModifiers::kNoPerspective_Flag
};
Modifiers(const ASTModifiers& modifiers)
@@ -53,6 +55,12 @@ struct Modifiers {
if (fFlags & kHighp_Flag) {
result += "highp ";
}
+ if (fFlags & kFlat_Flag) {
+ result += "flat ";
+ }
+ if (fFlags & kNoPerspective_Flag) {
+ result += "noperspective ";
+ }
if ((fFlags & kIn_Flag) && (fFlags & kOut_Flag)) {
result += "inout ";
@@ -73,8 +81,8 @@ struct Modifiers {
return !(*this == other);
}
- const Layout fLayout;
- const int fFlags;
+ Layout fLayout;
+ int fFlags;
};
} // namespace
diff --git a/src/sksl/ir/SkSLTypeReference.h b/src/sksl/ir/SkSLTypeReference.h
index 76923aae4d..10f36aa248 100644
--- a/src/sksl/ir/SkSLTypeReference.h
+++ b/src/sksl/ir/SkSLTypeReference.h
@@ -23,8 +23,8 @@ struct TypeReference : public Expression {
, fValue(type) {}
std::string description() const override {
- ASSERT(false);
- return "<type>";
+ ASSERT(false);
+ return "<type>";
}
const Type& fValue;
diff --git a/src/sksl/ir/SkSLUnresolvedFunction.h b/src/sksl/ir/SkSLUnresolvedFunction.h
index 3a368ad8d3..7e8a3601e8 100644
--- a/src/sksl/ir/SkSLUnresolvedFunction.h
+++ b/src/sksl/ir/SkSLUnresolvedFunction.h
@@ -20,9 +20,9 @@ struct UnresolvedFunction : public Symbol {
: INHERITED(Position(), kUnresolvedFunction_Kind, funcs[0]->fName)
, fFunctions(std::move(funcs)) {
#ifdef DEBUG
- for (auto func : funcs) {
- ASSERT(func->fName == fName);
- }
+ for (auto func : funcs) {
+ ASSERT(func->fName == fName);
+ }
#endif
}
diff --git a/src/sksl/ir/SkSLVarDeclaration.h b/src/sksl/ir/SkSLVarDeclaration.h
index b234231b86..ca3c7f95b2 100644
--- a/src/sksl/ir/SkSLVarDeclaration.h
+++ b/src/sksl/ir/SkSLVarDeclaration.h
@@ -16,14 +16,15 @@ namespace SkSL {
/**
* A variable declaration, which may consist of multiple individual variables. For instance
- * 'int x, y = 1, z[4][2];' is a single VarDeclaration. This declaration would have a type of 'int',
- * names ['x', 'y', 'z'], sizes of [[], [], [4, 2]], and values of [null, 1, null].
+ * 'int x, y = 1, z[4][2];' is a single VarDeclaration. This declaration would have a base type of
+ * 'int', names ['x', 'y', 'z'], sizes of [[], [], [4, 2]], and values of [null, 1, null].
*/
struct VarDeclaration : public ProgramElement {
- VarDeclaration(Position position, std::vector<const Variable*> vars,
+ VarDeclaration(Position position, const Type* baseType, std::vector<const Variable*> vars,
std::vector<std::vector<std::unique_ptr<Expression>>> sizes,
std::vector<std::unique_ptr<Expression>> values)
- : INHERITED(position, kVar_Kind)
+ : INHERITED(position, kVar_Kind)
+ , fBaseType(*baseType)
, fVars(std::move(vars))
, fSizes(std::move(sizes))
, fValues(std::move(values)) {}
@@ -55,6 +56,7 @@ struct VarDeclaration : public ProgramElement {
return result;
}
+ const Type& fBaseType;
const std::vector<const Variable*> fVars;
const std::vector<std::vector<std::unique_ptr<Expression>>> fSizes;
const std::vector<std::unique_ptr<Expression>> fValues;
diff --git a/src/sksl/ir/SkSLVariable.h b/src/sksl/ir/SkSLVariable.h
index 39af3093b6..217b1006b6 100644
--- a/src/sksl/ir/SkSLVariable.h
+++ b/src/sksl/ir/SkSLVariable.h
@@ -40,7 +40,7 @@ struct Variable : public Symbol {
return fModifiers.description() + fType.fName + " " + fName;
}
- const Modifiers fModifiers;
+ mutable Modifiers fModifiers;
const Type& fType;
const Storage fStorage;
diff --git a/src/sksl/lex.sksl.c b/src/sksl/lex.sksl.c
index 7afbd942ff..4993fac3a5 100644
--- a/src/sksl/lex.sksl.c
+++ b/src/sksl/lex.sksl.c
@@ -4,7 +4,7 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
-
+
#line 3 "lex.sksl.c"
#define YY_INT_ALIGNED short int
@@ -14,7 +14,7 @@
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
+#define YY_FLEX_SUBMINOR_VERSION 37
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
@@ -52,7 +52,6 @@ typedef int16_t flex_int16_t;
typedef uint16_t flex_uint16_t;
typedef int32_t flex_int32_t;
typedef uint32_t flex_uint32_t;
-typedef uint64_t flex_uint64_t;
#else
typedef signed char flex_int8_t;
typedef short int flex_int16_t;
@@ -60,7 +59,6 @@ typedef int flex_int32_t;
typedef unsigned char flex_uint8_t;
typedef unsigned short int flex_uint16_t;
typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
/* Limits of integral types. */
#ifndef INT8_MIN
@@ -91,6 +89,8 @@ typedef unsigned int flex_uint32_t;
#define UINT32_MAX (4294967295U)
#endif
+#endif /* ! C99 */
+
#endif /* ! FLEXINT_H */
#ifdef __cplusplus
@@ -194,7 +194,7 @@ typedef size_t yy_size_t;
*/
#define YY_LESS_LINENO(n) \
do { \
- yy_size_t yyl;\
+ int yyl;\
for ( yyl = n; yyl < yyleng; ++yyl )\
if ( yytext[yyl] == '\n' )\
--yylineno;\
@@ -360,13 +360,13 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
*/
#define YY_DO_BEFORE_ACTION \
yyg->yytext_ptr = yy_bp; \
- yyleng = (yy_size_t) (yy_cp - yy_bp); \
+ yyleng = (size_t) (yy_cp - yy_bp); \
yyg->yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 80
-#define YY_END_OF_BUFFER 81
+#define YY_NUM_RULES 82
+#define YY_END_OF_BUFFER 83
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -374,28 +374,30 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[185] =
+static yyconst flex_int16_t yy_accept[201] =
{ 0,
- 0, 0, 81, 79, 78, 78, 52, 79, 27, 43,
- 48, 29, 30, 41, 39, 36, 40, 35, 42, 4,
- 54, 75, 59, 55, 58, 53, 33, 34, 47, 27,
- 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 27, 31, 46, 32, 78, 57,
- 28, 27, 66, 51, 71, 64, 37, 62, 38, 63,
- 1, 0, 76, 65, 2, 4, 0, 44, 61, 56,
- 60, 45, 70, 50, 27, 27, 27, 11, 27, 27,
- 27, 27, 7, 16, 27, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 69, 49, 28, 74, 0, 0,
-
- 0, 76, 1, 0, 0, 3, 67, 68, 73, 27,
- 27, 27, 27, 27, 9, 27, 27, 27, 27, 27,
- 17, 27, 27, 27, 27, 27, 27, 72, 0, 1,
- 77, 0, 0, 2, 27, 27, 27, 27, 8, 27,
- 27, 27, 27, 21, 27, 27, 27, 27, 5, 27,
- 27, 0, 1, 12, 20, 27, 27, 6, 23, 18,
- 27, 27, 27, 27, 27, 27, 10, 27, 27, 25,
- 27, 27, 15, 24, 27, 27, 14, 22, 27, 19,
- 13, 27, 26, 0
+ 0, 0, 83, 81, 80, 80, 54, 81, 29, 45,
+ 50, 31, 32, 43, 41, 38, 42, 37, 44, 4,
+ 56, 77, 61, 57, 60, 55, 35, 36, 49, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 33, 48, 34, 80,
+ 59, 30, 29, 68, 53, 73, 66, 39, 64, 40,
+ 65, 1, 0, 78, 67, 2, 4, 0, 46, 63,
+ 58, 62, 47, 72, 52, 29, 29, 29, 11, 29,
+ 29, 29, 29, 29, 7, 16, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 71, 51, 30,
+
+ 76, 0, 0, 0, 78, 1, 0, 0, 3, 69,
+ 70, 75, 29, 29, 29, 29, 29, 29, 9, 29,
+ 29, 29, 29, 29, 29, 17, 29, 29, 29, 29,
+ 29, 29, 74, 0, 1, 79, 0, 0, 2, 29,
+ 29, 29, 29, 8, 29, 24, 29, 29, 29, 21,
+ 29, 29, 29, 29, 29, 5, 29, 29, 0, 1,
+ 12, 20, 29, 29, 6, 23, 18, 29, 29, 29,
+ 29, 29, 29, 29, 10, 29, 29, 27, 29, 29,
+ 29, 15, 26, 29, 29, 14, 22, 29, 29, 19,
+ 13, 29, 29, 29, 28, 29, 29, 29, 25, 0
+
} ;
static yyconst flex_int32_t yy_ec[256] =
@@ -412,8 +414,8 @@ static yyconst flex_int32_t yy_ec[256] =
25, 1, 26, 27, 6, 1, 28, 29, 30, 31,
32, 33, 34, 35, 36, 6, 37, 38, 39, 40,
- 41, 42, 6, 43, 44, 45, 46, 6, 47, 6,
- 48, 6, 49, 50, 51, 1, 1, 1, 1, 1,
+ 41, 42, 6, 43, 44, 45, 46, 47, 48, 6,
+ 49, 6, 50, 51, 52, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -430,140 +432,152 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static yyconst flex_int32_t yy_meta[52] =
+static yyconst flex_int32_t yy_meta[53] =
{ 0,
1, 1, 2, 1, 1, 3, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 4, 1, 1, 1,
1, 1, 1, 3, 1, 1, 1, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 1, 1,
- 1
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 1,
+ 1, 1
} ;
-static yyconst flex_int16_t yy_base[190] =
+static yyconst flex_int16_t yy_base[206] =
{ 0,
- 0, 0, 222, 223, 50, 52, 200, 0, 0, 199,
- 48, 223, 223, 198, 45, 223, 44, 201, 51, 44,
- 223, 223, 43, 196, 49, 223, 223, 223, 52, 173,
- 174, 39, 176, 46, 177, 44, 50, 180, 165, 167,
- 177, 163, 164, 166, 170, 223, 39, 223, 79, 223,
- 0, 0, 223, 183, 223, 223, 223, 223, 223, 223,
- 66, 192, 0, 223, 68, 71, 82, 181, 223, 223,
- 223, 180, 223, 179, 167, 158, 153, 0, 152, 157,
- 151, 159, 0, 151, 143, 143, 158, 143, 155, 141,
- 142, 138, 147, 146, 223, 160, 0, 223, 90, 169,
-
- 163, 0, 84, 97, 161, 160, 223, 223, 223, 148,
- 61, 145, 142, 129, 0, 137, 125, 129, 127, 132,
- 0, 137, 120, 119, 132, 130, 124, 223, 144, 143,
- 223, 98, 142, 141, 120, 111, 119, 126, 0, 121,
- 110, 106, 104, 0, 103, 112, 104, 116, 0, 104,
- 112, 126, 125, 0, 0, 101, 97, 0, 0, 0,
- 94, 99, 93, 96, 90, 91, 0, 87, 101, 0,
- 89, 94, 0, 0, 90, 94, 0, 0, 72, 0,
- 0, 57, 0, 223, 90, 114, 116, 120, 124
+ 0, 0, 238, 239, 51, 53, 216, 0, 0, 215,
+ 49, 239, 239, 214, 46, 239, 45, 217, 52, 45,
+ 239, 239, 44, 212, 50, 239, 239, 239, 53, 189,
+ 190, 40, 192, 47, 193, 46, 50, 196, 186, 180,
+ 182, 192, 178, 179, 181, 185, 239, 61, 239, 81,
+ 239, 0, 0, 239, 198, 239, 239, 239, 239, 239,
+ 239, 70, 207, 0, 239, 72, 75, 81, 196, 239,
+ 239, 239, 195, 239, 194, 182, 173, 168, 0, 167,
+ 172, 181, 165, 173, 0, 165, 156, 156, 172, 160,
+ 156, 168, 154, 155, 151, 160, 159, 239, 173, 0,
+
+ 239, 89, 182, 176, 0, 91, 97, 174, 173, 239,
+ 239, 239, 161, 72, 158, 155, 142, 140, 0, 149,
+ 137, 141, 139, 144, 147, 0, 148, 131, 130, 143,
+ 141, 135, 239, 155, 154, 239, 107, 153, 152, 131,
+ 122, 130, 137, 0, 132, 0, 121, 117, 115, 0,
+ 114, 116, 122, 114, 126, 0, 114, 122, 136, 135,
+ 0, 0, 111, 107, 0, 0, 0, 104, 109, 103,
+ 102, 105, 99, 100, 0, 96, 110, 0, 98, 97,
+ 102, 0, 0, 98, 102, 0, 0, 90, 79, 0,
+ 0, 88, 73, 65, 0, 69, 53, 65, 0, 239,
+
+ 58, 122, 124, 128, 132
} ;
-static yyconst flex_int16_t yy_def[190] =
+static yyconst flex_int16_t yy_def[206] =
{ 0,
- 184, 1, 184, 184, 184, 184, 184, 185, 186, 184,
- 184, 184, 184, 184, 184, 184, 184, 184, 184, 184,
- 184, 184, 184, 184, 184, 184, 184, 184, 184, 186,
- 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 186, 186, 186, 184, 184, 184, 184, 184,
- 187, 186, 184, 184, 184, 184, 184, 184, 184, 184,
- 184, 188, 189, 184, 184, 184, 184, 184, 184, 184,
- 184, 184, 184, 184, 186, 186, 186, 186, 186, 186,
- 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 186, 186, 184, 184, 187, 184, 184, 188,
-
- 188, 189, 184, 184, 184, 184, 184, 184, 184, 186,
- 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 186, 186, 186, 186, 186, 184, 184, 184,
- 184, 184, 184, 184, 186, 186, 186, 186, 186, 186,
- 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 184, 184, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 186, 0, 184, 184, 184, 184, 184
+ 200, 1, 200, 200, 200, 200, 200, 201, 202, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200, 200, 202,
+ 202, 202, 202, 202, 202, 202, 202, 202, 202, 202,
+ 202, 202, 202, 202, 202, 202, 200, 200, 200, 200,
+ 200, 203, 202, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 204, 205, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 202, 202, 202, 202, 202,
+ 202, 202, 202, 202, 202, 202, 202, 202, 202, 202,
+ 202, 202, 202, 202, 202, 202, 202, 200, 200, 203,
+
+ 200, 200, 204, 204, 205, 200, 200, 200, 200, 200,
+ 200, 200, 202, 202, 202, 202, 202, 202, 202, 202,
+ 202, 202, 202, 202, 202, 202, 202, 202, 202, 202,
+ 202, 202, 200, 200, 200, 200, 200, 200, 200, 202,
+ 202, 202, 202, 202, 202, 202, 202, 202, 202, 202,
+ 202, 202, 202, 202, 202, 202, 202, 202, 200, 200,
+ 202, 202, 202, 202, 202, 202, 202, 202, 202, 202,
+ 202, 202, 202, 202, 202, 202, 202, 202, 202, 202,
+ 202, 202, 202, 202, 202, 202, 202, 202, 202, 202,
+ 202, 202, 202, 202, 202, 202, 202, 202, 202, 0,
+
+ 200, 200, 200, 200, 200
} ;
-static yyconst flex_int16_t yy_nxt[275] =
+static yyconst flex_int16_t yy_nxt[292] =
{ 0,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 9, 27, 28, 29, 9, 30, 31,
- 32, 33, 34, 9, 35, 36, 9, 37, 38, 9,
- 39, 40, 41, 42, 43, 44, 45, 9, 46, 47,
- 48, 49, 49, 49, 49, 54, 57, 59, 65, 95,
- 66, 62, 68, 69, 60, 58, 63, 67, 55, 71,
- 72, 64, 73, 80, 77, 67, 83, 85, 74, 78,
- 49, 49, 61, 84, 103, 65, 81, 66, 96, 99,
- 86, 104, 51, 105, 67, 105, 183, 99, 106, 104,
-
- 103, 129, 67, 129, 136, 137, 130, 132, 133, 152,
- 133, 152, 182, 134, 153, 132, 52, 52, 97, 97,
- 100, 100, 100, 100, 102, 181, 102, 102, 180, 179,
- 178, 177, 176, 175, 174, 173, 172, 171, 170, 169,
- 168, 153, 153, 167, 166, 165, 164, 163, 162, 161,
- 160, 159, 158, 157, 156, 155, 154, 134, 134, 130,
- 130, 151, 150, 149, 148, 147, 146, 145, 144, 143,
- 142, 141, 140, 139, 138, 135, 106, 106, 131, 101,
- 128, 127, 126, 125, 124, 123, 122, 121, 120, 119,
- 118, 117, 116, 115, 114, 113, 112, 111, 110, 109,
-
- 108, 107, 101, 98, 94, 93, 92, 91, 90, 89,
- 88, 87, 82, 79, 76, 75, 70, 61, 56, 53,
- 50, 184, 3, 184, 184, 184, 184, 184, 184, 184,
- 184, 184, 184, 184, 184, 184, 184, 184, 184, 184,
- 184, 184, 184, 184, 184, 184, 184, 184, 184, 184,
- 184, 184, 184, 184, 184, 184, 184, 184, 184, 184,
- 184, 184, 184, 184, 184, 184, 184, 184, 184, 184,
- 184, 184, 184, 184
+ 32, 33, 34, 9, 35, 36, 9, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 9, 46, 9, 47,
+ 48, 49, 50, 50, 50, 50, 55, 58, 60, 66,
+ 52, 67, 63, 69, 70, 61, 59, 64, 68, 56,
+ 72, 73, 65, 74, 81, 78, 68, 87, 85, 75,
+ 79, 98, 50, 50, 82, 86, 62, 83, 106, 66,
+ 88, 67, 108, 102, 108, 107, 199, 109, 68, 198,
+
+ 134, 102, 134, 107, 197, 135, 68, 106, 138, 196,
+ 138, 99, 195, 139, 137, 141, 142, 194, 159, 193,
+ 159, 192, 137, 160, 53, 53, 100, 100, 103, 103,
+ 103, 103, 105, 191, 105, 105, 190, 189, 188, 187,
+ 186, 185, 184, 183, 182, 181, 180, 179, 178, 177,
+ 176, 160, 160, 175, 174, 173, 172, 171, 170, 169,
+ 168, 167, 166, 165, 164, 163, 162, 161, 139, 139,
+ 135, 135, 158, 157, 156, 155, 154, 153, 152, 151,
+ 150, 149, 148, 147, 146, 145, 144, 143, 140, 109,
+ 109, 136, 104, 133, 132, 131, 130, 129, 128, 127,
+
+ 126, 125, 124, 123, 122, 121, 120, 119, 118, 117,
+ 116, 115, 114, 113, 112, 111, 110, 104, 101, 97,
+ 96, 95, 94, 93, 92, 91, 90, 89, 84, 80,
+ 77, 76, 71, 62, 57, 54, 51, 200, 3, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
+ 200
+
} ;
-static yyconst flex_int16_t yy_chk[275] =
+static yyconst flex_int16_t yy_chk[292] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 5, 5, 6, 6, 11, 15, 17, 20, 47,
- 20, 19, 23, 23, 17, 15, 19, 20, 11, 25,
- 25, 19, 29, 34, 32, 20, 36, 37, 29, 32,
- 49, 49, 61, 36, 65, 66, 34, 66, 47, 61,
- 37, 65, 185, 67, 66, 67, 182, 61, 67, 65,
-
- 103, 99, 66, 99, 111, 111, 99, 103, 104, 132,
- 104, 132, 179, 104, 132, 103, 186, 186, 187, 187,
- 188, 188, 188, 188, 189, 176, 189, 189, 175, 172,
- 171, 169, 168, 166, 165, 164, 163, 162, 161, 157,
- 156, 153, 152, 151, 150, 148, 147, 146, 145, 143,
- 142, 141, 140, 138, 137, 136, 135, 134, 133, 130,
- 129, 127, 126, 125, 124, 123, 122, 120, 119, 118,
- 117, 116, 114, 113, 112, 110, 106, 105, 101, 100,
- 96, 94, 93, 92, 91, 90, 89, 88, 87, 86,
- 85, 84, 82, 81, 80, 79, 77, 76, 75, 74,
-
- 72, 68, 62, 54, 45, 44, 43, 42, 41, 40,
- 39, 38, 35, 33, 31, 30, 24, 18, 14, 10,
- 7, 3, 184, 184, 184, 184, 184, 184, 184, 184,
- 184, 184, 184, 184, 184, 184, 184, 184, 184, 184,
- 184, 184, 184, 184, 184, 184, 184, 184, 184, 184,
- 184, 184, 184, 184, 184, 184, 184, 184, 184, 184,
- 184, 184, 184, 184, 184, 184, 184, 184, 184, 184,
- 184, 184, 184, 184
+ 1, 1, 5, 5, 6, 6, 11, 15, 17, 20,
+ 201, 20, 19, 23, 23, 17, 15, 19, 20, 11,
+ 25, 25, 19, 29, 34, 32, 20, 37, 36, 29,
+ 32, 48, 50, 50, 34, 36, 62, 34, 66, 67,
+ 37, 67, 68, 62, 68, 66, 198, 68, 67, 197,
+
+ 102, 62, 102, 66, 196, 102, 67, 106, 107, 194,
+ 107, 48, 193, 107, 106, 114, 114, 192, 137, 189,
+ 137, 188, 106, 137, 202, 202, 203, 203, 204, 204,
+ 204, 204, 205, 185, 205, 205, 184, 181, 180, 179,
+ 177, 176, 174, 173, 172, 171, 170, 169, 168, 164,
+ 163, 160, 159, 158, 157, 155, 154, 153, 152, 151,
+ 149, 148, 147, 145, 143, 142, 141, 140, 139, 138,
+ 135, 134, 132, 131, 130, 129, 128, 127, 125, 124,
+ 123, 122, 121, 120, 118, 117, 116, 115, 113, 109,
+ 108, 104, 103, 99, 97, 96, 95, 94, 93, 92,
+
+ 91, 90, 89, 88, 87, 86, 84, 83, 82, 81,
+ 80, 78, 77, 76, 75, 73, 69, 63, 55, 46,
+ 45, 44, 43, 42, 41, 40, 39, 38, 35, 33,
+ 31, 30, 24, 18, 14, 10, 7, 3, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
+ 200
+
} ;
/* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[81] =
+static yyconst flex_int32_t yy_rule_can_match_eol[83] =
{ 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
- 0, };
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 1, 0, 0, };
/* The intent behind this definition is that it'll catch
* any uses of REJECT which flex missed.
@@ -582,9 +596,11 @@ static yyconst flex_int32_t yy_rule_can_match_eol[81] =
flex sksl.flex
+ You will have to manually add a copyright notice to the top of lex.sksl.c.
+
*/
#define YY_NO_UNISTD_H 1
-#line 582 "lex.sksl.c"
+#line 598 "lex.sksl.c"
#define INITIAL 0
@@ -669,6 +685,10 @@ int skslget_lineno (yyscan_t yyscanner );
void skslset_lineno (int line_number ,yyscan_t yyscanner );
+int skslget_column (yyscan_t yyscanner );
+
+void skslset_column (int column_no ,yyscan_t yyscanner );
+
/* Macros after this point can all be overridden by user definitions in
* section 1.
*/
@@ -711,7 +731,7 @@ static int input (yyscan_t yyscanner );
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
-#define ECHO fwrite( yytext, yyleng, 1, yyout )
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
#endif
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
@@ -722,7 +742,7 @@ static int input (yyscan_t yyscanner );
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
int c = '*'; \
- yy_size_t n; \
+ size_t n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
@@ -805,10 +825,10 @@ YY_DECL
register int yy_act;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-#line 21 "sksl.flex"
+#line 23 "sksl.flex"
-#line 806 "lex.sksl.c"
+#line 826 "lex.sksl.c"
if ( !yyg->yy_init )
{
@@ -861,13 +881,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 185 )
+ if ( yy_current_state >= 201 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
- while ( yy_current_state != 184 );
+ while ( yy_current_state != 200 );
yy_cp = yyg->yy_last_accepting_cpos;
yy_current_state = yyg->yy_last_accepting_state;
@@ -878,7 +898,7 @@ yy_find_action:
if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
{
- yy_size_t yyl;
+ int yyl;
for ( yyl = 0; yyl < yyleng; ++yyl )
if ( yytext[yyl] == '\n' )
@@ -901,407 +921,417 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
YY_RULE_SETUP
-#line 23 "sksl.flex"
+#line 25 "sksl.flex"
{ return SkSL::Token::FLOAT_LITERAL; }
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 25 "sksl.flex"
+#line 27 "sksl.flex"
{ return SkSL::Token::FLOAT_LITERAL; }
YY_BREAK
case 3:
YY_RULE_SETUP
-#line 27 "sksl.flex"
+#line 29 "sksl.flex"
{ return SkSL::Token::FLOAT_LITERAL; }
YY_BREAK
case 4:
YY_RULE_SETUP
-#line 29 "sksl.flex"
+#line 31 "sksl.flex"
{ return SkSL::Token::INT_LITERAL; }
YY_BREAK
case 5:
YY_RULE_SETUP
-#line 31 "sksl.flex"
+#line 33 "sksl.flex"
{ return SkSL::Token::TRUE_LITERAL; }
YY_BREAK
case 6:
YY_RULE_SETUP
-#line 33 "sksl.flex"
+#line 35 "sksl.flex"
{ return SkSL::Token::FALSE_LITERAL; }
YY_BREAK
case 7:
YY_RULE_SETUP
-#line 35 "sksl.flex"
+#line 37 "sksl.flex"
{ return SkSL::Token::IF; }
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 37 "sksl.flex"
+#line 39 "sksl.flex"
{ return SkSL::Token::ELSE; }
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 39 "sksl.flex"
+#line 41 "sksl.flex"
{ return SkSL::Token::FOR; }
YY_BREAK
case 10:
YY_RULE_SETUP
-#line 41 "sksl.flex"
+#line 43 "sksl.flex"
{ return SkSL::Token::WHILE; }
YY_BREAK
case 11:
YY_RULE_SETUP
-#line 43 "sksl.flex"
+#line 45 "sksl.flex"
{ return SkSL::Token::DO; }
YY_BREAK
case 12:
YY_RULE_SETUP
-#line 45 "sksl.flex"
+#line 47 "sksl.flex"
{ return SkSL::Token::BREAK; }
YY_BREAK
case 13:
YY_RULE_SETUP
-#line 47 "sksl.flex"
+#line 49 "sksl.flex"
{ return SkSL::Token::CONTINUE; }
YY_BREAK
case 14:
YY_RULE_SETUP
-#line 49 "sksl.flex"
+#line 51 "sksl.flex"
{ return SkSL::Token::DISCARD; }
YY_BREAK
case 15:
YY_RULE_SETUP
-#line 51 "sksl.flex"
+#line 53 "sksl.flex"
{ return SkSL::Token::RETURN; }
YY_BREAK
case 16:
YY_RULE_SETUP
-#line 53 "sksl.flex"
+#line 55 "sksl.flex"
{ return SkSL::Token::IN; }
YY_BREAK
case 17:
YY_RULE_SETUP
-#line 55 "sksl.flex"
+#line 57 "sksl.flex"
{ return SkSL::Token::OUT; }
YY_BREAK
case 18:
YY_RULE_SETUP
-#line 57 "sksl.flex"
+#line 59 "sksl.flex"
{ return SkSL::Token::INOUT; }
YY_BREAK
case 19:
YY_RULE_SETUP
-#line 59 "sksl.flex"
+#line 61 "sksl.flex"
{ return SkSL::Token::UNIFORM; }
YY_BREAK
case 20:
YY_RULE_SETUP
-#line 61 "sksl.flex"
+#line 63 "sksl.flex"
{ return SkSL::Token::CONST; }
YY_BREAK
case 21:
YY_RULE_SETUP
-#line 63 "sksl.flex"
+#line 65 "sksl.flex"
{ return SkSL::Token::LOWP; }
YY_BREAK
case 22:
YY_RULE_SETUP
-#line 65 "sksl.flex"
+#line 67 "sksl.flex"
{ return SkSL::Token::MEDIUMP; }
YY_BREAK
case 23:
YY_RULE_SETUP
-#line 67 "sksl.flex"
+#line 69 "sksl.flex"
{ return SkSL::Token::HIGHP; }
YY_BREAK
case 24:
YY_RULE_SETUP
-#line 69 "sksl.flex"
-{ return SkSL::Token::STRUCT; }
+#line 71 "sksl.flex"
+{ return SkSL::Token::FLAT; }
YY_BREAK
case 25:
YY_RULE_SETUP
-#line 71 "sksl.flex"
-{ return SkSL::Token::LAYOUT; }
+#line 73 "sksl.flex"
+{ return SkSL::Token::NOPERSPECTIVE; }
YY_BREAK
case 26:
YY_RULE_SETUP
-#line 73 "sksl.flex"
-{ return SkSL::Token::PRECISION; }
+#line 75 "sksl.flex"
+{ return SkSL::Token::STRUCT; }
YY_BREAK
case 27:
YY_RULE_SETUP
-#line 75 "sksl.flex"
-{ return SkSL::Token::IDENTIFIER; }
+#line 77 "sksl.flex"
+{ return SkSL::Token::LAYOUT; }
YY_BREAK
case 28:
YY_RULE_SETUP
-#line 77 "sksl.flex"
-{ return SkSL::Token::DIRECTIVE; }
+#line 79 "sksl.flex"
+{ return SkSL::Token::PRECISION; }
YY_BREAK
case 29:
YY_RULE_SETUP
-#line 79 "sksl.flex"
-{ return SkSL::Token::LPAREN; }
+#line 81 "sksl.flex"
+{ return SkSL::Token::IDENTIFIER; }
YY_BREAK
case 30:
YY_RULE_SETUP
-#line 81 "sksl.flex"
-{ return SkSL::Token::RPAREN; }
+#line 83 "sksl.flex"
+{ return SkSL::Token::DIRECTIVE; }
YY_BREAK
case 31:
YY_RULE_SETUP
-#line 83 "sksl.flex"
-{ return SkSL::Token::LBRACE; }
+#line 85 "sksl.flex"
+{ return SkSL::Token::LPAREN; }
YY_BREAK
case 32:
YY_RULE_SETUP
-#line 85 "sksl.flex"
-{ return SkSL::Token::RBRACE; }
+#line 87 "sksl.flex"
+{ return SkSL::Token::RPAREN; }
YY_BREAK
case 33:
YY_RULE_SETUP
-#line 87 "sksl.flex"
-{ return SkSL::Token::LBRACKET; }
+#line 89 "sksl.flex"
+{ return SkSL::Token::LBRACE; }
YY_BREAK
case 34:
YY_RULE_SETUP
-#line 89 "sksl.flex"
-{ return SkSL::Token::RBRACKET; }
+#line 91 "sksl.flex"
+{ return SkSL::Token::RBRACE; }
YY_BREAK
case 35:
YY_RULE_SETUP
-#line 91 "sksl.flex"
-{ return SkSL::Token::DOT; }
+#line 93 "sksl.flex"
+{ return SkSL::Token::LBRACKET; }
YY_BREAK
case 36:
YY_RULE_SETUP
-#line 93 "sksl.flex"
-{ return SkSL::Token::COMMA; }
+#line 95 "sksl.flex"
+{ return SkSL::Token::RBRACKET; }
YY_BREAK
case 37:
YY_RULE_SETUP
-#line 95 "sksl.flex"
-{ return SkSL::Token::PLUSPLUS; }
+#line 97 "sksl.flex"
+{ return SkSL::Token::DOT; }
YY_BREAK
case 38:
YY_RULE_SETUP
-#line 97 "sksl.flex"
-{ return SkSL::Token::MINUSMINUS; }
+#line 99 "sksl.flex"
+{ return SkSL::Token::COMMA; }
YY_BREAK
case 39:
YY_RULE_SETUP
-#line 99 "sksl.flex"
-{ return SkSL::Token::PLUS; }
+#line 101 "sksl.flex"
+{ return SkSL::Token::PLUSPLUS; }
YY_BREAK
case 40:
YY_RULE_SETUP
-#line 101 "sksl.flex"
-{ return SkSL::Token::MINUS; }
+#line 103 "sksl.flex"
+{ return SkSL::Token::MINUSMINUS; }
YY_BREAK
case 41:
YY_RULE_SETUP
-#line 103 "sksl.flex"
-{ return SkSL::Token::STAR; }
+#line 105 "sksl.flex"
+{ return SkSL::Token::PLUS; }
YY_BREAK
case 42:
YY_RULE_SETUP
-#line 105 "sksl.flex"
-{ return SkSL::Token::SLASH; }
+#line 107 "sksl.flex"
+{ return SkSL::Token::MINUS; }
YY_BREAK
case 43:
YY_RULE_SETUP
-#line 107 "sksl.flex"
-{ return SkSL::Token::PERCENT; }
+#line 109 "sksl.flex"
+{ return SkSL::Token::STAR; }
YY_BREAK
case 44:
YY_RULE_SETUP
-#line 109 "sksl.flex"
-{ return SkSL::Token::SHL; }
+#line 111 "sksl.flex"
+{ return SkSL::Token::SLASH; }
YY_BREAK
case 45:
YY_RULE_SETUP
-#line 111 "sksl.flex"
-{ return SkSL::Token::SHR; }
+#line 113 "sksl.flex"
+{ return SkSL::Token::PERCENT; }
YY_BREAK
case 46:
YY_RULE_SETUP
-#line 113 "sksl.flex"
-{ return SkSL::Token::BITWISEOR; }
+#line 115 "sksl.flex"
+{ return SkSL::Token::SHL; }
YY_BREAK
case 47:
YY_RULE_SETUP
-#line 115 "sksl.flex"
-{ return SkSL::Token::BITWISEXOR; }
+#line 117 "sksl.flex"
+{ return SkSL::Token::SHR; }
YY_BREAK
case 48:
YY_RULE_SETUP
-#line 117 "sksl.flex"
-{ return SkSL::Token::BITWISEAND; }
+#line 119 "sksl.flex"
+{ return SkSL::Token::BITWISEOR; }
YY_BREAK
case 49:
YY_RULE_SETUP
-#line 119 "sksl.flex"
-{ return SkSL::Token::LOGICALOR; }
+#line 121 "sksl.flex"
+{ return SkSL::Token::BITWISEXOR; }
YY_BREAK
case 50:
YY_RULE_SETUP
-#line 121 "sksl.flex"
-{ return SkSL::Token::LOGICALXOR; }
+#line 123 "sksl.flex"
+{ return SkSL::Token::BITWISEAND; }
YY_BREAK
case 51:
YY_RULE_SETUP
-#line 123 "sksl.flex"
-{ return SkSL::Token::LOGICALAND; }
+#line 125 "sksl.flex"
+{ return SkSL::Token::LOGICALOR; }
YY_BREAK
case 52:
YY_RULE_SETUP
-#line 125 "sksl.flex"
-{ return SkSL::Token::NOT; }
+#line 127 "sksl.flex"
+{ return SkSL::Token::LOGICALXOR; }
YY_BREAK
case 53:
YY_RULE_SETUP
-#line 127 "sksl.flex"
-{ return SkSL::Token::QUESTION; }
+#line 129 "sksl.flex"
+{ return SkSL::Token::LOGICALAND; }
YY_BREAK
case 54:
YY_RULE_SETUP
-#line 129 "sksl.flex"
-{ return SkSL::Token::COLON; }
+#line 131 "sksl.flex"
+{ return SkSL::Token::NOT; }
YY_BREAK
case 55:
YY_RULE_SETUP
-#line 131 "sksl.flex"
-{ return SkSL::Token::EQ; }
+#line 133 "sksl.flex"
+{ return SkSL::Token::QUESTION; }
YY_BREAK
case 56:
YY_RULE_SETUP
-#line 133 "sksl.flex"
-{ return SkSL::Token::EQEQ; }
+#line 135 "sksl.flex"
+{ return SkSL::Token::COLON; }
YY_BREAK
case 57:
YY_RULE_SETUP
-#line 135 "sksl.flex"
-{ return SkSL::Token::NEQ; }
+#line 137 "sksl.flex"
+{ return SkSL::Token::EQ; }
YY_BREAK
case 58:
YY_RULE_SETUP
-#line 137 "sksl.flex"
-{ return SkSL::Token::GT; }
+#line 139 "sksl.flex"
+{ return SkSL::Token::EQEQ; }
YY_BREAK
case 59:
YY_RULE_SETUP
-#line 139 "sksl.flex"
-{ return SkSL::Token::LT; }
+#line 141 "sksl.flex"
+{ return SkSL::Token::NEQ; }
YY_BREAK
case 60:
YY_RULE_SETUP
-#line 141 "sksl.flex"
-{ return SkSL::Token::GTEQ; }
+#line 143 "sksl.flex"
+{ return SkSL::Token::GT; }
YY_BREAK
case 61:
YY_RULE_SETUP
-#line 143 "sksl.flex"
-{ return SkSL::Token::LTEQ; }
+#line 145 "sksl.flex"
+{ return SkSL::Token::LT; }
YY_BREAK
case 62:
YY_RULE_SETUP
-#line 145 "sksl.flex"
-{ return SkSL::Token::PLUSEQ; }
+#line 147 "sksl.flex"
+{ return SkSL::Token::GTEQ; }
YY_BREAK
case 63:
YY_RULE_SETUP
-#line 147 "sksl.flex"
-{ return SkSL::Token::MINUSEQ; }
+#line 149 "sksl.flex"
+{ return SkSL::Token::LTEQ; }
YY_BREAK
case 64:
YY_RULE_SETUP
-#line 149 "sksl.flex"
-{ return SkSL::Token::STAREQ; }
+#line 151 "sksl.flex"
+{ return SkSL::Token::PLUSEQ; }
YY_BREAK
case 65:
YY_RULE_SETUP
-#line 151 "sksl.flex"
-{ return SkSL::Token::SLASHEQ; }
+#line 153 "sksl.flex"
+{ return SkSL::Token::MINUSEQ; }
YY_BREAK
case 66:
YY_RULE_SETUP
-#line 153 "sksl.flex"
-{ return SkSL::Token::PERCENTEQ; }
+#line 155 "sksl.flex"
+{ return SkSL::Token::STAREQ; }
YY_BREAK
case 67:
YY_RULE_SETUP
-#line 155 "sksl.flex"
-{ return SkSL::Token::SHLEQ; }
+#line 157 "sksl.flex"
+{ return SkSL::Token::SLASHEQ; }
YY_BREAK
case 68:
YY_RULE_SETUP
-#line 157 "sksl.flex"
-{ return SkSL::Token::SHREQ; }
+#line 159 "sksl.flex"
+{ return SkSL::Token::PERCENTEQ; }
YY_BREAK
case 69:
YY_RULE_SETUP
-#line 159 "sksl.flex"
-{ return SkSL::Token::BITWISEOREQ; }
+#line 161 "sksl.flex"
+{ return SkSL::Token::SHLEQ; }
YY_BREAK
case 70:
YY_RULE_SETUP
-#line 161 "sksl.flex"
-{ return SkSL::Token::BITWISEXOREQ; }
+#line 163 "sksl.flex"
+{ return SkSL::Token::SHREQ; }
YY_BREAK
case 71:
YY_RULE_SETUP
-#line 163 "sksl.flex"
-{ return SkSL::Token::BITWISEANDEQ; }
+#line 165 "sksl.flex"
+{ return SkSL::Token::BITWISEOREQ; }
YY_BREAK
case 72:
YY_RULE_SETUP
-#line 165 "sksl.flex"
-{ return SkSL::Token::LOGICALOREQ; }
+#line 167 "sksl.flex"
+{ return SkSL::Token::BITWISEXOREQ; }
YY_BREAK
case 73:
YY_RULE_SETUP
-#line 167 "sksl.flex"
-{ return SkSL::Token::LOGICALXOREQ; }
+#line 169 "sksl.flex"
+{ return SkSL::Token::BITWISEANDEQ; }
YY_BREAK
case 74:
YY_RULE_SETUP
-#line 169 "sksl.flex"
-{ return SkSL::Token::LOGICALANDEQ; }
+#line 171 "sksl.flex"
+{ return SkSL::Token::LOGICALOREQ; }
YY_BREAK
case 75:
YY_RULE_SETUP
-#line 171 "sksl.flex"
-{ return SkSL::Token::SEMICOLON; }
+#line 173 "sksl.flex"
+{ return SkSL::Token::LOGICALXOREQ; }
YY_BREAK
case 76:
YY_RULE_SETUP
-#line 173 "sksl.flex"
-/* line comment */
+#line 175 "sksl.flex"
+{ return SkSL::Token::LOGICALANDEQ; }
YY_BREAK
case 77:
-/* rule 77 can match eol */
YY_RULE_SETUP
-#line 175 "sksl.flex"
-/* block comment */
+#line 177 "sksl.flex"
+{ return SkSL::Token::SEMICOLON; }
YY_BREAK
case 78:
-/* rule 78 can match eol */
YY_RULE_SETUP
-#line 177 "sksl.flex"
-/* whitespace */
+#line 179 "sksl.flex"
+/* line comment */
YY_BREAK
case 79:
+/* rule 79 can match eol */
YY_RULE_SETUP
-#line 179 "sksl.flex"
-{ return SkSL::Token::INVALID_TOKEN; }
+#line 181 "sksl.flex"
+/* block comment */
YY_BREAK
case 80:
+/* rule 80 can match eol */
YY_RULE_SETUP
-#line 181 "sksl.flex"
+#line 183 "sksl.flex"
+/* whitespace */
+ YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 185 "sksl.flex"
+{ return SkSL::Token::INVALID_TOKEN; }
+ YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 187 "sksl.flex"
ECHO;
YY_BREAK
-#line 1299 "lex.sksl.c"
+#line 1329 "lex.sksl.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
@@ -1496,7 +1526,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
{ /* Not enough room in the buffer - grow it. */
/* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
int yy_c_buf_p_offset =
(int) (yyg->yy_c_buf_p - b->yy_ch_buf);
@@ -1596,7 +1626,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 185 )
+ if ( yy_current_state >= 201 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1625,12 +1655,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 185 )
+ if ( yy_current_state >= 201 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 184);
+ yy_is_jam = (yy_current_state == 200);
+ (void)yyg;
return yy_is_jam ? 0 : yy_current_state;
}
@@ -1725,7 +1756,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
case EOB_ACT_END_OF_FILE:
{
if ( skslwrap(yyscanner ) )
- return 0;
+ return EOF;
if ( ! yyg->yy_did_buffer_switch_on_eof )
YY_NEW_FILE;
@@ -2081,8 +2112,8 @@ YY_BUFFER_STATE sksl_scan_string (yyconst char * yystr , yyscan_t yyscanner)
/** Setup the input buffer state to scan the given bytes. The next call to sksllex() will
* scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
*/
@@ -2090,7 +2121,8 @@ YY_BUFFER_STATE sksl_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_le
{
YY_BUFFER_STATE b;
char *buf;
- yy_size_t n, i;
+ yy_size_t n;
+ int i;
/* Get memory for full buffer, including space for trailing EOB's. */
n = _yybytes_len + 2;
@@ -2236,7 +2268,7 @@ void skslset_lineno (int line_number , yyscan_t yyscanner)
/* lineno is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "skslset_lineno called with no buffer" , yyscanner);
+ YY_FATAL_ERROR( "skslset_lineno called with no buffer" );
yylineno = line_number;
}
@@ -2251,7 +2283,7 @@ void skslset_column (int column_no , yyscan_t yyscanner)
/* column is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "skslset_column called with no buffer" , yyscanner);
+ YY_FATAL_ERROR( "skslset_column called with no buffer" );
yycolumn = column_no;
}
@@ -2463,7 +2495,7 @@ void skslfree (void * ptr , yyscan_t yyscanner)
#define YYTABLES_NAME "yytables"
-#line 181 "sksl.flex"
+#line 187 "sksl.flex"
diff --git a/src/sksl/sksl.flex b/src/sksl/sksl.flex
index cbc938a3bb..67b48e9cb9 100644
--- a/src/sksl/sksl.flex
+++ b/src/sksl/sksl.flex
@@ -68,6 +68,10 @@ mediump { return SkSL::Token::MEDIUMP; }
highp { return SkSL::Token::HIGHP; }
+flat { return SkSL::Token::FLAT; }
+
+noperspective { return SkSL::Token::NOPERSPECTIVE; }
+
struct { return SkSL::Token::STRUCT; }
layout { return SkSL::Token::LAYOUT; }