blob: 6aebb783c890583161766ddf87e3aba402c6307e [file] [log] [blame]
ethannicholasb3058bd2016-07-01 08:22:01 -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 */
Ethan Nicholas0df1b042017-03-31 13:56:23 -04007
ethannicholasb3058bd2016-07-01 08:22:01 -07008#ifndef SKSL_COMPILER
9#define SKSL_COMPILER
10
Ethan Nicholasdb80f692019-11-22 14:06:12 -050011#include <map>
ethannicholas22f939e2016-10-13 13:25:34 -070012#include <set>
Ethan Nicholascb670962017-04-20 19:31:52 -040013#include <unordered_set>
ethannicholasb3058bd2016-07-01 08:22:01 -070014#include <vector>
Ethan Nicholasdb80f692019-11-22 14:06:12 -050015#include "src/sksl/SkSLASTFile.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050016#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"
ethannicholasb3058bd2016-07-01 08:22:01 -070022
Brian Osman2e29ab52019-09-20 12:19:11 -040023#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
24#include "src/gpu/GrShaderVar.h"
25#endif
26
Ethan Nicholas762466e2017-06-29 10:03:38 -040027#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
Ethan Nicholas16c11962018-03-16 12:20:54 -040033#define SK_OUT_BUILTIN 10007
Ethan Nicholaseab2baa2018-04-13 15:16:27 -040034#define SK_LASTFRAGCOLOR_BUILTIN 10008
Brian Osman7353dc52020-02-07 13:37:12 -050035#define SK_MAIN_COORDS_BUILTIN 10009
Ethan Nicholascd700e92018-08-24 16:43:57 -040036#define SK_WIDTH_BUILTIN 10011
37#define SK_HEIGHT_BUILTIN 10012
Ethan Nicholas762466e2017-06-29 10:03:38 -040038#define SK_FRAGCOORD_BUILTIN 15
Chris Dalton49d14e92018-07-27 12:38:35 -060039#define SK_CLOCKWISE_BUILTIN 17
Chris Daltonb0fd4b12019-10-29 13:41:22 -060040#define SK_SAMPLEMASK_BUILTIN 20
Ethan Nicholas9eded2c2018-03-22 10:10:44 -040041#define SK_VERTEXID_BUILTIN 42
42#define SK_INSTANCEID_BUILTIN 43
Ethan Nicholas762466e2017-06-29 10:03:38 -040043#define SK_CLIPDISTANCE_BUILTIN 3
44#define SK_INVOCATIONID_BUILTIN 8
Ethan Nicholascc305772017-10-13 16:17:45 -040045#define SK_POSITION_BUILTIN 0
ethannicholas5961bc92016-10-12 06:39:56 -070046
ethannicholasb3058bd2016-07-01 08:22:01 -070047namespace SkSL {
48
Brian Osman9b8b4552019-09-30 13:23:14 -040049class ByteCode;
Brian Osman3257dda2019-09-17 12:01:11 -040050class ExternalValue;
ethannicholasb3058bd2016-07-01 08:22:01 -070051class IRGenerator;
Brian Osman107c6662019-12-30 15:02:30 -050052struct PipelineStageArgs;
ethannicholasb3058bd2016-07-01 08:22:01 -070053
54/**
55 * Main compiler entry point. This is a traditional compiler design which first parses the .sksl
Ethan Nicholas941e7e22016-12-12 15:33:30 -050056 * file into an abstract syntax tree (a tree of ASTNodes), then performs semantic analysis to
ethannicholasb3058bd2016-07-01 08:22:01 -070057 * produce a Program (a tree of IRNodes), then feeds the Program into a CodeGenerator to produce
58 * compiled output.
ethannicholas5961bc92016-10-12 06:39:56 -070059 *
60 * See the README for information about SkSL.
ethannicholasb3058bd2016-07-01 08:22:01 -070061 */
Ethan Nicholas4100b7c2019-03-12 11:50:48 -040062class SK_API Compiler : public ErrorReporter {
ethannicholasb3058bd2016-07-01 08:22:01 -070063public:
Robert Phillipsfe8da172018-01-24 14:52:02 +000064 static constexpr const char* RTADJUST_NAME = "sk_RTAdjust";
65 static constexpr const char* PERVERTEX_NAME = "sk_PerVertex";
66
Ethan Nicholas6e1cbc02017-07-14 10:12:15 -040067 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
Ethan Nicholasce008112018-08-30 09:19:50 -040075 struct FormatArg {
76 enum class Kind {
77 kInput,
78 kOutput,
Brian Osman7353dc52020-02-07 13:37:12 -050079 kCoords,
Ethan Nicholasce008112018-08-30 09:19:50 -040080 kUniform,
Brian Osman2e29ab52019-09-20 12:19:11 -040081 kChildProcessor,
82 kFunctionName
Ethan Nicholasce008112018-08-30 09:19:50 -040083 };
84
85 FormatArg(Kind kind)
86 : fKind(kind) {}
87
88 FormatArg(Kind kind, int index)
89 : fKind(kind)
90 , fIndex(index) {}
91
92 Kind fKind;
Ethan Nicholasce008112018-08-30 09:19:50 -040093 int fIndex;
Brian Osman87e3bef2020-01-27 16:21:34 -050094 String fCoords;
Ethan Nicholas00543112018-07-31 09:44:36 -040095 };
96
Brian Osman2e29ab52019-09-20 12:19:11 -040097#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;
Ethan Nicholasfc671ad2019-11-21 11:14:11 -0500106 std::vector<Compiler::FormatArg> fFormatArgs;
Brian Osman2e29ab52019-09-20 12:19:11 -0400107 };
108#endif
109
Ethan Nicholas6e1cbc02017-07-14 10:12:15 -0400110 Compiler(Flags flags = kNone_Flags);
ethannicholasb3058bd2016-07-01 08:22:01 -0700111
Brian Salomond3b65972017-03-22 12:05:03 -0400112 ~Compiler() override;
ethannicholasb3058bd2016-07-01 08:22:01 -0700113
Brian Osman14003822019-04-10 11:47:26 -0400114 Compiler(const Compiler&) = delete;
115 Compiler& operator=(const Compiler&) = delete;
116
Ethan Nicholas91164d12019-05-15 15:29:54 -0400117 /**
118 * Registers an ExternalValue as a top-level symbol which is visible in the global namespace.
119 */
120 void registerExternalValue(ExternalValue* value);
121
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400122 std::unique_ptr<Program> convertProgram(Program::Kind kind, String text,
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500123 const Program::Settings& settings);
ethannicholasb3058bd2016-07-01 08:22:01 -0700124
Ethan Nicholas00543112018-07-31 09:44:36 -0400125 bool optimize(Program& program);
ethannicholasf789b382016-08-03 12:43:36 -0700126
Ethan Nicholas00543112018-07-31 09:44:36 -0400127 std::unique_ptr<Program> specialize(Program& program,
128 const std::unordered_map<SkSL::String, SkSL::Program::Settings::Value>& inputs);
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500129
Ethan Nicholas00543112018-07-31 09:44:36 -0400130 bool toSPIRV(Program& program, OutputStream& out);
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500131
Ethan Nicholas00543112018-07-31 09:44:36 -0400132 bool toSPIRV(Program& program, String* out);
ethannicholasb3058bd2016-07-01 08:22:01 -0700133
Ethan Nicholas00543112018-07-31 09:44:36 -0400134 bool toGLSL(Program& program, OutputStream& out);
Ethan Nicholascc305772017-10-13 16:17:45 -0400135
Ethan Nicholas00543112018-07-31 09:44:36 -0400136 bool toGLSL(Program& program, String* out);
Timothy Liangb8eeb802018-07-23 16:46:16 -0400137
Brian Osmanc0243912020-02-19 15:35:26 -0500138 bool toHLSL(Program& program, String* out);
139
Ethan Nicholas00543112018-07-31 09:44:36 -0400140 bool toMetal(Program& program, OutputStream& out);
Ethan Nicholas762466e2017-06-29 10:03:38 -0400141
Ethan Nicholas00543112018-07-31 09:44:36 -0400142 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
Ethan Nicholas0e9401d2019-03-21 11:05:37 -0400148 std::unique_ptr<ByteCode> toByteCode(Program& program);
149
Brian Osman2e29ab52019-09-20 12:19:11 -0400150#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
Brian Osman107c6662019-12-30 15:02:30 -0500151 bool toPipelineStage(const Program& program, PipelineStageArgs* outArgs);
Brian Osman2e29ab52019-09-20 12:19:11 -0400152#endif
Ethan Nicholas762466e2017-06-29 10:03:38 -0400153
Ethan Nicholas91164d12019-05-15 15:29:54 -0400154 /**
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
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700159 void error(int offset, String msg) override;
ethannicholasb3058bd2016-07-01 08:22:01 -0700160
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400161 String errorText();
ethannicholasb3058bd2016-07-01 08:22:01 -0700162
163 void writeErrorCount();
164
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500165 int errorCount() override {
166 return fErrorCount;
167 }
168
Ethan Nicholas26a9aad2018-03-27 14:10:52 -0400169 Context& context() {
170 return *fContext;
171 }
172
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700173 static const char* OperatorName(Token::Kind token);
174
175 static bool IsAssignment(Token::Kind token);
176
ethannicholasb3058bd2016-07-01 08:22:01 -0700177private:
Ethan Nicholas8da1e652019-05-24 11:01:59 -0400178 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
Ethan Nicholas86a43402017-01-19 13:32:00 -0500183 void addDefinition(const Expression* lvalue, std::unique_ptr<Expression>* expr,
184 DefinitionMap* definitions);
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500185
Ethan Nicholas86a43402017-01-19 13:32:00 -0500186 void addDefinitions(const BasicBlock::Node& node, DefinitionMap* definitions);
ethannicholas22f939e2016-10-13 13:25:34 -0700187
188 void scanCFG(CFG* cfg, BlockId block, std::set<BlockId>* workList);
189
Ethan Nicholascb670962017-04-20 19:31:52 -0400190 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);
ethannicholasb3058bd2016-07-01 08:22:01 -0700215
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700216 Position position(int offset);
217
Ethan Nicholasb962eff2020-01-23 16:49:41 -0500218 std::map<String, std::pair<std::unique_ptr<ProgramElement>, bool>> fGPUIntrinsics;
219 std::map<String, std::pair<std::unique_ptr<ProgramElement>, bool>> fInterpreterIntrinsics;
Ethan Nicholasdb80f692019-11-22 14:06:12 -0500220 std::unique_ptr<ASTFile> fGpuIncludeSource;
Ethan Nicholas8da1e652019-05-24 11:01:59 -0400221 std::shared_ptr<SymbolTable> fGpuSymbolTable;
Ethan Nicholas3c6ae622018-04-24 13:06:09 -0400222 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;
Ethan Nicholas8da1e652019-05-24 11:01:59 -0400228 std::vector<std::unique_ptr<ProgramElement>> fPipelineInclude;
229 std::shared_ptr<SymbolTable> fPipelineSymbolTable;
Ethan Nicholasb962eff2020-01-23 16:49:41 -0500230 std::unique_ptr<ASTFile> fInterpreterIncludeSource;
Ethan Nicholas8da1e652019-05-24 11:01:59 -0400231 std::vector<std::unique_ptr<ProgramElement>> fInterpreterInclude;
232 std::shared_ptr<SymbolTable> fInterpreterSymbolTable;
Ethan Nicholas3c6ae622018-04-24 13:06:09 -0400233
ethannicholasb3058bd2016-07-01 08:22:01 -0700234 std::shared_ptr<SymbolTable> fTypes;
235 IRGenerator* fIRGenerator;
Ethan Nicholas6e1cbc02017-07-14 10:12:15 -0400236 int fFlags;
ethannicholasb3058bd2016-07-01 08:22:01 -0700237
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700238 const String* fSource;
Ethan Nicholas26a9aad2018-03-27 14:10:52 -0400239 std::shared_ptr<Context> fContext;
ethannicholasb3058bd2016-07-01 08:22:01 -0700240 int fErrorCount;
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400241 String fErrorText;
ethannicholasb3058bd2016-07-01 08:22:01 -0700242};
243
Brian Osman107c6662019-12-30 15:02:30 -0500244#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
245struct PipelineStageArgs {
246 String fCode;
247 std::vector<Compiler::FormatArg> fFormatArgs;
248 std::vector<Compiler::GLSLFunction> fFunctions;
249};
250#endif
251
ethannicholasb3058bd2016-07-01 08:22:01 -0700252} // namespace
253
254#endif