blob: 9eeacd082de1870f76135a21b9d88d91c0f25a0b [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 */
7
8#include "SkSLCompiler.h"
9
10#include <fstream>
11#include <streambuf>
12
ethannicholas5961bc92016-10-12 06:39:56 -070013#include "ast/SkSLASTPrecision.h"
ethannicholasb3058bd2016-07-01 08:22:01 -070014#include "SkSLIRGenerator.h"
15#include "SkSLParser.h"
16#include "SkSLSPIRVCodeGenerator.h"
17#include "ir/SkSLExpression.h"
18#include "ir/SkSLIntLiteral.h"
ethannicholas5961bc92016-10-12 06:39:56 -070019#include "ir/SkSLModifiersDeclaration.h"
ethannicholasb3058bd2016-07-01 08:22:01 -070020#include "ir/SkSLSymbolTable.h"
21#include "ir/SkSLVarDeclaration.h"
22#include "SkMutex.h"
23
24#define STRINGIFY(x) #x
25
26// include the built-in shader symbols as static strings
27
ethannicholas5961bc92016-10-12 06:39:56 -070028static const char* SKSL_INCLUDE =
ethannicholasb3058bd2016-07-01 08:22:01 -070029#include "sksl.include"
30;
31
ethannicholas5961bc92016-10-12 06:39:56 -070032static const char* SKSL_VERT_INCLUDE =
ethannicholasb3058bd2016-07-01 08:22:01 -070033#include "sksl_vert.include"
34;
35
ethannicholas5961bc92016-10-12 06:39:56 -070036static const char* SKSL_FRAG_INCLUDE =
ethannicholasb3058bd2016-07-01 08:22:01 -070037#include "sksl_frag.include"
38;
39
40namespace SkSL {
41
42Compiler::Compiler()
43: fErrorCount(0) {
44 auto types = std::shared_ptr<SymbolTable>(new SymbolTable(*this));
45 auto symbols = std::shared_ptr<SymbolTable>(new SymbolTable(types, *this));
ethannicholasd598f792016-07-25 10:08:54 -070046 fIRGenerator = new IRGenerator(&fContext, symbols, *this);
ethannicholasb3058bd2016-07-01 08:22:01 -070047 fTypes = types;
ethannicholasd598f792016-07-25 10:08:54 -070048 #define ADD_TYPE(t) types->addWithoutOwnership(fContext.f ## t ## _Type->fName, \
49 fContext.f ## t ## _Type.get())
ethannicholasb3058bd2016-07-01 08:22:01 -070050 ADD_TYPE(Void);
51 ADD_TYPE(Float);
52 ADD_TYPE(Vec2);
53 ADD_TYPE(Vec3);
54 ADD_TYPE(Vec4);
55 ADD_TYPE(Double);
56 ADD_TYPE(DVec2);
57 ADD_TYPE(DVec3);
58 ADD_TYPE(DVec4);
59 ADD_TYPE(Int);
60 ADD_TYPE(IVec2);
61 ADD_TYPE(IVec3);
62 ADD_TYPE(IVec4);
63 ADD_TYPE(UInt);
64 ADD_TYPE(UVec2);
65 ADD_TYPE(UVec3);
66 ADD_TYPE(UVec4);
67 ADD_TYPE(Bool);
68 ADD_TYPE(BVec2);
69 ADD_TYPE(BVec3);
70 ADD_TYPE(BVec4);
71 ADD_TYPE(Mat2x2);
ethannicholasf789b382016-08-03 12:43:36 -070072 types->addWithoutOwnership("mat2x2", fContext.fMat2x2_Type.get());
ethannicholasb3058bd2016-07-01 08:22:01 -070073 ADD_TYPE(Mat2x3);
74 ADD_TYPE(Mat2x4);
75 ADD_TYPE(Mat3x2);
76 ADD_TYPE(Mat3x3);
ethannicholasf789b382016-08-03 12:43:36 -070077 types->addWithoutOwnership("mat3x3", fContext.fMat3x3_Type.get());
ethannicholasb3058bd2016-07-01 08:22:01 -070078 ADD_TYPE(Mat3x4);
79 ADD_TYPE(Mat4x2);
80 ADD_TYPE(Mat4x3);
81 ADD_TYPE(Mat4x4);
ethannicholasf789b382016-08-03 12:43:36 -070082 types->addWithoutOwnership("mat4x4", fContext.fMat4x4_Type.get());
ethannicholasb3058bd2016-07-01 08:22:01 -070083 ADD_TYPE(GenType);
84 ADD_TYPE(GenDType);
85 ADD_TYPE(GenIType);
86 ADD_TYPE(GenUType);
87 ADD_TYPE(GenBType);
88 ADD_TYPE(Mat);
89 ADD_TYPE(Vec);
90 ADD_TYPE(GVec);
91 ADD_TYPE(GVec2);
92 ADD_TYPE(GVec3);
93 ADD_TYPE(GVec4);
94 ADD_TYPE(DVec);
95 ADD_TYPE(IVec);
96 ADD_TYPE(UVec);
97 ADD_TYPE(BVec);
98
99 ADD_TYPE(Sampler1D);
100 ADD_TYPE(Sampler2D);
101 ADD_TYPE(Sampler3D);
ethannicholas5961bc92016-10-12 06:39:56 -0700102 ADD_TYPE(SamplerExternalOES);
ethannicholasb3058bd2016-07-01 08:22:01 -0700103 ADD_TYPE(SamplerCube);
104 ADD_TYPE(Sampler2DRect);
105 ADD_TYPE(Sampler1DArray);
106 ADD_TYPE(Sampler2DArray);
107 ADD_TYPE(SamplerCubeArray);
108 ADD_TYPE(SamplerBuffer);
109 ADD_TYPE(Sampler2DMS);
110 ADD_TYPE(Sampler2DMSArray);
111
112 ADD_TYPE(GSampler1D);
113 ADD_TYPE(GSampler2D);
114 ADD_TYPE(GSampler3D);
115 ADD_TYPE(GSamplerCube);
116 ADD_TYPE(GSampler2DRect);
117 ADD_TYPE(GSampler1DArray);
118 ADD_TYPE(GSampler2DArray);
119 ADD_TYPE(GSamplerCubeArray);
120 ADD_TYPE(GSamplerBuffer);
121 ADD_TYPE(GSampler2DMS);
122 ADD_TYPE(GSampler2DMSArray);
123
124 ADD_TYPE(Sampler1DShadow);
125 ADD_TYPE(Sampler2DShadow);
126 ADD_TYPE(SamplerCubeShadow);
127 ADD_TYPE(Sampler2DRectShadow);
128 ADD_TYPE(Sampler1DArrayShadow);
129 ADD_TYPE(Sampler2DArrayShadow);
130 ADD_TYPE(SamplerCubeArrayShadow);
131 ADD_TYPE(GSampler2DArrayShadow);
132 ADD_TYPE(GSamplerCubeArrayShadow);
133
ethannicholas5961bc92016-10-12 06:39:56 -0700134 Modifiers::Flag ignored1;
135 std::vector<std::unique_ptr<ProgramElement>> ignored2;
136 this->internalConvertProgram(SKSL_INCLUDE, &ignored1, &ignored2);
ethannicholasb3058bd2016-07-01 08:22:01 -0700137 ASSERT(!fErrorCount);
138}
139
140Compiler::~Compiler() {
141 delete fIRGenerator;
142}
143
144void Compiler::internalConvertProgram(std::string text,
ethannicholas5961bc92016-10-12 06:39:56 -0700145 Modifiers::Flag* defaultPrecision,
ethannicholasb3058bd2016-07-01 08:22:01 -0700146 std::vector<std::unique_ptr<ProgramElement>>* result) {
147 Parser parser(text, *fTypes, *this);
148 std::vector<std::unique_ptr<ASTDeclaration>> parsed = parser.file();
149 if (fErrorCount) {
150 return;
151 }
ethannicholas5961bc92016-10-12 06:39:56 -0700152 *defaultPrecision = Modifiers::kHighp_Flag;
ethannicholasb3058bd2016-07-01 08:22:01 -0700153 for (size_t i = 0; i < parsed.size(); i++) {
154 ASTDeclaration& decl = *parsed[i];
155 switch (decl.fKind) {
156 case ASTDeclaration::kVar_Kind: {
ethannicholas14fe8cc2016-09-07 13:37:16 -0700157 std::unique_ptr<VarDeclarations> s = fIRGenerator->convertVarDeclarations(
158 (ASTVarDeclarations&) decl,
ethannicholasb3058bd2016-07-01 08:22:01 -0700159 Variable::kGlobal_Storage);
160 if (s) {
161 result->push_back(std::move(s));
162 }
163 break;
164 }
165 case ASTDeclaration::kFunction_Kind: {
166 std::unique_ptr<FunctionDefinition> f = fIRGenerator->convertFunction(
167 (ASTFunction&) decl);
168 if (f) {
169 result->push_back(std::move(f));
170 }
171 break;
172 }
ethannicholas5961bc92016-10-12 06:39:56 -0700173 case ASTDeclaration::kModifiers_Kind: {
174 std::unique_ptr<ModifiersDeclaration> f = fIRGenerator->convertModifiersDeclaration(
175 (ASTModifiersDeclaration&) decl);
176 if (f) {
177 result->push_back(std::move(f));
178 }
179 break;
180 }
ethannicholasb3058bd2016-07-01 08:22:01 -0700181 case ASTDeclaration::kInterfaceBlock_Kind: {
182 std::unique_ptr<InterfaceBlock> i = fIRGenerator->convertInterfaceBlock(
183 (ASTInterfaceBlock&) decl);
184 if (i) {
185 result->push_back(std::move(i));
186 }
187 break;
188 }
189 case ASTDeclaration::kExtension_Kind: {
190 std::unique_ptr<Extension> e = fIRGenerator->convertExtension((ASTExtension&) decl);
191 if (e) {
192 result->push_back(std::move(e));
193 }
194 break;
195 }
ethannicholas5961bc92016-10-12 06:39:56 -0700196 case ASTDeclaration::kPrecision_Kind: {
197 *defaultPrecision = ((ASTPrecision&) decl).fPrecision;
198 break;
199 }
ethannicholasb3058bd2016-07-01 08:22:01 -0700200 default:
201 ABORT("unsupported declaration: %s\n", decl.description().c_str());
202 }
203 }
204}
205
206std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, std::string text) {
207 fErrorText = "";
208 fErrorCount = 0;
209 fIRGenerator->pushSymbolTable();
ethannicholasd598f792016-07-25 10:08:54 -0700210 std::vector<std::unique_ptr<ProgramElement>> elements;
ethannicholas5961bc92016-10-12 06:39:56 -0700211 Modifiers::Flag ignored;
ethannicholasb3058bd2016-07-01 08:22:01 -0700212 switch (kind) {
213 case Program::kVertex_Kind:
ethannicholas5961bc92016-10-12 06:39:56 -0700214 this->internalConvertProgram(SKSL_VERT_INCLUDE, &ignored, &elements);
ethannicholasb3058bd2016-07-01 08:22:01 -0700215 break;
216 case Program::kFragment_Kind:
ethannicholas5961bc92016-10-12 06:39:56 -0700217 this->internalConvertProgram(SKSL_FRAG_INCLUDE, &ignored, &elements);
ethannicholasb3058bd2016-07-01 08:22:01 -0700218 break;
219 }
ethannicholas5961bc92016-10-12 06:39:56 -0700220 Modifiers::Flag defaultPrecision;
221 this->internalConvertProgram(text, &defaultPrecision, &elements);
222 auto result = std::unique_ptr<Program>(new Program(kind, defaultPrecision, std::move(elements),
ethannicholasd598f792016-07-25 10:08:54 -0700223 fIRGenerator->fSymbolTable));;
ethannicholasb3058bd2016-07-01 08:22:01 -0700224 fIRGenerator->popSymbolTable();
225 this->writeErrorCount();
ethannicholasd598f792016-07-25 10:08:54 -0700226 return result;
ethannicholasb3058bd2016-07-01 08:22:01 -0700227}
228
229void Compiler::error(Position position, std::string msg) {
230 fErrorCount++;
231 fErrorText += "error: " + position.description() + ": " + msg.c_str() + "\n";
232}
233
234std::string Compiler::errorText() {
235 std::string result = fErrorText;
236 return result;
237}
238
239void Compiler::writeErrorCount() {
240 if (fErrorCount) {
241 fErrorText += to_string(fErrorCount) + " error";
242 if (fErrorCount > 1) {
243 fErrorText += "s";
244 }
245 fErrorText += "\n";
246 }
247}
248
ethannicholasf789b382016-08-03 12:43:36 -0700249bool Compiler::toSPIRV(Program::Kind kind, const std::string& text, std::ostream& out) {
ethannicholasb3058bd2016-07-01 08:22:01 -0700250 auto program = this->convertProgram(kind, text);
251 if (fErrorCount == 0) {
ethannicholasd598f792016-07-25 10:08:54 -0700252 SkSL::SPIRVCodeGenerator cg(&fContext);
ethannicholasb3058bd2016-07-01 08:22:01 -0700253 cg.generateCode(*program.get(), out);
254 ASSERT(!out.rdstate());
255 }
256 return fErrorCount == 0;
257}
258
ethannicholasf789b382016-08-03 12:43:36 -0700259bool Compiler::toSPIRV(Program::Kind kind, const std::string& text, std::string* out) {
ethannicholasb3058bd2016-07-01 08:22:01 -0700260 std::stringstream buffer;
261 bool result = this->toSPIRV(kind, text, buffer);
262 if (result) {
263 *out = buffer.str();
264 }
ethannicholasf789b382016-08-03 12:43:36 -0700265 return result;
266}
267
268bool Compiler::toGLSL(Program::Kind kind, const std::string& text, GLCaps caps,
269 std::ostream& out) {
270 auto program = this->convertProgram(kind, text);
271 if (fErrorCount == 0) {
272 SkSL::GLSLCodeGenerator cg(&fContext, caps);
273 cg.generateCode(*program.get(), out);
274 ASSERT(!out.rdstate());
275 }
ethannicholasb3058bd2016-07-01 08:22:01 -0700276 return fErrorCount == 0;
277}
278
ethannicholasf789b382016-08-03 12:43:36 -0700279bool Compiler::toGLSL(Program::Kind kind, const std::string& text, GLCaps caps,
280 std::string* out) {
281 std::stringstream buffer;
282 bool result = this->toGLSL(kind, text, caps, buffer);
283 if (result) {
284 *out = buffer.str();
285 }
286 return result;
287}
288
ethannicholasb3058bd2016-07-01 08:22:01 -0700289} // namespace