Skip to content

Commit 9e7cf16

Browse files
Use MMShuffle consts everywhere and refactor explicit shuffle components to use them
1 parent d9192c6 commit 9e7cf16

File tree

9 files changed

+369
-117
lines changed

9 files changed

+369
-117
lines changed

src/ImageSharp/Common/Helpers/Shuffle/IComponentShuffle.cs

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Numerics;
66
using System.Runtime.CompilerServices;
77
using System.Runtime.InteropServices;
8+
using static SixLabors.ImageSharp.SimdUtils;
89

910
// The JIT can detect and optimize rotation idioms ROTL (Rotate Left)
1011
// and ROTR (Rotate Right) emitting efficient CPU instructions:
@@ -18,9 +19,12 @@ namespace SixLabors.ImageSharp;
1819
internal interface IComponentShuffle
1920
{
2021
/// <summary>
21-
/// Gets the shuffle control.
22+
/// Shuffles then slices 8-bit integers within 128-bit lanes in <paramref name="source"/>
23+
/// using the control and store the results in <paramref name="dest"/>.
2224
/// </summary>
23-
byte Control { get; }
25+
/// <param name="source">The source span of bytes.</param>
26+
/// <param name="dest">The destination span of bytes.</param>
27+
void ShuffleReduce(ref ReadOnlySpan<byte> source, ref Span<byte> dest);
2428

2529
/// <summary>
2630
/// Shuffle 8-bit integers within 128-bit lanes in <paramref name="source"/>
@@ -58,11 +62,15 @@ public DefaultShuffle4(byte p3, byte p2, byte p1, byte p0)
5862
this.p2 = p2;
5963
this.p1 = p1;
6064
this.p0 = p0;
61-
this.Control = SimdUtils.Shuffle.MmShuffle(p3, p2, p1, p0);
65+
this.Control = Shuffle.MmShuffle(p3, p2, p1, p0);
6266
}
6367

6468
public byte Control { get; }
6569

