SkSLByteCode.cpp 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266
  1. /*
  2. * Copyright 2018 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. #ifndef SKSL_STANDALONE
  8. #include "include/core/SkPoint3.h"
  9. #include "include/private/SkVx.h"
  10. #include "src/core/SkUtils.h" // sk_unaligned_load
  11. #include "src/sksl/SkSLByteCode.h"
  12. #include "src/sksl/SkSLByteCodeGenerator.h"
  13. #include "src/sksl/SkSLExternalValue.h"
  14. #include <vector>
  15. namespace SkSL {
  16. #if defined(SK_ENABLE_SKSL_INTERPRETER)
  17. namespace Interpreter {
  18. constexpr int VecWidth = ByteCode::kVecWidth;
  19. using F32 = skvx::Vec<VecWidth, float>;
  20. using I32 = skvx::Vec<VecWidth, int32_t>;
  21. using U32 = skvx::Vec<VecWidth, uint32_t>;
  22. #define READ8() (*(ip++))
  23. #define READ16() (ip += 2, sk_unaligned_load<uint16_t>(ip - 2))
  24. #define READ32() (ip += 4, sk_unaligned_load<uint32_t>(ip - 4))
  25. #define VECTOR_DISASSEMBLE(op, text) \
  26. case ByteCodeInstruction::op: printf(text); break; \
  27. case ByteCodeInstruction::op##2: printf(text "2"); break; \
  28. case ByteCodeInstruction::op##3: printf(text "3"); break; \
  29. case ByteCodeInstruction::op##4: printf(text "4"); break;
  30. #define VECTOR_MATRIX_DISASSEMBLE(op, text) \
  31. case ByteCodeInstruction::op: printf(text); break; \
  32. case ByteCodeInstruction::op##2: printf(text "2"); break; \
  33. case ByteCodeInstruction::op##3: printf(text "3"); break; \
  34. case ByteCodeInstruction::op##4: printf(text "4"); break; \
  35. case ByteCodeInstruction::op##N: printf(text "N %d", READ8()); break;
  36. static const uint8_t* disassemble_instruction(const uint8_t* ip) {
  37. switch ((ByteCodeInstruction) READ16()) {
  38. VECTOR_MATRIX_DISASSEMBLE(kAddF, "addf")
  39. VECTOR_DISASSEMBLE(kAddI, "addi")
  40. case ByteCodeInstruction::kAndB: printf("andb"); break;
  41. case ByteCodeInstruction::kBranch: printf("branch %d", READ16()); break;
  42. case ByteCodeInstruction::kCall: printf("call %d", READ8()); break;
  43. case ByteCodeInstruction::kCallExternal: {
  44. int argumentCount = READ8();
  45. int returnCount = READ8();
  46. int externalValue = READ8();
  47. printf("callexternal %d, %d, %d", argumentCount, returnCount, externalValue);
  48. break;
  49. }
  50. case ByteCodeInstruction::kClampIndex: printf("clampindex %d", READ8()); break;
  51. VECTOR_DISASSEMBLE(kCompareIEQ, "compareieq")
  52. VECTOR_DISASSEMBLE(kCompareINEQ, "compareineq")
  53. VECTOR_MATRIX_DISASSEMBLE(kCompareFEQ, "comparefeq")
  54. VECTOR_MATRIX_DISASSEMBLE(kCompareFNEQ, "comparefneq")
  55. VECTOR_DISASSEMBLE(kCompareFGT, "comparefgt")
  56. VECTOR_DISASSEMBLE(kCompareFGTEQ, "comparefgteq")
  57. VECTOR_DISASSEMBLE(kCompareFLT, "compareflt")
  58. VECTOR_DISASSEMBLE(kCompareFLTEQ, "compareflteq")
  59. VECTOR_DISASSEMBLE(kCompareSGT, "comparesgt")
  60. VECTOR_DISASSEMBLE(kCompareSGTEQ, "comparesgteq")
  61. VECTOR_DISASSEMBLE(kCompareSLT, "compareslt")
  62. VECTOR_DISASSEMBLE(kCompareSLTEQ, "compareslteq")
  63. VECTOR_DISASSEMBLE(kCompareUGT, "compareugt")
  64. VECTOR_DISASSEMBLE(kCompareUGTEQ, "compareugteq")
  65. VECTOR_DISASSEMBLE(kCompareULT, "compareult")
  66. VECTOR_DISASSEMBLE(kCompareULTEQ, "compareulteq")
  67. VECTOR_DISASSEMBLE(kConvertFtoI, "convertftoi")
  68. VECTOR_DISASSEMBLE(kConvertStoF, "convertstof")
  69. VECTOR_DISASSEMBLE(kConvertUtoF, "convertutof")
  70. VECTOR_DISASSEMBLE(kCos, "cos")
  71. case ByteCodeInstruction::kCross: printf("cross"); break;
  72. VECTOR_MATRIX_DISASSEMBLE(kDivideF, "dividef")
  73. VECTOR_DISASSEMBLE(kDivideS, "divideS")
  74. VECTOR_DISASSEMBLE(kDivideU, "divideu")
  75. VECTOR_MATRIX_DISASSEMBLE(kDup, "dup")
  76. case ByteCodeInstruction::kInverse2x2: printf("inverse2x2"); break;
  77. case ByteCodeInstruction::kInverse3x3: printf("inverse3x3"); break;
  78. case ByteCodeInstruction::kInverse4x4: printf("inverse4x4"); break;
  79. case ByteCodeInstruction::kLoad: printf("load %d", READ8()); break;
  80. case ByteCodeInstruction::kLoad2: printf("load2 %d", READ8()); break;
  81. case ByteCodeInstruction::kLoad3: printf("load3 %d", READ8()); break;
  82. case ByteCodeInstruction::kLoad4: printf("load4 %d", READ8()); break;
  83. case ByteCodeInstruction::kLoadGlobal: printf("loadglobal %d", READ8()); break;
  84. case ByteCodeInstruction::kLoadGlobal2: printf("loadglobal2 %d", READ8()); break;
  85. case ByteCodeInstruction::kLoadGlobal3: printf("loadglobal3 %d", READ8()); break;
  86. case ByteCodeInstruction::kLoadGlobal4: printf("loadglobal4 %d", READ8()); break;
  87. case ByteCodeInstruction::kLoadSwizzle: {
  88. int target = READ8();
  89. int count = READ8();
  90. printf("loadswizzle %d %d", target, count);
  91. for (int i = 0; i < count; ++i) {
  92. printf(", %d", READ8());
  93. }
  94. break;
  95. }
  96. case ByteCodeInstruction::kLoadSwizzleGlobal: {
  97. int target = READ8();
  98. int count = READ8();
  99. printf("loadswizzleglobal %d %d", target, count);
  100. for (int i = 0; i < count; ++i) {
  101. printf(", %d", READ8());
  102. }
  103. break;
  104. }
  105. case ByteCodeInstruction::kLoadExtended: printf("loadextended %d", READ8()); break;
  106. case ByteCodeInstruction::kLoadExtendedGlobal: printf("loadextendedglobal %d", READ8());
  107. break;
  108. case ByteCodeInstruction::kMatrixToMatrix: {
  109. int srcCols = READ8();
  110. int srcRows = READ8();
  111. int dstCols = READ8();
  112. int dstRows = READ8();
  113. printf("matrixtomatrix %dx%d %dx%d", srcCols, srcRows, dstCols, dstRows);
  114. break;
  115. }
  116. case ByteCodeInstruction::kMatrixMultiply: {
  117. int lCols = READ8();
  118. int lRows = READ8();
  119. int rCols = READ8();
  120. printf("matrixmultiply %dx%d %dx%d", lCols, lRows, rCols, lCols);
  121. break;
  122. }
  123. VECTOR_DISASSEMBLE(kMix, "mix")
  124. VECTOR_MATRIX_DISASSEMBLE(kMultiplyF, "multiplyf")
  125. VECTOR_DISASSEMBLE(kMultiplyI, "multiplyi")
  126. VECTOR_MATRIX_DISASSEMBLE(kNegateF, "negatef")
  127. VECTOR_DISASSEMBLE(kNegateI, "negatei")
  128. case ByteCodeInstruction::kNotB: printf("notb"); break;
  129. case ByteCodeInstruction::kOrB: printf("orb"); break;
  130. VECTOR_MATRIX_DISASSEMBLE(kPop, "pop")
  131. case ByteCodeInstruction::kPushImmediate: {
  132. uint32_t v = READ32();
  133. union { uint32_t u; float f; } pun = { v };
  134. printf("pushimmediate %s", (to_string(v) + "(" + to_string(pun.f) + ")").c_str());
  135. break;
  136. }
  137. case ByteCodeInstruction::kReadExternal: printf("readexternal %d", READ8()); break;
  138. case ByteCodeInstruction::kReadExternal2: printf("readexternal2 %d", READ8()); break;
  139. case ByteCodeInstruction::kReadExternal3: printf("readexternal3 %d", READ8()); break;
  140. case ByteCodeInstruction::kReadExternal4: printf("readexternal4 %d", READ8()); break;
  141. VECTOR_DISASSEMBLE(kRemainderF, "remainderf")
  142. VECTOR_DISASSEMBLE(kRemainderS, "remainders")
  143. VECTOR_DISASSEMBLE(kRemainderU, "remainderu")
  144. case ByteCodeInstruction::kReserve: printf("reserve %d", READ8()); break;
  145. case ByteCodeInstruction::kReturn: printf("return %d", READ8()); break;
  146. case ByteCodeInstruction::kScalarToMatrix: {
  147. int cols = READ8();
  148. int rows = READ8();
  149. printf("scalartomatrix %dx%d", cols, rows);
  150. break;
  151. }
  152. VECTOR_DISASSEMBLE(kSin, "sin")
  153. VECTOR_DISASSEMBLE(kSqrt, "sqrt")
  154. case ByteCodeInstruction::kStore: printf("store %d", READ8()); break;
  155. case ByteCodeInstruction::kStore2: printf("store2 %d", READ8()); break;
  156. case ByteCodeInstruction::kStore3: printf("store3 %d", READ8()); break;
  157. case ByteCodeInstruction::kStore4: printf("store4 %d", READ8()); break;
  158. case ByteCodeInstruction::kStoreGlobal: printf("storeglobal %d", READ8()); break;
  159. case ByteCodeInstruction::kStoreGlobal2: printf("storeglobal2 %d", READ8()); break;
  160. case ByteCodeInstruction::kStoreGlobal3: printf("storeglobal3 %d", READ8()); break;
  161. case ByteCodeInstruction::kStoreGlobal4: printf("storeglobal4 %d", READ8()); break;
  162. case ByteCodeInstruction::kStoreSwizzle: {
  163. int target = READ8();
  164. int count = READ8();
  165. printf("storeswizzle %d %d", target, count);
  166. for (int i = 0; i < count; ++i) {
  167. printf(", %d", READ8());
  168. }
  169. break;
  170. }
  171. case ByteCodeInstruction::kStoreSwizzleGlobal: {
  172. int target = READ8();
  173. int count = READ8();
  174. printf("storeswizzleglobal %d %d", target, count);
  175. for (int i = 0; i < count; ++i) {
  176. printf(", %d", READ8());
  177. }
  178. break;
  179. }
  180. case ByteCodeInstruction::kStoreSwizzleIndirect: {
  181. int count = READ8();
  182. printf("storeswizzleindirect %d", count);
  183. for (int i = 0; i < count; ++i) {
  184. printf(", %d", READ8());
  185. }
  186. break;
  187. }
  188. case ByteCodeInstruction::kStoreSwizzleIndirectGlobal: {
  189. int count = READ8();
  190. printf("storeswizzleindirectglobal %d", count);
  191. for (int i = 0; i < count; ++i) {
  192. printf(", %d", READ8());
  193. }
  194. break;
  195. }
  196. case ByteCodeInstruction::kStoreExtended: printf("storeextended %d", READ8()); break;
  197. case ByteCodeInstruction::kStoreExtendedGlobal: printf("storeextendedglobal %d", READ8());
  198. break;
  199. VECTOR_MATRIX_DISASSEMBLE(kSubtractF, "subtractf")
  200. VECTOR_DISASSEMBLE(kSubtractI, "subtracti")
  201. case ByteCodeInstruction::kSwizzle: {
  202. printf("swizzle %d, ", READ8());
  203. int count = READ8();
  204. printf("%d", count);
  205. for (int i = 0; i < count; ++i) {
  206. printf(", %d", READ8());
  207. }
  208. break;
  209. }
  210. VECTOR_DISASSEMBLE(kTan, "tan")
  211. case ByteCodeInstruction::kWriteExternal: printf("writeexternal %d", READ8()); break;
  212. case ByteCodeInstruction::kWriteExternal2: printf("writeexternal2 %d", READ8()); break;
  213. case ByteCodeInstruction::kWriteExternal3: printf("writeexternal3 %d", READ8()); break;
  214. case ByteCodeInstruction::kWriteExternal4: printf("writeexternal4 %d", READ8()); break;
  215. case ByteCodeInstruction::kXorB: printf("xorb"); break;
  216. case ByteCodeInstruction::kMaskPush: printf("maskpush"); break;
  217. case ByteCodeInstruction::kMaskPop: printf("maskpop"); break;
  218. case ByteCodeInstruction::kMaskNegate: printf("masknegate"); break;
  219. case ByteCodeInstruction::kMaskBlend: printf("maskblend %d", READ8()); break;
  220. case ByteCodeInstruction::kBranchIfAllFalse:
  221. printf("branchifallfalse %d", READ16());
  222. break;
  223. case ByteCodeInstruction::kLoopBegin: printf("loopbegin"); break;
  224. case ByteCodeInstruction::kLoopNext: printf("loopnext"); break;
  225. case ByteCodeInstruction::kLoopMask: printf("loopmask"); break;
  226. case ByteCodeInstruction::kLoopEnd: printf("loopend"); break;
  227. case ByteCodeInstruction::kLoopContinue: printf("loopcontinue"); break;
  228. case ByteCodeInstruction::kLoopBreak: printf("loopbreak"); break;
  229. default: printf("unknown(%d)\n", *(ip - 1)); SkASSERT(false);
  230. }
  231. return ip;
  232. }
  233. #define VECTOR_BINARY_OP(base, field, op) \
  234. case ByteCodeInstruction::base ## 4: \
  235. sp[-4] = sp[-4].field op sp[0].field; \
  236. POP(); \
  237. /* fall through */ \
  238. case ByteCodeInstruction::base ## 3: { \
  239. int count = (int) ByteCodeInstruction::base - (int) inst - 1; \
  240. sp[count] = sp[count].field op sp[0].field; \
  241. POP(); \
  242. } /* fall through */ \
  243. case ByteCodeInstruction::base ## 2: { \
  244. int count = (int) ByteCodeInstruction::base - (int) inst - 1; \
  245. sp[count] = sp[count].field op sp[0].field; \
  246. POP(); \
  247. } /* fall through */ \
  248. case ByteCodeInstruction::base: { \
  249. int count = (int) ByteCodeInstruction::base - (int) inst - 1; \
  250. sp[count] = sp[count].field op sp[0].field; \
  251. POP(); \
  252. break; \
  253. }
  254. #define VECTOR_MATRIX_BINARY_OP(base, field, op) \
  255. VECTOR_BINARY_OP(base, field, op) \
  256. case ByteCodeInstruction::base ## N: { \
  257. int count = READ8(); \
  258. for (int i = count; i > 0; --i) { \
  259. sp[-count] = sp[-count].field op sp[0].field; \
  260. POP(); \
  261. } \
  262. break; \
  263. }
  264. #define VECTOR_BINARY_FN(base, field, fn) \
  265. case ByteCodeInstruction::base ## 4: \
  266. sp[-4] = fn(sp[-4].field, sp[0].field); \
  267. POP(); \
  268. /* fall through */ \
  269. case ByteCodeInstruction::base ## 3: { \
  270. int target = (int) ByteCodeInstruction::base - (int) inst - 1; \
  271. sp[target] = fn(sp[target].field, sp[0].field); \
  272. POP(); \
  273. } /* fall through */ \
  274. case ByteCodeInstruction::base ## 2: { \
  275. int target = (int) ByteCodeInstruction::base - (int) inst - 1; \
  276. sp[target] = fn(sp[target].field, sp[0].field); \
  277. POP(); \
  278. } /* fall through */ \
  279. case ByteCodeInstruction::base: { \
  280. int target = (int) ByteCodeInstruction::base - (int) inst - 1; \
  281. sp[target] = fn(sp[target].field, sp[0].field); \
  282. POP(); \
  283. break; \
  284. }
  285. #define VECTOR_UNARY_FN(base, fn, field) \
  286. case ByteCodeInstruction::base ## 4: sp[-3] = fn(sp[-3].field); \
  287. case ByteCodeInstruction::base ## 3: sp[-2] = fn(sp[-2].field); \
  288. case ByteCodeInstruction::base ## 2: sp[-1] = fn(sp[-1].field); \
  289. case ByteCodeInstruction::base: sp[ 0] = fn(sp[ 0].field); \
  290. break;
  291. #define VECTOR_UNARY_FN_VEC(base, fn) \
  292. case ByteCodeInstruction::base ## 4: \
  293. case ByteCodeInstruction::base ## 3: \
  294. case ByteCodeInstruction::base ## 2: \
  295. case ByteCodeInstruction::base : { \
  296. int count = (int)inst - (int)ByteCodeInstruction::base + 1; \
  297. float* v = (float*)sp - count + 1; \
  298. for (int i = VecWidth * count; i > 0; --i, ++v) { \
  299. *v = fn(*v); \
  300. } \
  301. break; \
  302. }
  303. union VValue {
  304. VValue() {}
  305. VValue(F32 f)
  306. : fFloat(f) {
  307. }
  308. VValue(I32 s)
  309. : fSigned(s) {
  310. }
  311. VValue(U32 u)
  312. : fUnsigned(u) {
  313. }
  314. F32 fFloat;
  315. I32 fSigned;
  316. U32 fUnsigned;
  317. };
  318. struct StackFrame {
  319. const uint8_t* fCode;
  320. const uint8_t* fIP;
  321. VValue* fStack;
  322. int fParameterCount;
  323. };
  324. static F32 mix(F32 start, F32 end, F32 t) {
  325. return start * (1 - t) + end * t;
  326. }
  327. // TODO: trunc on integers?
  328. template <typename T>
  329. static T vec_mod(T a, T b) {
  330. return a - skvx::trunc(a / b) * b;
  331. }
  332. #define spf(index) sp[index].fFloat
  333. static bool innerRun(const ByteCode* byteCode, const ByteCodeFunction* f, VValue* stack,
  334. float* outReturn[], VValue globals[], bool stripedOutput, int N,
  335. int baseIndex) {
  336. // Needs to be the first N non-negative integers, at least as large as VecWidth
  337. static const Interpreter::I32 gLanes = {
  338. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
  339. };
  340. VValue* sp = stack + f->fParameterCount + f->fLocalCount - 1;
  341. auto POP = [&] { SkASSERT(sp >= stack); return *(sp--); };
  342. auto PUSH = [&](VValue v) { SkASSERT(sp + 1 >= stack); *(++sp) = v; };
  343. const uint8_t* code = f->fCode.data();
  344. const uint8_t* ip = code;
  345. std::vector<StackFrame> frames;
  346. I32 condStack[16]; // Independent condition masks
  347. I32 maskStack[16]; // Combined masks (eg maskStack[0] & maskStack[1] & ...)
  348. I32 contStack[16]; // Continue flags for loops
  349. I32 loopStack[16]; // Loop execution masks
  350. condStack[0] = maskStack[0] = (gLanes < N);
  351. contStack[0] = I32( 0);
  352. loopStack[0] = I32(~0);
  353. I32* condPtr = condStack;
  354. I32* maskPtr = maskStack;
  355. I32* contPtr = contStack;
  356. I32* loopPtr = loopStack;
  357. if (f->fConditionCount + 1 > (int)SK_ARRAY_COUNT(condStack) ||
  358. f->fLoopCount + 1 > (int)SK_ARRAY_COUNT(loopStack)) {
  359. return false;
  360. }
  361. auto mask = [&]() { return *maskPtr & *loopPtr; };
  362. for (;;) {
  363. #ifdef TRACE
  364. printf("at %3d ", (int) (ip - code));
  365. disassemble_instruction(ip);
  366. printf("\n");
  367. #endif
  368. ByteCodeInstruction inst = (ByteCodeInstruction) READ16();
  369. switch (inst) {
  370. VECTOR_BINARY_OP(kAddI, fSigned, +)
  371. VECTOR_MATRIX_BINARY_OP(kAddF, fFloat, +)
  372. // Booleans are integer masks: 0/~0 for false/true. So bitwise ops do what we want:
  373. case ByteCodeInstruction::kAndB:
  374. sp[-1] = sp[-1].fSigned & sp[0].fSigned;
  375. POP();
  376. break;
  377. case ByteCodeInstruction::kNotB:
  378. sp[0] = ~sp[0].fSigned;
  379. break;
  380. case ByteCodeInstruction::kOrB:
  381. sp[-1] = sp[-1].fSigned | sp[0].fSigned;
  382. POP();
  383. break;
  384. case ByteCodeInstruction::kXorB:
  385. sp[-1] = sp[-1].fSigned ^ sp[0].fSigned;
  386. POP();
  387. break;
  388. case ByteCodeInstruction::kBranch:
  389. ip = code + READ16();
  390. break;
  391. case ByteCodeInstruction::kCall: {
  392. // Precursor code reserved space for the return value, and pushed all parameters to
  393. // the stack. Update our bottom of stack to point at the first parameter, and our
  394. // sp to point past those parameters (plus space for locals).
  395. int target = READ8();
  396. const ByteCodeFunction* fun = byteCode->fFunctions[target].get();
  397. if (skvx::any(mask())) {
  398. frames.push_back({ code, ip, stack, fun->fParameterCount });
  399. ip = code = fun->fCode.data();
  400. stack = sp - fun->fParameterCount + 1;
  401. sp = stack + fun->fParameterCount + fun->fLocalCount - 1;
  402. }
  403. break;
  404. }
  405. case ByteCodeInstruction::kCallExternal: {
  406. int argumentCount = READ8();
  407. int returnCount = READ8();
  408. int target = READ8();
  409. ExternalValue* v = byteCode->fExternalValues[target];
  410. sp -= argumentCount - 1;
  411. float tmpArgs[4];
  412. float tmpReturn[4];
  413. SkASSERT(argumentCount <= (int)SK_ARRAY_COUNT(tmpArgs));
  414. SkASSERT(returnCount <= (int)SK_ARRAY_COUNT(tmpReturn));
  415. I32 m = mask();
  416. for (int i = 0; i < VecWidth; ++i) {
  417. if (m[i]) {
  418. for (int j = 0; j < argumentCount; ++j) {
  419. tmpArgs[j] = sp[j].fFloat[i];
  420. }
  421. v->call(baseIndex + i, tmpArgs, tmpReturn);
  422. for (int j = 0; j < returnCount; ++j) {
  423. sp[j].fFloat[i] = tmpReturn[j];
  424. }
  425. }
  426. }
  427. sp += returnCount - 1;
  428. break;
  429. }
  430. case ByteCodeInstruction::kClampIndex: {
  431. int length = READ8();
  432. if (skvx::any(mask() & ((sp[0].fSigned < 0) | (sp[0].fSigned >= length)))) {
  433. return false;
  434. }
  435. break;
  436. }
  437. VECTOR_BINARY_OP(kCompareIEQ, fSigned, ==)
  438. VECTOR_MATRIX_BINARY_OP(kCompareFEQ, fFloat, ==)
  439. VECTOR_BINARY_OP(kCompareINEQ, fSigned, !=)
  440. VECTOR_MATRIX_BINARY_OP(kCompareFNEQ, fFloat, !=)
  441. VECTOR_BINARY_OP(kCompareSGT, fSigned, >)
  442. VECTOR_BINARY_OP(kCompareUGT, fUnsigned, >)
  443. VECTOR_BINARY_OP(kCompareFGT, fFloat, >)
  444. VECTOR_BINARY_OP(kCompareSGTEQ, fSigned, >=)
  445. VECTOR_BINARY_OP(kCompareUGTEQ, fUnsigned, >=)
  446. VECTOR_BINARY_OP(kCompareFGTEQ, fFloat, >=)
  447. VECTOR_BINARY_OP(kCompareSLT, fSigned, <)
  448. VECTOR_BINARY_OP(kCompareULT, fUnsigned, <)
  449. VECTOR_BINARY_OP(kCompareFLT, fFloat, <)
  450. VECTOR_BINARY_OP(kCompareSLTEQ, fSigned, <=)
  451. VECTOR_BINARY_OP(kCompareULTEQ, fUnsigned, <=)
  452. VECTOR_BINARY_OP(kCompareFLTEQ, fFloat, <=)
  453. case ByteCodeInstruction::kConvertFtoI4: sp[-3] = skvx::cast<int>(sp[-3].fFloat);
  454. case ByteCodeInstruction::kConvertFtoI3: sp[-2] = skvx::cast<int>(sp[-2].fFloat);
  455. case ByteCodeInstruction::kConvertFtoI2: sp[-1] = skvx::cast<int>(sp[-1].fFloat);
  456. case ByteCodeInstruction::kConvertFtoI: sp[ 0] = skvx::cast<int>(sp[ 0].fFloat);
  457. break;
  458. case ByteCodeInstruction::kConvertStoF4: sp[-3] = skvx::cast<float>(sp[-3].fSigned);
  459. case ByteCodeInstruction::kConvertStoF3: sp[-2] = skvx::cast<float>(sp[-2].fSigned);
  460. case ByteCodeInstruction::kConvertStoF2: sp[-1] = skvx::cast<float>(sp[-1].fSigned);
  461. case ByteCodeInstruction::kConvertStoF : sp[ 0] = skvx::cast<float>(sp[ 0].fSigned);
  462. break;
  463. case ByteCodeInstruction::kConvertUtoF4: sp[-3] = skvx::cast<float>(sp[-3].fUnsigned);
  464. case ByteCodeInstruction::kConvertUtoF3: sp[-2] = skvx::cast<float>(sp[-2].fUnsigned);
  465. case ByteCodeInstruction::kConvertUtoF2: sp[-1] = skvx::cast<float>(sp[-1].fUnsigned);
  466. case ByteCodeInstruction::kConvertUtoF : sp[ 0] = skvx::cast<float>(sp[ 0].fUnsigned);
  467. break;
  468. VECTOR_UNARY_FN_VEC(kCos, cosf)
  469. case ByteCodeInstruction::kCross: {
  470. F32 ax = sp[-5].fFloat, ay = sp[-4].fFloat, az = sp[-3].fFloat,
  471. bx = sp[-2].fFloat, by = sp[-1].fFloat, bz = sp[ 0].fFloat;
  472. F32 cx = ay*bz - az*by,
  473. cy = az*bx - ax*bz,
  474. cz = ax*by - ay*bx;
  475. sp -= 3;
  476. sp[-2] = cx;
  477. sp[-1] = cy;
  478. sp[ 0] = cz;
  479. break;
  480. }
  481. VECTOR_BINARY_OP(kDivideS, fSigned, /)
  482. VECTOR_BINARY_OP(kDivideU, fUnsigned, /)
  483. VECTOR_MATRIX_BINARY_OP(kDivideF, fFloat, /)
  484. case ByteCodeInstruction::kDup4: PUSH(sp[(int)ByteCodeInstruction::kDup - (int)inst]);
  485. case ByteCodeInstruction::kDup3: PUSH(sp[(int)ByteCodeInstruction::kDup - (int)inst]);
  486. case ByteCodeInstruction::kDup2: PUSH(sp[(int)ByteCodeInstruction::kDup - (int)inst]);
  487. case ByteCodeInstruction::kDup : PUSH(sp[(int)ByteCodeInstruction::kDup - (int)inst]);
  488. break;
  489. case ByteCodeInstruction::kDupN: {
  490. int count = READ8();
  491. memcpy(sp + 1, sp - count + 1, count * sizeof(VValue));
  492. sp += count;
  493. break;
  494. }
  495. case ByteCodeInstruction::kInverse2x2: {
  496. F32 a = sp[-3].fFloat,
  497. b = sp[-2].fFloat,
  498. c = sp[-1].fFloat,
  499. d = sp[ 0].fFloat;
  500. F32 idet = F32(1) / (a*d - b*c);
  501. sp[-3].fFloat = d * idet;
  502. sp[-2].fFloat = -b * idet;
  503. sp[-1].fFloat = -c * idet;
  504. sp[ 0].fFloat = a * idet;
  505. break;
  506. }
  507. case ByteCodeInstruction::kInverse3x3: {
  508. F32 a11 = sp[-8].fFloat, a12 = sp[-5].fFloat, a13 = sp[-2].fFloat,
  509. a21 = sp[-7].fFloat, a22 = sp[-4].fFloat, a23 = sp[-1].fFloat,
  510. a31 = sp[-6].fFloat, a32 = sp[-3].fFloat, a33 = sp[ 0].fFloat;
  511. F32 idet = F32(1) / (a11 * a22 * a33 + a12 * a23 * a31 + a13 * a21 * a32 -
  512. a11 * a23 * a32 - a12 * a21 * a33 - a13 * a22 * a31);
  513. sp[-8].fFloat = (a22 * a33 - a23 * a32) * idet;
  514. sp[-7].fFloat = (a23 * a31 - a21 * a33) * idet;
  515. sp[-6].fFloat = (a21 * a32 - a22 * a31) * idet;
  516. sp[-5].fFloat = (a13 * a32 - a12 * a33) * idet;
  517. sp[-4].fFloat = (a11 * a33 - a13 * a31) * idet;
  518. sp[-3].fFloat = (a12 * a31 - a11 * a32) * idet;
  519. sp[-2].fFloat = (a12 * a23 - a13 * a22) * idet;
  520. sp[-1].fFloat = (a13 * a21 - a11 * a23) * idet;
  521. sp[ 0].fFloat = (a11 * a22 - a12 * a21) * idet;
  522. break;
  523. }
  524. case ByteCodeInstruction::kInverse4x4: {
  525. F32 a00 = spf(-15), a10 = spf(-11), a20 = spf( -7), a30 = spf( -3),
  526. a01 = spf(-14), a11 = spf(-10), a21 = spf( -6), a31 = spf( -2),
  527. a02 = spf(-13), a12 = spf( -9), a22 = spf( -5), a32 = spf( -1),
  528. a03 = spf(-12), a13 = spf( -8), a23 = spf( -4), a33 = spf( 0);
  529. F32 b00 = a00 * a11 - a01 * a10,
  530. b01 = a00 * a12 - a02 * a10,
  531. b02 = a00 * a13 - a03 * a10,
  532. b03 = a01 * a12 - a02 * a11,
  533. b04 = a01 * a13 - a03 * a11,
  534. b05 = a02 * a13 - a03 * a12,
  535. b06 = a20 * a31 - a21 * a30,
  536. b07 = a20 * a32 - a22 * a30,
  537. b08 = a20 * a33 - a23 * a30,
  538. b09 = a21 * a32 - a22 * a31,
  539. b10 = a21 * a33 - a23 * a31,
  540. b11 = a22 * a33 - a23 * a32;
  541. F32 idet = F32(1) /
  542. (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06);
  543. b00 *= idet;
  544. b01 *= idet;
  545. b02 *= idet;
  546. b03 *= idet;
  547. b04 *= idet;
  548. b05 *= idet;
  549. b06 *= idet;
  550. b07 *= idet;
  551. b08 *= idet;
  552. b09 *= idet;
  553. b10 *= idet;
  554. b11 *= idet;
  555. spf(-15) = a11 * b11 - a12 * b10 + a13 * b09;
  556. spf(-14) = a02 * b10 - a01 * b11 - a03 * b09;
  557. spf(-13) = a31 * b05 - a32 * b04 + a33 * b03;
  558. spf(-12) = a22 * b04 - a21 * b05 - a23 * b03;
  559. spf(-11) = a12 * b08 - a10 * b11 - a13 * b07;
  560. spf(-10) = a00 * b11 - a02 * b08 + a03 * b07;
  561. spf( -9) = a32 * b02 - a30 * b05 - a33 * b01;
  562. spf( -8) = a20 * b05 - a22 * b02 + a23 * b01;
  563. spf( -7) = a10 * b10 - a11 * b08 + a13 * b06;
  564. spf( -6) = a01 * b08 - a00 * b10 - a03 * b06;
  565. spf( -5) = a30 * b04 - a31 * b02 + a33 * b00;
  566. spf( -4) = a21 * b02 - a20 * b04 - a23 * b00;
  567. spf( -3) = a11 * b07 - a10 * b09 - a12 * b06;
  568. spf( -2) = a00 * b09 - a01 * b07 + a02 * b06;
  569. spf( -1) = a31 * b01 - a30 * b03 - a32 * b00;
  570. spf( 0) = a20 * b03 - a21 * b01 + a22 * b00;
  571. break;
  572. }
  573. case ByteCodeInstruction::kLoad4: sp[4] = stack[*ip + 3];
  574. case ByteCodeInstruction::kLoad3: sp[3] = stack[*ip + 2];
  575. case ByteCodeInstruction::kLoad2: sp[2] = stack[*ip + 1];
  576. case ByteCodeInstruction::kLoad : sp[1] = stack[*ip + 0];
  577. ++ip;
  578. sp += (int)inst - (int)ByteCodeInstruction::kLoad + 1;
  579. break;
  580. case ByteCodeInstruction::kLoadGlobal4: sp[4] = globals[*ip + 3];
  581. case ByteCodeInstruction::kLoadGlobal3: sp[3] = globals[*ip + 2];
  582. case ByteCodeInstruction::kLoadGlobal2: sp[2] = globals[*ip + 1];
  583. case ByteCodeInstruction::kLoadGlobal : sp[1] = globals[*ip + 0];
  584. ++ip;
  585. sp += (int)inst -
  586. (int)ByteCodeInstruction::kLoadGlobal + 1;
  587. break;
  588. case ByteCodeInstruction::kLoadExtended: {
  589. int count = READ8();
  590. I32 src = POP().fSigned;
  591. I32 m = mask();
  592. for (int i = 0; i < count; ++i) {
  593. for (int j = 0; j < VecWidth; ++j) {
  594. if (m[j]) {
  595. sp[i + 1].fSigned[j] = stack[src[j] + i].fSigned[j];
  596. }
  597. }
  598. }
  599. sp += count;
  600. break;
  601. }
  602. case ByteCodeInstruction::kLoadExtendedGlobal: {
  603. int count = READ8();
  604. I32 src = POP().fSigned;
  605. I32 m = mask();
  606. for (int i = 0; i < count; ++i) {
  607. for (int j = 0; j < VecWidth; ++j) {
  608. if (m[j]) {
  609. sp[i + 1].fSigned[j] = globals[src[j] + i].fSigned[j];
  610. }
  611. }
  612. }
  613. sp += count;
  614. break;
  615. }
  616. case ByteCodeInstruction::kLoadSwizzle: {
  617. int src = READ8();
  618. int count = READ8();
  619. for (int i = 0; i < count; ++i) {
  620. PUSH(stack[src + *(ip + i)]);
  621. }
  622. ip += count;
  623. break;
  624. }
  625. case ByteCodeInstruction::kLoadSwizzleGlobal: {
  626. int src = READ8();
  627. int count = READ8();
  628. for (int i = 0; i < count; ++i) {
  629. PUSH(globals[src + *(ip + i)]);
  630. }
  631. ip += count;
  632. break;
  633. }
  634. case ByteCodeInstruction::kMatrixToMatrix: {
  635. int srcCols = READ8();
  636. int srcRows = READ8();
  637. int dstCols = READ8();
  638. int dstRows = READ8();
  639. SkASSERT(srcCols >= 2 && srcCols <= 4);
  640. SkASSERT(srcRows >= 2 && srcRows <= 4);
  641. SkASSERT(dstCols >= 2 && dstCols <= 4);
  642. SkASSERT(dstRows >= 2 && dstRows <= 4);
  643. F32 tmp[16];
  644. memset(tmp, 0, sizeof(tmp));
  645. tmp[0] = tmp[5] = tmp[10] = tmp[15] = F32(1.0f);
  646. for (int c = srcCols - 1; c >= 0; --c) {
  647. for (int r = srcRows - 1; r >= 0; --r) {
  648. tmp[c*4 + r] = POP().fFloat;
  649. }
  650. }
  651. for (int c = 0; c < dstCols; ++c) {
  652. for (int r = 0; r < dstRows; ++r) {
  653. PUSH(tmp[c*4 + r]);
  654. }
  655. }
  656. break;
  657. }
  658. case ByteCodeInstruction::kMatrixMultiply: {
  659. int lCols = READ8();
  660. int lRows = READ8();
  661. int rCols = READ8();
  662. int rRows = lCols;
  663. F32 tmp[16] = { 0.0f };
  664. F32* B = &(sp - (rCols * rRows) + 1)->fFloat;
  665. F32* A = B - (lCols * lRows);
  666. for (int c = 0; c < rCols; ++c) {
  667. for (int r = 0; r < lRows; ++r) {
  668. for (int j = 0; j < lCols; ++j) {
  669. tmp[c*lRows + r] += A[j*lRows + r] * B[c*rRows + j];
  670. }
  671. }
  672. }
  673. sp -= (lCols * lRows) + (rCols * rRows);
  674. memcpy(sp + 1, tmp, rCols * lRows * sizeof(VValue));
  675. sp += (rCols * lRows);
  676. break;
  677. }
  678. // stack looks like: X1 Y1 Z1 W1 X2 Y2 Z2 W2 T
  679. case ByteCodeInstruction::kMix4:
  680. sp[-5] = mix(sp[-5].fFloat, sp[-1].fFloat, sp[0].fFloat);
  681. // fall through
  682. case ByteCodeInstruction::kMix3: {
  683. int count = (int) inst - (int) ByteCodeInstruction::kMix + 1;
  684. int target = 2 - count * 2;
  685. sp[target] = mix(sp[target].fFloat, sp[2 - count].fFloat, sp[0].fFloat);
  686. // fall through
  687. }
  688. case ByteCodeInstruction::kMix2: {
  689. int count = (int) inst - (int) ByteCodeInstruction::kMix + 1;
  690. int target = 1 - count * 2;
  691. sp[target] = mix(sp[target].fFloat, sp[1 - count].fFloat, sp[0].fFloat);
  692. // fall through
  693. }
  694. case ByteCodeInstruction::kMix: {
  695. int count = (int) inst - (int) ByteCodeInstruction::kMix + 1;
  696. int target = -count * 2;
  697. sp[target] = mix(sp[target].fFloat, sp[-count].fFloat, sp[0].fFloat);
  698. sp -= 1 + count;
  699. break;
  700. }
  701. VECTOR_BINARY_OP(kMultiplyI, fSigned, *)
  702. VECTOR_MATRIX_BINARY_OP(kMultiplyF, fFloat, *)
  703. case ByteCodeInstruction::kNegateF4: sp[-3] = -sp[-3].fFloat;
  704. case ByteCodeInstruction::kNegateF3: sp[-2] = -sp[-2].fFloat;
  705. case ByteCodeInstruction::kNegateF2: sp[-1] = -sp[-1].fFloat;
  706. case ByteCodeInstruction::kNegateF : sp[ 0] = -sp[ 0].fFloat;
  707. break;
  708. case ByteCodeInstruction::kNegateFN: {
  709. int count = READ8();
  710. for (int i = count - 1; i >= 0; --i) {
  711. sp[-i] = -sp[-i].fFloat;
  712. }
  713. break;
  714. }
  715. case ByteCodeInstruction::kNegateI4: sp[-3] = -sp[-3].fSigned;
  716. case ByteCodeInstruction::kNegateI3: sp[-2] = -sp[-2].fSigned;
  717. case ByteCodeInstruction::kNegateI2: sp[-1] = -sp[-1].fSigned;
  718. case ByteCodeInstruction::kNegateI : sp[ 0] = -sp[ 0].fSigned;
  719. break;
  720. case ByteCodeInstruction::kPop4: POP();
  721. case ByteCodeInstruction::kPop3: POP();
  722. case ByteCodeInstruction::kPop2: POP();
  723. case ByteCodeInstruction::kPop : POP();
  724. break;
  725. case ByteCodeInstruction::kPopN:
  726. sp -= READ8();
  727. break;
  728. case ByteCodeInstruction::kPushImmediate:
  729. PUSH(U32(READ32()));
  730. break;
  731. case ByteCodeInstruction::kReadExternal:
  732. case ByteCodeInstruction::kReadExternal2:
  733. case ByteCodeInstruction::kReadExternal3:
  734. case ByteCodeInstruction::kReadExternal4: {
  735. int count = (int)inst - (int)ByteCodeInstruction::kReadExternal + 1;
  736. int src = READ8();
  737. float tmp[4];
  738. I32 m = mask();
  739. for (int i = 0; i < VecWidth; ++i) {
  740. if (m[i]) {
  741. byteCode->fExternalValues[src]->read(baseIndex + i, tmp);
  742. for (int j = 0; j < count; ++j) {
  743. sp[j + 1].fFloat[i] = tmp[j];
  744. }
  745. }
  746. }
  747. sp += count;
  748. break;
  749. }
  750. VECTOR_BINARY_FN(kRemainderF, fFloat, vec_mod<F32>)
  751. VECTOR_BINARY_FN(kRemainderS, fSigned, vec_mod<I32>)
  752. VECTOR_BINARY_FN(kRemainderU, fUnsigned, vec_mod<U32>)
  753. case ByteCodeInstruction::kReserve:
  754. sp += READ8();
  755. break;
  756. case ByteCodeInstruction::kReturn: {
  757. int count = READ8();
  758. if (frames.empty()) {
  759. if (outReturn) {
  760. VValue* src = sp - count + 1;
  761. if (stripedOutput) {
  762. for (int i = 0; i < count; ++i) {
  763. memcpy(outReturn[i], &src->fFloat, N * sizeof(float));
  764. ++src;
  765. }
  766. } else {
  767. float* outPtr = outReturn[0];
  768. for (int i = 0; i < count; ++i) {
  769. for (int j = 0; j < N; ++j) {
  770. outPtr[count * j] = src->fFloat[j];
  771. }
  772. ++outPtr;
  773. ++src;
  774. }
  775. }
  776. }
  777. return true;
  778. } else {
  779. // When we were called, the caller reserved stack space for their copy of our
  780. // return value, then 'stack' was positioned after that, where our parameters
  781. // were placed. Copy our return values to their reserved area.
  782. memcpy(stack - count, sp - count + 1, count * sizeof(VValue));
  783. // Now move the stack pointer to the end of the passed-in parameters. This odd
  784. // calling convention requires the caller to pop the arguments after calling,
  785. // but allows them to store any out-parameters back during that unwinding.
  786. // After that sequence finishes, the return value will be the top of the stack.
  787. const StackFrame& frame(frames.back());
  788. sp = stack + frame.fParameterCount - 1;
  789. stack = frame.fStack;
  790. code = frame.fCode;
  791. ip = frame.fIP;
  792. frames.pop_back();
  793. break;
  794. }
  795. }
  796. case ByteCodeInstruction::kScalarToMatrix: {
  797. int cols = READ8();
  798. int rows = READ8();
  799. VValue v = POP();
  800. for (int c = 0; c < cols; ++c) {
  801. for (int r = 0; r < rows; ++r) {
  802. PUSH(c == r ? v : F32(0.0f));
  803. }
  804. }
  805. break;
  806. }
  807. VECTOR_UNARY_FN_VEC(kSin, sinf)
  808. VECTOR_UNARY_FN(kSqrt, skvx::sqrt, fFloat)
  809. case ByteCodeInstruction::kStore4:
  810. stack[*ip+3] = skvx::if_then_else(mask(), POP().fFloat, stack[*ip+3].fFloat);
  811. case ByteCodeInstruction::kStore3:
  812. stack[*ip+2] = skvx::if_then_else(mask(), POP().fFloat, stack[*ip+2].fFloat);
  813. case ByteCodeInstruction::kStore2:
  814. stack[*ip+1] = skvx::if_then_else(mask(), POP().fFloat, stack[*ip+1].fFloat);
  815. case ByteCodeInstruction::kStore :
  816. stack[*ip+0] = skvx::if_then_else(mask(), POP().fFloat, stack[*ip+0].fFloat);
  817. ++ip;
  818. break;
  819. case ByteCodeInstruction::kStoreGlobal4:
  820. globals[*ip+3] = skvx::if_then_else(mask(), POP().fFloat, globals[*ip+3].fFloat);
  821. case ByteCodeInstruction::kStoreGlobal3:
  822. globals[*ip+2] = skvx::if_then_else(mask(), POP().fFloat, globals[*ip+2].fFloat);
  823. case ByteCodeInstruction::kStoreGlobal2:
  824. globals[*ip+1] = skvx::if_then_else(mask(), POP().fFloat, globals[*ip+1].fFloat);
  825. case ByteCodeInstruction::kStoreGlobal :
  826. globals[*ip+0] = skvx::if_then_else(mask(), POP().fFloat, globals[*ip+0].fFloat);
  827. ++ip;
  828. break;
  829. case ByteCodeInstruction::kStoreExtended: {
  830. int count = READ8();
  831. I32 target = POP().fSigned;
  832. VValue* src = sp - count + 1;
  833. I32 m = mask();
  834. for (int i = 0; i < count; ++i) {
  835. for (int j = 0; j < VecWidth; ++j) {
  836. if (m[j]) {
  837. stack[target[j] + i].fSigned[j] = src[i].fSigned[j];
  838. }
  839. }
  840. }
  841. sp -= count;
  842. break;
  843. }
  844. case ByteCodeInstruction::kStoreExtendedGlobal: {
  845. int count = READ8();
  846. I32 target = POP().fSigned;
  847. VValue* src = sp - count + 1;
  848. I32 m = mask();
  849. for (int i = 0; i < count; ++i) {
  850. for (int j = 0; j < VecWidth; ++j) {
  851. if (m[j]) {
  852. globals[target[j] + i].fSigned[j] = src[i].fSigned[j];
  853. }
  854. }
  855. }
  856. sp -= count;
  857. break;
  858. }
  859. case ByteCodeInstruction::kStoreSwizzle: {
  860. int target = READ8();
  861. int count = READ8();
  862. for (int i = count - 1; i >= 0; --i) {
  863. stack[target + *(ip + i)] = skvx::if_then_else(
  864. mask(), POP().fFloat, stack[target + *(ip + i)].fFloat);
  865. }
  866. ip += count;
  867. break;
  868. }
  869. case ByteCodeInstruction::kStoreSwizzleGlobal: {
  870. int target = READ8();
  871. int count = READ8();
  872. for (int i = count - 1; i >= 0; --i) {
  873. globals[target + *(ip + i)] = skvx::if_then_else(
  874. mask(), POP().fFloat, globals[target + *(ip + i)].fFloat);
  875. }
  876. ip += count;
  877. break;
  878. }
  879. case ByteCodeInstruction::kStoreSwizzleIndirect: {
  880. int count = READ8();
  881. I32 target = POP().fSigned;
  882. I32 m = mask();
  883. for (int i = count - 1; i >= 0; --i) {
  884. I32 v = POP().fSigned;
  885. for (int j = 0; j < VecWidth; ++j) {
  886. if (m[j]) {
  887. stack[target[j] + *(ip + i)].fSigned[j] = v[j];
  888. }
  889. }
  890. }
  891. ip += count;
  892. break;
  893. }
  894. case ByteCodeInstruction::kStoreSwizzleIndirectGlobal: {
  895. int count = READ8();
  896. I32 target = POP().fSigned;
  897. I32 m = mask();
  898. for (int i = count - 1; i >= 0; --i) {
  899. I32 v = POP().fSigned;
  900. for (int j = 0; j < VecWidth; ++j) {
  901. if (m[j]) {
  902. globals[target[j] + *(ip + i)].fSigned[j] = v[j];
  903. }
  904. }
  905. }
  906. ip += count;
  907. break;
  908. }
  909. VECTOR_BINARY_OP(kSubtractI, fSigned, -)
  910. VECTOR_MATRIX_BINARY_OP(kSubtractF, fFloat, -)
  911. case ByteCodeInstruction::kSwizzle: {
  912. VValue tmp[4];
  913. for (int i = READ8() - 1; i >= 0; --i) {
  914. tmp[i] = POP();
  915. }
  916. for (int i = READ8() - 1; i >= 0; --i) {
  917. PUSH(tmp[READ8()]);
  918. }
  919. break;
  920. }
  921. VECTOR_UNARY_FN_VEC(kTan, tanf)
  922. case ByteCodeInstruction::kWriteExternal:
  923. case ByteCodeInstruction::kWriteExternal2:
  924. case ByteCodeInstruction::kWriteExternal3:
  925. case ByteCodeInstruction::kWriteExternal4: {
  926. int count = (int)inst - (int)ByteCodeInstruction::kWriteExternal + 1;
  927. int target = READ8();
  928. float tmp[4];
  929. I32 m = mask();
  930. sp -= count;
  931. for (int i = 0; i < VecWidth; ++i) {
  932. if (m[i]) {
  933. for (int j = 0; j < count; ++j) {
  934. tmp[j] = sp[j + 1].fFloat[i];
  935. }
  936. byteCode->fExternalValues[target]->write(baseIndex + i, tmp);
  937. }
  938. }
  939. break;
  940. }
  941. case ByteCodeInstruction::kMaskPush:
  942. condPtr[1] = POP().fSigned;
  943. maskPtr[1] = maskPtr[0] & condPtr[1];
  944. ++condPtr; ++maskPtr;
  945. break;
  946. case ByteCodeInstruction::kMaskPop:
  947. --condPtr; --maskPtr;
  948. break;
  949. case ByteCodeInstruction::kMaskNegate:
  950. maskPtr[0] = maskPtr[-1] & ~condPtr[0];
  951. break;
  952. case ByteCodeInstruction::kMaskBlend: {
  953. int count = READ8();
  954. I32 m = condPtr[0];
  955. --condPtr; --maskPtr;
  956. for (int i = 0; i < count; ++i) {
  957. sp[-count] = skvx::if_then_else(m, sp[-count].fFloat, sp[0].fFloat);
  958. --sp;
  959. }
  960. break;
  961. }
  962. case ByteCodeInstruction::kBranchIfAllFalse: {
  963. int target = READ16();
  964. if (!skvx::any(mask())) {
  965. ip = code + target;
  966. }
  967. break;
  968. }
  969. case ByteCodeInstruction::kLoopBegin:
  970. contPtr[1] = 0;
  971. loopPtr[1] = loopPtr[0];
  972. ++contPtr; ++loopPtr;
  973. break;
  974. case ByteCodeInstruction::kLoopNext:
  975. *loopPtr |= *contPtr;
  976. *contPtr = 0;
  977. break;
  978. case ByteCodeInstruction::kLoopMask:
  979. *loopPtr &= POP().fSigned;
  980. break;
  981. case ByteCodeInstruction::kLoopEnd:
  982. --contPtr; --loopPtr;
  983. break;
  984. case ByteCodeInstruction::kLoopBreak:
  985. *loopPtr &= ~mask();
  986. break;
  987. case ByteCodeInstruction::kLoopContinue: {
  988. I32 m = mask();
  989. *contPtr |= m;
  990. *loopPtr &= ~m;
  991. break;
  992. }
  993. default:
  994. SkDEBUGFAILF("unsupported instruction %d\n", (int) inst);
  995. return false;
  996. }
  997. }
  998. // Unreachable
  999. return false;
  1000. }
  1001. } // namespace Interpreter
  1002. #endif // SK_ENABLE_SKSL_INTERPRETER
  1003. #undef spf
  1004. void ByteCodeFunction::disassemble() const {
  1005. #if defined(SK_ENABLE_SKSL_INTERPRETER)
  1006. const uint8_t* ip = fCode.data();
  1007. while (ip < fCode.data() + fCode.size()) {
  1008. printf("%d: ", (int)(ip - fCode.data()));
  1009. ip = Interpreter::disassemble_instruction(ip);
  1010. printf("\n");
  1011. }
  1012. #endif
  1013. }
  1014. bool ByteCode::run(const ByteCodeFunction* f, float* args, float* outReturn, int N,
  1015. const float* uniforms, int uniformCount) const {
  1016. #if defined(SK_ENABLE_SKSL_INTERPRETER)
  1017. #ifdef TRACE
  1018. f->disassemble();
  1019. #endif
  1020. Interpreter::VValue stack[128];
  1021. int stackNeeded = f->fParameterCount + f->fLocalCount + f->fStackCount;
  1022. if (stackNeeded > (int)SK_ARRAY_COUNT(stack)) {
  1023. return false;
  1024. }
  1025. if (uniformCount != (int)fInputSlots.size()) {
  1026. return false;
  1027. }
  1028. Interpreter::VValue globals[32];
  1029. if (fGlobalCount > (int)SK_ARRAY_COUNT(globals)) {
  1030. return false;
  1031. }
  1032. for (uint8_t slot : fInputSlots) {
  1033. globals[slot].fFloat = *uniforms++;
  1034. }
  1035. int baseIndex = 0;
  1036. while (N) {
  1037. int w = std::min(N, Interpreter::VecWidth);
  1038. // Transpose args into stack
  1039. {
  1040. float* src = args;
  1041. for (int i = 0; i < w; ++i) {
  1042. float* dst = (float*)stack + i;
  1043. for (int j = f->fParameterCount; j > 0; --j) {
  1044. *dst = *src++;
  1045. dst += Interpreter::VecWidth;
  1046. }
  1047. }
  1048. }
  1049. bool stripedOutput = false;
  1050. float** outArray = outReturn ? &outReturn : nullptr;
  1051. if (!innerRun(this, f, stack, outArray, globals, stripedOutput, w, baseIndex)) {
  1052. return false;
  1053. }
  1054. // Transpose out parameters back
  1055. {
  1056. float* dst = args;
  1057. for (int i = 0; i < w; ++i) {
  1058. float* src = (float*)stack + i;
  1059. for (const auto& p : f->fParameters) {
  1060. if (p.fIsOutParameter) {
  1061. for (int j = p.fSlotCount; j > 0; --j) {
  1062. *dst++ = *src;
  1063. src += Interpreter::VecWidth;
  1064. }
  1065. } else {
  1066. dst += p.fSlotCount;
  1067. src += p.fSlotCount * Interpreter::VecWidth;
  1068. }
  1069. }
  1070. }
  1071. }
  1072. args += f->fParameterCount * w;
  1073. if (outReturn) {
  1074. outReturn += f->fReturnCount * w;
  1075. }
  1076. N -= w;
  1077. baseIndex += w;
  1078. }
  1079. return true;
  1080. #else
  1081. SkDEBUGFAIL("ByteCode interpreter not enabled");
  1082. return false;
  1083. #endif
  1084. }
  1085. bool ByteCode::runStriped(const ByteCodeFunction* f, float* args[], int nargs, int N,
  1086. const float* uniforms, int uniformCount,
  1087. float* outArgs[], int outCount) const {
  1088. #if defined(SK_ENABLE_SKSL_INTERPRETER)
  1089. #ifdef TRACE
  1090. f->disassemble();
  1091. #endif
  1092. Interpreter::VValue stack[128];
  1093. int stackNeeded = f->fParameterCount + f->fLocalCount + f->fStackCount;
  1094. if (stackNeeded > (int)SK_ARRAY_COUNT(stack)) {
  1095. return false;
  1096. }
  1097. if (nargs != f->fParameterCount ||
  1098. outCount != f->fReturnCount ||
  1099. uniformCount != (int)fInputSlots.size()) {
  1100. return false;
  1101. }
  1102. Interpreter::VValue globals[32];
  1103. if (fGlobalCount > (int)SK_ARRAY_COUNT(globals)) {
  1104. return false;
  1105. }
  1106. for (uint8_t slot : fInputSlots) {
  1107. globals[slot].fFloat = *uniforms++;
  1108. }
  1109. // innerRun just takes outArgs, so clear it if the count is zero
  1110. if (outCount == 0) {
  1111. outArgs = nullptr;
  1112. }
  1113. int baseIndex = 0;
  1114. while (N) {
  1115. int w = std::min(N, Interpreter::VecWidth);
  1116. // Copy args into stack
  1117. for (int i = 0; i < nargs; ++i) {
  1118. memcpy(stack + i, args[i], w * sizeof(float));
  1119. }
  1120. bool stripedOutput = true;
  1121. if (!innerRun(this, f, stack, outArgs, globals, stripedOutput, w, baseIndex)) {
  1122. return false;
  1123. }
  1124. // Copy out parameters back
  1125. int slot = 0;
  1126. for (const auto& p : f->fParameters) {
  1127. if (p.fIsOutParameter) {
  1128. for (int i = slot; i < slot + p.fSlotCount; ++i) {
  1129. memcpy(args[i], stack + i, w * sizeof(float));
  1130. }
  1131. }
  1132. slot += p.fSlotCount;
  1133. }
  1134. // Step each argument pointer ahead
  1135. for (int i = 0; i < nargs; ++i) {
  1136. args[i] += w;
  1137. }
  1138. N -= w;
  1139. baseIndex += w;
  1140. }
  1141. return true;
  1142. #else
  1143. SkDEBUGFAIL("ByteCode interpreter not enabled");
  1144. return false;
  1145. #endif
  1146. }
  1147. } // namespace SkSL
  1148. #endif