mirror of https://github.com/SixLabors/ImageSharp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
45 lines
1.7 KiB
45 lines
1.7 KiB
// Copyright (c) Six Labors and contributors.
|
|
// Licensed under the Apache License, Version 2.0.
|
|
|
|
using System;
|
|
using System.Numerics;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
namespace SixLabors.ImageSharp
|
|
{
|
|
/// <summary>
|
|
/// Various extension and utility methods for <see cref="Vector4"/> and <see cref="Vector{T}"/> utilizing SIMD capabilities
|
|
/// </summary>
|
|
internal static class SimdUtils
|
|
{
|
|
/// <summary>
|
|
/// Transform all scalars in 'v' in a way that converting them to <see cref="int"/> would have rounding semantics.
|
|
/// </summary>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
internal static Vector4 PseudoRound(this Vector4 v)
|
|
{
|
|
var sign = Vector4.Clamp(v, new Vector4(-1), new Vector4(1));
|
|
|
|
return v + (sign * 0.5f);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Rounds all values in 'v' to the nearest integer following <see cref="MidpointRounding.ToEven"/> semantics.
|
|
/// Source:
|
|
/// <see>
|
|
/// <cref>https://github.com/g-truc/glm/blob/master/glm/simd/common.h#L110</cref>
|
|
/// </see>
|
|
/// </summary>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
internal static Vector<float> FastRound(this Vector<float> x)
|
|
{
|
|
Vector<int> magic0 = new Vector<int>(int.MinValue); // 0x80000000
|
|
Vector<float> sgn0 = Vector.AsVectorSingle(magic0);
|
|
Vector<float> and0 = Vector.BitwiseAnd(sgn0, x);
|
|
Vector<float> or0 = Vector.BitwiseOr(and0, new Vector<float>(8388608.0f));
|
|
Vector<float> add0 = Vector.Add(x, or0);
|
|
Vector<float> sub0 = Vector.Subtract(add0, or0);
|
|
return sub0;
|
|
}
|
|
}
|
|
}
|