blob: 985112370822eceb67eaea7fd2178d53798a4ce7 [file] [log] [blame]
ethannicholasf789b382016-08-03 12:43:36 -07001/*
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 "SkSLCodeGenerator.h"
16#include "ir/SkSLBinaryExpression.h"
17#include "ir/SkSLBoolLiteral.h"
18#include "ir/SkSLConstructor.h"
19#include "ir/SkSLDoStatement.h"
20#include "ir/SkSLExtension.h"
21#include "ir/SkSLFloatLiteral.h"
22#include "ir/SkSLIfStatement.h"
23#include "ir/SkSLIndexExpression.h"
24#include "ir/SkSLInterfaceBlock.h"
25#include "ir/SkSLIntLiteral.h"
26#include "ir/SkSLFieldAccess.h"
27#include "ir/SkSLForStatement.h"
28#include "ir/SkSLFunctionCall.h"
29#include "ir/SkSLFunctionDeclaration.h"
30#include "ir/SkSLFunctionDefinition.h"
31#include "ir/SkSLPrefixExpression.h"
32#include "ir/SkSLPostfixExpression.h"
33#include "ir/SkSLProgramElement.h"
34#include "ir/SkSLReturnStatement.h"
35#include "ir/SkSLStatement.h"
36#include "ir/SkSLSwizzle.h"
37#include "ir/SkSLTernaryExpression.h"
38#include "ir/SkSLVarDeclaration.h"
39#include "ir/SkSLVarDeclarationStatement.h"
40#include "ir/SkSLVariableReference.h"
41#include "ir/SkSLWhileStatement.h"
42
43namespace SkSL {
44
45#define kLast_Capability SpvCapabilityMultiViewport
46
47struct GLCaps {
48 int fVersion;
49 enum {
50 kGL_Standard,
51 kGLES_Standard
52 } fStandard;
ethannicholasdcfe6db2016-10-10 10:09:00 -070053 bool fIsCoreProfile;
54 bool fUsesPrecisionModifiers;
55 bool fMustDeclareFragmentShaderOutput;
56 // The Tegra3 compiler will sometimes never return if we have min(abs(x), y)
57 bool fCanUseMinAndAbsTogether;
ethannicholasf789b382016-08-03 12:43:36 -070058};
59
60/**
61 * Converts a Program into GLSL code.
62 */
63class GLSLCodeGenerator : public CodeGenerator {
64public:
65 enum Precedence {
66 kParentheses_Precedence = 1,
67 kPostfix_Precedence = 2,
68 kPrefix_Precedence = 3,
69 kMultiplicative_Precedence = 4,
70 kAdditive_Precedence = 5,
71 kShift_Precedence = 6,
72 kRelational_Precedence = 7,
73 kEquality_Precedence = 8,
74 kBitwiseAnd_Precedence = 9,
75 kBitwiseXor_Precedence = 10,
76 kBitwiseOr_Precedence = 11,
77 kLogicalAnd_Precedence = 12,
78 kLogicalXor_Precedence = 13,
79 kLogicalOr_Precedence = 14,
80 kTernary_Precedence = 15,
81 kAssignment_Precedence = 16,
82 kSequence_Precedence = 17,
83 kTopLevel_Precedence = 18
84 };
85
86 GLSLCodeGenerator(const Context* context, GLCaps caps)
87 : fContext(*context)
88 , fCaps(caps)
ethannicholasdcfe6db2016-10-10 10:09:00 -070089 , fOut(nullptr)
90 , fVarCount(0)
ethannicholasf789b382016-08-03 12:43:36 -070091 , fIndentation(0)
92 , fAtLineStart(true) {}
93
94 void generateCode(const Program& program, std::ostream& out) override;
95
96private:
97 void write(const char* s);
98
99 void writeLine();
100
101 void writeLine(const char* s);
102
103 void write(const std::string& s);
104
105 void writeLine(const std::string& s);
106
107 void writeType(const Type& type);
108
109 void writeExtension(const Extension& ext);
110
111 void writeInterfaceBlock(const InterfaceBlock& intf);
112
113 void writeFunctionStart(const FunctionDeclaration& f);
114
115 void writeFunctionDeclaration(const FunctionDeclaration& f);
116
117 void writeFunction(const FunctionDefinition& f);
118
119 void writeLayout(const Layout& layout);
120
ethannicholasdcfe6db2016-10-10 10:09:00 -0700121 void writeModifiers(const Modifiers& modifiers, bool globalContext);
ethannicholasf789b382016-08-03 12:43:36 -0700122
123 void writeGlobalVars(const VarDeclaration& vs);
124
ethannicholasdcfe6db2016-10-10 10:09:00 -0700125 void writeVarDeclarations(const VarDeclarations& decl, bool global);
ethannicholasf789b382016-08-03 12:43:36 -0700126
127 void writeVariableReference(const VariableReference& ref);
128
129 void writeExpression(const Expression& expr, Precedence parentPrecedence);
130
131 void writeIntrinsicCall(const FunctionCall& c);
132
ethannicholasdcfe6db2016-10-10 10:09:00 -0700133 void writeMinAbsHack(Expression& absExpr, Expression& otherExpr);
134
ethannicholasf789b382016-08-03 12:43:36 -0700135 void writeFunctionCall(const FunctionCall& c);
136
137 void writeConstructor(const Constructor& c);
138
139 void writeFieldAccess(const FieldAccess& f);
140
141 void writeSwizzle(const Swizzle& swizzle);
142
143 void writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence);
144
145 void writeTernaryExpression(const TernaryExpression& t, Precedence parentPrecedence);
146
147 void writeIndexExpression(const IndexExpression& expr);
148
149 void writePrefixExpression(const PrefixExpression& p, Precedence parentPrecedence);
150
151 void writePostfixExpression(const PostfixExpression& p, Precedence parentPrecedence);
152
153 void writeBoolLiteral(const BoolLiteral& b);
154
155 void writeIntLiteral(const IntLiteral& i);
156
157 void writeFloatLiteral(const FloatLiteral& f);
158
159 void writeStatement(const Statement& s);
160
161 void writeBlock(const Block& b);
162
163 void writeIfStatement(const IfStatement& stmt);
164
165 void writeForStatement(const ForStatement& f);
166
167 void writeWhileStatement(const WhileStatement& w);
168
169 void writeDoStatement(const DoStatement& d);
170
171 void writeReturnStatement(const ReturnStatement& r);
172
173 const Context& fContext;
174 const GLCaps fCaps;
175 std::ostream* fOut;
ethannicholasdcfe6db2016-10-10 10:09:00 -0700176 std::string fFunctionHeader;
177 Program::Kind fProgramKind;
178 int fVarCount;
ethannicholasf789b382016-08-03 12:43:36 -0700179 int fIndentation;
180 bool fAtLineStart;
181 // Keeps track of which struct types we have written. Given that we are unlikely to ever write
182 // more than one or two structs per shader, a simple linear search will be faster than anything
183 // fancier.
184 std::vector<const Type*> fWrittenStructs;
185};
186
187}
188
189#endif