Skip to content

Commit 1f22bce

Browse files
Merge pull request #2654 from SixLabors/js/xplat-intrinsics
Cleanup SimdUtils
2 parents 2d979f9 + 4e494d4 commit 1f22bce

22 files changed

+748
-869
lines changed

src/ImageSharp/Common/Helpers/Numerics.cs

+40
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,26 @@ public static nuint Vector256Count<TVector>(this ReadOnlySpan<byte> span)
10101010
where TVector : struct
10111011
=> (uint)span.Length / (uint)Vector256<TVector>.Count;
10121012

1013+
/// <summary>
1014+
/// Gets the count of vectors that safely fit into the given span.
1015+
/// </summary>
1016+
/// <typeparam name="TVector">The type of the vector.</typeparam>
1017+
/// <param name="span">The given span.</param>
1018+
/// <returns>Count of vectors that safely fit into the span.</returns>
1019+
public static nuint Vector512Count<TVector>(this Span<byte> span)
1020+
where TVector : struct
1021+
=> (uint)span.Length / (uint)Vector512<TVector>.Count;
1022+
1023+
/// <summary>
1024+
/// Gets the count of vectors that safely fit into the given span.
1025+
/// </summary>
1026+
/// <typeparam name="TVector">The type of the vector.</typeparam>
1027+
/// <param name="span">The given span.</param>
1028+
/// <returns>Count of vectors that safely fit into the span.</returns>
1029+
public static nuint Vector512Count<TVector>(this ReadOnlySpan<byte> span)
1030+
where TVector : struct
1031+
=> (uint)span.Length / (uint)Vector512<TVector>.Count;
1032+
10131033
/// <summary>
10141034
/// Gets the count of vectors that safely fit into the given span.
10151035
/// </summary>
@@ -1049,4 +1069,24 @@ public static nuint Vector256Count<TVector>(this Span<float> span)
10491069
public static nuint Vector256Count<TVector>(int length)
10501070
where TVector : struct
10511071
=> (uint)length / (uint)Vector256<TVector>.Count;
1072+
1073+
/// <summary>
1074+
/// Gets the count of vectors that safely fit into the given span.
1075+
/// </summary>
1076+
/// <typeparam name="TVector">The type of the vector.</typeparam>
1077+
/// <param name="span">The given span.</param>
1078+
/// <returns>Count of vectors that safely fit into the span.</returns>
1079+
public static nuint Vector512Count<TVector>(this Span<float> span)
1080+
where TVector : struct
1081+
=> (uint)span.Length / (uint)Vector512<TVector>.Count;
1082+
1083+
/// <summary>
1084+
/// Gets the count of vectors that safely fit into length.
1085+
/// </summary>
1086+
/// <typeparam name="TVector">The type of the vector.</typeparam>
1087+
/// <param name="length">The given length.</param>
1088+
/// <returns>Count of vectors that safely fit into the length.</returns>
1089+
public static nuint Vector512Count<TVector>(int length)
1090+
where TVector : struct
1091+
=> (uint)length / (uint)Vector512<TVector>.Count;
10521092
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
using System.Runtime.CompilerServices;
5+
using System.Runtime.InteropServices;
6+
7+
namespace SixLabors.ImageSharp;
8+
9+
internal static partial class SimdUtils
10+
{
11+
/// <summary>
12+
/// Converts all input <see cref="byte"/>-s to <see cref="float"/>-s normalized into [0..1].
13+
/// <paramref name="source"/> should be the of the same size as <paramref name="destination"/>,
14+
/// but there are no restrictions on the span's length.
15+
/// </summary>
16+
/// <param name="source">The source span of bytes</param>
17+
/// <param name="destination">The destination span of floats</param>
18+
[MethodImpl(InliningOptions.ShortMethod)]
19+
internal static void ByteToNormalizedFloat(ReadOnlySpan<byte> source, Span<float> destination)
20+
{
21+
DebugGuard.IsTrue(source.Length == destination.Length, nameof(source), "Input spans must be of same length!");
22+
23+
HwIntrinsics.ByteToNormalizedFloatReduce(ref source, ref destination);
24+
25+
if (source.Length > 0)
26+
{
27+
ConvertByteToNormalizedFloatRemainder(source, destination);
28+
}
29+
}
30+
31+
/// <summary>
32+
/// Convert all <see cref="float"/> values normalized into [0..1] from 'source' into 'destination' buffer of <see cref="byte"/>.
33+
/// The values are scaled up into [0-255] and rounded, overflows are clamped.
34+
/// <paramref name="source"/> should be the of the same size as <paramref name="destination"/>,
35+
/// but there are no restrictions on the span's length.
36+
/// </summary>
37+
/// <param name="source">The source span of floats</param>
38+
/// <param name="destination">The destination span of bytes</param>
39+
[MethodImpl(InliningOptions.ShortMethod)]
40+
internal static void NormalizedFloatToByteSaturate(ReadOnlySpan<float> source, Span<byte> destination)
41+
{
42+
DebugGuard.IsTrue(source.Length == destination.Length, nameof(source), "Input spans must be of same length!");
43+
44+
HwIntrinsics.NormalizedFloatToByteSaturateReduce(ref source, ref destination);
45+
46+
if (source.Length > 0)
47+
{
48+
ConvertNormalizedFloatToByteRemainder(source, destination);
49+
}
50+
}
51+
52+
[MethodImpl(MethodImplOptions.NoInlining)]
53+
private static void ConvertByteToNormalizedFloatRemainder(ReadOnlySpan<byte> source, Span<float> destination)
54+
{
55+
ref byte sBase = ref MemoryMarshal.GetReference(source);
56+
ref float dBase = ref MemoryMarshal.GetReference(destination);
57+
58+
for (int i = 0; i < source.Length; i++)
59+
{
60+
Unsafe.Add(ref dBase, (uint)i) = Unsafe.Add(ref sBase, (uint)i) / 255f;
61+
}
62+
}
63+
64+
[MethodImpl(MethodImplOptions.NoInlining)]
65+
private static void ConvertNormalizedFloatToByteRemainder(ReadOnlySpan<float> source, Span<byte> destination)
66+
{
67+
ref float sBase = ref MemoryMarshal.GetReference(source);
68+
ref byte dBase = ref MemoryMarshal.GetReference(destination);
69+
70+
for (int i = 0; i < source.Length; i++)
71+
{
72+
Unsafe.Add(ref dBase, (uint)i) = ConvertToByte(Unsafe.Add(ref sBase, (uint)i));
73+
}
74+
}
75+
76+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
77+
private static byte ConvertToByte(float f) => (byte)Numerics.Clamp((f * 255f) + 0.5f, 0, 255f);
78+
}

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

-182
This file was deleted.

0 commit comments

Comments
 (0)