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 class LValue { |
| 52 public: |
| 53 virtual ~LValue() {} |
| 54 |
| 55 // returns a pointer to the lvalue, if possible. If the lvalue cannot be
directly referenced |
| 56 // by a pointer (e.g. vector swizzles), returns 0. |
| 57 virtual SpvId getPointer() = 0; |
| 58 |
| 59 virtual SpvId load(std::ostream& out) = 0; |
| 60 |
| 61 virtual void store(SpvId value, std::ostream& out) = 0; |
| 62 }; |
| 63 |
| 64 SPIRVCodeGenerator() |
| 65 : fCapabilities(1 << SpvCapabilityShader) |
| 66 , fIdCount(1) |
| 67 , fBoolTrue(0) |
| 68 , fBoolFalse(0) |
| 69 , fCurrentBlock(0) { |
| 70 this->setupIntrinsics(); |
| 71 } |
| 72 |
| 73 void generateCode(Program& program, std::ostream& out) override; |
| 74 |
| 75 private: |
| 76 enum IntrinsicKind { |
| 77 kGLSL_STD_450_IntrinsicKind, |
| 78 kSPIRV_IntrinsicKind, |
| 79 kSpecial_IntrinsicKind |
| 80 }; |
| 81 |
| 82 enum SpecialIntrinsic { |
| 83 kAtan_SpecialIntrinsic, |
| 84 kTexture_SpecialIntrinsic, |
| 85 kTexture2D_SpecialIntrinsic, |
| 86 kTextureProj_SpecialIntrinsic |
| 87 }; |
| 88 |
| 89 void setupIntrinsics(); |
| 90 |
| 91 SpvId nextId(); |
| 92 |
| 93 SpvId getType(const Type& type); |
| 94 |
| 95 SpvId getFunctionType(std::shared_ptr<FunctionDeclaration> function); |
| 96 |
| 97 SpvId getPointerType(std::shared_ptr<Type> type, SpvStorageClass_ storageCla
ss); |
| 98 |
| 99 std::vector<SpvId> getAccessChain(Expression& expr, std::ostream& out); |
| 100 |
| 101 void writeLayout(const Layout& layout, SpvId target); |
| 102 |
| 103 void writeLayout(const Layout& layout, SpvId target, int member); |
| 104 |
| 105 void writeStruct(const Type& type, SpvId resultId); |
| 106 |
| 107 void writeProgramElement(ProgramElement& pe, std::ostream& out); |
| 108 |
| 109 SpvId writeInterfaceBlock(InterfaceBlock& intf); |
| 110 |
| 111 SpvId writeFunctionStart(std::shared_ptr<FunctionDeclaration> f, std::ostrea
m& out); |
| 112 |
| 113 SpvId writeFunctionDeclaration(std::shared_ptr<FunctionDeclaration> f, std::
ostream& out); |
| 114 |
| 115 SpvId writeFunction(FunctionDefinition& f, std::ostream& out); |
| 116 |
| 117 void writeGlobalVars(VarDeclaration& v, std::ostream& out); |
| 118 |
| 119 void writeVarDeclaration(VarDeclaration& decl, std::ostream& out); |
| 120 |
| 121 SpvId writeVariableReference(VariableReference& ref, std::ostream& out); |
| 122 |
| 123 std::unique_ptr<LValue> getLValue(Expression& value, std::ostream& out); |
| 124 |
| 125 SpvId writeExpression(Expression& expr, std::ostream& out); |
| 126 |
| 127 SpvId writeIntrinsicCall(FunctionCall& c, std::ostream& out); |
| 128 |
| 129 SpvId writeFunctionCall(FunctionCall& c, std::ostream& out); |
| 130 |
| 131 SpvId writeSpecialIntrinsic(FunctionCall& c, SpecialIntrinsic kind, std::ost
ream& out); |
| 132 |
| 133 SpvId writeConstantVector(Constructor& c); |
| 134 |
| 135 SpvId writeFloatConstructor(Constructor& c, std::ostream& out); |
| 136 |
| 137 SpvId writeIntConstructor(Constructor& c, std::ostream& out); |
| 138 |
| 139 SpvId writeMatrixConstructor(Constructor& c, std::ostream& out); |
| 140 |
| 141 SpvId writeVectorConstructor(Constructor& c, std::ostream& out); |
| 142 |
| 143 SpvId writeConstructor(Constructor& c, std::ostream& out); |
| 144 |
| 145 SpvId writeFieldAccess(FieldAccess& f, std::ostream& out); |
| 146 |
| 147 SpvId writeSwizzle(Swizzle& swizzle, std::ostream& out); |
| 148 |
| 149 SpvId writeBinaryOperation(const Type& resultType, const Type& operandType,
SpvId lhs, |
| 150 SpvId rhs, SpvOp_ ifFloat, SpvOp_ ifInt, SpvOp_ i
fUInt, |
| 151 SpvOp_ ifBool, std::ostream& out); |
| 152 |
| 153 SpvId writeBinaryOperation(BinaryExpression& expr, SpvOp_ ifFloat, SpvOp_ if
Int, SpvOp_ ifUInt, |
| 154 std::ostream& out); |
| 155 |
| 156 SpvId writeBinaryExpression(BinaryExpression& b, std::ostream& out); |
| 157 |
| 158 SpvId writeTernaryExpression(TernaryExpression& t, std::ostream& out); |
| 159 |
| 160 SpvId writeIndexExpression(IndexExpression& expr, std::ostream& out); |
| 161 |
| 162 SpvId writeLogicalAnd(BinaryExpression& b, std::ostream& out); |
| 163 |
| 164 SpvId writeLogicalOr(BinaryExpression& o, std::ostream& out); |
| 165 |
| 166 SpvId writePrefixExpression(PrefixExpression& p, std::ostream& out); |
| 167 |
| 168 SpvId writePostfixExpression(PostfixExpression& p, std::ostream& out); |
| 169 |
| 170 SpvId writeBoolLiteral(BoolLiteral& b); |
| 171 |
| 172 SpvId writeIntLiteral(IntLiteral& i); |
| 173 |
| 174 SpvId writeFloatLiteral(FloatLiteral& f); |
| 175 |
| 176 void writeStatement(Statement& s, std::ostream& out); |
| 177 |
| 178 void writeBlock(Block& b, std::ostream& out); |
| 179 |
| 180 void writeIfStatement(IfStatement& stmt, std::ostream& out); |
| 181 |
| 182 void writeForStatement(ForStatement& f, std::ostream& out); |
| 183 |
| 184 void writeReturnStatement(ReturnStatement& r, std::ostream& out); |
| 185 |
| 186 void writeCapabilities(std::ostream& out); |
| 187 |
| 188 void writeInstructions(Program& program, std::ostream& out); |
| 189 |
| 190 void writeOpCode(SpvOp_ opCode, int length, std::ostream& out); |
| 191 |
| 192 void writeWord(int32_t word, std::ostream& out); |
| 193 |
| 194 void writeString(const char* string, std::ostream& out); |
| 195 |
| 196 void writeLabel(SpvId id, std::ostream& out); |
| 197 |
| 198 void writeInstruction(SpvOp_ opCode, std::ostream& out); |
| 199 |
| 200 void writeInstruction(SpvOp_ opCode, const char* string, std::ostream& out); |
| 201 |
| 202 void writeInstruction(SpvOp_ opCode, int32_t word1, std::ostream& out); |
| 203 |
| 204 void writeInstruction(SpvOp_ opCode, int32_t word1, const char* string, std:
:ostream& out); |
| 205 |
| 206 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, const cha
r* string, |
| 207 std::ostream& out); |
| 208 |
| 209 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, std::ostr
eam& out); |
| 210 |
| 211 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w
ord3, |
| 212 std::ostream& out); |
| 213 |
| 214 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w
ord3, int32_t word4, |
| 215 std::ostream& out); |
| 216 |
| 217 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w
ord3, int32_t word4, |
| 218 int32_t word5, std::ostream& out); |
| 219 |
| 220 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w
ord3, int32_t word4, |
| 221 int32_t word5, int32_t word6, std::ostream& out); |
| 222 |
| 223 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w
ord3, int32_t word4, |
| 224 int32_t word5, int32_t word6, int32_t word7, std::ostr
eam& out); |
| 225 |
| 226 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w
ord3, int32_t word4, |
| 227 int32_t word5, int32_t word6, int32_t word7, int32_t w
ord8, |
| 228 std::ostream& out); |
| 229 |
| 230 uint64_t fCapabilities; |
| 231 SpvId fIdCount; |
| 232 SpvId fGLSLExtendedInstructions; |
| 233 typedef std::tuple<IntrinsicKind, int32_t, int32_t, int32_t, int32_t> Intrin
sic; |
| 234 std::unordered_map<std::string, Intrinsic> fIntrinsicMap; |
| 235 std::unordered_map<std::shared_ptr<FunctionDeclaration>, SpvId> fFunctionMap
; |
| 236 std::unordered_map<std::shared_ptr<Variable>, SpvId> fVariableMap; |
| 237 std::unordered_map<std::shared_ptr<Variable>, int32_t> fInterfaceBlockMap; |
| 238 std::unordered_map<std::string, SpvId> fTypeMap; |
| 239 std::stringstream fCapabilitiesBuffer; |
| 240 std::stringstream fGlobalInitializersBuffer; |
| 241 std::stringstream fConstantBuffer; |
| 242 std::stringstream fExternalFunctionsBuffer; |
| 243 std::stringstream fVariableBuffer; |
| 244 std::stringstream fNameBuffer; |
| 245 std::stringstream fDecorationBuffer; |
| 246 |
| 247 SpvId fBoolTrue; |
| 248 SpvId fBoolFalse; |
| 249 std::unordered_map<int64_t, SpvId> fIntConstants; |
| 250 std::unordered_map<uint64_t, SpvId> fUIntConstants; |
| 251 std::unordered_map<float, SpvId> fFloatConstants; |
| 252 std::unordered_map<double, SpvId> fDoubleConstants; |
| 253 // label of the current block, or 0 if we are not in a block |
| 254 SpvId fCurrentBlock; |
| 255 std::stack<SpvId> fBreakTarget; |
| 256 std::stack<SpvId> fContinueTarget; |
| 257 |
| 258 friend class PointerLValue; |
| 259 friend class SwizzleLValue; |
| 260 }; |
| 261 |
| 262 } |
| 263 |
| 264 #endif |
OLD | NEW |