358namespace Intrinsics {
361double coalesce_length(
double a,
double b,
double) {
return a + (
b *
b); }
362double finalize_length(
double a) {
return std::sqrt(
a); }
364double coalesce_distance(
double a,
double b,
double c) {
b -= c;
return a + (
b *
b); }
365double finalize_distance(
double a) {
return std::sqrt(
a); }
367double coalesce_dot(
double a,
double b,
double c) {
return a + (
b * c); }
368double coalesce_any(
double a,
double b,
double) {
return a ||
b; }
369double coalesce_all(
double a,
double b,
double) {
return a &&
b; }
371bool compare_lessThan(
double a,
double b) {
return a <
b; }
372bool compare_lessThanEqual(
double a,
double b) {
return a <=
b; }
373bool compare_greaterThan(
double a,
double b) {
return a >
b; }
374bool compare_greaterThanEqual(
double a,
double b) {
return a >=
b; }
375bool compare_equal(
double a,
double b) {
return a ==
b; }
376bool compare_notEqual(
double a,
double b) {
return a !=
b; }
378double evaluate_radians(
double a,
double,
double) {
return a * 0.0174532925; }
379double evaluate_degrees(
double a,
double,
double) {
return a * 57.2957795; }
380double evaluate_sin(
double a,
double,
double) {
return std::sin(
a); }
381double evaluate_cos(
double a,
double,
double) {
return std::cos(
a); }
382double evaluate_tan(
double a,
double,
double) {
return std::tan(
a); }
383double evaluate_asin(
double a,
double,
double) {
return std::asin(
a); }
384double evaluate_acos(
double a,
double,
double) {
return std::acos(
a); }
385double evaluate_atan(
double a,
double,
double) {
return std::atan(
a); }
386double evaluate_atan2(
double a,
double b,
double) {
return std::atan2(
a,
b); }
387double evaluate_asinh(
double a,
double,
double) {
return std::asinh(
a); }
388double evaluate_acosh(
double a,
double,
double) {
return std::acosh(
a); }
389double evaluate_atanh(
double a,
double,
double) {
return std::atanh(
a); }
391double evaluate_pow(
double a,
double b,
double) {
return std::pow(
a,
b); }
392double evaluate_exp(
double a,
double,
double) {
return std::exp(
a); }
393double evaluate_log(
double a,
double,
double) {
return std::log(
a); }
394double evaluate_exp2(
double a,
double,
double) {
return std::exp2(
a); }
395double evaluate_log2(
double a,
double,
double) {
return std::log2(
a); }
396double evaluate_sqrt(
double a,
double,
double) {
return std::sqrt(
a); }
397double evaluate_inversesqrt(
double a,
double,
double) {
401double evaluate_add(
double a,
double b,
double) {
return a +
b; }
402double evaluate_sub(
double a,
double b,
double) {
return a -
b; }
403double evaluate_mul(
double a,
double b,
double) {
return a *
b; }
405double evaluate_abs(
double a,
double,
double) {
return std::abs(
a); }
406double evaluate_sign(
double a,
double,
double) {
return (
a > 0) - (
a < 0); }
407double evaluate_opposite_sign(
double a,
double,
double) {
return (
a < 0) - (
a > 0); }
408double evaluate_floor(
double a,
double,
double) {
return std::floor(
a); }
409double evaluate_ceil(
double a,
double,
double) {
return std::ceil(
a); }
410double evaluate_fract(
double a,
double,
double) {
return a - std::floor(
a); }
411double evaluate_min(
double a,
double b,
double) {
return (
a <
b) ?
a :
b; }
412double evaluate_max(
double a,
double b,
double) {
return (
a >
b) ?
a :
b; }
413double evaluate_clamp(
double x,
double l,
double h) {
return (
x < l) ? l : (
x >
h) ?
h :
x; }
414double evaluate_fma(
double a,
double b,
double c) {
return a *
b + c; }
415double evaluate_saturate(
double a,
double,
double) {
return (
a < 0) ? 0 : (
a > 1) ? 1 :
a; }
416double evaluate_mix(
double x,
double y,
double a) {
return x * (1 -
a) +
y *
a; }
417double evaluate_step(
double e,
double x,
double) {
return (
x < e) ? 0 : 1; }
418double evaluate_mod(
double a,
double b,
double) {
421double evaluate_smoothstep(
double edge0,
double edge1,
double x) {
423 t = (t < 0) ? 0 : (t > 1) ? 1 : t;
424 return t * t * (3.0 - 2.0 * t);
427double evaluate_matrixCompMult(
double x,
double y,
double) {
return x *
y; }
429double evaluate_not(
double a,
double,
double) {
return !
a; }
430double evaluate_sinh(
double a,
double,
double) {
return std::sinh(
a); }
431double evaluate_cosh(
double a,
double,
double) {
return std::cosh(
a); }
432double evaluate_tanh(
double a,
double,
double) {
return std::tanh(
a); }
433double evaluate_trunc(
double a,
double,
double) {
return std::trunc(
a); }
434double evaluate_round(
double a,
double,
double) {
437 return a - std::remainder(
a, 1.0);
439double evaluate_floatBitsToInt(
double a,
double,
double) {
return pun_value<float, int32_t> (
a); }
440double evaluate_floatBitsToUint(
double a,
double,
double) {
return pun_value<float, uint32_t>(
a); }
441double evaluate_intBitsToFloat(
double a,
double,
double) {
return pun_value<int32_t, float>(
a); }
442double evaluate_uintBitsToFloat(
double a,
double,
double) {
return pun_value<uint32_t, float>(
a); }
445 return coalesce_vector<float>(arguments, 0,
446 arguments[0]->
type().componentType(),
452 return coalesce_pairwise_vectors<float>(arguments, 0,
453 arguments[0]->
type().componentType(),
458 return coalesce_pairwise_vectors<float>(arguments, 0,
459 arguments[0]->
type().componentType(),
464std::unique_ptr<Expression> evaluate_sign(
const Context& context,
470std::unique_ptr<Expression> evaluate_opposite_sign(
const Context& context,
473 evaluate_opposite_sign);
476std::unique_ptr<Expression> evaluate_add(
const Context& context,
482std::unique_ptr<Expression> evaluate_sub(
const Context& context,
488std::unique_ptr<Expression> evaluate_mul(
const Context& context,
494std::unique_ptr<Expression> evaluate_div(
const Context& context,
500std::unique_ptr<Expression> evaluate_normalize(
const Context& context,
503 std::unique_ptr<Expression>
length = Intrinsics::evaluate_length(arguments);
504 if (!
length) {
return nullptr; }
507 return Intrinsics::evaluate_div(context, divArgs);
510std::unique_ptr<Expression> evaluate_faceforward(
const Context& context,
518 std::unique_ptr<Expression> dotExpr = Intrinsics::evaluate_dot(dotArgs);
519 if (!dotExpr) {
return nullptr; }
522 std::unique_ptr<Expression> signExpr = Intrinsics::evaluate_opposite_sign(context, signArgs);
523 if (!signExpr) {
return nullptr; }
526 return Intrinsics::evaluate_mul(context, mulArgs);
529std::unique_ptr<Expression> evaluate_reflect(
const Context& context,
536 std::unique_ptr<Expression> dotExpr = Intrinsics::evaluate_dot(dotArgs);
537 if (!dotExpr) {
return nullptr; }
540 std::unique_ptr<Expression> mulExpr = Intrinsics::evaluate_mul(context, mulArgs);
541 if (!mulExpr) {
return nullptr; }
544 std::unique_ptr<Expression> addExpr = Intrinsics::evaluate_add(context, addArgs);
545 if (!addExpr) {
return nullptr; }
548 return Intrinsics::evaluate_sub(context, subArgs);
551std::unique_ptr<Expression> evaluate_refract(
const Context& context,
561 std::unique_ptr<Expression> DotNIExpr = Intrinsics::evaluate_dot(DotNIArgs);
562 if (!DotNIExpr) {
return nullptr; }
566 std::unique_ptr<Expression> DotNI2Expr = Intrinsics::evaluate_mul(context, DotNI2Args);
567 if (!DotNI2Expr) {
return nullptr; }
572 std::unique_ptr<Expression> OneMinusDotExpr= Intrinsics::evaluate_sub(context, OneMinusDotArgs);
573 if (!OneMinusDotExpr) {
return nullptr; }
577 std::unique_ptr<Expression> Eta2Expr = Intrinsics::evaluate_mul(context, Eta2Args);
578 if (!Eta2Expr) {
return nullptr; }
581 const IntrinsicArguments Eta2xDotArgs = {Eta2Expr.get(), OneMinusDotExpr.get(),
nullptr};
582 std::unique_ptr<Expression> Eta2xDotExpr = Intrinsics::evaluate_mul(context, Eta2xDotArgs);
583 if (!Eta2xDotExpr) {
return nullptr; }
587 std::unique_ptr<Expression> KExpr = Intrinsics::evaluate_sub(context, KArgs);
588 if (!KExpr || !KExpr->is<
Literal>()) {
return nullptr; }
593 constexpr double kZero[4] = {};
601 std::unique_ptr<Expression> EtaDotExpr = Intrinsics::evaluate_mul(context, EtaDotArgs);
602 if (!EtaDotExpr) {
return nullptr; }
607 std::unique_ptr<Expression> EtaDotSqrtExpr = Intrinsics::evaluate_add(context, EtaDotSqrtArgs);
608 if (!EtaDotSqrtExpr) {
return nullptr; }
612 std::unique_ptr<Expression> NxEDSExpr = Intrinsics::evaluate_mul(context, NxEDSArgs);
613 if (!NxEDSExpr) {
return nullptr; }
617 std::unique_ptr<Expression> IEtaExpr = Intrinsics::evaluate_mul(context, IEtaArgs);
618 if (!IEtaExpr) {
return nullptr; }
622 return Intrinsics::evaluate_sub(context, RefractArgs);
639 const Type& returnType) {
643 for (
int index = 0; index < argArray.
size(); ++index) {
647 auto Get = [&](
int idx,
int col) ->
float {
648 return *arguments[idx]->getConstantValue(col);
653 case k_radians_IntrinsicKind:
654 return evaluate_intrinsic<float>(context, arguments, returnType,
655 Intrinsics::evaluate_radians);
656 case k_degrees_IntrinsicKind:
657 return evaluate_intrinsic<float>(context, arguments, returnType,
658 Intrinsics::evaluate_degrees);
659 case k_sin_IntrinsicKind:
660 return evaluate_intrinsic<float>(context, arguments, returnType,
661 Intrinsics::evaluate_sin);
662 case k_cos_IntrinsicKind:
663 return evaluate_intrinsic<float>(context, arguments, returnType,
664 Intrinsics::evaluate_cos);
665 case k_tan_IntrinsicKind:
666 return evaluate_intrinsic<float>(context, arguments, returnType,
667 Intrinsics::evaluate_tan);
668 case k_sinh_IntrinsicKind:
669 return evaluate_intrinsic<float>(context, arguments, returnType,
670 Intrinsics::evaluate_sinh);
671 case k_cosh_IntrinsicKind:
672 return evaluate_intrinsic<float>(context, arguments, returnType,
673 Intrinsics::evaluate_cosh);
674 case k_tanh_IntrinsicKind:
675 return evaluate_intrinsic<float>(context, arguments, returnType,
676 Intrinsics::evaluate_tanh);
677 case k_asin_IntrinsicKind:
678 return evaluate_intrinsic<float>(context, arguments, returnType,
679 Intrinsics::evaluate_asin);
680 case k_acos_IntrinsicKind:
681 return evaluate_intrinsic<float>(context, arguments, returnType,
682 Intrinsics::evaluate_acos);
683 case k_atan_IntrinsicKind:
684 if (argArray.
size() == 1) {
685 return evaluate_intrinsic<float>(context, arguments, returnType,
686 Intrinsics::evaluate_atan);
689 Intrinsics::evaluate_atan2);
691 case k_asinh_IntrinsicKind:
692 return evaluate_intrinsic<float>(context, arguments, returnType,
693 Intrinsics::evaluate_asinh);
695 case k_acosh_IntrinsicKind:
696 return evaluate_intrinsic<float>(context, arguments, returnType,
697 Intrinsics::evaluate_acosh);
698 case k_atanh_IntrinsicKind:
699 return evaluate_intrinsic<float>(context, arguments, returnType,
700 Intrinsics::evaluate_atanh);
702 case k_pow_IntrinsicKind:
704 Intrinsics::evaluate_pow);
705 case k_exp_IntrinsicKind:
706 return evaluate_intrinsic<float>(context, arguments, returnType,
707 Intrinsics::evaluate_exp);
708 case k_log_IntrinsicKind:
709 return evaluate_intrinsic<float>(context, arguments, returnType,
710 Intrinsics::evaluate_log);
711 case k_exp2_IntrinsicKind:
712 return evaluate_intrinsic<float>(context, arguments, returnType,
713 Intrinsics::evaluate_exp2);
714 case k_log2_IntrinsicKind:
715 return evaluate_intrinsic<float>(context, arguments, returnType,
716 Intrinsics::evaluate_log2);
717 case k_sqrt_IntrinsicKind:
718 return evaluate_intrinsic<float>(context, arguments, returnType,
719 Intrinsics::evaluate_sqrt);
720 case k_inversesqrt_IntrinsicKind:
721 return evaluate_intrinsic<float>(context, arguments, returnType,
722 Intrinsics::evaluate_inversesqrt);
724 case k_abs_IntrinsicKind:
726 Intrinsics::evaluate_abs);
727 case k_sign_IntrinsicKind:
728 return Intrinsics::evaluate_sign(context, arguments);
730 case k_floor_IntrinsicKind:
731 return evaluate_intrinsic<float>(context, arguments, returnType,
732 Intrinsics::evaluate_floor);
733 case k_ceil_IntrinsicKind:
734 return evaluate_intrinsic<float>(context, arguments, returnType,
735 Intrinsics::evaluate_ceil);
736 case k_fract_IntrinsicKind:
737 return evaluate_intrinsic<float>(context, arguments, returnType,
738 Intrinsics::evaluate_fract);
739 case k_mod_IntrinsicKind:
741 Intrinsics::evaluate_mod);
742 case k_min_IntrinsicKind:
744 Intrinsics::evaluate_min);
745 case k_max_IntrinsicKind:
747 Intrinsics::evaluate_max);
748 case k_clamp_IntrinsicKind:
750 Intrinsics::evaluate_clamp);
751 case k_fma_IntrinsicKind:
753 Intrinsics::evaluate_fma);
754 case k_saturate_IntrinsicKind:
755 return evaluate_intrinsic<float>(context, arguments, returnType,
756 Intrinsics::evaluate_saturate);
757 case k_mix_IntrinsicKind:
758 if (arguments[2]->
type().componentType().isBoolean()) {
775 returnType, Intrinsics::evaluate_mix);
778 Intrinsics::evaluate_mix);
780 case k_step_IntrinsicKind:
782 Intrinsics::evaluate_step);
783 case k_smoothstep_IntrinsicKind:
785 Intrinsics::evaluate_smoothstep);
786 case k_trunc_IntrinsicKind:
787 return evaluate_intrinsic<float>(context, arguments, returnType,
788 Intrinsics::evaluate_trunc);
789 case k_round_IntrinsicKind:
790 case k_roundEven_IntrinsicKind:
791 return evaluate_intrinsic<float>(context, arguments, returnType,
792 Intrinsics::evaluate_round);
793 case k_floatBitsToInt_IntrinsicKind:
794 return evaluate_intrinsic<float>(context, arguments, returnType,
795 Intrinsics::evaluate_floatBitsToInt);
796 case k_floatBitsToUint_IntrinsicKind:
797 return evaluate_intrinsic<float>(context, arguments, returnType,
798 Intrinsics::evaluate_floatBitsToUint);
799 case k_intBitsToFloat_IntrinsicKind:
800 return evaluate_intrinsic<SKSL_INT>(context, arguments, returnType,
801 Intrinsics::evaluate_intBitsToFloat);
802 case k_uintBitsToFloat_IntrinsicKind:
803 return evaluate_intrinsic<SKSL_INT>(context, arguments, returnType,
804 Intrinsics::evaluate_uintBitsToFloat);
806 case k_packUnorm2x16_IntrinsicKind: {
807 auto Pack = [&](
int n) ->
unsigned int {
809 return (
int)std::round(Intrinsics::evaluate_clamp(
x, 0.0, 1.0) * 65535.0);
811 const double packed = ((Pack(0) << 0) & 0x0000FFFF) |
812 ((Pack(1) << 16) & 0xFFFF0000);
816 case k_packSnorm2x16_IntrinsicKind: {
817 auto Pack = [&](
int n) ->
unsigned int {
819 return (
int)std::round(Intrinsics::evaluate_clamp(
x, -1.0, 1.0) * 32767.0);
821 const double packed = ((Pack(0) << 0) & 0x0000FFFF) |
822 ((Pack(1) << 16) & 0xFFFF0000);
826 case k_packHalf2x16_IntrinsicKind: {
827 auto Pack = [&](
int n) ->
unsigned int {
830 const double packed = ((Pack(0) << 0) & 0x0000FFFF) |
831 ((Pack(1) << 16) & 0xFFFF0000);
835 case k_unpackUnorm2x16_IntrinsicKind: {
836 SKSL_INT x = *arguments[0]->getConstantValue(0);
837 uint16_t
a = ((
x >> 0) & 0x0000FFFF);
838 uint16_t
b = ((
x >> 16) & 0x0000FFFF);
839 const double unpacked[2] = {double(
a) / 65535.0,
840 double(
b) / 65535.0};
844 case k_unpackSnorm2x16_IntrinsicKind: {
845 SKSL_INT x = *arguments[0]->getConstantValue(0);
846 int16_t
a = ((
x >> 0) & 0x0000FFFF);
847 int16_t
b = ((
x >> 16) & 0x0000FFFF);
848 const double unpacked[2] = {Intrinsics::evaluate_clamp(
double(
a) / 32767.0, -1.0, 1.0),
849 Intrinsics::evaluate_clamp(
double(
b) / 32767.0, -1.0, 1.0)};
853 case k_unpackHalf2x16_IntrinsicKind: {
854 SKSL_INT x = *arguments[0]->getConstantValue(0);
855 uint16_t
a = ((
x >> 0) & 0x0000FFFF);
856 uint16_t
b = ((
x >> 16) & 0x0000FFFF);
863 case k_length_IntrinsicKind:
864 return Intrinsics::evaluate_length(arguments);
866 case k_distance_IntrinsicKind:
867 return Intrinsics::evaluate_distance(arguments);
869 case k_dot_IntrinsicKind:
870 return Intrinsics::evaluate_dot(arguments);
872 case k_cross_IntrinsicKind: {
873 auto X = [&](
int n) ->
float {
return Get(0, n); };
874 auto Y = [&](
int n) ->
float {
return Get(1, n); };
877 double vec[3] = {
X(1) *
Y(2) -
Y(1) *
X(2),
878 X(2) *
Y(0) -
Y(2) *
X(0),
879 X(0) *
Y(1) -
Y(0) *
X(1)};
883 case k_normalize_IntrinsicKind:
884 return Intrinsics::evaluate_normalize(context, arguments);
886 case k_faceforward_IntrinsicKind:
887 return Intrinsics::evaluate_faceforward(context, arguments);
889 case k_reflect_IntrinsicKind:
890 return Intrinsics::evaluate_reflect(context, arguments);
892 case k_refract_IntrinsicKind:
893 return Intrinsics::evaluate_refract(context, arguments);
896 case k_matrixCompMult_IntrinsicKind:
898 Intrinsics::evaluate_matrixCompMult);
899 case k_transpose_IntrinsicKind: {
902 for (
int c = 0; c < returnType.
columns(); ++c) {
903 for (
int r = 0; r < returnType.
rows(); ++r) {
904 mat[index++] = Get(0, (returnType.
columns() * r) + c);
910 case k_outerProduct_IntrinsicKind: {
913 for (
int c = 0; c < returnType.
columns(); ++c) {
914 for (
int r = 0; r < returnType.
rows(); ++r) {
915 mat[index++] = Get(0, r) * Get(1, c);
921 case k_determinant_IntrinsicKind: {
925 switch (arguments[0]->
type().slotCount()) {
936 SkDEBUGFAILF(
"unsupported type %s", arguments[0]->
type().description().c_str());
941 case k_inverse_IntrinsicKind: {
944 switch (arguments[0]->
type().slotCount()) {
961 SkDEBUGFAILF(
"unsupported type %s", arguments[0]->
type().description().c_str());
966 std::copy(mat, mat + std::size(mat), dmat);
971 case k_lessThan_IntrinsicKind:
974 case k_lessThanEqual_IntrinsicKind:
977 case k_greaterThan_IntrinsicKind:
980 case k_greaterThanEqual_IntrinsicKind:
983 case k_equal_IntrinsicKind:
986 case k_notEqual_IntrinsicKind:
989 case k_any_IntrinsicKind:
990 return coalesce_vector<bool>(arguments,
false, returnType,
991 Intrinsics::coalesce_any,
993 case k_all_IntrinsicKind:
994 return coalesce_vector<bool>(arguments,
true, returnType,
995 Intrinsics::coalesce_all,
997 case k_not_IntrinsicKind:
998 return evaluate_intrinsic<bool>(context, arguments, returnType,
999 Intrinsics::evaluate_not);