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
46namespace SkSL {
47
48#define kLast_Capability SpvCapabilityMultiViewport
49
50/**
51 * Converts a Program into GLSL code.
52 */
53class GLSLCodeGenerator : public CodeGenerator {
54public:
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
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
85protected:
86 enum class SwizzleOrder {
87 MASK_FIRST,
88 CONSTANTS_FIRST
89 };
90
91 void write(const char* s);
92
93 void writeLine();
94
95 void writeLine(const char* s);
96
97 void write(const String& s);
98
99 void write(StringFragment s);
100
101 void writeLine(const String& s);
102
103 virtual void writeHeader();
104
105 virtual bool usesPrecisionModifiers() const;
106
107 virtual String getTypeName(const Type& type);
108
109 void writeType(const Type& type);
110
111 void writeExtension(const String& name);
112
113 void writeExtension(const String& name, bool require);
114
115 void writeInterfaceBlock(const InterfaceBlock& intf);
116
117 void writeFunctionStart(const FunctionDeclaration& f);
118
119 void writeFunctionDeclaration(const FunctionDeclaration& f);
120
121 virtual void writeFunction(const FunctionDefinition& f);
122
123 void writeLayout(const Layout& layout);
124
125 void writeModifiers(const Modifiers& modifiers, bool globalContext);
126
127 virtual void writeInputVars();
128
129 virtual void writeVarInitializer(const Variable& var, const Expression& value);
130
131 const char* getTypePrecision(const Type& type);
132
133 void writeTypePrecision(const Type& type);
134
135 void writeVarDeclarations(const VarDeclarations& decl, bool global);
136
137 void writeFragCoord();
138
139 virtual void writeVariableReference(const VariableReference& ref);
140
141 void writeExpression(const Expression& expr, Precedence parentPrecedence);
142
143 void writeIntrinsicCall(const FunctionCall& c);
144
145 void writeMinAbsHack(Expression& absExpr, Expression& otherExpr);
146
147 void writeDeterminantHack(const Expression& mat);
148
149 void writeInverseHack(const Expression& mat);
150
151 void writeTransposeHack(const Expression& mat);
152
153 void writeInverseSqrtHack(const Expression& x);
154
155 virtual void writeFunctionCall(const FunctionCall& c);
156
157 void writeConstructor(const Constructor& c, Precedence parentPrecedence);
158
159 virtual void writeFieldAccess(const FieldAccess& f);
160
161 void writeConstantSwizzle(const Swizzle& swizzle, const String& constants);
162
163 void writeSwizzleMask(const Swizzle& swizzle, const String& mask);
164
165 void writeSwizzleConstructor(const Swizzle& swizzle, const String& constants,
166 const String& mask, SwizzleOrder order);
167
168 void writeSwizzleConstructor(const Swizzle& swizzle, const String& constants,
169 const String& mask, const String& reswizzle);
170 virtual void writeSwizzle(const Swizzle& swizzle);
171
172 static Precedence GetBinaryPrecedence(Token::Kind op);
173
174 virtual void writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence);
175 void writeShortCircuitWorkaroundExpression(const BinaryExpression& b,
176 Precedence parentPrecedence);
177
178 void writeTernaryExpression(const TernaryExpression& t, Precedence parentPrecedence);
179
180 virtual void writeIndexExpression(const IndexExpression& expr);
181
182 void writePrefixExpression(const PrefixExpression& p, Precedence parentPrecedence);
183
184 void writePostfixExpression(const PostfixExpression& p, Precedence parentPrecedence);
185
186 void writeBoolLiteral(const BoolLiteral& b);
187
188 virtual void writeIntLiteral(const IntLiteral& i);
189
190 void writeFloatLiteral(const FloatLiteral& f);
191
192 virtual void writeSetting(const Setting& s);
193
194 void writeStatement(const Statement& s);
195
196 void writeStatements(const std::vector<std::unique_ptr<Statement>>& statements);
197
198 void writeBlock(const Block& b);
199
200 virtual void writeIfStatement(const IfStatement& stmt);
201
202 void writeForStatement(const ForStatement& f);
203
204 void writeWhileStatement(const WhileStatement& w);
205
206 void writeDoStatement(const DoStatement& d);
207
208 virtual void writeSwitchStatement(const SwitchStatement& s);
209
210 virtual void writeReturnStatement(const ReturnStatement& r);
211
212 virtual void writeProgramElement(const ProgramElement& e);
213
214 const char* fLineEnding;
215 const Context& fContext;
216 StringStream fExtensions;
217 StringStream fGlobals;
218 StringStream fExtraFunctions;
219 String fFunctionHeader;
220 Program::Kind fProgramKind;
221 int fVarCount = 0;
222 int fIndentation = 0;
223 bool fAtLineStart = false;
224 // Keeps track of which struct types we have written. Given that we are unlikely to ever write
225 // more than one or two structs per shader, a simple linear search will be faster than anything
226 // fancier.
227 std::vector<const Type*> fWrittenStructs;
228 std::set<String> fWrittenIntrinsics;
229 // true if we have run into usages of dFdx / dFdy
230 bool fFoundDerivatives = false;
231 bool fFoundExternalSamplerDecl = false;
232 bool fFoundRectSamplerDecl = false;
233 bool fFoundGSInvocations = false;
234 bool fSetupFragPositionGlobal = false;
235 bool fSetupFragPositionLocal = false;
236 bool fSetupFragCoordWorkaround = false;
237 // if non-empty, replace all texture / texture2D / textureProj / etc. calls with this name
238 String fTextureFunctionOverride;
239
240 // We map function names to function class so we can quickly deal with function calls that need
241 // extra processing
242 enum class FunctionClass {
243 kAbs,
244 kAtan,
245 kDeterminant,
246 kDFdx,
247 kDFdy,
248 kFwidth,
249 kFMA,
250 kFract,
251 kInverse,
252 kInverseSqrt,
253 kMin,
254 kPow,
255 kSaturate,
256 kTexture,
257 kTranspose
258 };
259 static std::unordered_map<StringFragment, FunctionClass>* fFunctionClasses;
260
261 typedef CodeGenerator INHERITED;
262};
263
264}
265
266#endif
267