• 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_COMPILER
9 #define SKSL_COMPILER
10 
11 #include <set>
12 #include <unordered_set>
13 #include <vector>
14 #include "ir/SkSLProgram.h"
15 #include "ir/SkSLSymbolTable.h"
16 #include "SkSLCFGGenerator.h"
17 #include "SkSLContext.h"
18 #include "SkSLErrorReporter.h"
19 #include "SkSLLexer.h"
20 
21 #define SK_FRAGCOLOR_BUILTIN           10001
22 #define SK_IN_BUILTIN                  10002
23 #define SK_INCOLOR_BUILTIN             10003
24 #define SK_OUTCOLOR_BUILTIN            10004
25 #define SK_TRANSFORMEDCOORDS2D_BUILTIN 10005
26 #define SK_TEXTURESAMPLERS_BUILTIN     10006
27 #define SK_OUT_BUILTIN                 10007
28 #define SK_LASTFRAGCOLOR_BUILTIN       10008
29 #define SK_MAIN_X_BUILTIN              10009
30 #define SK_MAIN_Y_BUILTIN              10010
31 #define SK_WIDTH_BUILTIN               10011
32 #define SK_HEIGHT_BUILTIN              10012
33 #define SK_FRAGCOORD_BUILTIN              15
34 #define SK_CLOCKWISE_BUILTIN              17
35 #define SK_VERTEXID_BUILTIN               42
36 #define SK_INSTANCEID_BUILTIN             43
37 #define SK_CLIPDISTANCE_BUILTIN            3
38 #define SK_INVOCATIONID_BUILTIN            8
39 #define SK_POSITION_BUILTIN                0
40 
41 namespace SkSL {
42 
43 class IRGenerator;
44 
45 /**
46  * Main compiler entry point. This is a traditional compiler design which first parses the .sksl
47  * file into an abstract syntax tree (a tree of ASTNodes), then performs semantic analysis to
48  * produce a Program (a tree of IRNodes), then feeds the Program into a CodeGenerator to produce
49  * compiled output.
50  *
51  * See the README for information about SkSL.
52  */
53 class Compiler : public ErrorReporter {
54 public:
55     static constexpr const char* RTADJUST_NAME  = "sk_RTAdjust";
56     static constexpr const char* PERVERTEX_NAME = "sk_PerVertex";
57 
58     enum Flags {
59         kNone_Flags = 0,
60         // permits static if/switch statements to be used with non-constant tests. This is used when
61         // producing H and CPP code; the static tests don't have to have constant values *yet*, but
62         // the generated code will contain a static test which then does have to be a constant.
63         kPermitInvalidStaticTests_Flag = 1,
64     };
65 
66     struct FormatArg {
67         enum class Kind {
68             kInput,
69             kOutput,
70             kUniform,
71             kChildProcessor
72         };
73 
FormatArgFormatArg74         FormatArg(Kind kind)
75                 : fKind(kind) {}
76 
FormatArgFormatArg77         FormatArg(Kind kind, int index)
78                 : fKind(kind)
79                 , fIndex(index) {}
80 
81         Kind fKind;
82 
83         int fIndex;
84     };
85 
86     Compiler(Flags flags = kNone_Flags);
87 
88     ~Compiler() override;
89 
90     std::unique_ptr<Program> convertProgram(Program::Kind kind, String text,
91                                             const Program::Settings& settings);
92 
93     bool optimize(Program& program);
94 
95     std::unique_ptr<Program> specialize(Program& program,
96                     const std::unordered_map<SkSL::String, SkSL::Program::Settings::Value>& inputs);
97 
98     bool toSPIRV(Program& program, OutputStream& out);
99 
100     bool toSPIRV(Program& program, String* out);
101 
102     bool toGLSL(Program& program, OutputStream& out);
103 
104     bool toGLSL(Program& program, String* out);
105 
106     bool toMetal(Program& program, OutputStream& out);
107 
108     bool toMetal(Program& program, String* out);
109 
110     bool toCPP(Program& program, String name, OutputStream& out);
111 
112     bool toH(Program& program, String name, OutputStream& out);
113 
114     bool toPipelineStage(const Program& program, String* out,
115                          std::vector<FormatArg>* outFormatArgs);
116 
117     void error(int offset, String msg) override;
118 
119     String errorText();
120 
121     void writeErrorCount();
122 
errorCount()123     int errorCount() override {
124         return fErrorCount;
125     }
126 
context()127     Context& context() {
128         return *fContext;
129     }
130 
131     static const char* OperatorName(Token::Kind token);
132 
133     static bool IsAssignment(Token::Kind token);
134 
135 private:
136     void addDefinition(const Expression* lvalue, std::unique_ptr<Expression>* expr,
137                        DefinitionMap* definitions);
138 
139     void addDefinitions(const BasicBlock::Node& node, DefinitionMap* definitions);
140 
141     void scanCFG(CFG* cfg, BlockId block, std::set<BlockId>* workList);
142 
143     void computeDataFlow(CFG* cfg);
144 
145     /**
146      * Simplifies the expression pointed to by iter (in both the IR and CFG structures), if
147      * possible.
148      */
149     void simplifyExpression(DefinitionMap& definitions,
150                             BasicBlock& b,
151                             std::vector<BasicBlock::Node>::iterator* iter,
152                             std::unordered_set<const Variable*>* undefinedVariables,
153                             bool* outUpdated,
154                             bool* outNeedsRescan);
155 
156     /**
157      * Simplifies the statement pointed to by iter (in both the IR and CFG structures), if
158      * possible.
159      */
160     void simplifyStatement(DefinitionMap& definitions,
161                            BasicBlock& b,
162                            std::vector<BasicBlock::Node>::iterator* iter,
163                            std::unordered_set<const Variable*>* undefinedVariables,
164                            bool* outUpdated,
165                            bool* outNeedsRescan);
166 
167     void scanCFG(FunctionDefinition& f);
168 
169     Position position(int offset);
170 
171     std::vector<std::unique_ptr<ProgramElement>> fVertexInclude;
172     std::shared_ptr<SymbolTable> fVertexSymbolTable;
173     std::vector<std::unique_ptr<ProgramElement>> fFragmentInclude;
174     std::shared_ptr<SymbolTable> fFragmentSymbolTable;
175     std::vector<std::unique_ptr<ProgramElement>> fGeometryInclude;
176     std::shared_ptr<SymbolTable> fGeometrySymbolTable;
177 
178     std::shared_ptr<SymbolTable> fTypes;
179     IRGenerator* fIRGenerator;
180     int fFlags;
181 
182     const String* fSource;
183     std::shared_ptr<Context> fContext;
184     int fErrorCount;
185     String fErrorText;
186 };
187 
188 } // namespace
189 
190 #endif
191