70+
[MethodImpl(InliningOptions.ShortMethod)]
71+
public void ShuffleReduce(ref ReadOnlySpan<byte> source, ref Span<byte> dest)
72+
=> HwIntrinsics.Shuffle4Reduce(ref source, ref dest, this.Control);
73+
6674
[MethodImpl(InliningOptions.ShortMethod)]
6775
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
6876
{
@@ -86,11 +94,9 @@ public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
8694

8795
internal readonly struct WXYZShuffle4 : IShuffle4
8896
{
89-
public byte Control
90-
{
91-
[MethodImpl(InliningOptions.ShortMethod)]
92-
get => SimdUtils.Shuffle.MmShuffle(2, 1, 0, 3);
93-
}
97+
[MethodImpl(InliningOptions.ShortMethod)]
98+
public void ShuffleReduce(ref ReadOnlySpan<byte> source, ref Span<byte> dest)
99+
=> HwIntrinsics.Shuffle4Reduce(ref source, ref dest, Shuffle.MMShuffle2103);
94100

95101
[MethodImpl(InliningOptions.ShortMethod)]
96102
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
@@ -112,11 +118,9 @@ public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
112118

113119
internal readonly struct WZYXShuffle4 : IShuffle4
114120
{
115-
public byte Control
116-
{
117-
[MethodImpl(InliningOptions.ShortMethod)]
118-
get => SimdUtils.Shuffle.MmShuffle(0, 1, 2, 3);
119-
}
121+
[MethodImpl(InliningOptions.ShortMethod)]
122+
public void ShuffleReduce(ref ReadOnlySpan<byte> source, ref Span<byte> dest)
123+
=> HwIntrinsics.Shuffle4Reduce(ref source, ref dest, Shuffle.MMShuffle0123);
120124

121125
[MethodImpl(InliningOptions.ShortMethod)]
122126
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
@@ -138,11 +142,9 @@ public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
138142

139143
internal readonly struct YZWXShuffle4 : IShuffle4
140144
{
141-
public byte Control
142-
{
143-
[MethodImpl(InliningOptions.ShortMethod)]
144-
get => SimdUtils.Shuffle.MmShuffle(0, 3, 2, 1);
145-
}
145+
[MethodImpl(InliningOptions.ShortMethod)]
146+
public void ShuffleReduce(ref ReadOnlySpan<byte> source, ref Span<byte> dest)
147+
=> HwIntrinsics.Shuffle4Reduce(ref source, ref dest, Shuffle.MMShuffle0321);
146148

147149
[MethodImpl(InliningOptions.ShortMethod)]
148150
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
@@ -164,11 +166,9 @@ public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
164166

165167
internal readonly struct ZYXWShuffle4 : IShuffle4
166168
{
167-
public byte Control
168-
{
169-
[MethodImpl(InliningOptions.ShortMethod)]
170-
get => SimdUtils.Shuffle.MmShuffle(3, 0, 1, 2);
171-
}
169+
[MethodImpl(InliningOptions.ShortMethod)]
170+
public void ShuffleReduce(ref ReadOnlySpan<byte> source, ref Span<byte> dest)
171+
=> HwIntrinsics.Shuffle4Reduce(ref source, ref dest, Shuffle.MMShuffle3012);
172172

173173
[MethodImpl(InliningOptions.ShortMethod)]
174174
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
@@ -197,11 +197,9 @@ public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
197197

198198
internal readonly struct XWZYShuffle4 : IShuffle4
199199
{
200-
public byte Control
201-
{
202-
[MethodImpl(InliningOptions.ShortMethod)]
203-
get => SimdUtils.Shuffle.MmShuffle(1, 2, 3, 0);
204-
}
200+
[MethodImpl(InliningOptions.ShortMethod)]
201+
public void ShuffleReduce(ref ReadOnlySpan<byte> source, ref Span<byte> dest)
202+
=> HwIntrinsics.Shuffle4Reduce(ref source, ref dest, Shuffle.MMShuffle1230);
205203

206204
[MethodImpl(InliningOptions.ShortMethod)]
207205
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)

src/ImageSharp/Common/Helpers/Shuffle/IPad3Shuffle4.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Runtime.CompilerServices;
55
using System.Runtime.InteropServices;
6+
using static SixLabors.ImageSharp.SimdUtils;
67

78
namespace SixLabors.ImageSharp;
89

@@ -29,11 +30,15 @@ public DefaultPad3Shuffle4(byte p3, byte p2, byte p1, byte p0)
2930
this.p2 = p2;
3031
this.p1 = p1;
3132
this.p0 = p0;
32-
this.Control = SimdUtils.Shuffle.MmShuffle(p3, p2, p1, p0);
33+
this.Control = Shuffle.MmShuffle(p3, p2, p1, p0);
3334
}
3435

3536
public byte Control { get; }
3637

38+
[MethodImpl(InliningOptions.ShortMethod)]
39+
public void ShuffleReduce(ref ReadOnlySpan<byte> source, ref Span<byte> dest)
40+
=> HwIntrinsics.Pad3Shuffle4Reduce(ref source, ref dest, this.Control);
41+
3742
[MethodImpl(InliningOptions.ShortMethod)]
3843
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
3944
{
@@ -51,7 +56,7 @@ public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
5156

5257
for (int i = 0, j = 0; i < source.Length; i += 3, j += 4)
5358
{
54-
ref var s = ref Unsafe.Add(ref sBase, i);
59+
ref byte s = ref Unsafe.Add(ref sBase, i);
5560
tu = Unsafe.As<byte, uint>(ref s) | 0xFF000000;
5661

5762
Unsafe.Add(ref dBase, j) = Unsafe.Add(ref t, p0);
@@ -64,11 +69,9 @@ public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
6469

6570
internal readonly struct XYZWPad3Shuffle4 : IPad3Shuffle4
6671
{
67-
public byte Control
68-
{
69-
[MethodImpl(InliningOptions.ShortMethod)]
70-
get => SimdUtils.Shuffle.MmShuffle(3, 2, 1, 0);
71-
}
72+
[MethodImpl(InliningOptions.ShortMethod)]
73+
public void ShuffleReduce(ref ReadOnlySpan<byte> source, ref Span<byte> dest)
74+
=> HwIntrinsics.Pad3Shuffle4Reduce(ref source, ref dest, Shuffle.MMShuffle3210);
7275

7376
[MethodImpl(InliningOptions.ShortMethod)]
7477
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)

src/ImageSharp/Common/Helpers/Shuffle/IShuffle3.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Runtime.CompilerServices;
55
using System.Runtime.InteropServices;
6+
using static SixLabors.ImageSharp.SimdUtils;
67

78
namespace SixLabors.ImageSharp;
89

@@ -26,11 +27,15 @@ public DefaultShuffle3(byte p2, byte p1, byte p0)
2627
this.p2 = p2;
2728
this.p1 = p1;
2829
this.p0 = p0;
29-
this.Control = SimdUtils.Shuffle.MmShuffle(3, p2, p1, p0);
30+
this.Control = Shuffle.MmShuffle(3, p2, p1, p0);
3031
}
3132

3233
public byte Control { get; }
3334

35+
[MethodImpl(InliningOptions.ShortMethod)]
36+
public void ShuffleReduce(ref ReadOnlySpan<byte> source, ref Span<byte> dest)
37+
=> HwIntrinsics.Shuffle3Reduce(ref source, ref dest, this.Control);
38+
3439
[MethodImpl(InliningOptions.ShortMethod)]
3540
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
3641
{

src/ImageSharp/Common/Helpers/Shuffle/IShuffle4Slice3.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Runtime.CompilerServices;
55
using System.Runtime.InteropServices;
6+
using static SixLabors.ImageSharp.SimdUtils;
67

78
namespace SixLabors.ImageSharp;
89

@@ -27,11 +28,15 @@ public DefaultShuffle4Slice3(byte p3, byte p2, byte p1, byte p0)
2728
this.p2 = p2;
2829
this.p1 = p1;
2930
this.p0 = p0;
30-
this.Control = SimdUtils.Shuffle.MmShuffle(p3, p2, p1, p0);
31+
this.Control = Shuffle.MmShuffle(p3, p2, p1, p0);
3132
}
3233

3334
public byte Control { get; }
3435

36+
[MethodImpl(InliningOptions.ShortMethod)]
37+
public void ShuffleReduce(ref ReadOnlySpan<byte> source, ref Span<byte> dest)
38+
=> HwIntrinsics.Shuffle4Slice3Reduce(ref source, ref dest, this.Control);
39+
3540
[MethodImpl(InliningOptions.ShortMethod)]
3641
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
3742
{
@@ -53,11 +58,9 @@ public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
5358

5459
internal readonly struct XYZWShuffle4Slice3 : IShuffle4Slice3
5560
{
56-
public byte Control
57-
{
58-
[MethodImpl(InliningOptions.ShortMethod)]
59-
get => SimdUtils.Shuffle.MmShuffle(3, 2, 1, 0);
60-
}
61+
[MethodImpl(InliningOptions.ShortMethod)]
62+
public void ShuffleReduce(ref ReadOnlySpan<byte> source, ref Span<byte> dest)
63+
=> HwIntrinsics.Shuffle4Slice3Reduce(ref source, ref dest, Shuffle.MMShuffle3210);
6164

6265
[MethodImpl(InliningOptions.ShortMethod)]
6366
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)

0 commit comments

Comments
 (0)