• 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 <map>
12 #include <set>
13 #include <unordered_set>
14 #include <vector>
15 #include "src/sksl/SkSLASTFile.h"
16 #include "src/sksl/SkSLCFGGenerator.h"
17 #include "src/sksl/SkSLContext.h"
18 #include "src/sksl/SkSLErrorReporter.h"
19 #include "src/sksl/SkSLLexer.h"
20 #include "src/sksl/ir/SkSLProgram.h"
21 #include "src/sksl/ir/SkSLSymbolTable.h"
22 
23 #if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
24 #include "src/gpu/GrShaderVar.h"
25 #endif
26 
27 #define SK_FRAGCOLOR_BUILTIN           10001
28 #define SK_IN_BUILTIN                  10002
29 #define SK_INCOLOR_BUILTIN             10003
30 #define SK_OUTCOLOR_BUILTIN            10004
31 #define SK_TRANSFORMEDCOORDS2D_BUILTIN 10005
32 #define SK_TEXTURESAMPLERS_BUILTIN     10006
33 #define SK_OUT_BUILTIN                 10007
34 #define SK_LASTFRAGCOLOR_BUILTIN       10008
35 #define SK_MAIN_COORDS_BUILTIN         10009
36 #define SK_WIDTH_BUILTIN               10011
37 #define SK_HEIGHT_BUILTIN              10012
38 #define SK_FRAGCOORD_BUILTIN              15
39 #define SK_CLOCKWISE_BUILTIN              17
40 #define SK_SAMPLEMASK_BUILTIN             20
41 #define SK_VERTEXID_BUILTIN               42
42 #define SK_INSTANCEID_BUILTIN             43
43 #define SK_CLIPDISTANCE_BUILTIN            3
44 #define SK_INVOCATIONID_BUILTIN            8
45 #define SK_POSITION_BUILTIN                0
46 
47 namespace SkSL {
48 
49 class ByteCode;
50 class ExternalValue;
51 class IRGenerator;
52 struct PipelineStageArgs;
53 
54 /**
55  * Main compiler entry point. This is a traditional compiler design which first parses the .sksl
56  * file into an abstract syntax tree (a tree of ASTNodes), then performs semantic analysis to
57  * produce a Program (a tree of IRNodes), then feeds the Program into a CodeGenerator to produce
58  * compiled output.
59  *
60  * See the README for information about SkSL.
61  */
62 class SK_API Compiler : public ErrorReporter {
63 public:
64     static constexpr const char* RTADJUST_NAME  = "sk_RTAdjust";
65     static constexpr const char* PERVERTEX_NAME = "sk_PerVertex";
66 
67     enum Flags {
68         kNone_Flags = 0,
69         // permits static if/switch statements to be used with non-constant tests. This is used when
70         // producing H and CPP code; the static tests don't have to have constant values *yet*, but
71         // the generated code will contain a static test which then does have to be a constant.
72         kPermitInvalidStaticTests_Flag = 1,
73     };
74 
75     struct FormatArg {
76         enum class Kind {
77             kInput,
78             kOutput,
79             kCoords,
80             kUniform,
81             kChildProcessor,
82             kFunctionName
83         };
84 
FormatArgFormatArg85         FormatArg(Kind kind)
86                 : fKind(kind) {}
87 
FormatArgFormatArg88         FormatArg(Kind kind, int index)
89                 : fKind(kind)
90                 , fIndex(index) {}
91 
92         Kind fKind;
93         int fIndex;
94         String fCoords;
95     };
96 
97 #if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
98     /**
99      * Represents the arguments to GrGLSLShaderBuilder::emitFunction.
100      */
101     struct GLSLFunction {
102         GrSLType fReturnType;
103         SkString fName;
104         std::vector<GrShaderVar> fParameters;
105         SkString fBody;
106         std::vector<Compiler::FormatArg> fFormatArgs;
107     };
108 #endif
109 
110     Compiler(Flags flags = kNone_Flags);
111 
112     ~Compiler() override;
113 
114     Compiler(const Compiler&) = delete;
115     Compiler& operator=(const Compiler&) = delete;
116 
117     /**
118      * Registers an ExternalValue as a top-level symbol which is visible in the global namespace.
119      */
120     void registerExternalValue(ExternalValue* value);
121 
122     std::unique_ptr<Program> convertProgram(Program::Kind kind, String text,
123                                             const Program::Settings& settings);
124 
125     bool optimize(Program& program);
126 
127     std::unique_ptr<Program> specialize(Program& program,
128                     const std::unordered_map<SkSL::String, SkSL::Program::Settings::Value>& inputs);
129 
130     bool toSPIRV(Program& program, OutputStream& out);
131 
132     bool toSPIRV(Program& program, String* out);
133 
134     bool toGLSL(Program& program, OutputStream& out);
135 
136     bool toGLSL(Program& program, String* out);
137 
138     bool toHLSL(Program& program, String* out);
139 
140     bool toMetal(Program& program, OutputStream& out);
141 
142     bool toMetal(Program& program, String* out);
143 
144     bool toCPP(Program& program, String name, OutputStream& out);
145 
146     bool toH(Program& program, String name, OutputStream& out);
147 
148     std::unique_ptr<ByteCode> toByteCode(Program& program);
149 
150 #if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
151     bool toPipelineStage(const Program& program, PipelineStageArgs* outArgs);
152 #endif
153 
154     /**
155      * Takes ownership of the given symbol. It will be destroyed when the compiler is destroyed.
156      */
157     Symbol* takeOwnership(std::unique_ptr<Symbol> symbol);
158 
159     void error(int offset, String msg) override;
160 
161     String errorText();
162 
163     void writeErrorCount();
164 
errorCount()165     int errorCount() override {
166         return fErrorCount;
167     }
168 
context()169     Context& context() {
170         return *fContext;
171     }
172 
173     static const char* OperatorName(Token::Kind token);
174 
175     static bool IsAssignment(Token::Kind token);
176 
177 private:
178     void processIncludeFile(Program::Kind kind, const char* src, size_t length,
179                             std::shared_ptr<SymbolTable> base,
180                             std::vector<std::unique_ptr<ProgramElement>>* outElements,
181                             std::shared_ptr<SymbolTable>* outSymbolTable);
182 
183     void addDefinition(const Expression* lvalue, std::unique_ptr<Expression>* expr,
184                        DefinitionMap* definitions);
185 
186     void addDefinitions(const BasicBlock::Node& node, DefinitionMap* definitions);
187 
188     void scanCFG(CFG* cfg, BlockId block, std::set<BlockId>* workList);
189 
190     void computeDataFlow(CFG* cfg);
191 
192     /**
193      * Simplifies the expression pointed to by iter (in both the IR and CFG structures), if
194      * possible.
195      */
196     void simplifyExpression(DefinitionMap& definitions,
197                             BasicBlock& b,
198                             std::vector<BasicBlock::Node>::iterator* iter,
199                             std::unordered_set<const Variable*>* undefinedVariables,
200                             bool* outUpdated,
201                             bool* outNeedsRescan);
202 
203     /**
204      * Simplifies the statement pointed to by iter (in both the IR and CFG structures), if
205      * possible.
206      */
207     void simplifyStatement(DefinitionMap& definitions,
208                            BasicBlock& b,
209                            std::vector<BasicBlock::Node>::iterator* iter,
210                            std::unordered_set<const Variable*>* undefinedVariables,
211                            bool* outUpdated,
212                            bool* outNeedsRescan);
213 
214     void scanCFG(FunctionDefinition& f);
215 
216     Position position(int offset);
217 
218     std::map<String, std::pair<std::unique_ptr<ProgramElement>, bool>> fGPUIntrinsics;
219     std::map<String, std::pair<std::unique_ptr<ProgramElement>, bool>> fInterpreterIntrinsics;
220     std::unique_ptr<ASTFile> fGpuIncludeSource;
221     std::shared_ptr<SymbolTable> fGpuSymbolTable;
222     std::vector<std::unique_ptr<ProgramElement>> fVertexInclude;
223     std::shared_ptr<SymbolTable> fVertexSymbolTable;
224     std::vector<std::unique_ptr<ProgramElement>> fFragmentInclude;
225     std::shared_ptr<SymbolTable> fFragmentSymbolTable;
226     std::vector<std::unique_ptr<ProgramElement>> fGeometryInclude;
227     std::shared_ptr<SymbolTable> fGeometrySymbolTable;
228     std::vector<std::unique_ptr<ProgramElement>> fPipelineInclude;
229     std::shared_ptr<SymbolTable> fPipelineSymbolTable;
230     std::unique_ptr<ASTFile> fInterpreterIncludeSource;
231     std::vector<std::unique_ptr<ProgramElement>> fInterpreterInclude;
232     std::shared_ptr<SymbolTable> fInterpreterSymbolTable;
233 
234     std::shared_ptr<SymbolTable> fTypes;
235     IRGenerator* fIRGenerator;
236     int fFlags;
237 
238     const String* fSource;
239     std::shared_ptr<Context> fContext;
240     int fErrorCount;
241     String fErrorText;
242 };
243 
244 #if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
245 struct PipelineStageArgs {
246     String fCode;
247     std::vector<Compiler::FormatArg>    fFormatArgs;
248     std::vector<Compiler::GLSLFunction> fFunctions;
249 };
250 #endif
251 
252 } // namespace
253 
254 #endif
255