1f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas/* 2f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas * Copyright 2016 Google Inc. 3f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas * 4f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas * Use of this source code is governed by a BSD-style license that can be 5f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas * found in the LICENSE file. 6f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas */ 7941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas 8f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#ifndef SKSL_GLSLCODEGENERATOR 9f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#define SKSL_GLSLCODEGENERATOR 10f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 11f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include <stack> 12f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include <tuple> 13f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include <unordered_map> 14f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 15f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "SkSLCodeGenerator.h" 16762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas#include "SkSLStringStream.h" 17f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLBinaryExpression.h" 18f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLBoolLiteral.h" 19f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLConstructor.h" 20f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLDoStatement.h" 21f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLExtension.h" 22f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLFloatLiteral.h" 23f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLIfStatement.h" 24f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLIndexExpression.h" 25f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLInterfaceBlock.h" 26f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLIntLiteral.h" 27f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLFieldAccess.h" 28f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLForStatement.h" 29f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLFunctionCall.h" 30f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLFunctionDeclaration.h" 31f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLFunctionDefinition.h" 32f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLPrefixExpression.h" 33f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLPostfixExpression.h" 34f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLProgramElement.h" 35f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLReturnStatement.h" 36762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas#include "ir/SkSLSetting.h" 37f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLStatement.h" 38af19769831f1c4c3b90c85aa9f8851cd8bbf86d5Ethan Nicholas#include "ir/SkSLSwitchStatement.h" 39f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLSwizzle.h" 40f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLTernaryExpression.h" 4122f939e849013b7fc51374c289b5bf37e63dfdb1ethannicholas#include "ir/SkSLVarDeclarations.h" 4222f939e849013b7fc51374c289b5bf37e63dfdb1ethannicholas#include "ir/SkSLVarDeclarationsStatement.h" 43f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLVariableReference.h" 44f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#include "ir/SkSLWhileStatement.h" 45f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 46f789b3893579b773bb4d7be6c2c65311500b53bbethannicholasnamespace SkSL { 47f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 48f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#define kLast_Capability SpvCapabilityMultiViewport 49f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 50f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas/** 51f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas * Converts a Program into GLSL code. 52f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas */ 53f789b3893579b773bb4d7be6c2c65311500b53bbethannicholasclass GLSLCodeGenerator : public CodeGenerator { 54f789b3893579b773bb4d7be6c2c65311500b53bbethannicholaspublic: 55f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas enum Precedence { 56f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kParentheses_Precedence = 1, 57f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kPostfix_Precedence = 2, 58f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kPrefix_Precedence = 3, 59f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kMultiplicative_Precedence = 4, 60f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kAdditive_Precedence = 5, 61f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kShift_Precedence = 6, 62f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kRelational_Precedence = 7, 63f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kEquality_Precedence = 8, 64f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kBitwiseAnd_Precedence = 9, 65f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kBitwiseXor_Precedence = 10, 66f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kBitwiseOr_Precedence = 11, 67f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kLogicalAnd_Precedence = 12, 68f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kLogicalXor_Precedence = 13, 69f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kLogicalOr_Precedence = 14, 70f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kTernary_Precedence = 15, 71f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kAssignment_Precedence = 16, 72f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas kSequence_Precedence = 17, 734b330dfd3334bf24bf93043acfcd31590a3cdbbfEthan Nicholas kTopLevel_Precedence = kSequence_Precedence 74f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas }; 75f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 76941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas GLSLCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors, 770df1b04db87c3d86ee0b0bd6aa2cb5b6be32cac2Ethan Nicholas OutputStream* out) 78941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas : INHERITED(program, errors, out) 79762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas , fLineEnding("\n") 80941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas , fContext(*context) {} 81f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 82762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas bool generateCode() override; 83f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 84762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholasprotected: 85f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void write(const char* s); 86f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 87f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeLine(); 88f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 89f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeLine(const char* s); 90f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 910df1b04db87c3d86ee0b0bd6aa2cb5b6be32cac2Ethan Nicholas void write(const String& s); 92f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 935b5f096a038259b8d9084834f877588a0db80250Ethan Nicholas void write(StringFragment s); 945b5f096a038259b8d9084834f877588a0db80250Ethan Nicholas 950df1b04db87c3d86ee0b0bd6aa2cb5b6be32cac2Ethan Nicholas void writeLine(const String& s); 96f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 97762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas virtual void writeHeader(); 98762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas 99f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas virtual bool usesPrecisionModifiers() const; 100762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas 101f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas virtual String getTypeName(const Type& type); 102f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas 103f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas void writeType(const Type& type); 104f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 105f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeExtension(const Extension& ext); 106f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 107f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeInterfaceBlock(const InterfaceBlock& intf); 108f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 109f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeFunctionStart(const FunctionDeclaration& f); 1100df1b04db87c3d86ee0b0bd6aa2cb5b6be32cac2Ethan Nicholas 111f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeFunctionDeclaration(const FunctionDeclaration& f); 112f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 113762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas virtual void writeFunction(const FunctionDefinition& f); 114f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 115f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeLayout(const Layout& layout); 116f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 1175961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas void writeModifiers(const Modifiers& modifiers, bool globalContext); 118941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas 11982a62d2d4ef55e53730a4f194a82d4e5da0c4a64Ethan Nicholas void writeGlobalVars(const VarDeclaration& vs); 12082a62d2d4ef55e53730a4f194a82d4e5da0c4a64Ethan Nicholas 121762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas virtual void writeVarInitializer(const Variable& var, const Expression& value); 122762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas 123f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas const char* getTypePrecision(const Type& type); 124f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas 125dcba08e891f1766b047cf0dbe8bbd275d9f55d2bEthan Nicholas void writeTypePrecision(const Type& type); 126dcba08e891f1766b047cf0dbe8bbd275d9f55d2bEthan Nicholas 1275961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas void writeVarDeclarations(const VarDeclarations& decl, bool global); 128f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 129941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas void writeFragCoord(); 130941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas 131762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas virtual void writeVariableReference(const VariableReference& ref); 132f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 133f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeExpression(const Expression& expr, Precedence parentPrecedence); 134941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas 135f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeIntrinsicCall(const FunctionCall& c); 136f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 1375961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas void writeMinAbsHack(Expression& absExpr, Expression& otherExpr); 1385961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas 1396e6525c930b683e6dcd5551bd7a3b68ecc68e45eEthan Nicholas void writeDeterminantHack(const Expression& mat); 1406e6525c930b683e6dcd5551bd7a3b68ecc68e45eEthan Nicholas 1416e6525c930b683e6dcd5551bd7a3b68ecc68e45eEthan Nicholas void writeInverseHack(const Expression& mat); 1426e6525c930b683e6dcd5551bd7a3b68ecc68e45eEthan Nicholas 1436e6525c930b683e6dcd5551bd7a3b68ecc68e45eEthan Nicholas void writeTransposeHack(const Expression& mat); 1446e6525c930b683e6dcd5551bd7a3b68ecc68e45eEthan Nicholas 1456e6525c930b683e6dcd5551bd7a3b68ecc68e45eEthan Nicholas void writeInverseSqrtHack(const Expression& x); 1466e6525c930b683e6dcd5551bd7a3b68ecc68e45eEthan Nicholas 147ceb4d48ef4839aab9d99d0200dcfe403ccd0cdf3Ethan Nicholas virtual void writeFunctionCall(const FunctionCall& c); 148f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 149f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas void writeConstructor(const Constructor& c, Precedence parentPrecedence); 150f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 151f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeFieldAccess(const FieldAccess& f); 152f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 153823994624aa5e805e16833ecd3d748fc769a164dEthan Nicholas virtual void writeSwizzle(const Swizzle& swizzle); 154f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 155762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas static Precedence GetBinaryPrecedence(Token::Kind op); 156762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas 157762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas virtual void writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence); 158f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 159f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeTernaryExpression(const TernaryExpression& t, Precedence parentPrecedence); 160f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 161762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas virtual void writeIndexExpression(const IndexExpression& expr); 162f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 163f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writePrefixExpression(const PrefixExpression& p, Precedence parentPrecedence); 164f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 165f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writePostfixExpression(const PostfixExpression& p, Precedence parentPrecedence); 166f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 167f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeBoolLiteral(const BoolLiteral& b); 168f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 169dcba08e891f1766b047cf0dbe8bbd275d9f55d2bEthan Nicholas virtual void writeIntLiteral(const IntLiteral& i); 170f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 171f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeFloatLiteral(const FloatLiteral& f); 172f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 173762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas virtual void writeSetting(const Setting& s); 174762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas 175f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeStatement(const Statement& s); 176f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 177cb67096b61f699b047fe8635984db1ac708a7b99Ethan Nicholas void writeStatements(const std::vector<std::unique_ptr<Statement>>& statements); 178cb67096b61f699b047fe8635984db1ac708a7b99Ethan Nicholas 179f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeBlock(const Block& b); 180f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 1816e1cbc012b10e99d9caed19eef43939778d1d8ffEthan Nicholas virtual void writeIfStatement(const IfStatement& stmt); 182f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 183f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeForStatement(const ForStatement& f); 184f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 185f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeWhileStatement(const WhileStatement& w); 186f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 187f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeDoStatement(const DoStatement& d); 188f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 1896e1cbc012b10e99d9caed19eef43939778d1d8ffEthan Nicholas virtual void writeSwitchStatement(const SwitchStatement& s); 190af19769831f1c4c3b90c85aa9f8851cd8bbf86d5Ethan Nicholas 191f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas void writeReturnStatement(const ReturnStatement& r); 192f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 193762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas virtual void writeProgramElement(const ProgramElement& e); 194762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas 195762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas const char* fLineEnding; 196f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas const Context& fContext; 1970df1b04db87c3d86ee0b0bd6aa2cb5b6be32cac2Ethan Nicholas StringStream fHeader; 1986e6525c930b683e6dcd5551bd7a3b68ecc68e45eEthan Nicholas StringStream fExtraFunctions; 1990df1b04db87c3d86ee0b0bd6aa2cb5b6be32cac2Ethan Nicholas String fFunctionHeader; 2005961bc9278a00e56dacdd9408d0744b5a0a3b493ethannicholas Program::Kind fProgramKind; 201ddb37d67ba4db42fa5c6012b58d0f4985b454dc0ethannicholas int fVarCount = 0; 202ddb37d67ba4db42fa5c6012b58d0f4985b454dc0ethannicholas int fIndentation = 0; 203ddb37d67ba4db42fa5c6012b58d0f4985b454dc0ethannicholas bool fAtLineStart = false; 204941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas // Keeps track of which struct types we have written. Given that we are unlikely to ever write 205941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas // more than one or two structs per shader, a simple linear search will be faster than anything 206f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas // fancier. 207f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas std::vector<const Type*> fWrittenStructs; 2086e6525c930b683e6dcd5551bd7a3b68ecc68e45eEthan Nicholas std::set<String> fWrittenIntrinsics; 209ddb37d67ba4db42fa5c6012b58d0f4985b454dc0ethannicholas // true if we have run into usages of dFdx / dFdy 210ddb37d67ba4db42fa5c6012b58d0f4985b454dc0ethannicholas bool fFoundDerivatives = false; 2112a51de82ceb6790f329b9f4cc85e61f34fc2d0d4Brian Salomon bool fFoundImageDecl = false; 212f1b47bb299e72456d70cf3eae8086a5e01766c67Chris Dalton bool fFoundGSInvocations = false; 213941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas bool fSetupFragPositionGlobal = false; 214941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas bool fSetupFragPositionLocal = false; 215dba65f95e40fb1a4ea936b453b9bcb3fdbe178e1Brian Salomon bool fSetupFragCoordWorkaround = false; 216941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas 217941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9Ethan Nicholas typedef CodeGenerator INHERITED; 218f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas}; 219f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 220f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas} 221f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas 222f789b3893579b773bb4d7be6c2c65311500b53bbethannicholas#endif 223