Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,17 @@ internal static void BulkConvertByteToNormalizedFloat(ReadOnlySpan<byte> source,
var magicInt = new Vector<uint>(1191182336); // reinterpreted value of 32768.0f
var mask = new Vector<uint>(255);

ref Octet.OfByte sourceBase = ref Unsafe.As<byte, Octet.OfByte>(ref MemoryMarshal.GetReference(source));
ref Octet.OfUInt32 destBaseAsWideOctet = ref Unsafe.As<float, Octet.OfUInt32>(ref MemoryMarshal.GetReference(dest));
ref Octet<byte> sourceBase = ref Unsafe.As<byte, Octet<byte>>(ref MemoryMarshal.GetReference(source));
ref Octet<uint> destBaseAsWideOctet = ref Unsafe.As<float, Octet<uint>>(ref MemoryMarshal.GetReference(dest));

ref Vector<float> destBaseAsFloat = ref Unsafe.As<Octet.OfUInt32, Vector<float>>(ref destBaseAsWideOctet);
ref Vector<float> destBaseAsFloat = ref Unsafe.As<Octet<uint>, Vector<float>>(ref destBaseAsWideOctet);

int n = dest.Length / 8;

for (int i = 0; i < n; i++)
{
ref Octet.OfByte s = ref Unsafe.Add(ref sourceBase, i);
ref Octet.OfUInt32 d = ref Unsafe.Add(ref destBaseAsWideOctet, i);
ref Octet<byte> s = ref Unsafe.Add(ref sourceBase, i);
ref Octet<uint> d = ref Unsafe.Add(ref destBaseAsWideOctet, i);
d.LoadFrom(ref s);
}

Expand Down Expand Up @@ -137,17 +137,17 @@ internal static void BulkConvertNormalizedFloatToByteClampOverflows(ReadOnlySpan
}

ref Vector<float> srcBase = ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(source));
ref Octet.OfByte destBase = ref Unsafe.As<byte, Octet.OfByte>(ref MemoryMarshal.GetReference(dest));
ref Octet<byte> destBase = ref Unsafe.As<byte, Octet<byte>>(ref MemoryMarshal.GetReference(dest));
int n = source.Length / 8;

var magick = new Vector<float>(32768.0f);
var scale = new Vector<float>(255f) / new Vector<float>(256f);

// need to copy to a temporary struct, because
// SimdUtils.Octet.OfUInt32 temp = Unsafe.As<Vector<float>, SimdUtils.Octet.OfUInt32>(ref x)
// SimdUtils.Octet<uint> temp = Unsafe.As<Vector<float>, SimdUtils.Octet<uint>>(ref x)
// does not work. TODO: This might be a CoreClr bug, need to ask/report
var temp = default(Octet.OfUInt32);
ref Vector<float> tempRef = ref Unsafe.As<Octet.OfUInt32, Vector<float>>(ref temp);
var temp = default(Octet<uint>);
ref Vector<float> tempRef = ref Unsafe.As<Octet<uint>, Vector<float>>(ref temp);

for (int i = 0; i < n; i++)
{
Expand All @@ -161,7 +161,7 @@ internal static void BulkConvertNormalizedFloatToByteClampOverflows(ReadOnlySpan
x = (x * scale) + magick;
tempRef = x;

ref Octet.OfByte d = ref Unsafe.Add(ref destBase, i);
ref Octet<byte> d = ref Unsafe.Add(ref destBase, i);
d.LoadFrom(ref temp);
}
}
Expand All @@ -186,17 +186,17 @@ internal static void BulkConvertNormalizedFloatToByte(ReadOnlySpan<float> source
}

ref Vector<float> srcBase = ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(source));
ref Octet.OfByte destBase = ref Unsafe.As<byte, Octet.OfByte>(ref MemoryMarshal.GetReference(dest));
ref Octet<byte> destBase = ref Unsafe.As<byte, Octet<byte>>(ref MemoryMarshal.GetReference(dest));
int n = source.Length / 8;

var magick = new Vector<float>(32768.0f);
var scale = new Vector<float>(255f) / new Vector<float>(256f);

// need to copy to a temporary struct, because
// SimdUtils.Octet.OfUInt32 temp = Unsafe.As<Vector<float>, SimdUtils.Octet.OfUInt32>(ref x)
// SimdUtils.Octet<uint> temp = Unsafe.As<Vector<float>, SimdUtils.Octet<uint>>(ref x)
// does not work. TODO: This might be a CoreClr bug, need to ask/report
var temp = default(Octet.OfUInt32);
ref Vector<float> tempRef = ref Unsafe.As<Octet.OfUInt32, Vector<float>>(ref temp);
var temp = default(Octet<uint>);
ref Vector<float> tempRef = ref Unsafe.As<Octet<uint>, Vector<float>>(ref temp);

for (int i = 0; i < n; i++)
{
Expand All @@ -207,7 +207,7 @@ internal static void BulkConvertNormalizedFloatToByte(ReadOnlySpan<float> source
x = (x * scale) + magick;
tempRef = x;

ref Octet.OfByte d = ref Unsafe.Add(ref destBase, i);
ref Octet<byte> d = ref Unsafe.Add(ref destBase, i);
d.LoadFrom(ref temp);
}
}
Expand Down
112 changes: 0 additions & 112 deletions src/ImageSharp/Common/Tuples/Octet.cs

