• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SKSL_GLSLCODEGENERATOR
9 #define SKSL_GLSLCODEGENERATOR
10 
11 #include <stack>
12 #include <tuple>
13 #include <unordered_map>
14 
15 #include "src/sksl/SkSLCodeGenerator.h"
16 #include "src/sksl/SkSLStringStream.h"
17 #include "src/sksl/ir/SkSLBinaryExpression.h"
18 #include "src/sksl/ir/SkSLBoolLiteral.h"
19 #include "src/sksl/ir/SkSLConstructor.h"
20 #include "src/sksl/ir/SkSLDoStatement.h"
21 #include "src/sksl/ir/SkSLExtension.h"
22 #include "src/sksl/ir/SkSLFieldAccess.h"
23 #include "src/sksl/ir/SkSLFloatLiteral.h"
24 #include "src/sksl/ir/SkSLForStatement.h"
25 #include "src/sksl/ir/SkSLFunctionCall.h"
26 #include "src/sksl/ir/SkSLFunctionDeclaration.h"
27 #include "src/sksl/ir/SkSLFunctionDefinition.h"
28 #include "src/sksl/ir/SkSLIfStatement.h"
29 #include "src/sksl/ir/SkSLIndexExpression.h"
30 #include "src/sksl/ir/SkSLIntLiteral.h"
31 #include "src/sksl/ir/SkSLInterfaceBlock.h"
32 #include "src/sksl/ir/SkSLPostfixExpression.h"
33 #include "src/sksl/ir/SkSLPrefixExpression.h"
34 #include "src/sksl/ir/SkSLProgramElement.h"
35 #include "src/sksl/ir/SkSLReturnStatement.h"
36 #include "src/sksl/ir/SkSLSetting.h"
37 #include "src/sksl/ir/SkSLStatement.h"
38 #include "src/sksl/ir/SkSLSwitchStatement.h"
39 #include "src/sksl/ir/SkSLSwizzle.h"
40 #include "src/sksl/ir/SkSLTernaryExpression.h"
41 #include "src/sksl/ir/SkSLVarDeclarations.h"
42 #include "src/sksl/ir/SkSLVarDeclarationsStatement.h"
43 #include "src/sksl/ir/SkSLVariableReference.h"
44 #include "src/sksl/ir/SkSLWhileStatement.h"
45 
46 namespace SkSL {
47 
48 #define kLast_Capability SpvCapabilityMultiViewport
49 
50 /**
51  * Converts a Program into GLSL code.
52  */
53 class GLSLCodeGenerator : public CodeGenerator {
54 public:
55     enum Precedence {
56         kParentheses_Precedence    =  1,
57         kPostfix_Precedence        =  2,
58         kPrefix_Precedence         =  3,
59         kMultiplicative_Precedence =  4,
60         kAdditive_Precedence       =  5,
61         kShift_Precedence          =  6,
62         kRelational_Precedence     =  7,
63         kEquality_Precedence       =  8,
64         kBitwiseAnd_Precedence     =  9,
65         kBitwiseXor_Precedence     = 10,
66         kBitwiseOr_Precedence      = 11,
67         kLogicalAnd_Precedence     = 12,
68         kLogicalXor_Precedence     = 13,
69         kLogicalOr_Precedence      = 14,
70         kTernary_Precedence        = 15,
71         kAssignment_Precedence     = 16,
72         kSequence_Precedence       = 17,
73         kTopLevel_Precedence       = kSequence_Precedence
74     };
75 
GLSLCodeGenerator(const Context * context,const Program * program,ErrorReporter * errors,OutputStream * out)76     GLSLCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors,
77                       OutputStream* out)
78     : INHERITED(program, errors, out)
79     , fLineEnding("\n")
80     , fContext(*context)
81     , fProgramKind(program->fKind) {}
82 
83     bool generateCode() override;
84 
85 protected:
86     void write(const char* s);
87 
88     void writeLine();
89 
90     void writeLine(const char* s);
91 
92     void write(const String& s);
93 
94     void write(StringFragment s);
95 
96     void writeLine(const String& s);
97 
98     virtual void writeHeader();
99 
100     virtual bool usesPrecisionModifiers() const;
101 
102     virtual String getTypeName(const Type& type);
103 
104     void writeType(const Type& type);
105 
106     void writeExtension(const String& name);
107 
108     void writeExtension(const String& name, bool require);
109 
110     void writeInterfaceBlock(const InterfaceBlock& intf);
111 
112     void writeFunctionStart(const FunctionDeclaration& f);
113 
114     void writeFunctionDeclaration(const FunctionDeclaration& f);
115 
116     virtual void writeFunction(const FunctionDefinition& f);
117 
118     void writeLayout(const Layout& layout);
119 
120     void writeModifiers(const Modifiers& modifiers, bool globalContext);
121 
122     virtual void writeInputVars();
123 
124     virtual void writeVarInitializer(const Variable& var, const Expression& value);
125 
126     const char* getTypePrecision(const Type& type);
127 
128     void writeTypePrecision(const Type& type);
129 
130     void writeVarDeclarations(const VarDeclarations& decl, bool global);
131 
132     void writeFragCoord();
133 
134     virtual void writeVariableReference(const VariableReference& ref);
135 
136     void writeExpression(const Expression& expr, Precedence parentPrecedence);
137 
138     void writeIntrinsicCall(const FunctionCall& c);
139 
140     void writeMinAbsHack(Expression& absExpr, Expression& otherExpr);
141 
142     void writeDeterminantHack(const Expression& mat);
143 
144     void writeInverseHack(const Expression& mat);
145 
146     void writeTransposeHack(const Expression& mat);
147 
148     void writeInverseSqrtHack(const Expression& x);
149 
150     virtual void writeFunctionCall(const FunctionCall& c);
151 
152     void writeConstructor(const Constructor& c, Precedence parentPrecedence);
153 
154     virtual void writeFieldAccess(const FieldAccess& f);
155 
156     virtual void writeSwizzle(const Swizzle& swizzle);
157 
158     static Precedence GetBinaryPrecedence(Token::Kind op);
159 
160     virtual void writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence);
161     void writeShortCircuitWorkaroundExpression(const BinaryExpression& b,
162                                                Precedence parentPrecedence);
163 
164     void writeTernaryExpression(const TernaryExpression& t, Precedence parentPrecedence);
165 
166     virtual void writeIndexExpression(const IndexExpression& expr);
167 
168     void writePrefixExpression(const PrefixExpression& p, Precedence parentPrecedence);
169 
170     void writePostfixExpression(const PostfixExpression& p, Precedence parentPrecedence);
171 
172     void writeBoolLiteral(const BoolLiteral& b);
173 
174     virtual void writeIntLiteral(const IntLiteral& i);
175 
176     void writeFloatLiteral(const FloatLiteral& f);
177 
178     virtual void writeSetting(const Setting& s);
179 
180     void writeStatement(const Statement& s);
181 
182     void writeStatements(const std::vector<std::unique_ptr<Statement>>& statements);
183 
184     void writeBlock(const Block& b);
185 
186     virtual void writeIfStatement(const IfStatement& stmt);
187 
188     void writeForStatement(const ForStatement& f);
189 
190     void writeWhileStatement(const WhileStatement& w);
191 
192     void writeDoStatement(const DoStatement& d);
193 
194     virtual void writeSwitchStatement(const SwitchStatement& s);
195 
196     virtual void writeReturnStatement(const ReturnStatement& r);
197 
198     virtual void writeProgramElement(const ProgramElement& e);
199 
200     const char* fLineEnding;
201     const Context& fContext;
202     StringStream fExtensions;
203     StringStream fGlobals;
204     StringStream fExtraFunctions;
205     String fFunctionHeader;
206     Program::Kind fProgramKind;
207     int fVarCount = 0;
208     int fIndentation = 0;
209     bool fAtLineStart = false;
210     // Keeps track of which struct types we have written. Given that we are unlikely to ever write
211     // more than one or two structs per shader, a simple linear search will be faster than anything
212     // fancier.
213     std::vector<const Type*> fWrittenStructs;
214     std::set<String> fWrittenIntrinsics;
215     // true if we have run into usages of dFdx / dFdy
216     bool fFoundDerivatives = false;
217     bool fFoundExternalSamplerDecl = false;
218     bool fFoundRectSamplerDecl = false;
219     bool fFoundGSInvocations = false;
220     bool fSetupFragPositionGlobal = false;
221     bool fSetupFragPositionLocal = false;
222     bool fSetupFragCoordWorkaround = false;
223     // if non-empty, replace all texture / texture2D / textureProj / etc. calls with this name
224     String fTextureFunctionOverride;
225 
226     // We map function names to function class so we can quickly deal with function calls that need
227     // extra processing
228     enum class FunctionClass {
229         kAbs,
230         kAtan,
231         kDeterminant,
232         kDFdx,
233         kDFdy,
234         kFwidth,
235         kFMA,
236         kFract,
237         kInverse,
238         kInverseSqrt,
239         kMin,
240         kPow,
241         kSaturate,
242         kTexture,
243         kTranspose
244     };
245     static std::unordered_map<StringFragment, FunctionClass>* fFunctionClasses;
246 
247     typedef CodeGenerator INHERITED;
248 };
249 
250 }
251 
252 #endif
253