From a75d6e6e7d28747f361a90e5a06421ee8d22173b Mon Sep 17 00:00:00 2001 From: Dmitry Pentin Date: Tue, 24 Aug 2021 14:34:55 +0300 Subject: [PATCH] Added sse/avx vector fields to the Block8x8, small QOL fixes --- .../Formats/Jpeg/Components/Block8x8.cs | 57 ++++++++++++++----- .../Formats/Jpeg/Components/Block8x8F.cs | 13 +---- 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs index d61a3c6fda..79b26a0421 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs @@ -2,17 +2,18 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; using System.Text; namespace SixLabors.ImageSharp.Formats.Jpeg.Components { /// - /// Represents a Jpeg block with coefficients. + /// 8x8 coefficients matrix of type. /// // ReSharper disable once InconsistentNaming + [StructLayout(LayoutKind.Explicit)] internal unsafe struct Block8x8 : IEquatable { /// @@ -20,13 +21,44 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// public const int Size = 64; +#pragma warning disable IDE0051 // Remove unused private member /// - /// A fixed size buffer holding the values. - /// See: - /// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/unsafe-code-pointers/fixed-size-buffers - /// + /// A placeholder buffer so the actual struct occupies exactly 64 * 2 bytes. /// + /// + /// This is not used directly in the code. + /// + [FieldOffset(0)] private fixed short data[Size]; +#pragma warning restore IDE0051 + +#if SUPPORTS_RUNTIME_INTRINSICS + [FieldOffset(0)] + public Vector128 V0; + [FieldOffset(16)] + public Vector128 V1; + [FieldOffset(32)] + public Vector128 V2; + [FieldOffset(48)] + public Vector128 V3; + [FieldOffset(64)] + public Vector128 V4; + [FieldOffset(80)] + public Vector128 V5; + [FieldOffset(96)] + public Vector128 V6; + [FieldOffset(112)] + public Vector128 V7; + + [FieldOffset(0)] + public Vector256 V01; + [FieldOffset(32)] + public Vector256 V23; + [FieldOffset(64)] + public Vector256 V45; + [FieldOffset(96)] + public Vector256 V67; +#endif /// /// Gets or sets a value at the given index @@ -38,7 +70,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - GuardBlockIndex(idx); + DebugGuard.MustBeBetweenOrEqualTo(idx, 0, Size - 1, nameof(idx)); + ref short selfRef = ref Unsafe.As(ref this); return Unsafe.Add(ref selfRef, idx); } @@ -46,7 +79,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components [MethodImpl(MethodImplOptions.AggressiveInlining)] set { - GuardBlockIndex(idx); + DebugGuard.MustBeBetweenOrEqualTo(idx, 0, Size - 1, nameof(idx)); + ref short selfRef = ref Unsafe.As(ref this); Unsafe.Add(ref selfRef, idx) = value; } @@ -204,13 +238,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } } - [Conditional("DEBUG")] - private static void GuardBlockIndex(int idx) - { - DebugGuard.MustBeLessThan(idx, Size, nameof(idx)); - DebugGuard.MustBeGreaterThanOrEqualTo(idx, 0, nameof(idx)); - } - /// public override string ToString() { diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs index d55dfced72..a11b807bb4 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs @@ -16,7 +16,7 @@ using System.Text; namespace SixLabors.ImageSharp.Formats.Jpeg.Components { /// - /// Represents a Jpeg block with coefficients. + /// 8x8 coefficients matrix of type. /// [StructLayout(LayoutKind.Explicit)] internal partial struct Block8x8F : IEquatable @@ -102,7 +102,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - GuardBlockIndex(idx); + DebugGuard.MustBeBetweenOrEqualTo(idx, 0, Size - 1, nameof(idx)); ref float selfRef = ref Unsafe.As(ref this); return Unsafe.Add(ref selfRef, idx); } @@ -110,7 +110,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components [MethodImpl(MethodImplOptions.AggressiveInlining)] set { - GuardBlockIndex(idx); + DebugGuard.MustBeBetweenOrEqualTo(idx, 0, Size - 1, nameof(idx)); ref float selfRef = ref Unsafe.As(ref this); Unsafe.Add(ref selfRef, idx) = value; } @@ -672,13 +672,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components return row.FastRound(); } - [Conditional("DEBUG")] - private static void GuardBlockIndex(int idx) - { - DebugGuard.MustBeLessThan(idx, Size, nameof(idx)); - DebugGuard.MustBeGreaterThanOrEqualTo(idx, 0, nameof(idx)); - } - /// /// Transpose the block into the destination block. ///