SkSLByteCode.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*
  2. * Copyright 2019 Google LLC
  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. #ifndef SKSL_BYTECODE
  8. #define SKSL_BYTECODE
  9. #include "src/sksl/SkSLString.h"
  10. #include <memory>
  11. #include <vector>
  12. namespace SkSL {
  13. class ExternalValue;
  14. struct FunctionDeclaration;
  15. #define VECTOR(name) name, name ## 2, name ## 3, name ## 4
  16. #define VECTOR_MATRIX(name) name, name ## 2, name ## 3, name ## 4, name ## N
  17. enum class ByteCodeInstruction : uint16_t {
  18. // B = bool, F = float, I = int, S = signed, U = unsigned
  19. VECTOR_MATRIX(kAddF),
  20. VECTOR(kAddI),
  21. kAndB,
  22. kBranch,
  23. // Followed by a byte indicating the index of the function to call
  24. kCall,
  25. // Followed by three bytes indicating: the number of argument slots, the number of return slots,
  26. // and the index of the external value to call
  27. kCallExternal,
  28. // For dynamic array access: Followed by byte indicating length of array
  29. kClampIndex,
  30. VECTOR(kCompareIEQ),
  31. VECTOR(kCompareINEQ),
  32. VECTOR_MATRIX(kCompareFEQ),
  33. VECTOR(kCompareFGT),
  34. VECTOR(kCompareFGTEQ),
  35. VECTOR(kCompareFLT),
  36. VECTOR(kCompareFLTEQ),
  37. VECTOR_MATRIX(kCompareFNEQ),
  38. VECTOR(kCompareSGT),
  39. VECTOR(kCompareSGTEQ),
  40. VECTOR(kCompareSLT),
  41. VECTOR(kCompareSLTEQ),
  42. VECTOR(kCompareUGT),
  43. VECTOR(kCompareUGTEQ),
  44. VECTOR(kCompareULT),
  45. VECTOR(kCompareULTEQ),
  46. VECTOR(kConvertFtoI),
  47. VECTOR(kConvertStoF),
  48. VECTOR(kConvertUtoF),
  49. VECTOR(kCos),
  50. kCross,
  51. VECTOR_MATRIX(kDivideF),
  52. VECTOR(kDivideS),
  53. VECTOR(kDivideU),
  54. // Duplicates the top stack value
  55. VECTOR_MATRIX(kDup),
  56. kInverse2x2, kInverse3x3, kInverse4x4,
  57. // kLoad/kLoadGlobal are followed by a byte indicating the local/global slot to load
  58. VECTOR(kLoad),
  59. VECTOR(kLoadGlobal),
  60. // As kLoad/kLoadGlobal, then a count byte (1-4), and then one byte per swizzle component (0-3).
  61. kLoadSwizzle,
  62. kLoadSwizzleGlobal,
  63. // kLoadExtended* are fallback load ops when we lack a specialization. They are followed by a
  64. // count byte, and get the slot to load from the top of the stack.
  65. kLoadExtended,
  66. kLoadExtendedGlobal,
  67. // Followed by four bytes: srcCols, srcRows, dstCols, dstRows. Consumes the src matrix from the
  68. // stack, and replaces it with the dst matrix. Per GLSL rules, there are no restrictions on
  69. // dimensions. Any overlapping values are copied, and any other values are filled in with the
  70. // identity matrix.
  71. kMatrixToMatrix,
  72. // Followed by three bytes: leftCols (== rightRows), leftRows, rightCols
  73. kMatrixMultiply,
  74. VECTOR_MATRIX(kNegateF),
  75. VECTOR(kNegateI),
  76. VECTOR(kMix),
  77. VECTOR_MATRIX(kMultiplyF),
  78. VECTOR(kMultiplyI),
  79. kNotB,
  80. kOrB,
  81. VECTOR_MATRIX(kPop),
  82. // Followed by a 32 bit value containing the value to push
  83. kPushImmediate,
  84. // Followed by a byte indicating external value to read
  85. VECTOR(kReadExternal),
  86. VECTOR(kRemainderF),
  87. VECTOR(kRemainderS),
  88. VECTOR(kRemainderU),
  89. // Followed by a byte indicating the number of slots to reserve on the stack (for later return)
  90. kReserve,
  91. // Followed by a byte indicating the number of slots being returned
  92. kReturn,
  93. // Followed by two bytes indicating columns and rows of matrix (2, 3, or 4 each).
  94. // Takes a single value from the top of the stack, and converts to a CxR matrix with that value
  95. // replicated along the diagonal (and zero elsewhere), per the GLSL matrix construction rules.
  96. kScalarToMatrix,
  97. VECTOR(kSin),
  98. VECTOR(kSqrt),
  99. // kStore/kStoreGlobal are followed by a byte indicating the local/global slot to store
  100. VECTOR(kStore),
  101. VECTOR(kStoreGlobal),
  102. // Fallback stores. Followed by count byte, and get the slot to store from the top of the stack
  103. kStoreExtended,
  104. kStoreExtendedGlobal,
  105. // As kStore/kStoreGlobal, then a count byte (1-4), then one byte per swizzle component (0-3).
  106. // Expects the stack to look like: ... v1 v2 v3 v4, where the number of 'v's is equal to the
  107. // number of swizzle components. After the store, all v's are popped from the stack.
  108. kStoreSwizzle,
  109. kStoreSwizzleGlobal,
  110. // As above, but gets the store slot from the top of the stack (before values to be stored)
  111. kStoreSwizzleIndirect,
  112. kStoreSwizzleIndirectGlobal,
  113. // Followed by two count bytes (1-4), and then one byte per swizzle component (0-3). The first
  114. // count byte provides the current vector size (the vector is the top n stack elements), and the
  115. // second count byte provides the swizzle component count.
  116. kSwizzle,
  117. VECTOR_MATRIX(kSubtractF),
  118. VECTOR(kSubtractI),
  119. VECTOR(kTan),
  120. // Followed by a byte indicating external value to write
  121. VECTOR(kWriteExternal),
  122. kXorB,
  123. kMaskPush,
  124. kMaskPop,
  125. kMaskNegate,
  126. // Followed by count byte
  127. kMaskBlend,
  128. // Followed by address
  129. kBranchIfAllFalse,
  130. kLoopBegin,
  131. kLoopNext,
  132. kLoopMask,
  133. kLoopEnd,
  134. kLoopBreak,
  135. kLoopContinue,
  136. };
  137. #undef VECTOR
  138. struct ByteCodeFunction {
  139. ByteCodeFunction(const FunctionDeclaration* declaration);
  140. struct Parameter {
  141. int fSlotCount;
  142. bool fIsOutParameter;
  143. };
  144. SkSL::String fName;
  145. std::vector<Parameter> fParameters;
  146. int fParameterCount;
  147. int fLocalCount = 0;
  148. int fStackCount = 0;
  149. int fConditionCount = 0;
  150. int fLoopCount = 0;
  151. int fReturnCount = 0;
  152. std::vector<uint8_t> fCode;
  153. /**
  154. * Print bytecode disassembly to stdout.
  155. */
  156. void disassemble() const;
  157. };
  158. struct SK_API ByteCode {
  159. static constexpr int kVecWidth = 16;
  160. ByteCode() = default;
  161. ByteCode(const ByteCode&) = delete;
  162. ByteCode& operator=(const ByteCode&) = delete;
  163. int fGlobalCount = 0;
  164. // one entry per input slot, contains the global slot to which the input slot maps
  165. std::vector<uint8_t> fInputSlots;
  166. std::vector<std::unique_ptr<ByteCodeFunction>> fFunctions;
  167. std::vector<ExternalValue*> fExternalValues;
  168. const ByteCodeFunction* getFunction(const char* name) const {
  169. for (const auto& f : fFunctions) {
  170. if (f->fName == name) {
  171. return f.get();
  172. }
  173. }
  174. return nullptr;
  175. }
  176. /**
  177. * Invokes the specified function with the given arguments, 'N' times.
  178. * 'args', 'outReturn', and 'uniforms' are collections of 32-bit values (typically floats,
  179. * but possibly int32_t or uint32_t, depending on the types used in the SkSL).
  180. * Any 'out' or 'inout' parameters will result in the 'args' array being modified.
  181. * The return value is stored in 'outReturn' (may be null, to discard the return value).
  182. * 'uniforms' are mapped to 'uniform' globals, in order.
  183. */
  184. bool SKSL_WARN_UNUSED_RESULT run(const ByteCodeFunction*, float* args, float* outReturn, int N,
  185. const float* uniforms, int uniformCount) const;
  186. bool SKSL_WARN_UNUSED_RESULT runStriped(const ByteCodeFunction*,
  187. float* args[], int nargs, int N,
  188. const float* uniforms, int uniformCount,
  189. float* outArgs[], int outArgCount) const;
  190. };
  191. }
  192. #endif