SkSLCompiler.cpp revision d214d6ae69c1dd9ef49fdce8fac699d00bffcdcd
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#include "SkSLCompiler.h" 9 10#include <fstream> 11#include <streambuf> 12 13#include "SkSLIRGenerator.h" 14#include "SkSLParser.h" 15#include "SkSLSPIRVCodeGenerator.h" 16#include "ir/SkSLExpression.h" 17#include "ir/SkSLIntLiteral.h" 18#include "ir/SkSLSymbolTable.h" 19#include "ir/SkSLVarDeclaration.h" 20#include "SkMutex.h" 21 22#define STRINGIFY(x) #x 23 24// include the built-in shader symbols as static strings 25 26static std::string SKSL_INCLUDE = 27#include "sksl.include" 28; 29 30static std::string SKSL_VERT_INCLUDE = 31#include "sksl_vert.include" 32; 33 34static std::string SKSL_FRAG_INCLUDE = 35#include "sksl_frag.include" 36; 37 38namespace SkSL { 39 40Compiler::Compiler() 41: fErrorCount(0) { 42 auto types = std::shared_ptr<SymbolTable>(new SymbolTable(*this)); 43 auto symbols = std::shared_ptr<SymbolTable>(new SymbolTable(types, *this)); 44 fIRGenerator = new IRGenerator(&fContext, symbols, *this); 45 fTypes = types; 46 #define ADD_TYPE(t) types->addWithoutOwnership(fContext.f ## t ## _Type->fName, \ 47 fContext.f ## t ## _Type.get()) 48 ADD_TYPE(Void); 49 ADD_TYPE(Float); 50 ADD_TYPE(Vec2); 51 ADD_TYPE(Vec3); 52 ADD_TYPE(Vec4); 53 ADD_TYPE(Double); 54 ADD_TYPE(DVec2); 55 ADD_TYPE(DVec3); 56 ADD_TYPE(DVec4); 57 ADD_TYPE(Int); 58 ADD_TYPE(IVec2); 59 ADD_TYPE(IVec3); 60 ADD_TYPE(IVec4); 61 ADD_TYPE(UInt); 62 ADD_TYPE(UVec2); 63 ADD_TYPE(UVec3); 64 ADD_TYPE(UVec4); 65 ADD_TYPE(Bool); 66 ADD_TYPE(BVec2); 67 ADD_TYPE(BVec3); 68 ADD_TYPE(BVec4); 69 ADD_TYPE(Mat2x2); 70 types->addWithoutOwnership("mat2x2", fContext.fMat2x2_Type.get()); 71 ADD_TYPE(Mat2x3); 72 ADD_TYPE(Mat2x4); 73 ADD_TYPE(Mat3x2); 74 ADD_TYPE(Mat3x3); 75 types->addWithoutOwnership("mat3x3", fContext.fMat3x3_Type.get()); 76 ADD_TYPE(Mat3x4); 77 ADD_TYPE(Mat4x2); 78 ADD_TYPE(Mat4x3); 79 ADD_TYPE(Mat4x4); 80 types->addWithoutOwnership("mat4x4", fContext.fMat4x4_Type.get()); 81 ADD_TYPE(GenType); 82 ADD_TYPE(GenDType); 83 ADD_TYPE(GenIType); 84 ADD_TYPE(GenUType); 85 ADD_TYPE(GenBType); 86 ADD_TYPE(Mat); 87 ADD_TYPE(Vec); 88 ADD_TYPE(GVec); 89 ADD_TYPE(GVec2); 90 ADD_TYPE(GVec3); 91 ADD_TYPE(GVec4); 92 ADD_TYPE(DVec); 93 ADD_TYPE(IVec); 94 ADD_TYPE(UVec); 95 ADD_TYPE(BVec); 96 97 ADD_TYPE(Sampler1D); 98 ADD_TYPE(Sampler2D); 99 ADD_TYPE(Sampler3D); 100 ADD_TYPE(SamplerCube); 101 ADD_TYPE(Sampler2DRect); 102 ADD_TYPE(Sampler1DArray); 103 ADD_TYPE(Sampler2DArray); 104 ADD_TYPE(SamplerCubeArray); 105 ADD_TYPE(SamplerBuffer); 106 ADD_TYPE(Sampler2DMS); 107 ADD_TYPE(Sampler2DMSArray); 108 109 ADD_TYPE(GSampler1D); 110 ADD_TYPE(GSampler2D); 111 ADD_TYPE(GSampler3D); 112 ADD_TYPE(GSamplerCube); 113 ADD_TYPE(GSampler2DRect); 114 ADD_TYPE(GSampler1DArray); 115 ADD_TYPE(GSampler2DArray); 116 ADD_TYPE(GSamplerCubeArray); 117 ADD_TYPE(GSamplerBuffer); 118 ADD_TYPE(GSampler2DMS); 119 ADD_TYPE(GSampler2DMSArray); 120 121 ADD_TYPE(Sampler1DShadow); 122 ADD_TYPE(Sampler2DShadow); 123 ADD_TYPE(SamplerCubeShadow); 124 ADD_TYPE(Sampler2DRectShadow); 125 ADD_TYPE(Sampler1DArrayShadow); 126 ADD_TYPE(Sampler2DArrayShadow); 127 ADD_TYPE(SamplerCubeArrayShadow); 128 ADD_TYPE(GSampler2DArrayShadow); 129 ADD_TYPE(GSamplerCubeArrayShadow); 130 131 std::vector<std::unique_ptr<ProgramElement>> ignored; 132 this->internalConvertProgram(SKSL_INCLUDE, &ignored); 133 ASSERT(!fErrorCount); 134} 135 136Compiler::~Compiler() { 137 delete fIRGenerator; 138} 139 140void Compiler::internalConvertProgram(std::string text, 141 std::vector<std::unique_ptr<ProgramElement>>* result) { 142 Parser parser(text, *fTypes, *this); 143 std::vector<std::unique_ptr<ASTDeclaration>> parsed = parser.file(); 144 if (fErrorCount) { 145 return; 146 } 147 for (size_t i = 0; i < parsed.size(); i++) { 148 ASTDeclaration& decl = *parsed[i]; 149 switch (decl.fKind) { 150 case ASTDeclaration::kVar_Kind: { 151 std::unique_ptr<VarDeclarations> s = fIRGenerator->convertVarDeclarations( 152 (ASTVarDeclarations&) decl, 153 Variable::kGlobal_Storage); 154 if (s) { 155 result->push_back(std::move(s)); 156 } 157 break; 158 } 159 case ASTDeclaration::kFunction_Kind: { 160 std::unique_ptr<FunctionDefinition> f = fIRGenerator->convertFunction( 161 (ASTFunction&) decl); 162 if (f) { 163 result->push_back(std::move(f)); 164 } 165 break; 166 } 167 case ASTDeclaration::kInterfaceBlock_Kind: { 168 std::unique_ptr<InterfaceBlock> i = fIRGenerator->convertInterfaceBlock( 169 (ASTInterfaceBlock&) decl); 170 if (i) { 171 result->push_back(std::move(i)); 172 } 173 break; 174 } 175 case ASTDeclaration::kExtension_Kind: { 176 std::unique_ptr<Extension> e = fIRGenerator->convertExtension((ASTExtension&) decl); 177 if (e) { 178 result->push_back(std::move(e)); 179 } 180 break; 181 } 182 default: 183 ABORT("unsupported declaration: %s\n", decl.description().c_str()); 184 } 185 } 186} 187 188std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, std::string text) { 189 fErrorText = ""; 190 fErrorCount = 0; 191 fIRGenerator->pushSymbolTable(); 192 std::vector<std::unique_ptr<ProgramElement>> elements; 193 switch (kind) { 194 case Program::kVertex_Kind: 195 this->internalConvertProgram(SKSL_VERT_INCLUDE, &elements); 196 break; 197 case Program::kFragment_Kind: 198 this->internalConvertProgram(SKSL_FRAG_INCLUDE, &elements); 199 break; 200 } 201 this->internalConvertProgram(text, &elements); 202 auto result = std::unique_ptr<Program>(new Program(kind, std::move(elements), 203 fIRGenerator->fSymbolTable));; 204 fIRGenerator->popSymbolTable(); 205 this->writeErrorCount(); 206 return result; 207} 208 209void Compiler::error(Position position, std::string msg) { 210 fErrorCount++; 211 fErrorText += "error: " + position.description() + ": " + msg.c_str() + "\n"; 212} 213 214std::string Compiler::errorText() { 215 std::string result = fErrorText; 216 return result; 217} 218 219void Compiler::writeErrorCount() { 220 if (fErrorCount) { 221 fErrorText += to_string(fErrorCount) + " error"; 222 if (fErrorCount > 1) { 223 fErrorText += "s"; 224 } 225 fErrorText += "\n"; 226 } 227} 228 229bool Compiler::toSPIRV(Program::Kind kind, const std::string& text, std::ostream& out) { 230 auto program = this->convertProgram(kind, text); 231 if (fErrorCount == 0) { 232 SkSL::SPIRVCodeGenerator cg(&fContext); 233 cg.generateCode(*program.get(), out); 234 ASSERT(!out.rdstate()); 235 } 236 return fErrorCount == 0; 237} 238 239bool Compiler::toSPIRV(Program::Kind kind, const std::string& text, std::string* out) { 240 std::stringstream buffer; 241 bool result = this->toSPIRV(kind, text, buffer); 242 if (result) { 243 *out = buffer.str(); 244 } 245 return result; 246} 247 248bool Compiler::toGLSL(Program::Kind kind, const std::string& text, GLCaps caps, 249 std::ostream& out) { 250 auto program = this->convertProgram(kind, text); 251 if (fErrorCount == 0) { 252 SkSL::GLSLCodeGenerator cg(&fContext, caps); 253 cg.generateCode(*program.get(), out); 254 ASSERT(!out.rdstate()); 255 } 256 return fErrorCount == 0; 257} 258 259bool Compiler::toGLSL(Program::Kind kind, const std::string& text, GLCaps caps, 260 std::string* out) { 261 std::stringstream buffer; 262 bool result = this->toGLSL(kind, text, caps, buffer); 263 if (result) { 264 *out = buffer.str(); 265 } 266 return result; 267} 268 269} // namespace 270