/src/skia/src/sksl/codegen/SkSLSPIRVCodeGenerator.h
Line | Count | Source (jump to first uncovered line) |
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 <stack> |
12 | | #include <tuple> |
13 | | #include <unordered_map> |
14 | | #include <unordered_set> |
15 | | |
16 | | #include "include/private/SkSLModifiers.h" |
17 | | #include "include/private/SkSLProgramElement.h" |
18 | | #include "include/private/SkSLStatement.h" |
19 | | #include "src/core/SkOpts.h" |
20 | | #include "src/sksl/SkSLMemoryLayout.h" |
21 | | #include "src/sksl/SkSLStringStream.h" |
22 | | #include "src/sksl/codegen/SkSLCodeGenerator.h" |
23 | | #include "src/sksl/ir/SkSLBinaryExpression.h" |
24 | | #include "src/sksl/ir/SkSLBoolLiteral.h" |
25 | | #include "src/sksl/ir/SkSLConstructor.h" |
26 | | #include "src/sksl/ir/SkSLConstructorArray.h" |
27 | | #include "src/sksl/ir/SkSLConstructorCompound.h" |
28 | | #include "src/sksl/ir/SkSLConstructorCompoundCast.h" |
29 | | #include "src/sksl/ir/SkSLConstructorDiagonalMatrix.h" |
30 | | #include "src/sksl/ir/SkSLConstructorMatrixResize.h" |
31 | | #include "src/sksl/ir/SkSLConstructorScalarCast.h" |
32 | | #include "src/sksl/ir/SkSLConstructorSplat.h" |
33 | | #include "src/sksl/ir/SkSLConstructorStruct.h" |
34 | | #include "src/sksl/ir/SkSLDoStatement.h" |
35 | | #include "src/sksl/ir/SkSLFieldAccess.h" |
36 | | #include "src/sksl/ir/SkSLFloatLiteral.h" |
37 | | #include "src/sksl/ir/SkSLForStatement.h" |
38 | | #include "src/sksl/ir/SkSLFunctionCall.h" |
39 | | #include "src/sksl/ir/SkSLFunctionDeclaration.h" |
40 | | #include "src/sksl/ir/SkSLFunctionDefinition.h" |
41 | | #include "src/sksl/ir/SkSLIfStatement.h" |
42 | | #include "src/sksl/ir/SkSLIndexExpression.h" |
43 | | #include "src/sksl/ir/SkSLIntLiteral.h" |
44 | | #include "src/sksl/ir/SkSLInterfaceBlock.h" |
45 | | #include "src/sksl/ir/SkSLPostfixExpression.h" |
46 | | #include "src/sksl/ir/SkSLPrefixExpression.h" |
47 | | #include "src/sksl/ir/SkSLReturnStatement.h" |
48 | | #include "src/sksl/ir/SkSLSwitchStatement.h" |
49 | | #include "src/sksl/ir/SkSLSwizzle.h" |
50 | | #include "src/sksl/ir/SkSLTernaryExpression.h" |
51 | | #include "src/sksl/ir/SkSLVarDeclarations.h" |
52 | | #include "src/sksl/ir/SkSLVariableReference.h" |
53 | | #include "src/sksl/spirv.h" |
54 | | |
55 | | namespace SkSL { |
56 | | |
57 | | struct SPIRVNumberConstant { |
58 | 109k | bool operator==(const SPIRVNumberConstant& that) const { |
59 | 109k | return fValueBits == that.fValueBits && |
60 | 69.4k | fKind == that.fKind; |
61 | 109k | } |
62 | | int64_t fValueBits; // contains either an SKSL_INT or zero-padded bits from an SKSL_FLOAT |
63 | | SkSL::Type::NumberKind fKind; |
64 | | }; |
65 | | |
66 | | struct SPIRVVectorConstant { |
67 | 14.7k | bool operator==(const SPIRVVectorConstant& that) const { |
68 | 14.7k | return fTypeId == that.fTypeId && |
69 | 14.5k | fValueId[0] == that.fValueId[0] && |
70 | 8.16k | fValueId[1] == that.fValueId[1] && |
71 | 7.70k | fValueId[2] == that.fValueId[2] && |
72 | 7.67k | fValueId[3] == that.fValueId[3]; |
73 | 14.7k | } |
74 | | SpvId fTypeId; |
75 | | SpvId fValueId[4]; |
76 | | }; |
77 | | |
78 | | } // namespace SkSL |
79 | | |
80 | | namespace std { |
81 | | |
82 | | template <> |
83 | | struct hash<SkSL::SPIRVNumberConstant> { |
84 | 86.4k | size_t operator()(const SkSL::SPIRVNumberConstant& key) const { |
85 | 86.4k | return key.fValueBits ^ (int)key.fKind; |
86 | 86.4k | } |
87 | | }; |
88 | | |
89 | | template <> |
90 | | struct hash<SkSL::SPIRVVectorConstant> { |
91 | 11.7k | size_t operator()(const SkSL::SPIRVVectorConstant& key) const { |
92 | 11.7k | return SkOpts::hash(&key, sizeof(key)); |
93 | 11.7k | } |
94 | | }; |
95 | | |
96 | | } // namespace std |
97 | | |
98 | | namespace SkSL { |
99 | | |
100 | | /** |
101 | | * Converts a Program into a SPIR-V binary. |
102 | | */ |
103 | | class SPIRVCodeGenerator : public CodeGenerator { |
104 | | public: |
105 | | class LValue { |
106 | | public: |
107 | 31.3k | virtual ~LValue() {} |
108 | | |
109 | | // returns a pointer to the lvalue, if possible. If the lvalue cannot be directly referenced |
110 | | // by a pointer (e.g. vector swizzles), returns -1. |
111 | 0 | virtual SpvId getPointer() { return -1; } |
112 | | |
113 | | // Returns true if a valid pointer returned by getPointer represents a memory object |
114 | | // (see https://github.com/KhronosGroup/SPIRV-Tools/issues/2892). Has no meaning if |
115 | | // getPointer() returns -1. |
116 | 0 | virtual bool isMemoryObjectPointer() const { return true; } |
117 | | |
118 | | // Applies a swizzle to the components of the LValue, if possible. This is used to create |
119 | | // LValues that are swizzes-of-swizzles. Non-swizzle LValues can just return false. |
120 | 5.27k | virtual bool applySwizzle(const ComponentArray& components, const Type& newType) { |
121 | 5.27k | return false; |
122 | 5.27k | } |
123 | | |
124 | | virtual SpvId load(OutputStream& out) = 0; |
125 | | |
126 | | virtual void store(SpvId value, OutputStream& out) = 0; |
127 | | }; |
128 | | |
129 | | SPIRVCodeGenerator(const Context* context, |
130 | | const Program* program, |
131 | | OutputStream* out) |
132 | | : INHERITED(context, program, out) |
133 | | , fDefaultLayout(MemoryLayout::k140_Standard) |
134 | | , fCapabilities(0) |
135 | | , fIdCount(1) |
136 | | , fBoolTrue(0) |
137 | | , fBoolFalse(0) |
138 | | , fSetupFragPosition(false) |
139 | | , fCurrentBlock(0) |
140 | 4.85k | , fSynthetics(&fContext.errors(), /*builtin=*/true) { |
141 | 4.85k | this->setupIntrinsics(); |
142 | 4.85k | } |
143 | | |
144 | | bool generateCode() override; |
145 | | |
146 | | private: |
147 | | enum IntrinsicOpcodeKind { |
148 | | kGLSL_STD_450_IntrinsicOpcodeKind, |
149 | | kSPIRV_IntrinsicOpcodeKind, |
150 | | kSpecial_IntrinsicOpcodeKind |
151 | | }; |
152 | | |
153 | | enum SpecialIntrinsic { |
154 | | kAtan_SpecialIntrinsic, |
155 | | kClamp_SpecialIntrinsic, |
156 | | kMatrixCompMult_SpecialIntrinsic, |
157 | | kMax_SpecialIntrinsic, |
158 | | kMin_SpecialIntrinsic, |
159 | | kMix_SpecialIntrinsic, |
160 | | kMod_SpecialIntrinsic, |
161 | | kDFdy_SpecialIntrinsic, |
162 | | kSaturate_SpecialIntrinsic, |
163 | | kSampledImage_SpecialIntrinsic, |
164 | | kSmoothStep_SpecialIntrinsic, |
165 | | kStep_SpecialIntrinsic, |
166 | | kSubpassLoad_SpecialIntrinsic, |
167 | | kTexture_SpecialIntrinsic, |
168 | | }; |
169 | | |
170 | | enum class Precision { |
171 | | kDefault, |
172 | | kRelaxed, |
173 | | }; |
174 | | |
175 | | void setupIntrinsics(); |
176 | | |
177 | | /** |
178 | | * Pass in the type to automatically add a RelaxedPrecision decoration for the id when |
179 | | * appropriate, or null to never add one. |
180 | | */ |
181 | | SpvId nextId(const Type* type); |
182 | | |
183 | | SpvId nextId(Precision precision); |
184 | | |
185 | | const Type& getActualType(const Type& type); |
186 | | |
187 | | SpvId getType(const Type& type); |
188 | | |
189 | | SpvId getType(const Type& type, const MemoryLayout& layout); |
190 | | |
191 | | SpvId getImageType(const Type& type); |
192 | | |
193 | | SpvId getFunctionType(const FunctionDeclaration& function); |
194 | | |
195 | | SpvId getPointerType(const Type& type, SpvStorageClass_ storageClass); |
196 | | |
197 | | SpvId getPointerType(const Type& type, const MemoryLayout& layout, |
198 | | SpvStorageClass_ storageClass); |
199 | | |
200 | | std::vector<SpvId> getAccessChain(const Expression& expr, OutputStream& out); |
201 | | |
202 | | void writeLayout(const Layout& layout, SpvId target); |
203 | | |
204 | | void writeLayout(const Layout& layout, SpvId target, int member); |
205 | | |
206 | | void writeStruct(const Type& type, const MemoryLayout& layout, SpvId resultId); |
207 | | |
208 | | void writeProgramElement(const ProgramElement& pe, OutputStream& out); |
209 | | |
210 | | SpvId writeInterfaceBlock(const InterfaceBlock& intf, bool appendRTFlip = true); |
211 | | |
212 | | SpvId writeFunctionStart(const FunctionDeclaration& f, OutputStream& out); |
213 | | |
214 | | SpvId writeFunctionDeclaration(const FunctionDeclaration& f, OutputStream& out); |
215 | | |
216 | | SpvId writeFunction(const FunctionDefinition& f, OutputStream& out); |
217 | | |
218 | | void writeGlobalVar(ProgramKind kind, const VarDeclaration& v); |
219 | | |
220 | | void writeVarDeclaration(const VarDeclaration& var, OutputStream& out); |
221 | | |
222 | | SpvId writeVariableReference(const VariableReference& ref, OutputStream& out); |
223 | | |
224 | | int findUniformFieldIndex(const Variable& var) const; |
225 | | |
226 | | std::unique_ptr<LValue> getLValue(const Expression& value, OutputStream& out); |
227 | | |
228 | | SpvId writeExpression(const Expression& expr, OutputStream& out); |
229 | | |
230 | | SpvId writeIntrinsicCall(const FunctionCall& c, OutputStream& out); |
231 | | |
232 | | SpvId writeFunctionCall(const FunctionCall& c, OutputStream& out); |
233 | | |
234 | | |
235 | | void writeGLSLExtendedInstruction(const Type& type, SpvId id, SpvId floatInst, |
236 | | SpvId signedInst, SpvId unsignedInst, |
237 | | const std::vector<SpvId>& args, OutputStream& out); |
238 | | |
239 | | /** |
240 | | * Promotes an expression to a vector. If the expression is already a vector with vectorSize |
241 | | * columns, returns it unmodified. If the expression is a scalar, either promotes it to a |
242 | | * vector (if vectorSize > 1) or returns it unmodified (if vectorSize == 1). Asserts if the |
243 | | * expression is already a vector and it does not have vectorSize columns. |
244 | | */ |
245 | | SpvId vectorize(const Expression& expr, int vectorSize, OutputStream& out); |
246 | | |
247 | | /** |
248 | | * Given a list of potentially mixed scalars and vectors, promotes the scalars to match the |
249 | | * size of the vectors and returns the ids of the written expressions. e.g. given (float, vec2), |
250 | | * returns (vec2(float), vec2). It is an error to use mismatched vector sizes, e.g. (float, |
251 | | * vec2, vec3). |
252 | | */ |
253 | | std::vector<SpvId> vectorize(const ExpressionArray& args, OutputStream& out); |
254 | | |
255 | | SpvId writeSpecialIntrinsic(const FunctionCall& c, SpecialIntrinsic kind, OutputStream& out); |
256 | | |
257 | | SpvId writeConstantVector(const AnyConstructor& c); |
258 | | |
259 | | SpvId writeScalarToMatrixSplat(const Type& matrixType, SpvId scalarId, OutputStream& out); |
260 | | |
261 | | SpvId writeFloatConstructor(const AnyConstructor& c, OutputStream& out); |
262 | | |
263 | | SpvId castScalarToFloat(SpvId inputId, const Type& inputType, const Type& outputType, |
264 | | OutputStream& out); |
265 | | |
266 | | SpvId writeIntConstructor(const AnyConstructor& c, OutputStream& out); |
267 | | |
268 | | SpvId castScalarToSignedInt(SpvId inputId, const Type& inputType, const Type& outputType, |
269 | | OutputStream& out); |
270 | | |
271 | | SpvId writeUIntConstructor(const AnyConstructor& c, OutputStream& out); |
272 | | |
273 | | SpvId castScalarToUnsignedInt(SpvId inputId, const Type& inputType, const Type& outputType, |
274 | | OutputStream& out); |
275 | | |
276 | | SpvId writeBooleanConstructor(const AnyConstructor& c, OutputStream& out); |
277 | | |
278 | | SpvId castScalarToBoolean(SpvId inputId, const Type& inputType, const Type& outputType, |
279 | | OutputStream& out); |
280 | | |
281 | | SpvId castScalarToType(SpvId inputExprId, const Type& inputType, const Type& outputType, |
282 | | OutputStream& out); |
283 | | |
284 | | /** |
285 | | * Writes a matrix with the diagonal entries all equal to the provided expression, and all other |
286 | | * entries equal to zero. |
287 | | */ |
288 | | void writeUniformScaleMatrix(SpvId id, SpvId diagonal, const Type& type, OutputStream& out); |
289 | | |
290 | | /** |
291 | | * Writes a potentially-different-sized copy of a matrix. Entries which do not exist in the |
292 | | * source matrix are filled with zero; entries which do not exist in the destination matrix are |
293 | | * ignored. |
294 | | */ |
295 | | SpvId writeMatrixCopy(SpvId src, const Type& srcType, const Type& dstType, OutputStream& out); |
296 | | |
297 | | void addColumnEntry(const Type& columnType, std::vector<SpvId>* currentColumn, |
298 | | std::vector<SpvId>* columnIds, int rows, SpvId entry, OutputStream& out); |
299 | | |
300 | | SpvId writeConstructorCompound(const ConstructorCompound& c, OutputStream& out); |
301 | | |
302 | | SpvId writeMatrixConstructor(const ConstructorCompound& c, OutputStream& out); |
303 | | |
304 | | SpvId writeVectorConstructor(const ConstructorCompound& c, OutputStream& out); |
305 | | |
306 | | SpvId writeCompositeConstructor(const AnyConstructor& c, OutputStream& out); |
307 | | |
308 | | SpvId writeConstructorDiagonalMatrix(const ConstructorDiagonalMatrix& c, OutputStream& out); |
309 | | |
310 | | SpvId writeConstructorMatrixResize(const ConstructorMatrixResize& c, OutputStream& out); |
311 | | |
312 | | SpvId writeConstructorScalarCast(const ConstructorScalarCast& c, OutputStream& out); |
313 | | |
314 | | SpvId writeConstructorSplat(const ConstructorSplat& c, OutputStream& out); |
315 | | |
316 | | SpvId writeConstructorCompoundCast(const ConstructorCompoundCast& c, OutputStream& out); |
317 | | |
318 | | SpvId writeComposite(const std::vector<SpvId>& arguments, const Type& type, OutputStream& out); |
319 | | |
320 | | SpvId writeFieldAccess(const FieldAccess& f, OutputStream& out); |
321 | | |
322 | | SpvId writeSwizzle(const Swizzle& swizzle, OutputStream& out); |
323 | | |
324 | | /** |
325 | | * Folds the potentially-vector result of a logical operation down to a single bool. If |
326 | | * operandType is a vector type, assumes that the intermediate result in id is a bvec of the |
327 | | * same dimensions, and applys all() to it to fold it down to a single bool value. Otherwise, |
328 | | * returns the original id value. |
329 | | */ |
330 | | SpvId foldToBool(SpvId id, const Type& operandType, SpvOp op, OutputStream& out); |
331 | | |
332 | | SpvId writeMatrixComparison(const Type& operandType, SpvId lhs, SpvId rhs, SpvOp_ floatOperator, |
333 | | SpvOp_ intOperator, SpvOp_ vectorMergeOperator, |
334 | | SpvOp_ mergeOperator, OutputStream& out); |
335 | | |
336 | | SpvId writeStructComparison(const Type& structType, SpvId lhs, Operator op, SpvId rhs, |
337 | | OutputStream& out); |
338 | | |
339 | | SpvId writeArrayComparison(const Type& structType, SpvId lhs, Operator op, SpvId rhs, |
340 | | OutputStream& out); |
341 | | |
342 | | // Used by writeStructComparison and writeArrayComparison to logically combine field-by-field |
343 | | // comparisons into an overall comparison result. |
344 | | // - `a.x == b.x` merged with `a.y == b.y` generates `(a.x == b.x) && (a.y == b.y)` |
345 | | // - `a.x != b.x` merged with `a.y != b.y` generates `(a.x != b.x) || (a.y != b.y)` |
346 | | SpvId mergeComparisons(SpvId comparison, SpvId allComparisons, Operator op, OutputStream& out); |
347 | | |
348 | | SpvId writeComponentwiseMatrixBinary(const Type& operandType, SpvId lhs, SpvId rhs, |
349 | | SpvOp_ op, OutputStream& out); |
350 | | |
351 | | SpvId writeBinaryOperation(const Type& resultType, const Type& operandType, SpvId lhs, |
352 | | SpvId rhs, SpvOp_ ifFloat, SpvOp_ ifInt, SpvOp_ ifUInt, |
353 | | SpvOp_ ifBool, OutputStream& out); |
354 | | |
355 | | SpvId writeBinaryOperation(const BinaryExpression& expr, SpvOp_ ifFloat, SpvOp_ ifInt, |
356 | | SpvOp_ ifUInt, OutputStream& out); |
357 | | |
358 | | SpvId writeReciprocal(const Type& type, SpvId value, OutputStream& out); |
359 | | |
360 | | SpvId writeBinaryExpression(const Type& leftType, SpvId lhs, Operator op, |
361 | | const Type& rightType, SpvId rhs, const Type& resultType, |
362 | | OutputStream& out); |
363 | | |
364 | | SpvId writeBinaryExpression(const BinaryExpression& b, OutputStream& out); |
365 | | |
366 | | SpvId writeTernaryExpression(const TernaryExpression& t, OutputStream& out); |
367 | | |
368 | | SpvId writeIndexExpression(const IndexExpression& expr, OutputStream& out); |
369 | | |
370 | | SpvId writeLogicalAnd(const Expression& left, const Expression& right, OutputStream& out); |
371 | | |
372 | | SpvId writeLogicalOr(const Expression& left, const Expression& right, OutputStream& out); |
373 | | |
374 | | SpvId writePrefixExpression(const PrefixExpression& p, OutputStream& out); |
375 | | |
376 | | SpvId writePostfixExpression(const PostfixExpression& p, OutputStream& out); |
377 | | |
378 | | SpvId writeBoolLiteral(const BoolLiteral& b); |
379 | | |
380 | | SpvId writeIntLiteral(const IntLiteral& i); |
381 | | |
382 | | SpvId writeFloatLiteral(const FloatLiteral& f); |
383 | | |
384 | | void writeStatement(const Statement& s, OutputStream& out); |
385 | | |
386 | | void writeBlock(const Block& b, OutputStream& out); |
387 | | |
388 | | void writeIfStatement(const IfStatement& stmt, OutputStream& out); |
389 | | |
390 | | void writeForStatement(const ForStatement& f, OutputStream& out); |
391 | | |
392 | | void writeDoStatement(const DoStatement& d, OutputStream& out); |
393 | | |
394 | | void writeSwitchStatement(const SwitchStatement& s, OutputStream& out); |
395 | | |
396 | | void writeReturnStatement(const ReturnStatement& r, OutputStream& out); |
397 | | |
398 | | void writeCapabilities(OutputStream& out); |
399 | | |
400 | | void writeInstructions(const Program& program, OutputStream& out); |
401 | | |
402 | | void writeOpCode(SpvOp_ opCode, int length, OutputStream& out); |
403 | | |
404 | | void writeWord(int32_t word, OutputStream& out); |
405 | | |
406 | | void writeString(skstd::string_view s, OutputStream& out); |
407 | | |
408 | | void writeLabel(SpvId id, OutputStream& out); |
409 | | |
410 | | void writeInstruction(SpvOp_ opCode, OutputStream& out); |
411 | | |
412 | | void writeInstruction(SpvOp_ opCode, skstd::string_view string, OutputStream& out); |
413 | | |
414 | | void writeInstruction(SpvOp_ opCode, int32_t word1, OutputStream& out); |
415 | | |
416 | | void writeInstruction(SpvOp_ opCode, int32_t word1, skstd::string_view string, |
417 | | OutputStream& out); |
418 | | |
419 | | void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, skstd::string_view string, |
420 | | OutputStream& out); |
421 | | |
422 | | void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, OutputStream& out); |
423 | | |
424 | | void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, |
425 | | OutputStream& out); |
426 | | |
427 | | void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4, |
428 | | OutputStream& out); |
429 | | |
430 | | void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4, |
431 | | int32_t word5, OutputStream& out); |
432 | | |
433 | | void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4, |
434 | | int32_t word5, int32_t word6, OutputStream& out); |
435 | | |
436 | | void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4, |
437 | | int32_t word5, int32_t word6, int32_t word7, OutputStream& out); |
438 | | |
439 | | void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4, |
440 | | int32_t word5, int32_t word6, int32_t word7, int32_t word8, |
441 | | OutputStream& out); |
442 | | |
443 | | void writeGeometryShaderExecutionMode(SpvId entryPoint, OutputStream& out); |
444 | | |
445 | | bool isDead(const Variable& var) const; |
446 | | |
447 | | MemoryLayout memoryLayoutForVariable(const Variable&) const; |
448 | | |
449 | | struct EntrypointAdapter { |
450 | | std::unique_ptr<FunctionDefinition> entrypointDef; |
451 | | std::unique_ptr<FunctionDeclaration> entrypointDecl; |
452 | | Layout fLayout; |
453 | | Modifiers fModifiers; |
454 | | }; |
455 | | |
456 | | EntrypointAdapter writeEntrypointAdapter(const FunctionDeclaration& main); |
457 | | |
458 | | struct UniformBuffer { |
459 | | std::unique_ptr<InterfaceBlock> fInterfaceBlock; |
460 | | std::unique_ptr<Variable> fInnerVariable; |
461 | | std::unique_ptr<Type> fStruct; |
462 | | }; |
463 | | |
464 | | void writeUniformBuffer(std::shared_ptr<SymbolTable> topLevelSymbolTable); |
465 | | |
466 | | void addRTFlipUniform(int offset); |
467 | | |
468 | | const MemoryLayout fDefaultLayout; |
469 | | |
470 | | uint64_t fCapabilities; |
471 | | SpvId fIdCount; |
472 | | SpvId fGLSLExtendedInstructions; |
473 | | typedef std::tuple<IntrinsicOpcodeKind, int32_t, int32_t, int32_t, int32_t> Intrinsic; |
474 | | std::unordered_map<IntrinsicKind, Intrinsic> fIntrinsicMap; |
475 | | std::unordered_map<const FunctionDeclaration*, SpvId> fFunctionMap; |
476 | | std::unordered_map<const Variable*, SpvId> fVariableMap; |
477 | | std::unordered_map<const Variable*, int32_t> fInterfaceBlockMap; |
478 | | std::unordered_map<String, SpvId> fImageTypeMap; |
479 | | std::unordered_map<String, SpvId> fTypeMap; |
480 | | StringStream fCapabilitiesBuffer; |
481 | | StringStream fGlobalInitializersBuffer; |
482 | | StringStream fConstantBuffer; |
483 | | StringStream fExtraGlobalsBuffer; |
484 | | StringStream fVariableBuffer; |
485 | | StringStream fNameBuffer; |
486 | | StringStream fDecorationBuffer; |
487 | | |
488 | | SpvId fBoolTrue; |
489 | | SpvId fBoolFalse; |
490 | | std::unordered_map<SPIRVNumberConstant, SpvId> fNumberConstants; |
491 | | std::unordered_map<SPIRVVectorConstant, SpvId> fVectorConstants; |
492 | | bool fSetupFragPosition; |
493 | | // label of the current block, or 0 if we are not in a block |
494 | | SpvId fCurrentBlock; |
495 | | std::stack<SpvId> fBreakTarget; |
496 | | std::stack<SpvId> fContinueTarget; |
497 | | bool fWroteRTFlip = false; |
498 | | // holds variables synthesized during output, for lifetime purposes |
499 | | SymbolTable fSynthetics; |
500 | | int fSkInCount = 1; |
501 | | // Holds a list of uniforms that were declared as globals at the top-level instead of in an |
502 | | // interface block. |
503 | | UniformBuffer fUniformBuffer; |
504 | | std::vector<const VarDeclaration*> fTopLevelUniforms; |
505 | | std::unordered_map<const Variable*, int> fTopLevelUniformMap; //<var, UniformBuffer field index> |
506 | | std::unordered_set<const Variable*> fSPIRVBonusVariables; |
507 | | SpvId fUniformBufferId = -1; |
508 | | |
509 | | friend class PointerLValue; |
510 | | friend class SwizzleLValue; |
511 | | |
512 | | using INHERITED = CodeGenerator; |
513 | | }; |
514 | | |
515 | | } // namespace SkSL |
516 | | |
517 | | #endif |