270 alignas(64) int32_t initial[64] = {~0, ~0, ~0, ~0, ~0, 0, ~0, ~0,
271 ~0, 0, ~0, 0, ~0, ~0, ~0, ~0,
272 ~0, ~0, ~0, ~0, ~0, ~0, 0, ~0,
273 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
274 ~0, ~0, ~0, ~0, ~0, 0, ~0, ~0,
275 ~0, 0, ~0, 0, ~0, ~0, ~0, ~0,
276 ~0, ~0, ~0, ~0, ~0, ~0, 0, ~0,
277 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0};
278 alignas(64) int32_t mask[16] = {0, ~0, ~0, 0, ~0, ~0, ~0, ~0, 0, ~0, ~0, 0, ~0, ~0, ~0, ~0};
283 p.append(SkRasterPipelineOp::load_src, initial);
284 p.append(SkRasterPipelineOp::merge_loop_mask, mask);
285 p.append(SkRasterPipelineOp::store_src, src);
306 alignas(64) int32_t initial[64] = {~0, ~0, ~0, ~0, ~0, 0, ~0, ~0,
307 ~0, 0, ~0, 0, ~0, ~0, 0, ~0,
308 0, ~0, ~0, ~0, 0, 0, 0, ~0,
309 0, 0, ~0, 0, 0, 0, 0, ~0,
310 ~0, ~0, ~0, ~0, ~0, 0, ~0, ~0,
311 ~0, 0, ~0, 0, ~0, ~0, 0, ~0,
312 0, ~0, ~0, ~0, 0, 0, 0, ~0,
313 0, 0, ~0, 0, 0, 0, 0, ~0};
314 alignas(64) int32_t mask[16] = { 0, ~0, 0, 0, 0, 0, ~0, 0, 0, ~0, 0, 0, 0, 0, ~0, 0};
319 p.append(SkRasterPipelineOp::load_src, initial);
320 p.append(SkRasterPipelineOp::reenable_loop_mask, mask);
321 p.append(SkRasterPipelineOp::store_src, src);
342 alignas(64) int32_t initial[64] = {~0, ~0, ~0, ~0, ~0, 0, ~0, ~0,
343 0, ~0, ~0, 0, ~0, ~0, 0, ~0,
344 ~0, 0, ~0, ~0, 0, 0, 0, ~0,
345 0, 0, ~0, 0, 0, 0, 0, ~0,
346 ~0, ~0, ~0, ~0, ~0, 0, ~0, ~0,
347 0, ~0, ~0, 0, ~0, ~0, 0, ~0,
348 ~0, 0, ~0, ~0, 0, 0, 0, ~0,
349 0, 0, ~0, 0, 0, 0, 0, ~0};
353 constexpr int32_t actualValues[16] = { 2, 1, 2, 4, 5, 2, 2, 8};
368 p.append(SkRasterPipelineOp::load_src, initial);
369 p.append(SkRasterPipelineOp::set_base_pointer, &caseOpData[0]);
371 p.append(SkRasterPipelineOp::store_src, src);
383 int32_t expected = (actualValues[index] == 2) ? ~0 : initial[g + index];
397 expected = (actualValues[index] == 2) ? 0 : ~0;
403 alignas(64) int32_t initial[64] = {~0, ~0, ~0, ~0, ~0, 0, ~0, ~0,
404 ~0, 0, ~0, ~0, 0, 0, 0, ~0,
405 ~0, ~0, 0, ~0, 0, 0, ~0, ~0,
406 ~0, 0, 0, ~0, 0, 0, 0, ~0,
407 ~0, ~0, ~0, ~0, ~0, 0, ~0, ~0,
408 ~0, 0, ~0, ~0, 0, 0, 0, ~0,
409 ~0, ~0, 0, ~0, 0, 0, ~0, ~0,
410 ~0, 0, 0, ~0, 0, 0, 0, ~0};
415 p.append(SkRasterPipelineOp::load_src, initial);
416 p.append(SkRasterPipelineOp::mask_off_loop_mask);
417 p.append(SkRasterPipelineOp::store_src, src);
426 int32_t expected = initial[g + index] & ~initial[
a + index];
430 expected = src[r + index] & src[g + index] & src[
b + index];
436 alignas(64) int32_t initial[64] = {~0, ~0, ~0, ~0, ~0, 0, ~0, ~0,
437 ~0, 0, ~0, ~0, 0, 0, 0, ~0,
438 ~0, ~0, 0, ~0, 0, 0, ~0, ~0,
439 ~0, 0, 0, ~0, 0, 0, 0, ~0,
440 ~0, ~0, ~0, ~0, ~0, 0, ~0, ~0,
441 ~0, 0, ~0, ~0, 0, 0, 0, ~0,
442 ~0, ~0, 0, ~0, 0, 0, ~0, ~0,
443 ~0, 0, 0, ~0, 0, 0, 0, ~0};
448 p.append(SkRasterPipelineOp::load_src, initial);
449 p.append(SkRasterPipelineOp::mask_off_return_mask);
450 p.append(SkRasterPipelineOp::store_src, src);
459 int32_t expected = initial[
b + index] & ~initial[
a + index];
463 expected = src[r + index] & src[g + index] & src[
b + index];
524DEF_TEST(SkRasterPipeline_CopyFromIndirectUnmasked, r) {
531 alignas(64)
const uint32_t kOffsets1[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
532 alignas(64)
const uint32_t kOffsets2[16] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
533 alignas(64)
const uint32_t kOffsets3[16] = {0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2};
534 alignas(64)
const uint32_t kOffsets4[16] = {99, 99, 0, 0, 99, 99, 0, 0,
535 99, 99, 0, 0, 99, 99, 0, 0};
539 for (
const uint32_t* offsets : {kOffsets1, kOffsets2, kOffsets3, kOffsets4}) {
540 for (
int copySize = 1; copySize <= 5; ++copySize) {
542 std::iota(&dst[0], &dst[5 *
N], 0);
551 ctx->indirectOffset = offsets;
552 ctx->indirectLimit = 5 - copySize;
553 ctx->slots = copySize;
555 p.append(SkRasterPipelineOp::copy_from_indirect_unmasked, ctx);
562 int maxOffset = *std::max_element(offsets, offsets +
N);
563 if (copySize + maxOffset > 5) {
569 int expectedUnchanged = 0;
570 int expectedFromZero = src[0 *
N], expectedFromTwo = src[2 *
N];
572 for (
int checkSlot = 0; checkSlot < 5; ++checkSlot) {
573 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
574 if (checkSlot < copySize) {
575 if (offsets[checkLane] == 0) {
577 }
else if (offsets[checkLane] == 2) {
580 ERRORF(r,
"unexpected offset value");
587 expectedUnchanged += 1;
588 expectedFromZero += 1;
589 expectedFromTwo += 1;
596DEF_TEST(SkRasterPipeline_CopyFromIndirectUniformUnmasked, r) {
599 alignas(64)
int src[5];
604 alignas(64)
const uint32_t kOffsets1[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
605 alignas(64)
const uint32_t kOffsets2[16] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
606 alignas(64)
const uint32_t kOffsets3[16] = {0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2};
607 alignas(64)
const uint32_t kOffsets4[16] = {99, ~99u, 0, 0, ~99u, 99, 0, 0,
608 99, ~99u, 0, 0, ~99u, 99, 0, 0};
612 for (
const uint32_t* offsets : {kOffsets1, kOffsets2, kOffsets3, kOffsets4}) {
613 for (
int copySize = 1; copySize <= 5; ++copySize) {
615 std::iota(&dst[0], &dst[5 *
N], 0);
624 ctx->indirectOffset = offsets;
625 ctx->indirectLimit = 5 - copySize;
626 ctx->slots = copySize;
628 p.append(SkRasterPipelineOp::copy_from_indirect_uniform_unmasked, ctx);
635 uint32_t maxOffset = *std::max_element(offsets, offsets +
N);
636 if (copySize + maxOffset > 5) {
641 int expectedUnchanged = 0;
642 int expectedFromZero = src[0], expectedFromTwo = src[2];
644 for (
int checkSlot = 0; checkSlot < 5; ++checkSlot) {
645 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
646 if (checkSlot < copySize) {
647 if (offsets[checkLane] == 0) {
649 }
else if (offsets[checkLane] == 2) {
652 ERRORF(r,
"unexpected offset value");
659 expectedUnchanged += 1;
661 expectedFromZero += 1;
662 expectedFromTwo += 1;
668DEF_TEST(SkRasterPipeline_CopyToIndirectMasked, r) {
675 alignas(64)
const uint32_t kOffsets1[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
676 alignas(64)
const uint32_t kOffsets2[16] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
677 alignas(64)
const uint32_t kOffsets3[16] = {0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2};
678 alignas(64)
const uint32_t kOffsets4[16] = {99, ~99u, 0, 0, ~99u, 99, 0, 0,
679 99, ~99u, 0, 0, ~99u, 99, 0, 0};
682 alignas(64)
const int32_t kMask1[16] = {~0, ~0, ~0, ~0, ~0, 0, ~0, ~0,
683 ~0, ~0, ~0, ~0, ~0, 0, ~0, ~0};
684 alignas(64)
const int32_t kMask2[16] = {~0, 0, ~0, ~0, 0, 0, 0, ~0,
685 ~0, 0, ~0, ~0, 0, 0, 0, ~0};
686 alignas(64)
const int32_t kMask3[16] = {~0, ~0, 0, ~0, 0, 0, ~0, ~0,
687 ~0, ~0, 0, ~0, 0, 0, ~0, ~0};
688 alignas(64)
const int32_t kMask4[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
689 0, 0, 0, 0, 0, 0, 0, 0};
693 for (
const int32_t* mask : {kMask1, kMask2, kMask3, kMask4}) {
694 for (
const uint32_t* offsets : {kOffsets1, kOffsets2, kOffsets3, kOffsets4}) {
695 for (
int copySize = 1; copySize <= 5; ++copySize) {
697 std::iota(&dst[0], &dst[5 *
N], 0);
706 ctx->indirectOffset = offsets;
707 ctx->indirectLimit = 5 - copySize;
708 ctx->slots = copySize;
711 p.append(SkRasterPipelineOp::init_lane_masks, &initLaneMasksCtx);
712 p.append(SkRasterPipelineOp::load_condition_mask, mask);
713 p.append(SkRasterPipelineOp::copy_to_indirect_masked, ctx);
720 uint32_t maxOffset = *std::max_element(offsets, offsets +
N);
721 if (copySize + maxOffset > 5) {
727 int expectedUnchanged = 0;
728 int expectedFromZero = src[0], expectedFromTwo = src[0] - (2 *
N);
731 for (
int checkSlot = 0; checkSlot < 5; ++checkSlot) {
732 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
733 int rangeStart = offsets[checkLane] *
N;
734 int rangeEnd = (offsets[checkLane] + copySize) *
N;
735 if (mask[checkLane] &&
pos >= rangeStart &&
pos < rangeEnd) {
736 if (offsets[checkLane] == 0) {
738 }
else if (offsets[checkLane] == 2) {
741 ERRORF(r,
"unexpected offset value");
749 expectedUnchanged += 1;
750 expectedFromZero += 1;
751 expectedFromTwo += 1;
759DEF_TEST(SkRasterPipeline_SwizzleCopyToIndirectMasked, r) {
766 alignas(64)
const uint32_t kOffsets1[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
767 alignas(64)
const uint32_t kOffsets2[16] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
768 alignas(64)
const uint32_t kOffsets3[16] = {0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2};
769 alignas(64)
const uint32_t kOffsets4[16] = {99, ~99u, 0, 0, ~99u, 99, 0, 0,
770 99, ~99u, 0, 0, ~99u, 99, 0, 0};
773 alignas(64)
const int32_t kMask1[16] = {~0, ~0, ~0, ~0, ~0, 0, ~0, ~0,
774 ~0, ~0, ~0, ~0, ~0, 0, ~0, ~0};
775 alignas(64)
const int32_t kMask2[16] = {~0, 0, ~0, ~0, 0, 0, 0, ~0,
776 ~0, 0, ~0, ~0, 0, 0, 0, ~0};
777 alignas(64)
const int32_t kMask3[16] = {~0, ~0, 0, ~0, 0, 0, ~0, ~0,
778 ~0, ~0, 0, ~0, 0, 0, ~0, ~0};
779 alignas(64)
const int32_t kMask4[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
780 0, 0, 0, 0, 0, 0, 0, 0};
785 int swizzleUpperBound;
789 static const TestPattern kPatterns[] = {
793 {4, 4, {3, 0, 1, 2}},
807#define XX kOutOfBounds
808 static const Result kExpectationsAtZero[4][5] = {
810 {
__,
__,
__,S0,
__}, {S1,S0,
__,
__,
__}, {S2,S1,S0,
__,
__}, {S1,S2,S3,S0,
__},
812 static const Result kExpectationsAtTwo[4][5] = {
814 {
XX,
XX,
XX,
XX,
XX}, {
__,
__,S1,S0,
__}, {
__,
__,S2,S1,S0}, {
XX,
XX,
XX,
XX,
XX},
821 for (
const int32_t* mask : {kMask1, kMask2, kMask3, kMask4}) {
822 for (
const uint32_t* offsets : {kOffsets1, kOffsets2, kOffsets3, kOffsets4}) {
823 for (
size_t patternIndex = 0; patternIndex < std::size(kPatterns); ++patternIndex) {
824 const TestPattern& pattern = kPatterns[patternIndex];
827 std::iota(&dst[0], &dst[5 *
N], 0);
836 ctx->indirectOffset = offsets;
837 ctx->indirectLimit = 5 - pattern.swizzleUpperBound;
838 ctx->slots = pattern.swizzleSize;
839 ctx->offsets[0] = pattern.swizzle[0] *
N *
sizeof(float);
840 ctx->offsets[1] = pattern.swizzle[1] *
N *
sizeof(float);
841 ctx->offsets[2] = pattern.swizzle[2] *
N *
sizeof(float);
842 ctx->offsets[3] = pattern.swizzle[3] *
N *
sizeof(float);
845 p.append(SkRasterPipelineOp::init_lane_masks, &initLaneMasksCtx);
846 p.append(SkRasterPipelineOp::load_condition_mask, mask);
847 p.append(SkRasterPipelineOp::swizzle_copy_to_indirect_masked, ctx);
854 uint32_t maxOffset = *std::max_element(offsets, offsets +
N);
855 if (pattern.swizzleUpperBound + maxOffset > 5) {
861 int expectedUnchanged = 0;
863 for (
int checkSlot = 0; checkSlot < 5; ++checkSlot) {
864 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
865 Result expectedType = kUnchanged;
866 if (offsets[checkLane] == 0) {
867 expectedType = kExpectationsAtZero[patternIndex][checkSlot];
868 }
else if (offsets[checkLane] == 2) {
869 expectedType = kExpectationsAtTwo[patternIndex][checkSlot];
871 if (!mask[checkLane]) {
872 expectedType = kUnchanged;
874 switch (expectedType) {
898 expectedUnchanged += 1;
911 void line(
int)
override { fBuffer.push_back(-9999999); }
912 void enter(
int)
override { fBuffer.push_back(-9999999); }
913 void exit(
int)
override { fBuffer.push_back(-9999999); }
914 void scope(
int)
override { fBuffer.push_back(-9999999); }
915 void var(
int slot, int32_t val)
override {
916 fBuffer.push_back(slot);
917 fBuffer.push_back(val);
924 alignas(64)
static constexpr int32_t kMaskOn [16] = {~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
925 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0};
926 alignas(64)
static constexpr int32_t kMaskOff [16] = { 0, 0, 0, 0, 0, 0, 0, 0,
927 0, 0, 0, 0, 0, 0, 0, 0};
928 alignas(64)
static constexpr uint32_t kIndirect0[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
929 0, 0, 0, 0, 0, 0, 0, 0};
930 alignas(64)
static constexpr uint32_t kIndirect1[16] = { 1, 1, 1, 1, 1, 1, 1, 1,
931 1, 1, 1, 1, 1, 1, 1, 1};
932 alignas(64) int32_t kData333[16];
933 alignas(64) int32_t kData555[16];
934 alignas(64) int32_t kData666[16];
935 alignas(64) int32_t kData777[32];
936 alignas(64) int32_t kData999[32];
937 std::fill(kData333, kData333 +
N, 333);
938 std::fill(kData555, kData555 +
N, 555);
939 std::fill(kData666, kData666 +
N, 666);
940 std::fill(kData777, kData777 +
N, 777);
941 std::fill(kData777 +
N, kData777 + 2*
N, 707);
942 std::fill(kData999, kData999 +
N, 999);
943 std::fill(kData999 +
N, kData999 + 2*
N, 909);
949 p.append(SkRasterPipelineOp::init_lane_masks, &initLaneMasksCtx);
951 &trace, 2, 1, kData333,
955 &trace, 4, 1, kData555,
959 &trace, 5, 1, kData666,
963 &trace, 6, 2, kData777,
967 &trace, 8, 2, kData999,
971 &trace, 9, 1, kData999,
975 &trace, 9, 1, kData999,
979 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOn);
980 p.append(SkRasterPipelineOp::trace_var, &kTraceVar1);
981 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOn);
982 p.append(SkRasterPipelineOp::trace_var, &kTraceVar2);
983 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOff);
984 p.append(SkRasterPipelineOp::trace_var, &kTraceVar3);
985 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOn);
986 p.append(SkRasterPipelineOp::trace_var, &kTraceVar4);
987 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOff);
988 p.append(SkRasterPipelineOp::trace_var, &kTraceVar5);
989 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOn);
990 p.append(SkRasterPipelineOp::trace_var, &kTraceVar6);
991 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOn);
992 p.append(SkRasterPipelineOp::trace_var, &kTraceVar7);
995 REPORTER_ASSERT(r, (trace.fBuffer ==
TArray<int>{4, 555, 6, 777, 7, 707, 9, 999, 10, 909}));
1003 void var(
int, int32_t)
override { fBuffer.push_back(-9999999); }
1004 void enter(
int)
override { fBuffer.push_back(-9999999); }
1005 void exit(
int)
override { fBuffer.push_back(-9999999); }
1006 void scope(
int)
override { fBuffer.push_back(-9999999); }
1007 void line(
int lineNum)
override { fBuffer.push_back(lineNum); }
1013 alignas(64)
static constexpr int32_t kMaskOn [16] = {~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
1014 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0};
1015 alignas(64)
static constexpr int32_t kMaskOff[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
1016 0, 0, 0, 0, 0, 0, 0, 0};
1018 TestTraceHook trace;
1022 p.append(SkRasterPipelineOp::init_lane_masks, &initLaneMasksCtx);
1029 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOn);
1030 p.append(SkRasterPipelineOp::trace_line, &kTraceLine1);
1031 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOn);
1032 p.append(SkRasterPipelineOp::trace_line, &kTraceLine2);
1033 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOff);
1034 p.append(SkRasterPipelineOp::trace_line, &kTraceLine3);
1035 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOff);
1036 p.append(SkRasterPipelineOp::trace_line, &kTraceLine4);
1037 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOn);
1038 p.append(SkRasterPipelineOp::trace_line, &kTraceLine5);
1049 void line(
int)
override { fBuffer.push_back(-9999999); }
1050 void var(
int, int32_t)
override { fBuffer.push_back(-9999999); }
1051 void scope(
int)
override { fBuffer.push_back(-9999999); }
1052 void enter(
int fnIdx)
override {
1053 fBuffer.push_back(fnIdx);
1054 fBuffer.push_back(1);
1056 void exit(
int fnIdx)
override {
1057 fBuffer.push_back(fnIdx);
1058 fBuffer.push_back(0);
1065 alignas(64)
static constexpr int32_t kMaskOn [16] = {~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
1066 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0};
1067 alignas(64)
static constexpr int32_t kMaskOff[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
1068 0, 0, 0, 0, 0, 0, 0, 0};
1070 TestTraceHook trace;
1074 p.append(SkRasterPipelineOp::init_lane_masks, &initLaneMasksCtx);
1082 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOff);
1083 p.append(SkRasterPipelineOp::trace_enter, &kTraceFunc1);
1084 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOn);
1085 p.append(SkRasterPipelineOp::trace_enter, &kTraceFunc2);
1086 p.append(SkRasterPipelineOp::trace_enter, &kTraceFunc3);
1087 p.append(SkRasterPipelineOp::trace_exit, &kTraceFunc4);
1088 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOff);
1089 p.append(SkRasterPipelineOp::trace_exit, &kTraceFunc5);
1090 p.append(SkRasterPipelineOp::trace_exit, &kTraceFunc6);
1101 void line(
int)
override { fBuffer.push_back(-9999999); }
1102 void var(
int, int32_t)
override { fBuffer.push_back(-9999999); }
1103 void enter(
int)
override { fBuffer.push_back(-9999999); }
1104 void exit(
int)
override { fBuffer.push_back(-9999999); }
1105 void scope(
int delta)
override { fBuffer.push_back(delta); }
1111 alignas(64)
static constexpr int32_t kMaskOn [16] = {~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
1112 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0};
1113 alignas(64)
static constexpr int32_t kMaskOff[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
1114 0, 0, 0, 0, 0, 0, 0, 0};
1116 TestTraceHook trace;
1120 p.append(SkRasterPipelineOp::init_lane_masks, &initLaneMasksCtx);
1127 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOn);
1128 p.append(SkRasterPipelineOp::trace_scope, &kTraceScope1);
1129 p.append(SkRasterPipelineOp::trace_scope, &kTraceScope2);
1130 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOff);
1131 p.append(SkRasterPipelineOp::trace_scope, &kTraceScope3);
1132 p.append(SkRasterPipelineOp::trace_scope, &kTraceScope4);
1133 p.append(SkRasterPipelineOp::load_condition_mask, kMaskOn);
1134 p.append(SkRasterPipelineOp::trace_scope, &kTraceScope5);
1143 const int srcIndex = 0, dstIndex = 5;
1145 struct CopySlotsOp {
1147 int numSlotsAffected;
1150 static const CopySlotsOp kCopyOps[] = {
1151 {SkRasterPipelineOp::copy_slot_masked, 1},
1152 {SkRasterPipelineOp::copy_2_slots_masked, 2},
1153 {SkRasterPipelineOp::copy_3_slots_masked, 3},
1154 {SkRasterPipelineOp::copy_4_slots_masked, 4},
1158 alignas(64)
const int32_t kMask1[16] = {~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
1159 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0};
1160 alignas(64)
const int32_t kMask2[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
1161 0, 0, 0, 0, 0, 0, 0, 0};
1162 alignas(64)
const int32_t kMask3[16] = {~0, 0, ~0, ~0, ~0, ~0, 0, ~0,
1163 ~0, 0, ~0, ~0, ~0, ~0, 0, ~0};
1164 alignas(64)
const int32_t kMask4[16] = { 0, ~0, 0, 0, 0, ~0, ~0, 0,
1165 0, ~0, 0, 0, 0, ~0, ~0, 0};
1169 for (
const CopySlotsOp& op : kCopyOps) {
1170 for (
const int32_t* mask : {kMask1, kMask2, kMask3, kMask4}) {
1172 std::iota(&slots[
N * dstIndex], &slots[
N * (dstIndex + 5)], 0);
1179 ctx.
dst =
N * dstIndex *
sizeof(float);
1180 ctx.
src =
N * srcIndex *
sizeof(float);
1183 p.append(SkRasterPipelineOp::init_lane_masks, &initLaneMasksCtx);
1184 p.append(SkRasterPipelineOp::set_base_pointer, &slots[0]);
1185 p.append(SkRasterPipelineOp::load_condition_mask, mask);
1192 int* destPtr = &slots[
N * dstIndex];
1193 for (
int checkSlot = 0; checkSlot < 5; ++checkSlot) {
1194 for (
int checkMask = 0; checkMask <
N; ++checkMask) {
1195 if (checkSlot < op.numSlotsAffected && mask[checkMask]) {
1202 expectedUnchanged += 1;
1203 expectedChanged += 1;
1213 const int srcIndex = 0, dstIndex = 5;
1216 struct CopySlotsOp {
1218 int numSlotsAffected;
1221 static const CopySlotsOp kCopyOps[] = {
1222 {SkRasterPipelineOp::copy_slot_unmasked, 1},
1223 {SkRasterPipelineOp::copy_2_slots_unmasked, 2},
1224 {SkRasterPipelineOp::copy_3_slots_unmasked, 3},
1225 {SkRasterPipelineOp::copy_4_slots_unmasked, 4},
1228 for (
const CopySlotsOp& op : kCopyOps) {
1230 std::iota(&slots[
N * dstIndex], &slots[
N * (dstIndex + 5)], 0);
1237 ctx.
dst =
N * dstIndex *
sizeof(float);
1238 ctx.
src =
N * srcIndex *
sizeof(float);
1239 p.append(SkRasterPipelineOp::set_base_pointer, &slots[0]);
1245 int* destPtr = &slots[
N * dstIndex];
1246 for (
int checkSlot = 0; checkSlot < 5; ++checkSlot) {
1247 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
1248 if (checkSlot < op.numSlotsAffected) {
1255 expectedUnchanged += 1;
1256 expectedChanged += 1;
1268 struct CopyUniformsOp {
1270 int numSlotsAffected;
1273 static const CopyUniformsOp kCopyOps[] = {
1274 {SkRasterPipelineOp::copy_uniform, 1},
1275 {SkRasterPipelineOp::copy_2_uniforms, 2},
1276 {SkRasterPipelineOp::copy_3_uniforms, 3},
1277 {SkRasterPipelineOp::copy_4_uniforms, 4},
1280 for (
const CopyUniformsOp& op : kCopyOps) {
1282 std::iota(&slots[0], &slots[5 *
N], 1);
1291 ctx->src = uniforms;
1292 p.append(op.stage, ctx);
1296 int expectedUnchanged = 1;
1298 int* destPtr = &slots[0];
1299 for (
int checkSlot = 0; checkSlot < 5; ++checkSlot) {
1300 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
1301 if (checkSlot < op.numSlotsAffected) {
1308 expectedUnchanged += 1;
1310 expectedChanged += 1;
1357 struct TestPattern {
1360 uint8_t expectation[4];
1362 static const TestPattern kPatterns[] = {
1363 {SkRasterPipelineOp::swizzle_1, {3}, {3, 1, 2, 3}},
1364 {SkRasterPipelineOp::swizzle_2, {1, 0}, {1, 0, 2, 3}},
1365 {SkRasterPipelineOp::swizzle_3, {2, 2, 2}, {2, 2, 2, 3}},
1366 {SkRasterPipelineOp::swizzle_4, {0, 0, 1, 2}, {0, 0, 1, 2}},
1370 for (
const TestPattern& pattern : kPatterns) {
1379 for (
size_t index = 0; index < std::size(ctx.
offsets); ++index) {
1380 ctx.
offsets[index] = pattern.swizzle[index] *
N *
sizeof(float);
1382 p.append(SkRasterPipelineOp::set_base_pointer, &slots[0]);
1387 int* destPtr = &slots[0];
1388 for (
int checkSlot = 0; checkSlot < 4; ++checkSlot) {
1390 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
1403 struct TestPattern {
1405 uint16_t swizzle[4];
1406 uint16_t expectation[4];
1408 constexpr uint16_t _ = ~0;
1409 static const TestPattern kPatterns[] = {
1410 {SkRasterPipelineOp::swizzle_copy_slot_masked, {3,_,_,_}, {_,_,_,0}},
1411 {SkRasterPipelineOp::swizzle_copy_2_slots_masked, {1,0,_,_}, {1,0,_,_}},
1412 {SkRasterPipelineOp::swizzle_copy_3_slots_masked, {2,3,0,_}, {2,_,0,1}},
1413 {SkRasterPipelineOp::swizzle_copy_4_slots_masked, {3,0,1,2}, {1,2,3,0}},
1417 for (
const TestPattern& pattern : kPatterns) {
1432 for (
size_t index = 0; index < std::size(ctx.
offsets); ++index) {
1433 if (pattern.swizzle[index] != _) {
1434 ctx.
offsets[index] = pattern.swizzle[index] *
N *
sizeof(float);
1437 p.append(SkRasterPipelineOp::init_lane_masks, &initLaneMasksCtx);
1438 p.append(pattern.op, &ctx);
1442 int* destPtr = &dest[0];
1443 for (
int checkSlot = 0; checkSlot < 4; ++checkSlot) {
1444 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
1445 if (pattern.expectation[checkSlot] == _) {
1448 int expectedIdx = pattern.expectation[checkSlot] *
N + checkLane;
1463 struct TestPattern {
1465 uint16_t shuffle[16];
1466 uint16_t expectation[16];
1468 static const TestPattern kPatterns[] = {
1471 2, 5, 8, 0, 0, 0, 0, 0, 0, 0},
1474 2, 5, 8, 9, 10, 11, 12, 13, 14, 15}},
1486 for (
const TestPattern& pattern : kPatterns) {
1495 ctx.
count = pattern.count;
1496 for (
size_t index = 0; index < std::size(ctx.
offsets); ++index) {
1497 ctx.
offsets[index] = pattern.shuffle[index] *
N *
sizeof(float);
1499 p.append(SkRasterPipelineOp::shuffle, &ctx);
1503 int* destPtr = &slots[0];
1504 for (
int checkSlot = 0; checkSlot < 16; ++checkSlot) {
1506 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
1670DEF_TEST(SkRasterPipeline_FloatArithmeticWithNSlots, r) {
1675 struct ArithmeticOp {
1677 std::function<float(
float,
float)> verify;
1680 static const ArithmeticOp kArithmeticOps[] = {
1681 {SkRasterPipelineOp::add_n_floats, [](
float a,
float b) {
return a +
b; }},
1682 {SkRasterPipelineOp::sub_n_floats, [](
float a,
float b) {
return a -
b; }},
1683 {SkRasterPipelineOp::mul_n_floats, [](
float a,
float b) {
return a *
b; }},
1684 {SkRasterPipelineOp::div_n_floats, [](
float a,
float b) {
return a /
b; }},
1687 for (
const ArithmeticOp& op : kArithmeticOps) {
1688 for (
int numSlotsAffected = 1; numSlotsAffected <= 5; ++numSlotsAffected) {
1690 std::iota(&slots[0], &slots[10 *
N], 1.0f);
1697 ctx.
src = numSlotsAffected *
N *
sizeof(float);
1698 p.append(SkRasterPipelineOp::set_base_pointer, &slots[0]);
1703 float leftValue = 1.0f;
1704 float rightValue = float(numSlotsAffected *
N) + 1.0f;
1705 float* destPtr = &slots[0];
1706 for (
int checkSlot = 0; checkSlot < 10; ++checkSlot) {
1707 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
1708 if (checkSlot < numSlotsAffected) {
1723DEF_TEST(SkRasterPipeline_FloatArithmeticWithHardcodedSlots, r) {
1728 struct ArithmeticOp {
1730 int numSlotsAffected;
1731 std::function<float(
float,
float)> verify;
1734 static const ArithmeticOp kArithmeticOps[] = {
1735 {SkRasterPipelineOp::add_float, 1, [](
float a,
float b) {
return a +
b; }},
1736 {SkRasterPipelineOp::sub_float, 1, [](
float a,
float b) {
return a -
b; }},
1737 {SkRasterPipelineOp::mul_float, 1, [](
float a,
float b) {
return a *
b; }},
1738 {SkRasterPipelineOp::div_float, 1, [](
float a,
float b) {
return a /
b; }},
1740 {SkRasterPipelineOp::add_2_floats, 2, [](
float a,
float b) {
return a +
b; }},
1741 {SkRasterPipelineOp::sub_2_floats, 2, [](
float a,
float b) {
return a -
b; }},
1742 {SkRasterPipelineOp::mul_2_floats, 2, [](
float a,
float b) {
return a *
b; }},
1743 {SkRasterPipelineOp::div_2_floats, 2, [](
float a,
float b) {
return a /
b; }},
1745 {SkRasterPipelineOp::add_3_floats, 3, [](
float a,
float b) {
return a +
b; }},
1746 {SkRasterPipelineOp::sub_3_floats, 3, [](
float a,
float b) {
return a -
b; }},
1747 {SkRasterPipelineOp::mul_3_floats, 3, [](
float a,
float b) {
return a *
b; }},
1748 {SkRasterPipelineOp::div_3_floats, 3, [](
float a,
float b) {
return a /
b; }},
1750 {SkRasterPipelineOp::add_4_floats, 4, [](
float a,
float b) {
return a +
b; }},
1751 {SkRasterPipelineOp::sub_4_floats, 4, [](
float a,
float b) {
return a -
b; }},
1752 {SkRasterPipelineOp::mul_4_floats, 4, [](
float a,
float b) {
return a *
b; }},
1753 {SkRasterPipelineOp::div_4_floats, 4, [](
float a,
float b) {
return a /
b; }},
1756 for (
const ArithmeticOp& op : kArithmeticOps) {
1758 std::iota(&slots[0], &slots[10 *
N], 1.0f);
1763 p.append(op.stage, &slots[0]);
1767 float leftValue = 1.0f;
1768 float rightValue = float(op.numSlotsAffected *
N) + 1.0f;
1769 float* destPtr = &slots[0];
1770 for (
int checkSlot = 0; checkSlot < 10; ++checkSlot) {
1771 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
1772 if (checkSlot < op.numSlotsAffected) {
1795 struct ArithmeticOp {
1797 std::function<
int(
int,
int)> verify;
1800 static const ArithmeticOp kArithmeticOps[] = {
1801 {SkRasterPipelineOp::add_n_ints, [](
int a,
int b) {
return a +
b; }},
1802 {SkRasterPipelineOp::sub_n_ints, [](
int a,
int b) {
return a -
b; }},
1803 {SkRasterPipelineOp::mul_n_ints, [](
int a,
int b) {
return a *
b; }},
1804 {SkRasterPipelineOp::div_n_ints, [](
int a,
int b) {
return a /
b; }},
1806 {SkRasterPipelineOp::bitwise_and_n_ints, [](
int a,
int b) {
return a &
b; }},
1807 {SkRasterPipelineOp::bitwise_or_n_ints, [](
int a,
int b) {
return a |
b; }},
1808 {SkRasterPipelineOp::bitwise_xor_n_ints, [](
int a,
int b) {
return a ^
b; }},
1809 {SkRasterPipelineOp::min_n_ints, [](
int a,
int b) {
return a <
b ?
a :
b; }},
1811 {SkRasterPipelineOp::max_n_ints, [](
int a,
int b) {
return a >
b ?
a :
b; }},
1815 for (
const ArithmeticOp& op : kArithmeticOps) {
1816 for (
int numSlotsAffected = 1; numSlotsAffected <= 5; ++numSlotsAffected) {
1818 std::iota(&slots[0], &slots[10 *
N], 1);
1819 int leftValue = slots[0];
1820 int rightValue = slots[numSlotsAffected *
N];
1827 ctx.
src = numSlotsAffected *
N *
sizeof(float);
1828 p.append(SkRasterPipelineOp::set_base_pointer, &slots[0]);
1833 int* destPtr = &slots[0];
1834 for (
int checkSlot = 0; checkSlot < 10; ++checkSlot) {
1835 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
1836 if (checkSlot < numSlotsAffected) {
1851DEF_TEST(SkRasterPipeline_IntArithmeticWithHardcodedSlots, r) {
1856 struct ArithmeticOp {
1858 int numSlotsAffected;
1859 std::function<
int(
int,
int)> verify;
1862 static const ArithmeticOp kArithmeticOps[] = {
1863 {SkRasterPipelineOp::add_int, 1, [](
int a,
int b) {
return a +
b; }},
1864 {SkRasterPipelineOp::sub_int, 1, [](
int a,
int b) {
return a -
b; }},
1865 {SkRasterPipelineOp::mul_int, 1, [](
int a,
int b) {
return a *
b; }},
1866 {SkRasterPipelineOp::div_int, 1, [](
int a,
int b) {
return a /
b; }},
1868 {SkRasterPipelineOp::bitwise_and_int, 1, [](
int a,
int b) {
return a &
b; }},
1869 {SkRasterPipelineOp::bitwise_or_int, 1, [](
int a,
int b) {
return a |
b; }},
1870 {SkRasterPipelineOp::bitwise_xor_int, 1, [](
int a,
int b) {
return a ^
b; }},
1871 {SkRasterPipelineOp::min_int, 1, [](
int a,
int b) {
return a <
b ?
a:
b; }},
1873 {SkRasterPipelineOp::max_int, 1, [](
int a,
int b) {
return a >
b ?
a:
b; }},
1876 {SkRasterPipelineOp::add_2_ints, 2, [](
int a,
int b) {
return a +
b; }},
1877 {SkRasterPipelineOp::sub_2_ints, 2, [](
int a,
int b) {
return a -
b; }},
1878 {SkRasterPipelineOp::mul_2_ints, 2, [](
int a,
int b) {
return a *
b; }},
1879 {SkRasterPipelineOp::div_2_ints, 2, [](
int a,
int b) {
return a /
b; }},
1881 {SkRasterPipelineOp::bitwise_and_2_ints, 2, [](
int a,
int b) {
return a &
b; }},
1882 {SkRasterPipelineOp::bitwise_or_2_ints, 2, [](
int a,
int b) {
return a |
b; }},
1883 {SkRasterPipelineOp::bitwise_xor_2_ints, 2, [](
int a,
int b) {
return a ^
b; }},
1884 {SkRasterPipelineOp::min_2_ints, 2, [](
int a,
int b) {
return a <
b ?
a:
b; }},
1886 {SkRasterPipelineOp::max_2_ints, 2, [](
int a,
int b) {
return a >
b ?
a:
b; }},
1889 {SkRasterPipelineOp::add_3_ints, 3, [](
int a,
int b) {
return a +
b; }},
1890 {SkRasterPipelineOp::sub_3_ints, 3, [](
int a,
int b) {
return a -
b; }},
1891 {SkRasterPipelineOp::mul_3_ints, 3, [](
int a,
int b) {
return a *
b; }},
1892 {SkRasterPipelineOp::div_3_ints, 3, [](
int a,
int b) {
return a /
b; }},
1894 {SkRasterPipelineOp::bitwise_and_3_ints, 3, [](
int a,
int b) {
return a &
b; }},
1895 {SkRasterPipelineOp::bitwise_or_3_ints, 3, [](
int a,
int b) {
return a |
b; }},
1896 {SkRasterPipelineOp::bitwise_xor_3_ints, 3, [](
int a,
int b) {
return a ^
b; }},
1897 {SkRasterPipelineOp::min_3_ints, 3, [](
int a,
int b) {
return a <
b ?
a:
b; }},
1899 {SkRasterPipelineOp::max_3_ints, 3, [](
int a,
int b) {
return a >
b ?
a:
b; }},
1902 {SkRasterPipelineOp::add_4_ints, 4, [](
int a,
int b) {
return a +
b; }},
1903 {SkRasterPipelineOp::sub_4_ints, 4, [](
int a,
int b) {
return a -
b; }},
1904 {SkRasterPipelineOp::mul_4_ints, 4, [](
int a,
int b) {
return a *
b; }},
1905 {SkRasterPipelineOp::div_4_ints, 4, [](
int a,
int b) {
return a /
b; }},
1907 {SkRasterPipelineOp::bitwise_and_4_ints, 4, [](
int a,
int b) {
return a &
b; }},
1908 {SkRasterPipelineOp::bitwise_or_4_ints, 4, [](
int a,
int b) {
return a |
b; }},
1909 {SkRasterPipelineOp::bitwise_xor_4_ints, 4, [](
int a,
int b) {
return a ^
b; }},
1910 {SkRasterPipelineOp::min_4_ints, 4, [](
int a,
int b) {
return a <
b ?
a:
b; }},
1912 {SkRasterPipelineOp::max_4_ints, 4, [](
int a,
int b) {
return a >
b ?
a:
b; }},
1916 for (
const ArithmeticOp& op : kArithmeticOps) {
1918 std::iota(&slots[0], &slots[10 *
N], 1);
1919 int leftValue = slots[0];
1920 int rightValue = slots[op.numSlotsAffected *
N];
1925 p.append(op.stage, &slots[0]);
1929 int* destPtr = &slots[0];
1930 for (
int checkSlot = 0; checkSlot < 10; ++checkSlot) {
1931 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
1932 if (checkSlot < op.numSlotsAffected) {
1953 std::function<bool(
float,
float)> verify;
1956 static const CompareOp kCompareOps[] = {
1957 {SkRasterPipelineOp::cmpeq_n_floats, [](
float a,
float b) {
return a ==
b; }},
1958 {SkRasterPipelineOp::cmpne_n_floats, [](
float a,
float b) {
return a !=
b; }},
1959 {SkRasterPipelineOp::cmplt_n_floats, [](
float a,
float b) {
return a <
b; }},
1960 {SkRasterPipelineOp::cmple_n_floats, [](
float a,
float b) {
return a <=
b; }},
1963 for (
const CompareOp& op : kCompareOps) {
1964 for (
int numSlotsAffected = 1; numSlotsAffected <= 5; ++numSlotsAffected) {
1966 for (
int index = 0; index < 10 *
N; ++index) {
1967 slots[index] = std::fmod(index, 3.0f);
1970 float leftValue = slots[0];
1971 float rightValue = slots[numSlotsAffected *
N];
1978 ctx.
src = numSlotsAffected *
N *
sizeof(float);
1979 p.append(SkRasterPipelineOp::set_base_pointer, &slots[0]);
1984 float* destPtr = &slots[0];
1985 for (
int checkSlot = 0; checkSlot < 10; ++checkSlot) {
1986 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
1987 if (checkSlot < numSlotsAffected) {
1988 bool compareIsTrue = op.verify(leftValue, rightValue);
1995 leftValue = std::fmod(leftValue + 1.0f, 3.0f);
1996 rightValue = std::fmod(rightValue + 1.0f, 3.0f);
2003DEF_TEST(SkRasterPipeline_CompareFloatsWithHardcodedSlots, r) {
2010 int numSlotsAffected;
2011 std::function<bool(
float,
float)> verify;
2014 static const CompareOp kCompareOps[] = {
2015 {SkRasterPipelineOp::cmpeq_float, 1, [](
float a,
float b) {
return a ==
b; }},
2016 {SkRasterPipelineOp::cmpne_float, 1, [](
float a,
float b) {
return a !=
b; }},
2017 {SkRasterPipelineOp::cmplt_float, 1, [](
float a,
float b) {
return a <
b; }},
2018 {SkRasterPipelineOp::cmple_float, 1, [](
float a,
float b) {
return a <=
b; }},
2020 {SkRasterPipelineOp::cmpeq_2_floats, 2, [](
float a,
float b) {
return a ==
b; }},
2021 {SkRasterPipelineOp::cmpne_2_floats, 2, [](
float a,
float b) {
return a !=
b; }},
2022 {SkRasterPipelineOp::cmplt_2_floats, 2, [](
float a,
float b) {
return a <
b; }},
2023 {SkRasterPipelineOp::cmple_2_floats, 2, [](
float a,
float b) {
return a <=
b; }},
2025 {SkRasterPipelineOp::cmpeq_3_floats, 3, [](
float a,
float b) {
return a ==
b; }},
2026 {SkRasterPipelineOp::cmpne_3_floats, 3, [](
float a,
float b) {
return a !=
b; }},
2027 {SkRasterPipelineOp::cmplt_3_floats, 3, [](
float a,
float b) {
return a <
b; }},
2028 {SkRasterPipelineOp::cmple_3_floats, 3, [](
float a,
float b) {
return a <=
b; }},
2030 {SkRasterPipelineOp::cmpeq_4_floats, 4, [](
float a,
float b) {
return a ==
b; }},
2031 {SkRasterPipelineOp::cmpne_4_floats, 4, [](
float a,
float b) {
return a !=
b; }},
2032 {SkRasterPipelineOp::cmplt_4_floats, 4, [](
float a,
float b) {
return a <
b; }},
2033 {SkRasterPipelineOp::cmple_4_floats, 4, [](
float a,
float b) {
return a <=
b; }},
2036 for (
const CompareOp& op : kCompareOps) {
2038 for (
int index = 0; index < 10 *
N; ++index) {
2039 slots[index] = std::fmod(index, 3.0f);
2042 float leftValue = slots[0];
2043 float rightValue = slots[op.numSlotsAffected *
N];
2048 p.append(op.stage, &slots[0]);
2052 float* destPtr = &slots[0];
2053 for (
int checkSlot = 0; checkSlot < 10; ++checkSlot) {
2054 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2055 if (checkSlot < op.numSlotsAffected) {
2056 bool compareIsTrue = op.verify(leftValue, rightValue);
2063 leftValue = std::fmod(leftValue + 1.0f, 3.0f);
2064 rightValue = std::fmod(rightValue + 1.0f, 3.0f);
2080 std::function<bool(
int,
int)> verify;
2083 static const CompareOp kCompareOps[] = {
2084 {SkRasterPipelineOp::cmpeq_n_ints, [](
int a,
int b) {
return a ==
b; }},
2085 {SkRasterPipelineOp::cmpne_n_ints, [](
int a,
int b) {
return a !=
b; }},
2086 {SkRasterPipelineOp::cmplt_n_ints, [](
int a,
int b) {
return a <
b; }},
2087 {SkRasterPipelineOp::cmple_n_ints, [](
int a,
int b) {
return a <=
b; }},
2092 for (
const CompareOp& op : kCompareOps) {
2093 for (
int numSlotsAffected = 1; numSlotsAffected <= 5; ++numSlotsAffected) {
2095 for (
int index = 0; index < 10 *
N; ++index) {
2096 slots[index] = (index % 3) - 1;
2099 int leftValue = slots[0];
2100 int rightValue = slots[numSlotsAffected *
N];
2107 ctx.
src =
sizeof(float) * numSlotsAffected *
N;
2108 p.append(SkRasterPipelineOp::set_base_pointer, &slots[0]);
2113 int* destPtr = &slots[0];
2114 for (
int checkSlot = 0; checkSlot < 10; ++checkSlot) {
2115 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2116 if (checkSlot < numSlotsAffected) {
2117 bool compareIsTrue = op.verify(leftValue, rightValue);
2124 if (++leftValue == 2) {
2127 if (++rightValue == 2) {
2136DEF_TEST(SkRasterPipeline_CompareIntsWithHardcodedSlots, r) {
2143 int numSlotsAffected;
2144 std::function<bool(
int,
int)> verify;
2147 static const CompareOp kCompareOps[] = {
2148 {SkRasterPipelineOp::cmpeq_int, 1, [](
int a,
int b) {
return a ==
b; }},
2149 {SkRasterPipelineOp::cmpne_int, 1, [](
int a,
int b) {
return a !=
b; }},
2150 {SkRasterPipelineOp::cmplt_int, 1, [](
int a,
int b) {
return a <
b; }},
2151 {SkRasterPipelineOp::cmple_int, 1, [](
int a,
int b) {
return a <=
b; }},
2155 {SkRasterPipelineOp::cmpeq_2_ints, 2, [](
int a,
int b) {
return a ==
b; }},
2156 {SkRasterPipelineOp::cmpne_2_ints, 2, [](
int a,
int b) {
return a !=
b; }},
2157 {SkRasterPipelineOp::cmplt_2_ints, 2, [](
int a,
int b) {
return a <
b; }},
2158 {SkRasterPipelineOp::cmple_2_ints, 2, [](
int a,
int b) {
return a <=
b; }},
2162 {SkRasterPipelineOp::cmpeq_3_ints, 3, [](
int a,
int b) {
return a ==
b; }},
2163 {SkRasterPipelineOp::cmpne_3_ints, 3, [](
int a,
int b) {
return a !=
b; }},
2164 {SkRasterPipelineOp::cmplt_3_ints, 3, [](
int a,
int b) {
return a <
b; }},
2165 {SkRasterPipelineOp::cmple_3_ints, 3, [](
int a,
int b) {
return a <=
b; }},
2169 {SkRasterPipelineOp::cmpeq_4_ints, 4, [](
int a,
int b) {
return a ==
b; }},
2170 {SkRasterPipelineOp::cmpne_4_ints, 4, [](
int a,
int b) {
return a !=
b; }},
2171 {SkRasterPipelineOp::cmplt_4_ints, 4, [](
int a,
int b) {
return a <
b; }},
2172 {SkRasterPipelineOp::cmple_4_ints, 4, [](
int a,
int b) {
return a <=
b; }},
2177 for (
const CompareOp& op : kCompareOps) {
2179 for (
int index = 0; index < 10 *
N; ++index) {
2180 slots[index] = (index % 3) - 1;
2183 int leftValue = slots[0];
2184 int rightValue = slots[op.numSlotsAffected *
N];
2189 p.append(op.stage, &slots[0]);
2193 int* destPtr = &slots[0];
2194 for (
int checkSlot = 0; checkSlot < 10; ++checkSlot) {
2195 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2196 if (checkSlot < op.numSlotsAffected) {
2197 bool compareIsTrue = op.verify(leftValue, rightValue);
2204 if (++leftValue == 2) {
2207 if (++rightValue == 2) {
2224 int numSlotsAffected;
2225 std::function<
int(
int)> verify;
2228 static const UnaryOp kUnaryOps[] = {
2229 {SkRasterPipelineOp::cast_to_float_from_int, 1,
to_float},
2230 {SkRasterPipelineOp::cast_to_float_from_2_ints, 2,
to_float},
2231 {SkRasterPipelineOp::cast_to_float_from_3_ints, 3,
to_float},
2232 {SkRasterPipelineOp::cast_to_float_from_4_ints, 4,
to_float},
2234 {SkRasterPipelineOp::abs_int, 1, [](
int a) {
return a < 0 ? -
a :
a; }},
2235 {SkRasterPipelineOp::abs_2_ints, 2, [](
int a) {
return a < 0 ? -
a :
a; }},
2236 {SkRasterPipelineOp::abs_3_ints, 3, [](
int a) {
return a < 0 ? -
a :
a; }},
2237 {SkRasterPipelineOp::abs_4_ints, 4, [](
int a) {
return a < 0 ? -
a :
a; }},
2240 for (
const UnaryOp& op : kUnaryOps) {
2242 std::iota(&slots[0], &slots[5 *
N], -10);
2243 int inputValue = slots[0];
2248 p.append(op.stage, &slots[0]);
2252 int* destPtr = &slots[0];
2253 for (
int checkSlot = 0; checkSlot < 5; ++checkSlot) {
2254 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2255 if (checkSlot < op.numSlotsAffected) {
2256 int expected = op.verify(inputValue);
2279 int numSlotsAffected;
2280 std::function<float(
float)> verify;
2283 static const UnaryOp kUnaryOps[] = {
2284 {SkRasterPipelineOp::cast_to_int_from_float, 1,
to_int},
2285 {SkRasterPipelineOp::cast_to_int_from_2_floats, 2,
to_int},
2286 {SkRasterPipelineOp::cast_to_int_from_3_floats, 3,
to_int},
2287 {SkRasterPipelineOp::cast_to_int_from_4_floats, 4,
to_int},
2289 {SkRasterPipelineOp::cast_to_uint_from_float, 1,
to_uint},
2290 {SkRasterPipelineOp::cast_to_uint_from_2_floats, 2,
to_uint},
2291 {SkRasterPipelineOp::cast_to_uint_from_3_floats, 3,
to_uint},
2292 {SkRasterPipelineOp::cast_to_uint_from_4_floats, 4,
to_uint},
2294 {SkRasterPipelineOp::floor_float, 1, [](
float a) {
return floorf(
a); }},
2295 {SkRasterPipelineOp::floor_2_floats, 2, [](
float a) {
return floorf(
a); }},
2296 {SkRasterPipelineOp::floor_3_floats, 3, [](
float a) {
return floorf(
a); }},
2297 {SkRasterPipelineOp::floor_4_floats, 4, [](
float a) {
return floorf(
a); }},
2299 {SkRasterPipelineOp::ceil_float, 1, [](
float a) {
return ceilf(
a); }},
2300 {SkRasterPipelineOp::ceil_2_floats, 2, [](
float a) {
return ceilf(
a); }},
2301 {SkRasterPipelineOp::ceil_3_floats, 3, [](
float a) {
return ceilf(
a); }},
2302 {SkRasterPipelineOp::ceil_4_floats, 4, [](
float a) {
return ceilf(
a); }},
2305 for (
const UnaryOp& op : kUnaryOps) {
2307 bool positiveOnly = (op.stage == SkRasterPipelineOp::cast_to_uint_from_float ||
2308 op.stage == SkRasterPipelineOp::cast_to_uint_from_2_floats ||
2309 op.stage == SkRasterPipelineOp::cast_to_uint_from_3_floats ||
2310 op.stage == SkRasterPipelineOp::cast_to_uint_from_4_floats);
2312 float iotaStart = positiveOnly ? 1.0f : -9.75f;
2313 std::iota(&slots[0], &slots[5 *
N], iotaStart);
2314 float inputValue = slots[0];
2319 p.append(op.stage, &slots[0]);
2323 float* destPtr = &slots[0];
2324 for (
int checkSlot = 0; checkSlot < 5; ++checkSlot) {
2325 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2326 if (checkSlot < op.numSlotsAffected) {
2327 float expected = op.verify(inputValue);
2333 bool bitwiseMatch = (0 == memcmp(destPtr, &expected,
sizeof(
float)));
2334 bool valueMatch = (*destPtr == expected);
2359 int numSlotsAffected;
2363 static const MixOp kMixOps[] = {
2365 p->append(SkRasterPipelineOp::mix_float, slots);
2368 p->append(SkRasterPipelineOp::mix_2_floats, slots);
2371 p->append(SkRasterPipelineOp::mix_3_floats, slots);
2374 p->append(SkRasterPipelineOp::mix_4_floats, slots);
2379 ctx.
delta = 5 *
N *
sizeof(float);
2384 for (
const MixOp& op : kMixOps) {
2386 std::iota(&slots[0], &slots[15 *
N], 1.0f);
2388 float weightValue = slots[0];
2389 float fromValue = slots[1 * op.numSlotsAffected *
N];
2390 float toValue = slots[2 * op.numSlotsAffected *
N];
2393 for (
int idx = 0; idx < 1 * op.numSlotsAffected *
N; ++idx) {
2400 p.append(SkRasterPipelineOp::set_base_pointer, &slots[0]);
2401 op.append(&p, &alloc);
2405 float* destPtr = &slots[0];
2406 for (
int checkSlot = 0; checkSlot < op.numSlotsAffected; ++checkSlot) {
2407 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2408 float checkValue = (toValue - fromValue) *
to_mix_weight(weightValue) + fromValue;
2414 weightValue += 1.0f;
2426 int numSlotsAffected;
2430 static const MixOp kMixOps[] = {
2432 p->append(SkRasterPipelineOp::mix_int, slots);
2435 p->append(SkRasterPipelineOp::mix_2_ints, slots);
2438 p->append(SkRasterPipelineOp::mix_3_ints, slots);
2441 p->append(SkRasterPipelineOp::mix_4_ints, slots);
2451 for (
const MixOp& op : kMixOps) {
2453 for (
int idx = 0; idx < 1 * op.numSlotsAffected *
N; ++idx) {
2454 slots[idx] = (idx & 1) ? ~0 : 0;
2460 int weightValue = slots[0];
2461 int fromValue = slots[1 * op.numSlotsAffected *
N];
2462 int toValue = slots[2 * op.numSlotsAffected *
N];
2467 p.append(SkRasterPipelineOp::set_base_pointer, &slots[0]);
2468 op.append(&p, &alloc);
2472 int* destPtr = &slots[0];
2473 for (
int checkSlot = 0; checkSlot < op.numSlotsAffected; ++checkSlot) {
2474 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2475 int checkValue = weightValue ? toValue : fromValue;
2481 weightValue = ~weightValue;
2555 std::fill(&first [0], &first [
N], 0x12345678);
2556 std::fill(&second[0], &second[
N], 0x12345678);
2561 p.append(SkRasterPipelineOp::init_lane_masks, &initLaneMasksCtx);
2562 p.append(SkRasterPipelineOp::branch_if_all_lanes_active, &ctx);
2563 p.append(SkRasterPipelineOp::store_src_a, first);
2564 p.append(SkRasterPipelineOp::store_src_a, second);
2567 int32_t* firstPtr = first;
2568 int32_t* secondPtr = second;
2569 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2578 std::fill(&first [0], &first [
N], 0x12345678);
2579 std::fill(&second[0], &second[
N], 0x12345678);
2585 p.append(SkRasterPipelineOp::load_src, kNoLanesActive);
2586 p.append(SkRasterPipelineOp::branch_if_all_lanes_active, &ctx);
2587 p.append(SkRasterPipelineOp::store_src_a, first);
2588 p.append(SkRasterPipelineOp::store_src_a, second);
2591 int32_t* firstPtr = first;
2592 int32_t* secondPtr = second;
2593 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2602 std::fill(&first [0], &first [
N], 0x12345678);
2603 std::fill(&second[0], &second[
N], 0x12345678);
2607 std::fill(oneLaneInactive, &oneLaneInactive[4*
N], ~0);
2608 oneLaneInactive[4*
N - 1] = 0;
2612 p.append(SkRasterPipelineOp::load_src, oneLaneInactive);
2613 p.append(SkRasterPipelineOp::branch_if_all_lanes_active, &ctx);
2614 p.append(SkRasterPipelineOp::store_src_a, first);
2615 p.append(SkRasterPipelineOp::store_src_a, second);
2618 int32_t* firstPtr = first;
2619 int32_t* secondPtr = second;
2620 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2637 std::fill(&first [0], &first [
N], 0x12345678);
2638 std::fill(&second[0], &second[
N], 0x12345678);
2643 p.append(SkRasterPipelineOp::init_lane_masks, &initLaneMasksCtx);
2644 p.append(SkRasterPipelineOp::branch_if_any_lanes_active, &ctx);
2645 p.append(SkRasterPipelineOp::store_src_a, first);
2646 p.append(SkRasterPipelineOp::store_src_a, second);
2649 int32_t* firstPtr = first;
2650 int32_t* secondPtr = second;
2651 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2660 std::fill(&first [0], &first [
N], 0x12345678);
2661 std::fill(&second[0], &second[
N], 0x12345678);
2667 p.append(SkRasterPipelineOp::load_src, kNoLanesActive);
2668 p.append(SkRasterPipelineOp::branch_if_any_lanes_active, &ctx);
2669 p.append(SkRasterPipelineOp::store_src_a, first);
2670 p.append(SkRasterPipelineOp::store_src_a, second);
2673 int32_t* firstPtr = first;
2674 int32_t* secondPtr = second;
2675 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2684 std::fill(&first [0], &first [
N], 0x12345678);
2685 std::fill(&second[0], &second[
N], 0x12345678);
2689 oneLaneActive[4*
N - 1] = ~0;
2693 p.append(SkRasterPipelineOp::load_src, oneLaneActive);
2694 p.append(SkRasterPipelineOp::branch_if_any_lanes_active, &ctx);
2695 p.append(SkRasterPipelineOp::store_src_a, first);
2696 p.append(SkRasterPipelineOp::store_src_a, second);
2699 int32_t* firstPtr = first;
2700 int32_t* secondPtr = second;
2701 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2718 std::fill(&first [0], &first [
N], 0x12345678);
2719 std::fill(&second[0], &second[
N], 0x12345678);
2724 p.append(SkRasterPipelineOp::init_lane_masks, &initLaneMasksCtx);
2725 p.append(SkRasterPipelineOp::branch_if_no_lanes_active, &ctx);
2726 p.append(SkRasterPipelineOp::store_src_a, first);
2727 p.append(SkRasterPipelineOp::store_src_a, second);
2730 int32_t* firstPtr = first;
2731 int32_t* secondPtr = second;
2732 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2741 std::fill(&first [0], &first [
N], 0x12345678);
2742 std::fill(&second[0], &second[
N], 0x12345678);
2748 p.append(SkRasterPipelineOp::load_src, kNoLanesActive);
2749 p.append(SkRasterPipelineOp::branch_if_no_lanes_active, &ctx);
2750 p.append(SkRasterPipelineOp::store_src_a, first);
2751 p.append(SkRasterPipelineOp::store_src_a, second);
2754 int32_t* firstPtr = first;
2755 int32_t* secondPtr = second;
2756 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2765 std::fill(&first [0], &first [
N], 0x12345678);
2766 std::fill(&second[0], &second[
N], 0x12345678);
2770 oneLaneActive[4*
N - 1] = ~0;
2774 p.append(SkRasterPipelineOp::load_src, oneLaneActive);
2775 p.append(SkRasterPipelineOp::branch_if_no_lanes_active, &ctx);
2776 p.append(SkRasterPipelineOp::store_src_a, first);
2777 p.append(SkRasterPipelineOp::store_src_a, second);
2780 int32_t* firstPtr = first;
2781 int32_t* secondPtr = second;
2782 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2789DEF_TEST(SkRasterPipeline_BranchIfActiveLanesEqual, r) {
2795 std::fill(std::begin(allSixes), std::end(allSixes), 6);
2799 std::fill(std::begin(mostlySixesWithOneFive), std::end(mostlySixesWithOneFive), 6);
2800 mostlySixesWithOneFive[
N - 1] = 5;
2805 matching.
ptr = allSixes;
2809 nonmatching.
value = 5;
2810 nonmatching.
ptr = mostlySixesWithOneFive;
2816 std::fill(&first [0], &first [
N], 0x12345678);
2817 std::fill(&second[0], &second[
N], 0x12345678);
2822 p.append(SkRasterPipelineOp::init_lane_masks, &initLaneMasksCtx);
2823 p.append(SkRasterPipelineOp::branch_if_no_active_lanes_eq, &matching);
2824 p.append(SkRasterPipelineOp::store_src_a, first);
2825 p.append(SkRasterPipelineOp::store_src_a, second);
2828 int32_t* firstPtr = first;
2829 int32_t* secondPtr = second;
2830 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2839 std::fill(&first [0], &first [
N], 0x12345678);
2840 std::fill(&second[0], &second[
N], 0x12345678);
2845 p.append(SkRasterPipelineOp::init_lane_masks, &initLaneMasksCtx);
2846 p.append(SkRasterPipelineOp::branch_if_no_active_lanes_eq, &nonmatching);
2847 p.append(SkRasterPipelineOp::store_src_a, first);
2848 p.append(SkRasterPipelineOp::store_src_a, second);
2851 int32_t* firstPtr = first;
2852 int32_t* secondPtr = second;
2853 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2862 std::fill(&first [0], &first [
N], 0x12345678);
2863 std::fill(&second[0], &second[
N], 0x12345678);
2867 std::fill(std::begin(mask), std::end(mask), ~0);
2872 p.append(SkRasterPipelineOp::load_src, mask);
2873 p.append(SkRasterPipelineOp::branch_if_no_active_lanes_eq, &nonmatching);
2874 p.append(SkRasterPipelineOp::store_src_a, first);
2875 p.append(SkRasterPipelineOp::store_src_a, second);
2878 int32_t* firstPtr = first;
2879 int32_t* secondPtr = second;
2880 for (
int checkLane = 0; checkLane <
N; ++checkLane) {
2904 uint32_t buf[72] = {
2905 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2906 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
2907 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
2908 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2909 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2910 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2914 dst = { buf + 36, 0 };
2918 p.append(SkRasterPipelineOp::load_8888, &src);
2919 p.append(SkRasterPipelineOp::store_8888, &dst);
2922 for (
int i = 0; i < 36; i++) {
2923 if (i < 15 || i == 35) {
2957 dst = { &
buffer[0][0], 0 };
2959 for (
unsigned i = 1; i <= 4; i++) {
2962 p.append(SkRasterPipelineOp::load_f32, &src);
2963 p.append(SkRasterPipelineOp::store_f32, &dst);
2965 for (
unsigned j = 0; j < i; j++) {
2966 for (
unsigned k = 0; k < 4; k++) {
2967 if (
buffer[j][k] != data[j][k]) {
2968 ERRORF(r,
"(%u, %u) - a: %g r: %g\n", j, k, data[j][k],
buffer[j][k]);
2972 for (
int j = i; j < 4; j++) {
2973 for (
auto f :
buffer[j]) {
2981 alignas(8) uint16_t data[][4] = {
2982 {
h(00),
h(01),
h(02),
h(03)},
2983 {
h(10),
h(11),
h(12),
h(13)},
2984 {
h(20),
h(21),
h(22),
h(23)},
2985 {
h(30),
h(31),
h(32),
h(33)},
2987 alignas(8) uint16_t
buffer[4][4];
2989 dst = { &
buffer[0][0], 0 };
2991 for (
unsigned i = 1; i <= 4; i++) {
2994 p.append(SkRasterPipelineOp::load_f16, &src);
2995 p.append(SkRasterPipelineOp::store_f16, &dst);
2997 for (
unsigned j = 0; j < i; j++) {
2998 for (
int k = 0; k < 4; k++) {
3002 for (
int j = i; j < 4; j++) {
3003 for (
auto f :
buffer[j]) {
3011 alignas(8) uint16_t data[]= {
3017 alignas(8) uint16_t
buffer[4][4];
3019 dst = { &
buffer[0][0], 0 };
3021 for (
unsigned i = 1; i <= 4; i++) {
3024 p.append(SkRasterPipelineOp::load_af16, &src);
3025 p.append(SkRasterPipelineOp::store_f16, &dst);
3027 for (
unsigned j = 0; j < i; j++) {
3028 uint16_t expected[] = {0, 0, 0, data[j]};
3031 for (
int j = i; j < 4; j++) {
3032 for (
auto f :
buffer[j]) {
3040 alignas(8) uint16_t data[][4] = {
3041 {
h(00),
h(01),
h(02),
h(03)},
3042 {
h(10),
h(11),
h(12),
h(13)},
3043 {
h(20),
h(21),
h(22),
h(23)},
3044 {
h(30),
h(31),
h(32),
h(33)},
3046 alignas(8) uint16_t
buffer[4];
3050 for (
unsigned i = 1; i <= 4; i++) {
3053 p.append(SkRasterPipelineOp::load_f16, &src);
3054 p.append(SkRasterPipelineOp::store_af16, &dst);
3056 for (
unsigned j = 0; j < i; j++) {
3059 for (
int j = i; j < 4; j++) {
3066 alignas(8) uint16_t data[][4] = {
3067 {
h(00),
h(01),
h(02),
h(03)},
3068 {
h(10),
h(11),
h(12),
h(13)},
3069 {
h(20),
h(21),
h(22),
h(23)},
3070 {
h(30),
h(31),
h(32),
h(33)},
3072 alignas(8) uint16_t
buffer[4][2];
3074 dst = { &
buffer[0][0], 0 };
3076 for (
unsigned i = 1; i <= 4; i++) {
3079 p.append(SkRasterPipelineOp::load_f16, &src);
3080 p.append(SkRasterPipelineOp::store_rgf16, &dst);
3082 for (
unsigned j = 0; j < i; j++) {
3085 for (
int j = i; j < 4; j++) {
3094 alignas(8) uint16_t data[][2] = {
3100 alignas(8) uint16_t
buffer[4][4];
3102 dst = { &
buffer[0][0], 0 };
3104 for (
unsigned i = 1; i <= 4; i++) {
3107 p.append(SkRasterPipelineOp::load_rgf16, &src);
3108 p.append(SkRasterPipelineOp::store_f16, &dst);
3110 for (
unsigned j = 0; j < i; j++) {
3111 uint16_t expected[] = {data[j][0], data[j][1],
h(0),
h(1)};
3114 for (
int j = i; j < 4; j++) {
3125 alignas(8) uint16_t data[][2] = {
3133 dst = { &
buffer[0][0], 0 };
3135 for (
unsigned i = 1; i <= 4; i++) {
3138 p.append(SkRasterPipelineOp::load_rg1616, &src);
3139 p.append(SkRasterPipelineOp::store_8888, &dst);
3141 for (
unsigned j = 0; j < i; j++) {
3142 uint8_t expected[] = {
3150 for (
int j = i; j < 4; j++) {
3159 alignas(8) uint16_t data[] = {
3167 dst = { &
buffer[0][0], 0 };
3169 for (
unsigned i = 1; i <= 4; i++) {
3172 p.append(SkRasterPipelineOp::load_a16, &src);
3173 p.append(SkRasterPipelineOp::store_8888, &dst);
3175 for (
unsigned j = 0; j < i; j++) {
3176 uint8_t expected[] = {0x00, 0x00, 0x00,
SkToU8(data[j] >> 8)};
3179 for (
int j = i; j < 4; j++) {
3188 uint8_t data[][4] = {
3189 {0x00, 0x01, 0x02, 0x03},
3190 {0x10, 0x11, 0x12, 0x13},
3191 {0x20, 0x21, 0x22, 0x23},
3192 {0x30, 0x31, 0x32, 0x33},
3194 alignas(8) uint16_t
buffer[4];
3198 for (
unsigned i = 1; i <= 4; i++) {
3201 p.append(SkRasterPipelineOp::load_8888, &src);
3202 p.append(SkRasterPipelineOp::store_a16, &dst);
3204 for (
unsigned j = 0; j < i; j++) {
3205 uint16_t expected = (data[j][3] << 8) | data[j][3];
3208 for (
int j = i; j < 4; j++) {
3215 alignas(8) uint16_t data[][4] = {
3216 {0x0000, 0x1000, 0x2000, 0x3000},
3217 {0x0001, 0x1001, 0x2001, 0x3001},
3218 {0x0002, 0x1002, 0x2002, 0x3002},
3219 {0x0003, 0x1003, 0x2003, 0x3003},
3221 alignas(8) uint16_t
buffer[4][4];
3225 for (
unsigned i = 1; i <= 4; i++) {
3228 p.append(SkRasterPipelineOp::load_16161616, &src);
3229 p.append(SkRasterPipelineOp::swap_rb);
3230 p.append(SkRasterPipelineOp::store_16161616, &dst);
3232 for (
unsigned j = 0; j < i; j++) {
3233 uint16_t expected[4] = {data[j][2], data[j][1], data[j][0], data[j][3]};
3236 for (
int j = i; j < 4; j++) {
3237 for (uint16_t u16 :
buffer[j])
3414 uint32_t
rgba = 0xff0000ff;
3419 p.append(SkRasterPipelineOp::load_8888, &ptr);
3420 p.append(SkRasterPipelineOp::callback, stack.
expectGrowth());
3421 p.append(SkRasterPipelineOp::swap_rb);
3422 p.append(SkRasterPipelineOp::callback, stack.
expectGrowth());
3423 p.append(SkRasterPipelineOp::store_8888, &ptr);
3433 uint32_t
rgba = 0xff0000ff;
3438 p.append(SkRasterPipelineOp::load_8888, &ptr);
3439 p.append(SkRasterPipelineOp::callback, stack.
expectGrowth());
3440 p.appendStackRewind();
3442 p.append(SkRasterPipelineOp::swap_rb);
3443 p.append(SkRasterPipelineOp::callback, stack.
expectGrowth());
3444 p.appendStackRewind();
3446 p.append(SkRasterPipelineOp::store_8888, &ptr);