Browse Source

Avoid pinning

pull/1810/head
Brian Popow 5 years ago
parent
commit
6e135cbd79
  1. 33
      src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs

33
src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs

@ -4,6 +4,7 @@
using System; using System;
using System.Buffers.Binary; using System.Buffers.Binary;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
#if SUPPORTS_RUNTIME_INTRINSICS #if SUPPORTS_RUNTIME_INTRINSICS
using System.Runtime.Intrinsics; using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86; using System.Runtime.Intrinsics.X86;
@ -614,21 +615,16 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
{ {
Span<int> sum = scratch.Slice(0, 4); Span<int> sum = scratch.Slice(0, 4);
sum.Clear(); sum.Clear();
#pragma warning disable SA1503 // Braces should not be omitted
fixed (byte* inputAPtr = inputA)
fixed (byte* inputBPtr = inputB)
fixed (ushort* wPtr = w)
fixed (int* outputPtr = sum)
{
// Load and combine inputs. // Load and combine inputs.
Vector128<byte> ina0 = Sse2.LoadVector128(inputAPtr); Vector128<byte> ina0 = Unsafe.As<byte, Vector128<byte>>(ref MemoryMarshal.GetReference(inputA));
Vector128<byte> ina1 = Sse2.LoadVector128(inputAPtr + (WebpConstants.Bps * 1)); Vector128<byte> ina1 = Unsafe.As<byte, Vector128<byte>>(ref MemoryMarshal.GetReference(inputA.Slice(WebpConstants.Bps, 16)));
Vector128<byte> ina2 = Sse2.LoadVector128(inputAPtr + (WebpConstants.Bps * 2)); Vector128<byte> ina2 = Unsafe.As<byte, Vector128<byte>>(ref MemoryMarshal.GetReference(inputA.Slice(WebpConstants.Bps * 2, 16)));
Vector128<long> ina3 = Sse2.LoadVector128((long*)(inputAPtr + (WebpConstants.Bps * 3))); Vector128<long> ina3 = Unsafe.As<byte, Vector128<byte>>(ref MemoryMarshal.GetReference(inputA.Slice(WebpConstants.Bps * 3, 16))).AsInt64();
Vector128<byte> inb0 = Sse2.LoadVector128(inputBPtr); Vector128<byte> inb0 = Unsafe.As<byte, Vector128<byte>>(ref MemoryMarshal.GetReference(inputB));
Vector128<byte> inb1 = Sse2.LoadVector128(inputBPtr + (WebpConstants.Bps * 1)); Vector128<byte> inb1 = Unsafe.As<byte, Vector128<byte>>(ref MemoryMarshal.GetReference(inputB.Slice(WebpConstants.Bps, 16)));
Vector128<byte> inb2 = Sse2.LoadVector128(inputBPtr + (WebpConstants.Bps * 2)); Vector128<byte> inb2 = Unsafe.As<byte, Vector128<byte>>(ref MemoryMarshal.GetReference(inputB.Slice(WebpConstants.Bps * 2, 16)));
Vector128<long> inb3 = Sse2.LoadVector128((long*)(inputBPtr + (WebpConstants.Bps * 3))); Vector128<long> inb3 = Unsafe.As<byte, Vector128<byte>>(ref MemoryMarshal.GetReference(inputB.Slice(WebpConstants.Bps * 3, 16))).AsInt64();
// Combine inA and inB (we'll do two transforms in parallel). // Combine inA and inB (we'll do two transforms in parallel).
Vector128<int> inab0 = Sse2.UnpackLow(ina0.AsInt32(), inb0.AsInt32()); Vector128<int> inab0 = Sse2.UnpackLow(ina0.AsInt32(), inb0.AsInt32());
@ -689,8 +685,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
// a02 a12 a22 a32 b02 b12 b22 b32 // a02 a12 a22 a32 b02 b12 b22 b32
// a03 a13 a23 a33 b03 b13 b23 b33 // a03 a13 a23 a33 b03 b13 b23 b33
// Horizontal pass and difference of weighted sums. // Horizontal pass and difference of weighted sums.
Vector128<ushort> w0 = Sse2.LoadVector128(wPtr); Vector128<ushort> w0 = Unsafe.As<ushort, Vector128<ushort>>(ref MemoryMarshal.GetReference(w));
Vector128<ushort> w8 = Sse2.LoadVector128(wPtr + 8); Vector128<ushort> w8 = Unsafe.As<ushort, Vector128<ushort>>(ref MemoryMarshal.GetReference(w.Slice(8, 8)));
// Calculate a and b (two 4x4 at once). // Calculate a and b (two 4x4 at once).
a0 = Sse2.Add(output0.AsInt16(), output2.AsInt16()); a0 = Sse2.Add(output0.AsInt16(), output2.AsInt16());
@ -723,11 +719,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
// difference of weighted sums. // difference of weighted sums.
Vector128<int> result = Sse2.Subtract(ab0ab2Sum.AsInt32(), b0w0bb2w8Sum.AsInt32()); Vector128<int> result = Sse2.Subtract(ab0ab2Sum.AsInt32(), b0w0bb2w8Sum.AsInt32());
Sse2.Store(outputPtr, result.AsInt32());
}
ref int outputRef = ref MemoryMarshal.GetReference(sum);
Unsafe.As<int, Vector128<int>>(ref outputRef) = result.AsInt32();
return sum[3] + sum[2] + sum[1] + sum[0]; return sum[3] + sum[2] + sum[1] + sum[0];
#pragma warning restore SA1503 // Braces should not be omitted
} }
#endif #endif

Loading…
Cancel
Save