Skip to content

Commit cc9a514

Browse files
Merge pull request #3109 from SixLabors/js/modern-porter-duff
Modernize PorterDuffFunctions with operators and add tests
2 parents 66f21f7 + fd688db commit cc9a514

File tree

15 files changed

+18887
-767
lines changed

15 files changed

+18887
-767
lines changed

src/ImageSharp/Common/Helpers/Numerics.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,20 @@ public static Vector256<float> UnPremultiply(Vector256<float> source, Vector256<
643643
return Avx.Blend(result, alpha, BlendAlphaControl);
644644
}
645645

646+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
647+
public static Vector512<float> UnPremultiply(Vector512<float> source, Vector512<float> alpha)
648+
{
649+
// Check if alpha is zero to avoid division by zero
650+
Vector512<float> zeroMask = Vector512.Equals(alpha, Vector512<float>.Zero);
651+
652+
// Divide source by alpha if alpha is nonzero, otherwise set all components to match the source value
653+
Vector512<float> result = Vector512.ConditionalSelect(zeroMask, source, source / alpha);
654+
655+
// Blend the result with the alpha vector to ensure that the alpha component is unchanged
656+
Vector512<float> alphaMask = Vector512.Create(0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1).AsSingle();
657+
return Vector512.ConditionalSelect(alphaMask, alpha, result);
658+
}
659+
646660
/// <summary>
647661
/// Permutes the given vector return a new instance with all the values set to <see cref="Vector4.W"/>.
648662
/// </summary>
@@ -690,7 +704,7 @@ public static Vector4 WithW(Vector4 value, Vector4 w)
690704
/// </summary>
691705
/// <param name="vectors">The span of vectors</param>
692706
[MethodImpl(MethodImplOptions.AggressiveInlining)]
693-
public static unsafe void CubePowOnXYZ(Span<Vector4> vectors)
707+
public static void CubePowOnXYZ(Span<Vector4> vectors)
694708
{
695709
ref Vector4 baseRef = ref MemoryMarshal.GetReference(vectors);
696710
ref Vector4 endRef = ref Unsafe.Add(ref baseRef, (uint)vectors.Length);

src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -601,51 +601,6 @@ private static void Shuffle4Slice3(
601601
}
602602
}
603603

604-
/// <summary>
605-
/// Performs a multiplication and an addition of the <see cref="Vector256{Single}"/>.
606-
/// TODO: Fix. The arguments are in a different order to the FMA intrinsic.
607-
/// </summary>
608-
/// <remarks>ret = (vm0 * vm1) + va</remarks>
609-
/// <param name="va">The vector to add to the intermediate result.</param>
610-
/// <param name="vm0">The first vector to multiply.</param>
611-
/// <param name="vm1">The second vector to multiply.</param>
612-
/// <returns>The <see cref="Vector256{T}"/>.</returns>
613-
[MethodImpl(InliningOptions.AlwaysInline)]
614-
public static Vector256<float> MultiplyAdd(
615-
Vector256<float> va,
616-
Vector256<float> vm0,
617-
Vector256<float> vm1)
618-
{
619-
if (Fma.IsSupported)
620-
{
621-
return Fma.MultiplyAdd(vm1, vm0, va);
622-
}
623-
624-
return va + (vm0 * vm1);
625-
}
626-
627-
/// <summary>
628-
/// Performs a multiplication and a negated addition of the <see cref="Vector256{Single}"/>.
629-
/// </summary>
630-
/// <remarks>ret = c - (a * b)</remarks>
631-
/// <param name="a">The first vector to multiply.</param>
632-
/// <param name="b">The second vector to multiply.</param>
633-
/// <param name="c">The vector to add negated to the intermediate result.</param>
634-
/// <returns>The <see cref="Vector256{T}"/>.</returns>
635-
[MethodImpl(InliningOptions.ShortMethod)]
636-
public static Vector256<float> MultiplyAddNegated(
637-
Vector256<float> a,
638-
Vector256<float> b,
639-
Vector256<float> c)
640-
{
641-
if (Fma.IsSupported)
642-
{
643-
return Fma.MultiplyAddNegated(a, b, c);
644-
}
645-
646-
return Avx.Subtract(c, Avx.Multiply(a, b));
647-
}
648-
649604
/// <summary>
650605
/// Blend packed 8-bit integers from <paramref name="left"/> and <paramref name="right"/> using <paramref name="mask"/>.
651606
/// The high bit of each corresponding <paramref name="mask"/> byte determines the selection.

src/ImageSharp/Common/Helpers/Vector256Utilities.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,28 @@ public static Vector256<float> MultiplyAdd(
115115
return va + (vm0 * vm1);
116116
}
117117

118+
/// <summary>
119+
/// Performs a multiplication and a negated addition of the <see cref="Vector256{Single}"/>.
120+
/// </summary>
121+
/// <remarks>ret = va - (vm0 * vm1)</remarks>
122+
/// <param name="va">The vector to add to the negated intermediate result.</param>
123+
/// <param name="vm0">The first vector to multiply.</param>
124+
/// <param name="vm1">The second vector to multiply.</param>
125+
/// <returns>The <see cref="Vector256{T}"/>.</returns>
126+
[MethodImpl(InliningOptions.ShortMethod)]
127+
public static Vector256<float> MultiplyAddNegated(
128+
Vector256<float> va,
129+
Vector256<float> vm0,
130+
Vector256<float> vm1)
131+
{
132+
if (Fma.IsSupported)
133+
{
134+
return Fma.MultiplyAddNegated(vm0, vm1, va);
135+
}
136+
137+
return va - (vm0 * vm1);
138+
}
139+
118140
/// <summary>
119141
/// Performs a multiplication and a subtraction of the <see cref="Vector256{Single}"/>.
120142
/// </summary>

src/ImageSharp/Common/Helpers/Vector512Utilities.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,21 @@ public static Vector512<float> MultiplyAdd(
8787
Vector512<float> vm1)
8888
=> Avx512F.FusedMultiplyAdd(vm0, vm1, va);
8989

90+
/// <summary>
91+
/// Performs a multiplication and a negated addition of the <see cref="Vector512{Single}"/>.
92+
/// </summary>
93+
/// <remarks>ret = va - (vm0 * vm1)</remarks>
94+
/// <param name="va">The vector to add to the negated intermediate result.</param>
95+
/// <param name="vm0">The first vector to multiply.</param>
96+
/// <param name="vm1">The second vector to multiply.</param>
97+
/// <returns>The <see cref="Vector512{T}"/>.</returns>
98+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
99+
public static Vector512<float> MultiplyAddNegated(
100+
Vector512<float> va,
101+
Vector512<float> vm0,
102+
Vector512<float> vm1)
103+
=> Avx512F.FusedMultiplyAddNegated(vm0, vm1, va);
104+
90105
/// <summary>
91106
/// Restricts a vector between a minimum and a maximum value.
92107
/// </summary>

0 commit comments

Comments
 (0)