This file was deleted.

73 changes: 73 additions & 0 deletions src/ImageSharp/Common/Tuples/Octet{T}.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace SixLabors.ImageSharp.Tuples
{
/// <summary>
/// Contains 8 element value tuples of various types.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct Octet<T>
where T : unmanaged
{
public T V0;
public T V1;
public T V2;
public T V3;
public T V4;
public T V5;
public T V6;
public T V7;

/// <inheritdoc/>
public override readonly string ToString()
{
return $"Octet<{typeof(T)}>({this.V0},{this.V1},{this.V2},{this.V3},{this.V4},{this.V5},{this.V6},{this.V7})";
}
}

/// <summary>
/// Extension methods for the <see cref="Octet{T}"/> type.
/// </summary>
internal static class OctetExtensions
{
/// <summary>
/// Loads the fields in a target <see cref="Octet{T}"/> of <see cref="uint"/> from one of <see cref="byte"/> type.
/// </summary>
/// <param name="destination">The target <see cref="Octet{T}"/> of <see cref="uint"/> instance.</param>
/// <param name="source">The source <see cref="Octet{T}"/> of <see cref="byte"/> instance.</param>
[MethodImpl(InliningOptions.ShortMethod)]
public static void LoadFrom(ref this Octet<uint> destination, ref Octet<byte> source)
{
destination.V0 = source.V0;
destination.V1 = source.V1;
destination.V2 = source.V2;
destination.V3 = source.V3;
destination.V4 = source.V4;
destination.V5 = source.V5;
destination.V6 = source.V6;
destination.V7 = source.V7;
}

/// <summary>
/// Loads the fields in a target <see cref="Octet{T}"/> of <see cref="byte"/> from one of <see cref="uint"/> type.
/// </summary>
/// <param name="destination">The target <see cref="Octet{T}"/> of <see cref="byte"/> instance.</param>
/// <param name="source">The source <see cref="Octet{T}"/> of <see cref="uint"/> instance.</param>
[MethodImpl(InliningOptions.ShortMethod)]
public static void LoadFrom(ref this Octet<byte> destination, ref Octet<uint> source)
{
destination.V0 = (byte)source.V0;
destination.V1 = (byte)source.V1;
destination.V2 = (byte)source.V2;
destination.V3 = (byte)source.V3;
destination.V4 = (byte)source.V4;
destination.V5 = (byte)source.V5;
destination.V6 = (byte)source.V6;
destination.V7 = (byte)source.V7;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ public void Bitops_SingleTuple()
// [Benchmark]
public void Bitops_Simd()
{
ref Octet.OfUInt32 sBase = ref Unsafe.As<Rgba32, Octet.OfUInt32>(ref this.source[0]);
ref Octet.OfUInt32 dBase = ref Unsafe.As<Bgra32, Octet.OfUInt32>(ref this.dest[0]);
ref Octet<uint> sBase = ref Unsafe.As<Rgba32, Octet<uint>>(ref this.source[0]);
ref Octet<uint> dBase = ref Unsafe.As<Bgra32, Octet<uint>>(ref this.dest[0]);

for (int i = 0; i < this.Count / 8; i++)
{
Expand All @@ -257,9 +257,9 @@ private struct C
#pragma warning restore SA1132 // Do not combine fields

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void BitopsSimdImpl(ref Octet.OfUInt32 s, ref Octet.OfUInt32 d)
private static void BitopsSimdImpl(ref Octet<uint> s, ref Octet<uint> d)
{
Vector<uint> sVec = Unsafe.As<Octet.OfUInt32, Vector<uint>>(ref s);
Vector<uint> sVec = Unsafe.As<Octet<uint>, Vector<uint>>(ref s);
var aMask = new Vector<uint>(0xFF00FF00);
var bMask = new Vector<uint>(0x00FF00FF);

Expand All @@ -282,7 +282,7 @@ private static void BitopsSimdImpl(ref Octet.OfUInt32 s, ref Octet.OfUInt32 d)
Vector<uint> cc = Unsafe.As<C, Vector<uint>>(ref c);
Vector<uint> dd = aa + cc;

d = Unsafe.As<Vector<uint>, Octet.OfUInt32>(ref dd);
d = Unsafe.As<Vector<uint>, Octet<uint>>(ref dd);
}

// [Benchmark]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public void Standard()
{
const int N = Count / 8;

ref Octet.OfByte sBase = ref Unsafe.As<byte, Octet.OfByte>(ref this.source[0]);
ref Octet.OfUInt32 dBase = ref Unsafe.As<uint, Octet.OfUInt32>(ref this.dest[0]);
ref Octet<byte> sBase = ref Unsafe.As<byte, Octet<byte>>(ref this.source[0]);
ref Octet<uint> dBase = ref Unsafe.As<uint, Octet<uint>>(ref this.dest[0]);

for (int i = 0; i < N; i++)
{
Expand Down