Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 49b30f4

Browse files
brianosmanSkia Commit-Bot
authored and
Skia Commit-Bot
committed
SkSL ByteCode: Remove specialized instructions for N up to 4
Nearly all instructions have one form, with a count byte after the instruction. Simplifes the SkVM conversion logic, reduces code size. Change-Id: I5ff7bb2991a09198c5c8f5bcaf2c1017c06be5d4 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/299682 Reviewed-by: Mike Klein <[email protected]> Commit-Queue: Brian Osman <[email protected]>
1 parent e7e25ac commit 49b30f4

File tree

4 files changed

+517
-985
lines changed

4 files changed

+517
-985
lines changed

src/core/SkRuntimeEffect.cpp

Lines changed: 64 additions & 203 deletions
Original file line numberDiff line numberDiff line change
@@ -461,33 +461,36 @@ static std::vector<skvm::F32> program_fn(skvm::Builder* p,
461461
//auto u16 = [&]{ auto x = sk_unaligned_load<uint16_t>(ip); ip += sizeof(x); return x; };
462462
auto u32 = [&]{ auto x = sk_unaligned_load<uint32_t>(ip); ip += sizeof(x); return x; };
463463

464-
auto unary = [&](Inst base, auto&& fn, bool allow_big = false) {
465-
int N = (int)base - (int)inst + 1;
466-
SkASSERT(0 < N && N <= (allow_big ? 5 : 4));
467-
if (N == 5) { N = u8(); }
468-
std::vector<skvm::F32> args(N);
469-
for (int i = 0; i < N; ++i) {
470-
args[i] = pop();
471-
}
472-
for (int i = N; i --> 0;) {
473-
push(fn(args[i]));
464+
auto unary = [&](auto&& fn) {
465+
int N = u8();
466+
std::vector<skvm::F32> a(N);
467+
for (int i = N; i --> 0; ) { a[i] = pop(); }
468+
469+
for (int i = 0; i < N; i++) {
470+
push(fn(a[i]));
474471
}
475472
};
476473

477-
auto binary = [&](Inst base, auto&& fn, bool allow_big = false) {
478-
int N = (int)base - (int)inst + 1;
479-
SkASSERT(0 < N && N <= (allow_big ? 5 : 4));
480-
if (N == 5) { N = u8(); }
481-
std::vector<skvm::F32> right(N);
482-
for (int i = 0; i < N; ++i) {
483-
right[i] = pop();
484-
}
485-
std::vector<skvm::F32> left(N);
486-
for (int i = 0; i < N; ++i) {
487-
left[i] = pop();
474+
auto binary = [&](auto&& fn) {
475+
int N = u8();
476+
std::vector<skvm::F32> a(N), b(N);
477+
for (int i = N; i --> 0; ) { b[i] = pop(); }
478+
for (int i = N; i --> 0; ) { a[i] = pop(); }
479+
480+
for (int i = 0; i < N; i++) {
481+
push(fn(a[i], b[i]));
488482
}
489-
for (int i = N; i --> 0;) {
490-
push(fn(left[i], right[i]));
483+
};
484+
485+
auto ternary = [&](auto&& fn) {
486+
int N = u8();
487+
std::vector<skvm::F32> a(N), b(N), c(N);
488+
for (int i = N; i --> 0; ) { c[i] = pop(); }
489+
for (int i = N; i --> 0; ) { b[i] = pop(); }
490+
for (int i = N; i --> 0; ) { a[i] = pop(); }
491+
492+
for (int i = 0; i < N; i++) {
493+
push(fn(a[i], b[i], c[i]));
491494
}
492495
};
493496

@@ -552,55 +555,19 @@ static std::vector<skvm::F32> program_fn(skvm::Builder* p,
552555
} break;
553556

554557
case Inst::kLoad: {
555-
int ix = u8();
556-
push(stack[ix + 0]);
557-
} break;
558-
559-
case Inst::kLoad2: {
560-
int ix = u8();
561-
push(stack[ix + 0]);
562-
push(stack[ix + 1]);
563-
} break;
564-
565-
case Inst::kLoad3: {
566-
int ix = u8();
567-
push(stack[ix + 0]);
568-
push(stack[ix + 1]);
569-
push(stack[ix + 2]);
570-
} break;
571-
572-
case Inst::kLoad4: {
573-
int ix = u8();
574-
push(stack[ix + 0]);
575-
push(stack[ix + 1]);
576-
push(stack[ix + 2]);
577-
push(stack[ix + 3]);
558+
int N = u8(),
559+
ix = u8();
560+
for (int i = 0; i < N; ++i) {
561+
push(stack[ix + i]);
562+
}
578563
} break;
579564

580565
case Inst::kLoadUniform: {
581-
int ix = u8();
582-
push(uniform[ix]);
583-
} break;
584-
585-
case Inst::kLoadUniform2: {
586-
int ix = u8();
587-
push(uniform[ix + 0]);
588-
push(uniform[ix + 1]);
589-
} break;
590-
591-
case Inst::kLoadUniform3: {
592-
int ix = u8();
593-
push(uniform[ix + 0]);
594-
push(uniform[ix + 1]);
595-
push(uniform[ix + 2]);
596-
} break;
597-
598-
case Inst::kLoadUniform4: {
599-
int ix = u8();
600-
push(uniform[ix + 0]);
601-
push(uniform[ix + 1]);
602-
push(uniform[ix + 2]);
603-
push(uniform[ix + 3]);
566+
int N = u8(),
567+
ix = u8();
568+
for (int i = 0; i < N; ++i) {
569+
push(uniform[ix + i]);
570+
}
604571
} break;
605572

606573
case Inst::kLoadFragCoord: {
@@ -612,56 +579,22 @@ static std::vector<skvm::F32> program_fn(skvm::Builder* p,
612579
} break;
613580

614581
case Inst::kStore: {
615-
int ix = u8();
616-
stack[ix + 0] = pop();
617-
} break;
618-
619-
case Inst::kStore2: {
620-
int ix = u8();
621-
stack[ix + 1] = pop();
622-
stack[ix + 0] = pop();
623-
} break;
624-
625-
case Inst::kStore3: {
626-
int ix = u8();
627-
stack[ix + 2] = pop();
628-
stack[ix + 1] = pop();
629-
stack[ix + 0] = pop();
630-
} break;
631-
632-
case Inst::kStore4: {
633-
int ix = u8();
634-
stack[ix + 3] = pop();
635-
stack[ix + 2] = pop();
636-
stack[ix + 1] = pop();
637-
stack[ix + 0] = pop();
582+
int N = u8(),
583+
ix = u8();
584+
for (int i = N; i --> 0; ) {
585+
stack[ix + i] = pop();
586+
}
638587
} break;
639588

640-
641589
case Inst::kPushImmediate: {
642590
push(bit_cast(p->splat(u32())));
643591
} break;
644592

645593
case Inst::kDup: {
646-
push(stack[stack.size() - 1]);
647-
} break;
648-
649-
case Inst::kDup2: {
650-
push(stack[stack.size() - 2]);
651-
push(stack[stack.size() - 2]);
652-
} break;
653-
654-
case Inst::kDup3: {
655-
push(stack[stack.size() - 3]);
656-
push(stack[stack.size() - 3]);
657-
push(stack[stack.size() - 3]);
658-
} break;
659-
660-
case Inst::kDup4: {
661-
push(stack[stack.size() - 4]);
662-
push(stack[stack.size() - 4]);
663-
push(stack[stack.size() - 4]);
664-
push(stack[stack.size() - 4]);
594+
int N = u8();
595+
for (int i = 0; i < N; ++i) {
596+
push(stack[stack.size() - N]);
597+
}
665598
} break;
666599

667600
case Inst::kSwizzle: {
@@ -674,104 +607,34 @@ static std::vector<skvm::F32> program_fn(skvm::Builder* p,
674607
}
675608
} break;
676609

677-
case Inst::kAddF:
678-
case Inst::kAddF2:
679-
case Inst::kAddF3:
680-
case Inst::kAddF4:
681-
case Inst::kAddFN: binary(Inst::kAddF, std::plus<>{}, true); break;
682-
683-
case Inst::kSubtractF:
684-
case Inst::kSubtractF2:
685-
case Inst::kSubtractF3:
686-
case Inst::kSubtractF4:
687-
case Inst::kSubtractFN: binary(Inst::kSubtractF, std::minus<>{}, true); break;
688-
689-
case Inst::kMultiplyF:
690-
case Inst::kMultiplyF2:
691-
case Inst::kMultiplyF3:
692-
case Inst::kMultiplyF4:
693-
case Inst::kMultiplyFN: binary(Inst::kMultiplyF, std::multiplies<>{}, true); break;
694-
695-
case Inst::kDivideF:
696-
case Inst::kDivideF2:
697-
case Inst::kDivideF3:
698-
case Inst::kDivideF4:
699-
case Inst::kDivideFN: binary(Inst::kDivideF, std::divides<>{}, true); break;
610+
case Inst::kAddF: binary(std::plus<>{}); break;
611+
case Inst::kSubtractF: binary(std::minus<>{}); break;
612+
case Inst::kMultiplyF: binary(std::multiplies<>{}); break;
613+
case Inst::kDivideF: binary(std::divides<>{}); break;
614+
case Inst::kNegateF: unary(std::negate<>{}); break;
700615

701616
case Inst::kMinF:
702-
case Inst::kMinF2:
703-
case Inst::kMinF3:
704-
case Inst::kMinF4:
705-
binary(Inst::kMinF, [](skvm::F32 x, skvm::F32 y) { return skvm::min(x,y); });
617+
binary([](skvm::F32 x, skvm::F32 y) { return skvm::min(x,y); });
706618
break;
707619

708620
case Inst::kMaxF:
709-
case Inst::kMaxF2:
710-
case Inst::kMaxF3:
711-
case Inst::kMaxF4:
712-
binary(Inst::kMaxF, [](skvm::F32 x, skvm::F32 y) { return skvm::max(x,y); });
621+
binary([](skvm::F32 x, skvm::F32 y) { return skvm::max(x,y); });
713622
break;
714623

715-
case Inst::kNegateF:
716-
case Inst::kNegateF2:
717-
case Inst::kNegateF3:
718-
case Inst::kNegateF4:
719-
case Inst::kNegateFN: unary(Inst::kNegateF, std::negate<>{}, true); break;
720-
721624
case Inst::kPow:
722-
case Inst::kPow2:
723-
case Inst::kPow3:
724-
case Inst::kPow4:
725-
binary(Inst::kPow, [](skvm::F32 x, skvm::F32 y) { return skvm::approx_powf(x,y); });
625+
binary([](skvm::F32 x, skvm::F32 y) { return skvm::approx_powf(x,y); });
726626
break;
727627

728628
case Inst::kLerp:
729-
case Inst::kLerp2:
730-
case Inst::kLerp3:
731-
case Inst::kLerp4: {
732-
int N = (int)Inst::kLerp - (int)inst + 1;
733-
734-
skvm::F32 t[4],
735-
b[4],
736-
a[4];
737-
for (int i = N; i --> 0; ) { t[i] = pop(); }
738-
for (int i = N; i --> 0; ) { b[i] = pop(); }
739-
for (int i = N; i --> 0; ) { a[i] = pop(); }
740-
741-
for (int i = 0; i < N; i++) {
742-
push(skvm::lerp(a[i], b[i], t[i]));
743-
}
744-
} break;
745-
746-
case Inst::kATan:
747-
case Inst::kATan2:
748-
case Inst::kATan3:
749-
case Inst::kATan4: unary(Inst::kATan, skvm::approx_atan); break;
750-
751-
case Inst::kCeil:
752-
case Inst::kCeil2:
753-
case Inst::kCeil3:
754-
case Inst::kCeil4: unary(Inst::kCeil, skvm::ceil); break;
755-
756-
case Inst::kFloor:
757-
case Inst::kFloor2:
758-
case Inst::kFloor3:
759-
case Inst::kFloor4: unary(Inst::kFloor, skvm::floor); break;
760-
761-
case Inst::kFract:
762-
case Inst::kFract2:
763-
case Inst::kFract3:
764-
case Inst::kFract4: unary(Inst::kFract, skvm::fract); break;
765-
766-
case Inst::kSqrt:
767-
case Inst::kSqrt2:
768-
case Inst::kSqrt3:
769-
case Inst::kSqrt4: unary(Inst::kSqrt, skvm::sqrt); break;
629+
ternary([](skvm::F32 x, skvm::F32 y, skvm::F32 t) { return skvm::lerp(x, y, t); });
630+
break;
770631

771-
case Inst::kSin:
772-
case Inst::kSin2:
773-
case Inst::kSin3:
774-
case Inst::kSin4: unary(Inst::kSin, skvm::approx_sin); break;
632+
case Inst::kATan: unary(skvm::approx_atan); break;
633+
case Inst::kCeil: unary(skvm::ceil); break;
634+
case Inst::kFloor: unary(skvm::floor); break;
635+
case Inst::kFract: unary(skvm::fract); break;
636+
case Inst::kSqrt: unary(skvm::sqrt); break;
637+
case Inst::kSin: unary(skvm::approx_sin); break;
775638

776639
case Inst::kMatrixMultiply: {
777640
// Computes M = A*B (all stored column major)
@@ -798,11 +661,9 @@ static std::vector<skvm::F32> program_fn(skvm::Builder* p,
798661
case Inst::kMaskPush: break;
799662
case Inst::kMaskNegate: break;
800663

801-
case Inst::kCompareFLT: {
802-
skvm::F32 x = pop(),
803-
a = pop();
804-
push(bit_cast(a<x));
805-
} break;
664+
case Inst::kCompareFLT:
665+
binary([](skvm::F32 x, skvm::F32 y) { return bit_cast(x<y); });
666+
break;
806667

807668
case Inst::kMaskBlend: {
808669
std::vector<skvm::F32> if_true,

0 commit comments

Comments
 (0)