Browse Source

Fix Sse2 offset

pull/2588/head
James Jackson-South 2 years ago
parent
commit
43c8614530
  1. 29
      src/ImageSharp/Formats/AnimationUtilities.cs

29
src/ImageSharp/Formats/AnimationUtilities.cs

@ -71,10 +71,10 @@ internal static class AnimationUtilities
PixelOperations<TPixel>.Instance.ToRgba32(configuration, nextFrame.DangerousGetPixelRowMemory(y).Span, next);
}
ref Vector256<byte> previousBase = ref Unsafe.As<Rgba32, Vector256<byte>>(ref MemoryMarshal.GetReference(previous));
ref Vector256<byte> currentBase = ref Unsafe.As<Rgba32, Vector256<byte>>(ref MemoryMarshal.GetReference(current));
ref Vector256<byte> nextBase = ref Unsafe.As<Rgba32, Vector256<byte>>(ref MemoryMarshal.GetReference(next));
ref Vector256<byte> resultBase = ref Unsafe.As<Rgba32, Vector256<byte>>(ref MemoryMarshal.GetReference(result));
ref Vector256<byte> previousBase256 = ref Unsafe.As<Rgba32, Vector256<byte>>(ref MemoryMarshal.GetReference(previous));
ref Vector256<byte> currentBase256 = ref Unsafe.As<Rgba32, Vector256<byte>>(ref MemoryMarshal.GetReference(current));
ref Vector256<byte> nextBase256 = ref Unsafe.As<Rgba32, Vector256<byte>>(ref MemoryMarshal.GetReference(next));
ref Vector256<byte> resultBase256 = ref Unsafe.As<Rgba32, Vector256<byte>>(ref MemoryMarshal.GetReference(result));
int i = 0;
uint x = 0;
@ -93,19 +93,19 @@ internal static class AnimationUtilities
while (remaining >= 8)
{
Vector256<uint> p = Unsafe.Add(ref previousBase, x).AsUInt32();
Vector256<uint> c = Unsafe.Add(ref currentBase, x).AsUInt32();
Vector256<uint> p = Unsafe.Add(ref previousBase256, x).AsUInt32();
Vector256<uint> c = Unsafe.Add(ref currentBase256, x).AsUInt32();
Vector256<uint> eq = Avx2.CompareEqual(p, c);
Vector256<uint> r = Avx2.BlendVariable(c, r256, Avx2.And(eq, vmb256));
if (nextFrame != null)
{
Vector256<int> n = Avx2.ShiftRightLogical(Unsafe.Add(ref nextBase, x).AsUInt32(), 24).AsInt32();
Vector256<int> n = Avx2.ShiftRightLogical(Unsafe.Add(ref nextBase256, x).AsUInt32(), 24).AsInt32();
eq = Avx2.AndNot(Avx2.CompareGreaterThan(Avx2.ShiftRightLogical(c, 24).AsInt32(), n).AsUInt32(), eq);
}
Unsafe.Add(ref resultBase, x) = r.AsByte();
Unsafe.Add(ref resultBase256, x) = r.AsByte();
uint msk = (uint)Avx2.MoveMask(eq.AsByte());
msk = ~msk;
@ -128,9 +128,10 @@ internal static class AnimationUtilities
}
}
// TODO: There's a bug here. See WebpEncoderTests.Encode_AnimatedLossless
if (Sse2.IsSupported && remaining >= 4 && false)
if (Sse2.IsSupported && remaining >= 4)
{
// Update offset since we may be operating on the remainder previously incremented by pixel steps of 8.
x *= 2;
Vector128<uint> r128 = previousFrame != null ? Vector128.Create(bg.PackedValue) : Vector128<uint>.Zero;
Vector128<uint> vmb128 = Vector128<uint>.Zero;
if (blend)
@ -140,19 +141,19 @@ internal static class AnimationUtilities
while (remaining >= 4)
{
Vector128<uint> p = Unsafe.Add(ref Unsafe.As<Vector256<byte>, Vector128<uint>>(ref previousBase), x);
Vector128<uint> c = Unsafe.Add(ref Unsafe.As<Vector256<byte>, Vector128<uint>>(ref currentBase), x);
Vector128<uint> p = Unsafe.Add(ref Unsafe.As<Vector256<byte>, Vector128<uint>>(ref previousBase256), x);
Vector128<uint> c = Unsafe.Add(ref Unsafe.As<Vector256<byte>, Vector128<uint>>(ref currentBase256), x);
Vector128<uint> eq = Sse2.CompareEqual(p, c);
Vector128<uint> r = SimdUtils.HwIntrinsics.BlendVariable(c, r128, Sse2.And(eq, vmb128));
if (nextFrame != null)
{
Vector128<int> n = Sse2.ShiftRightLogical(Unsafe.Add(ref Unsafe.As<Vector256<byte>, Vector128<uint>>(ref nextBase), x), 24).AsInt32();
Vector128<int> n = Sse2.ShiftRightLogical(Unsafe.Add(ref Unsafe.As<Vector256<byte>, Vector128<uint>>(ref nextBase256), x), 24).AsInt32();
eq = Sse2.AndNot(Sse2.CompareGreaterThan(Sse2.ShiftRightLogical(c, 24).AsInt32(), n).AsUInt32(), eq);
}
Unsafe.Add(ref Unsafe.As<Vector256<byte>, Vector128<uint>>(ref resultBase), x) = r;
Unsafe.Add(ref Unsafe.As<Vector256<byte>, Vector128<uint>>(ref resultBase256), x) = r;
ushort msk = (ushort)(uint)Sse2.MoveMask(eq.AsByte());
msk = (ushort)~msk;

Loading…
Cancel
Save