Browse Source

Fix shuffle +m slice fallback

js/color-alpha-handling
James Jackson-South 6 years ago
parent
commit
863c672be1
  1. 30
      src/ImageSharp/Common/Helpers/Shuffle/IPad3Shuffle4.cs
  2. 18
      src/ImageSharp/Common/Helpers/Shuffle/IShuffle4Slice3.cs
  3. 2
      tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs

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

@ -72,29 +72,29 @@ namespace SixLabors.ImageSharp
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest) public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
{ {
ref byte rs = ref MemoryMarshal.GetReference(source); ref byte sBase = ref MemoryMarshal.GetReference(source);
ref byte rd = ref MemoryMarshal.GetReference(dest); ref byte dBase = ref MemoryMarshal.GetReference(dest);
ref byte rsEnd = ref Unsafe.Add(ref rs, source.Length); ref byte sEnd = ref Unsafe.Add(ref sBase, source.Length);
ref byte rsLoopEnd = ref Unsafe.Subtract(ref rsEnd, 4); ref byte sLoopEnd = ref Unsafe.Subtract(ref sEnd, 4);
while (Unsafe.IsAddressLessThan(ref rs, ref rsLoopEnd)) while (Unsafe.IsAddressLessThan(ref sBase, ref sLoopEnd))
{ {
Unsafe.As<byte, uint>(ref rd) = Unsafe.As<byte, uint>(ref rs) | 0xFF000000; Unsafe.As<byte, uint>(ref dBase) = Unsafe.As<byte, uint>(ref sBase) | 0xFF000000;
rs = ref Unsafe.Add(ref rs, 3); sBase = ref Unsafe.Add(ref sBase, 3);
rd = ref Unsafe.Add(ref rd, 4); dBase = ref Unsafe.Add(ref dBase, 4);
} }
while (Unsafe.IsAddressLessThan(ref rs, ref rsEnd)) while (Unsafe.IsAddressLessThan(ref sBase, ref sEnd))
{ {
Unsafe.Add(ref rd, 0) = Unsafe.Add(ref rs, 0); Unsafe.Add(ref dBase, 0) = Unsafe.Add(ref sBase, 0);
Unsafe.Add(ref rd, 1) = Unsafe.Add(ref rs, 1); Unsafe.Add(ref dBase, 1) = Unsafe.Add(ref sBase, 1);
Unsafe.Add(ref rd, 2) = Unsafe.Add(ref rs, 2); Unsafe.Add(ref dBase, 2) = Unsafe.Add(ref sBase, 2);
Unsafe.Add(ref rd, 3) = byte.MaxValue; Unsafe.Add(ref dBase, 3) = byte.MaxValue;
rs = ref Unsafe.Add(ref rs, 3); sBase = ref Unsafe.Add(ref sBase, 3);
rd = ref Unsafe.Add(ref rd, 4); dBase = ref Unsafe.Add(ref dBase, 4);
} }
} }
} }

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

@ -68,24 +68,26 @@ namespace SixLabors.ImageSharp
int m = ImageMaths.Modulo4(n); int m = ImageMaths.Modulo4(n);
int u = n - m; int u = n - m;
ref Byte3 dEnd = ref Unsafe.Add(ref dBase, u); ref uint sLoopEnd = ref Unsafe.Add(ref sBase, u);
ref uint sEnd = ref Unsafe.Add(ref sBase, n);
while (Unsafe.IsAddressLessThan(ref dBase, ref dEnd)) while (Unsafe.IsAddressLessThan(ref sBase, ref sLoopEnd))
{ {
Unsafe.Add(ref dBase, 0) = Unsafe.As<uint, Byte3>(ref Unsafe.Add(ref sBase, 0)); Unsafe.Add(ref dBase, 0) = Unsafe.As<uint, Byte3>(ref Unsafe.Add(ref sBase, 0));
Unsafe.Add(ref dBase, 1) = Unsafe.As<uint, Byte3>(ref Unsafe.Add(ref sBase, 1)); Unsafe.Add(ref dBase, 1) = Unsafe.As<uint, Byte3>(ref Unsafe.Add(ref sBase, 1));
Unsafe.Add(ref dBase, 2) = Unsafe.As<uint, Byte3>(ref Unsafe.Add(ref sBase, 2)); Unsafe.Add(ref dBase, 2) = Unsafe.As<uint, Byte3>(ref Unsafe.Add(ref sBase, 2));
Unsafe.Add(ref dBase, 3) = Unsafe.As<uint, Byte3>(ref Unsafe.Add(ref sBase, 3)); Unsafe.Add(ref dBase, 3) = Unsafe.As<uint, Byte3>(ref Unsafe.Add(ref sBase, 3));
dBase = ref Unsafe.Add(ref dBase, 4);
sBase = ref Unsafe.Add(ref sBase, 4); sBase = ref Unsafe.Add(ref sBase, 4);
dBase = ref Unsafe.Add(ref dBase, 4);
} }
if (m > 0) while (Unsafe.IsAddressLessThan(ref sBase, ref sEnd))
{ {
for (int i = u; i < n; i++) Unsafe.Add(ref dBase, 0) = Unsafe.As<uint, Byte3>(ref Unsafe.Add(ref sBase, 0));
{
Unsafe.Add(ref dBase, i) = Unsafe.As<uint, Byte3>(ref Unsafe.Add(ref sBase, i)); sBase = ref Unsafe.Add(ref sBase, 1);
} dBase = ref Unsafe.Add(ref dBase, 1);
} }
} }
} }

2
tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs

@ -91,7 +91,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk
SimdUtils.BasicIntrinsics256.NormalizedFloatToByteSaturate(sBytes, dFloats); SimdUtils.BasicIntrinsics256.NormalizedFloatToByteSaturate(sBytes, dFloats);
} }
[Benchmark(Baseline = true)] [Benchmark]
public void ExtendedIntrinsic() public void ExtendedIntrinsic()
{ {
Span<float> sBytes = MemoryMarshal.Cast<Vector4, float>(this.source.GetSpan()); Span<float> sBytes = MemoryMarshal.Cast<Vector4, float>(this.source.GetSpan());

Loading…
Cancel
Save