Browse Source

Avoid pinning of vp8 matrix data

pull/1811/head
Brian Popow 5 years ago
parent
commit
5c6e08b80c
  1. 41
      src/ImageSharp/Formats/Webp/Lossy/QuantEnc.cs

41
src/ImageSharp/Formats/Webp/Lossy/QuantEnc.cs

@ -3,6 +3,7 @@
using System; using System;
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;
@ -537,28 +538,21 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
if (Sse41.IsSupported) if (Sse41.IsSupported)
{ {
#pragma warning disable SA1503 // Braces should not be omitted #pragma warning disable SA1503 // Braces should not be omitted
fixed (ushort* mtxIqPtr = mtx.IQ)
fixed (ushort* mtxQPtr = mtx.Q)
fixed (uint* biasQPtr = mtx.Bias)
fixed (short* sharpenPtr = mtx.Sharpen)
fixed (short* inputPtr = input)
fixed (short* outputPtr = output)
{
// Load all inputs. // Load all inputs.
Vector128<short> input0 = Sse2.LoadVector128(inputPtr); Vector128<short> input0 = Unsafe.As<short, Vector128<short>>(ref MemoryMarshal.GetReference(input));
Vector128<short> input8 = Sse2.LoadVector128(inputPtr + 8); Vector128<short> input8 = Unsafe.As<short, Vector128<short>>(ref MemoryMarshal.GetReference(input.Slice(8, 8)));
Vector128<ushort> iq0 = Sse2.LoadVector128(mtxIqPtr); Vector128<ushort> iq0 = Unsafe.As<ushort, Vector128<ushort>>(ref MemoryMarshal.GetReference(mtx.IQ.AsSpan(0, 8)));
Vector128<ushort> iq8 = Sse2.LoadVector128(mtxIqPtr + 8); Vector128<ushort> iq8 = Unsafe.As<ushort, Vector128<ushort>>(ref MemoryMarshal.GetReference(mtx.IQ.AsSpan(8, 8)));
Vector128<ushort> q0 = Sse2.LoadVector128(mtxQPtr); Vector128<ushort> q0 = Unsafe.As<ushort, Vector128<ushort>>(ref MemoryMarshal.GetReference(mtx.Q.AsSpan(0, 8)));
Vector128<ushort> q8 = Sse2.LoadVector128(mtxQPtr + 8); Vector128<ushort> q8 = Unsafe.As<ushort, Vector128<ushort>>(ref MemoryMarshal.GetReference(mtx.Q.AsSpan(8, 8)));
// coeff = abs(in) // coeff = abs(in)
Vector128<ushort> coeff0 = Ssse3.Abs(input0); Vector128<ushort> coeff0 = Ssse3.Abs(input0);
Vector128<ushort> coeff8 = Ssse3.Abs(input8); Vector128<ushort> coeff8 = Ssse3.Abs(input8);
// coeff = abs(in) + sharpen // coeff = abs(in) + sharpen
Vector128<short> sharpen0 = Sse2.LoadVector128(sharpenPtr); Vector128<short> sharpen0 = Unsafe.As<short, Vector128<short>>(ref MemoryMarshal.GetReference(mtx.Sharpen.AsSpan(0, 8)));
Vector128<short> sharpen8 = Sse2.LoadVector128(sharpenPtr + 8); Vector128<short> sharpen8 = Unsafe.As<short, Vector128<short>>(ref MemoryMarshal.GetReference(mtx.Sharpen.AsSpan(8, 8)));
Sse2.Add(coeff0.AsInt16(), sharpen0); Sse2.Add(coeff0.AsInt16(), sharpen0);
Sse2.Add(coeff8.AsInt16(), sharpen8); Sse2.Add(coeff8.AsInt16(), sharpen8);
@ -575,10 +569,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
Vector128<ushort> out12 = Sse2.UnpackHigh(coeffiQ8L, coeffiQ8H); Vector128<ushort> out12 = Sse2.UnpackHigh(coeffiQ8L, coeffiQ8H);
// out = (coeff * iQ + B) // out = (coeff * iQ + B)
Vector128<uint> bias00 = Sse2.LoadVector128(biasQPtr); Vector128<uint> bias00 = Unsafe.As<uint, Vector128<uint>>(ref MemoryMarshal.GetReference(mtx.Bias.AsSpan(0, 4)));
Vector128<uint> bias04 = Sse2.LoadVector128(biasQPtr + 4); Vector128<uint> bias04 = Unsafe.As<uint, Vector128<uint>>(ref MemoryMarshal.GetReference(mtx.Bias.AsSpan(4, 4)));
Vector128<uint> bias08 = Sse2.LoadVector128(biasQPtr + 8); Vector128<uint> bias08 = Unsafe.As<uint, Vector128<uint>>(ref MemoryMarshal.GetReference(mtx.Bias.AsSpan(8, 4)));
Vector128<uint> bias12 = Sse2.LoadVector128(biasQPtr + 12); Vector128<uint> bias12 = Unsafe.As<uint, Vector128<uint>>(ref MemoryMarshal.GetReference(mtx.Bias.AsSpan(12, 4)));
out00 = Sse2.Add(out00.AsInt32(), bias00.AsInt32()).AsUInt16(); out00 = Sse2.Add(out00.AsInt32(), bias00.AsInt32()).AsUInt16();
out04 = Sse2.Add(out04.AsInt32(), bias04.AsInt32()).AsUInt16(); out04 = Sse2.Add(out04.AsInt32(), bias04.AsInt32()).AsUInt16();
out08 = Sse2.Add(out08.AsInt32(), bias08.AsInt32()).AsUInt16(); out08 = Sse2.Add(out08.AsInt32(), bias08.AsInt32()).AsUInt16();
@ -606,9 +600,12 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
input0 = Sse2.MultiplyLow(out0, q0.AsInt16()); input0 = Sse2.MultiplyLow(out0, q0.AsInt16());
input8 = Sse2.MultiplyLow(out8, q8.AsInt16()); input8 = Sse2.MultiplyLow(out8, q8.AsInt16());
fixed (short* inputPtr = input)
{
// in = out * Q // in = out * Q
Sse2.Store(inputPtr, input0); Sse2.Store(inputPtr, input0);
Sse2.Store(inputPtr + 8, input8); Sse2.Store(inputPtr + 8, input8);
}
// zigzag the output before storing it. The re-ordering is: // zigzag the output before storing it. The re-ordering is:
// 0 1 2 3 4 5 6 7 | 8 9 10 11 12 13 14 15 // 0 1 2 3 4 5 6 7 | 8 9 10 11 12 13 14 15
@ -622,14 +619,18 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
Vector128<byte> tmp8 = Ssse3.Shuffle(out8.AsByte(), Cst8); // extract #8 Vector128<byte> tmp8 = Ssse3.Shuffle(out8.AsByte(), Cst8); // extract #8
Vector128<byte> outZ0 = Sse2.Or(tmpLo, tmp8); Vector128<byte> outZ0 = Sse2.Or(tmpLo, tmp8);
Vector128<byte> outZ8 = Sse2.Or(tmpHi, tmp7); Vector128<byte> outZ8 = Sse2.Or(tmpHi, tmp7);
fixed (short* outputPtr = output)
{
Sse2.Store(outputPtr, outZ0.AsInt16()); Sse2.Store(outputPtr, outZ0.AsInt16());
Sse2.Store(outputPtr + 8, outZ8.AsInt16()); Sse2.Store(outputPtr + 8, outZ8.AsInt16());
}
Vector128<sbyte> packedOutput = Sse2.PackSignedSaturate(outZ0.AsInt16(), outZ8.AsInt16()); Vector128<sbyte> packedOutput = Sse2.PackSignedSaturate(outZ0.AsInt16(), outZ8.AsInt16());
// Detect if all 'out' values are zeroes or not. // Detect if all 'out' values are zeroes or not.
Vector128<sbyte> cmpeq = Sse2.CompareEqual(packedOutput, Vector128<sbyte>.Zero); Vector128<sbyte> cmpeq = Sse2.CompareEqual(packedOutput, Vector128<sbyte>.Zero);
return Sse2.MoveMask(cmpeq) != 0xffff ? 1 : 0; return Sse2.MoveMask(cmpeq) != 0xffff ? 1 : 0;
}
#pragma warning restore SA1503 // Braces should not be omitted #pragma warning restore SA1503 // Braces should not be omitted
} }
else else

Loading…
Cancel
Save