Somewhat improve sprite processing (#3587)

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
This commit is contained in:
Leon Friedrich
2022-12-26 12:48:08 +13:00
committed by GitHub
parent b9f7733c67
commit 27e0c22fe2
13 changed files with 382 additions and 135 deletions

View File

@@ -104,13 +104,12 @@ namespace Robust.Shared.Maths
// No calculation necessery when theta is zero
if (Theta == 0) return vec;
var (x, y) = vec;
var cos = Math.Cos(Theta);
var sin = Math.Sin(Theta);
var dx = cos * x - sin * y;
var dy = sin * x + cos * y;
var cos = MathF.Cos((float)Theta);
var sin = MathF.Sin((float)Theta);
var dx = cos * vec.X - sin * vec.Y;
var dy = sin * vec.X + cos * vec.Y;
return new Vector2((float)dx, (float)dy);
return new Vector2(dx, dy);
}
public bool EqualsApprox(Angle other, double tolerance)

View File

@@ -80,12 +80,23 @@ namespace Robust.Shared.Maths
allX = modX + originX;
allY = modY + originY;
var l = SimdHelpers.MinHorizontal128(allX);
var b = SimdHelpers.MinHorizontal128(allY);
var r = SimdHelpers.MaxHorizontal128(allX);
var t = SimdHelpers.MaxHorizontal128(allY);
// lrlr = vector containing [left right left right]
Vector128<float> lbrt;
var lbrt = SimdHelpers.MergeRows128(l, b, r, t);
if (Sse.IsSupported)
{
var lrlr = SimdHelpers.MinMaxHorizontalSse(allX);
var btbt = SimdHelpers.MinMaxHorizontalSse(allY);
lbrt = Sse.UnpackLow(lrlr, btbt);
}
else
{
var l = SimdHelpers.MinHorizontal128(allX);
var b = SimdHelpers.MinHorizontal128(allY);
var r = SimdHelpers.MaxHorizontal128(allX);
var t = SimdHelpers.MaxHorizontal128(allY);
lbrt = SimdHelpers.MergeRows128(l, b, r, t);
}
return Unsafe.As<Vector128<float>, Box2>(ref lbrt);
}

View File

@@ -9,6 +9,34 @@ namespace Robust.Shared.Maths
/// </summary>
internal static class SimdHelpers
{
/// <returns>A vector with the horizontal minimum and maximum values arranged as { min max min max} .</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> MinMaxHorizontalSse(Vector128<float> input)
{
var tmp = Sse.Shuffle(input, input, 0b00_01_10_11);
var min = Sse.Min(tmp, input);
var max = Sse.Max(tmp, input);
tmp = Sse.Shuffle(min, max, 0b01_00_00_01);
min = Sse.Min(tmp, min);
max = Sse.Max(tmp, max);
tmp = Sse.MoveScalar(max, min); // no generic Vector128 equivalent :(
return Sse.Shuffle(tmp, tmp, 0b11_00_11_00);
}
/// <returns>A vector with the horizontal minimum and maximum values arranged as { max min max min} .</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> MaxMinHorizontalSse(Vector128<float> input)
{
var tmp = Sse.Shuffle(input, input, 0b00_01_10_11);
var min = Sse.Min(tmp, input);
var max = Sse.Max(tmp, input);
tmp = Sse.Shuffle(min, max, 0b01_00_00_01);
min = Sse.Min(tmp, min);
max = Sse.Max(tmp, max);
tmp = Sse.MoveScalar(max, min); // no generic Vector128 equivalent :(
return Sse.Shuffle(tmp, tmp, 0b00_11_00_11);
}
/// <returns>The min value is broadcast to the whole vector.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> MinHorizontal128(Vector128<float> v)