OLD | NEW |
(Empty) | |
| 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_SPIRVCODEGENERATOR |
| 9 #define SKSL_SPIRVCODEGENERATOR |
| 10 |
| 11 #include <sstream> |
| 12 #include <stack> |
| 13 #include <tuple> |
| 14 #include <unordered_map> |
| 15 |
| 16 #include "SkSLCodeGenerator.h" |
| 17 #include "ir/SkSLBinaryExpression.h" |
| 18 #include "ir/SkSLBoolLiteral.h" |
| 19 #include "ir/SkSLConstructor.h" |
| 20 #include "ir/SkSLFloatLiteral.h" |
| 21 #include "ir/SkSLIfStatement.h" |
| 22 #include "ir/SkSLIndexExpression.h" |
| 23 #include "ir/SkSLInterfaceBlock.h" |
| 24 #include "ir/SkSLIntLiteral.h" |
| 25 #include "ir/SkSLFieldAccess.h" |
| 26 #include "ir/SkSLForStatement.h" |
| 27 #include "ir/SkSLFunctionCall.h" |
| 28 #include "ir/SkSLFunctionDeclaration.h" |
| 29 #include "ir/SkSLFunctionDefinition.h" |
| 30 #include "ir/SkSLPrefixExpression.h" |
| 31 #include "ir/SkSLPostfixExpression.h" |
| 32 #include "ir/SkSLProgramElement.h" |
| 33 #include "ir/SkSLReturnStatement.h" |
| 34 #include "ir/SkSLStatement.h" |
| 35 #include "ir/SkSLSwizzle.h" |
| 36 #include "ir/SkSLTernaryExpression.h" |
| 37 #include "ir/SkSLVarDeclaration.h" |
| 38 #include "ir/SkSLVarDeclarationStatement.h" |
| 39 #include "ir/SkSLVariableReference.h" |
| 40 #include "spirv.h" |
| 41 |
| 42 namespace SkSL { |
| 43 |
| 44 #define kLast_Capability SpvCapabilityMultiViewport |
| 45 |
| 46 /** |
| 47 * Converts a Program into a SPIR-V binary. |
| 48 */ |
| 49 class SPIRVCodeGenerator : public CodeGenerator { |
| 50 public: |
| 51 SPIRVCodeGenerator() |
| 52 : fCapabilities(1 << SpvCapabilityShader) |
| 53 , fIdCount(1) |
| 54 , fBoolTrue(0) |
| 55 , fBoolFalse(0) |
| 56 , fCurrentBlock(0) { |
| 57 this->setupIntrinsics(); |
| 58 } |
| 59 |
| 60 void generateCode(Program& program, std::ostream& out) override; |
| 61 |
| 62 private: |
| 63 enum IntrinsicKind { |
| 64 kGLSL_STD_450_IntrinsicKind, |
| 65 kSPIRV_IntrinsicKind, |
| 66 kSpecial_IntrinsicKind |
| 67 }; |
| 68 |
| 69 enum SpecialIntrinsic { |
| 70 kAtan_SpecialIntrinsic, |
| 71 kTexture_SpecialIntrinsic, |
| 72 kTexture2D_SpecialIntrinsic, |
| 73 kTextureProj_SpecialIntrinsic |
| 74 }; |
| 75 |
| 76 void setupIntrinsics(); |
| 77 |
| 78 SpvId nextId(); |
| 79 |
| 80 SpvId getType(const Type& type); |
| 81 |
| 82 SpvId getFunctionType(std::shared_ptr<FunctionDeclaration> function); |
| 83 |
| 84 SpvId getPointerType(std::shared_ptr<Type> type, SpvStorageClass_ storageCla
ss); |
| 85 |
| 86 std::vector<SpvId> getAccessChain(Expression& expr, std::ostream& out); |
| 87 |
| 88 void writeLayout(const Layout& layout, SpvId target); |
| 89 |
| 90 void writeLayout(const Layout& layout, SpvId target, int member); |
| 91 |
| 92 void writeStruct(const Type& type, SpvId resultId); |
| 93 |
| 94 void writeProgramElement(ProgramElement& pe, std::ostream& out); |
| 95 |
| 96 SpvId writeInterfaceBlock(InterfaceBlock& intf); |
| 97 |
| 98 SpvId writeFunctionStart(std::shared_ptr<FunctionDeclaration> f, std::ostrea
m& out); |
| 99 |
| 100 SpvId writeFunctionDeclaration(std::shared_ptr<FunctionDeclaration> f, std::
ostream& out); |
| 101 |
| 102 SpvId writeFunction(FunctionDefinition& f, std::ostream& out); |
| 103 |
| 104 void writeGlobalVars(VarDeclaration& v, std::ostream& out); |
| 105 |
| 106 void writeVarDeclaration(VarDeclaration& decl, std::ostream& out); |
| 107 |
| 108 SpvId writeVariableReference(VariableReference& ref, std::ostream& out); |
| 109 |
| 110 SpvId getLValue(Expression& value, std::ostream& out); |
| 111 |
| 112 void storeToLValue(Expression& lvalue, SpvId value, std::ostream& out); |
| 113 |
| 114 SpvId writeExpression(Expression& expr, std::ostream& out); |
| 115 |
| 116 SpvId writeIntrinsicCall(FunctionCall& c, std::ostream& out); |
| 117 |
| 118 SpvId writeFunctionCall(FunctionCall& c, std::ostream& out); |
| 119 |
| 120 SpvId writeSpecialIntrinsic(FunctionCall& c, SpecialIntrinsic kind, std::ost
ream& out); |
| 121 |
| 122 SpvId writeConstantVector(Constructor& c); |
| 123 |
| 124 SpvId writeFloatConstructor(Constructor& c, std::ostream& out); |
| 125 |
| 126 SpvId writeIntConstructor(Constructor& c, std::ostream& out); |
| 127 |
| 128 SpvId writeMatrixConstructor(Constructor& c, std::ostream& out); |
| 129 |
| 130 SpvId writeVectorConstructor(Constructor& c, std::ostream& out); |
| 131 |
| 132 SpvId writeConstructor(Constructor& c, std::ostream& out); |
| 133 |
| 134 SpvId writeFieldAccess(FieldAccess& f, std::ostream& out); |
| 135 |
| 136 SpvId writeSwizzle(Swizzle& swizzle, std::ostream& out); |
| 137 |
| 138 SpvId writeBinaryOperation(const Type& resultType, const Type& operandType,
SpvId lhs, |
| 139 SpvId rhs, SpvOp_ ifFloat, SpvOp_ ifInt, SpvOp_ i
fUInt, |
| 140 SpvOp_ ifBool, std::ostream& out); |
| 141 |
| 142 SpvId writeBinaryOperation(BinaryExpression& expr, SpvOp_ ifFloat, SpvOp_ if
Int, SpvOp_ ifUInt, |
| 143 std::ostream& out); |
| 144 |
| 145 SpvId writeBinaryExpression(BinaryExpression& b, std::ostream& out); |
| 146 |
| 147 SpvId writeTernaryExpression(TernaryExpression& t, std::ostream& out); |
| 148 |
| 149 SpvId writeIndexExpression(IndexExpression& expr, std::ostream& out); |
| 150 |
| 151 SpvId writeLogicalAnd(BinaryExpression& b, std::ostream& out); |
| 152 |
| 153 SpvId writeLogicalOr(BinaryExpression& o, std::ostream& out); |
| 154 |
| 155 SpvId writePrefixExpression(PrefixExpression& p, std::ostream& out); |
| 156 |
| 157 SpvId writePostfixExpression(PostfixExpression& p, std::ostream& out); |
| 158 |
| 159 SpvId writeBoolLiteral(BoolLiteral& b); |
| 160 |
| 161 SpvId writeIntLiteral(IntLiteral& i); |
| 162 |
| 163 SpvId writeFloatLiteral(FloatLiteral& f); |
| 164 |
| 165 void writeStatement(Statement& s, std::ostream& out); |
| 166 |
| 167 void writeBlock(Block& b, std::ostream& out); |
| 168 |
| 169 void writeIfStatement(IfStatement& stmt, std::ostream& out); |
| 170 |
| 171 void writeForStatement(ForStatement& f, std::ostream& out); |
| 172 |
| 173 void writeReturnStatement(ReturnStatement& r, std::ostream& out); |
| 174 |
| 175 void writeCapabilities(std::ostream& out); |
| 176 |
| 177 void writeInstructions(Program& program, std::ostream& out); |
| 178 |
| 179 void writeOpCode(SpvOp_ opCode, int length, std::ostream& out); |
| 180 |
| 181 void writeWord(int32_t word, std::ostream& out); |
| 182 |
| 183 void writeString(const char* string, std::ostream& out); |
| 184 |
| 185 void writeLabel(SpvId id, std::ostream& out); |
| 186 |
| 187 void writeInstruction(SpvOp_ opCode, std::ostream& out); |
| 188 |
| 189 void writeInstruction(SpvOp_ opCode, const char* string, std::ostream& out); |
| 190 |
| 191 void writeInstruction(SpvOp_ opCode, int32_t word1, std::ostream& out); |
| 192 |
| 193 void writeInstruction(SpvOp_ opCode, int32_t word1, const char* string, std:
:ostream& out); |
| 194 |
| 195 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, const cha
r* string, |
| 196 std::ostream& out); |
| 197 |
| 198 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, std::ostr
eam& out); |
| 199 |
| 200 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w
ord3, |
| 201 std::ostream& out); |
| 202 |
| 203 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w
ord3, int32_t word4, |
| 204 std::ostream& out); |
| 205 |
| 206 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w
ord3, int32_t word4, |
| 207 int32_t word5, std::ostream& out); |
| 208 |
| 209 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w
ord3, int32_t word4, |
| 210 int32_t word5, int32_t word6, std::ostream& out); |
| 211 |
| 212 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w
ord3, int32_t word4, |
| 213 int32_t word5, int32_t word6, int32_t word7, std::ostr
eam& out); |
| 214 |
| 215 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w
ord3, int32_t word4, |
| 216 int32_t word5, int32_t word6, int32_t word7, int32_t w
ord8, |
| 217 std::ostream& out); |
| 218 |
| 219 uint64_t fCapabilities; |
| 220 SpvId fIdCount; |
| 221 SpvId fGLSLExtendedInstructions; |
| 222 typedef std::tuple<IntrinsicKind, int32_t, int32_t, int32_t, int32_t> Intrin
sic; |
| 223 std::unordered_map<std::string, Intrinsic> fIntrinsicMap; |
| 224 std::unordered_map<std::shared_ptr<FunctionDeclaration>, SpvId> fFunctionMap
; |
| 225 std::unordered_map<std::shared_ptr<Variable>, SpvId> fVariableMap; |
| 226 std::unordered_map<std::shared_ptr<Variable>, int32_t> fInterfaceBlockMap; |
| 227 std::unordered_map<std::string, SpvId> fTypeMap; |
| 228 std::stringstream fCapabilitiesBuffer; |
| 229 std::stringstream fGlobalInitializersBuffer; |
| 230 std::stringstream fConstantBuffer; |
| 231 std::stringstream fExternalFunctionsBuffer; |
| 232 std::stringstream fVariableBuffer; |
| 233 std::stringstream fNameBuffer; |
| 234 std::stringstream fDecorationBuffer; |
| 235 |
| 236 SpvId fBoolTrue; |
| 237 SpvId fBoolFalse; |
| 238 std::unordered_map<int64_t, SpvId> fIntConstants; |
| 239 std::unordered_map<uint64_t, SpvId> fUIntConstants; |
| 240 std::unordered_map<float, SpvId> fFloatConstants; |
| 241 std::unordered_map<double, SpvId> fDoubleConstants; |
| 242 // label of the current block, or 0 if we are not in a block |
| 243 SpvId fCurrentBlock; |
| 244 std::stack<SpvId> fBreakTarget; |
| 245 std::stack<SpvId> fContinueTarget; |
| 246 }; |
| 247 |
| 248 } |
| 249 |
| 250 #endif |
OLD | NEW |