initial commit
This commit is contained in:
parent
6715289efe
commit
788c3389af
37645 changed files with 2526849 additions and 80 deletions
|
@ -0,0 +1,453 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using NUnit.Framework;
|
||||
|
||||
#if BURST_INTERNAL
|
||||
using System.Text;
|
||||
using Unity.Burst.Intrinsics;
|
||||
using Unity.Mathematics;
|
||||
#endif
|
||||
|
||||
namespace Burst.Compiler.IL.Tests.Helpers
|
||||
{
|
||||
internal static class AssertHelper
|
||||
{
|
||||
#if BURST_INTERNAL
|
||||
// Workaround for Mono broken Equals() on v64/v128/v256
|
||||
private static bool AreVectorsEqual(v64 a, v64 b)
|
||||
{
|
||||
return a.SLong0 == b.SLong0;
|
||||
}
|
||||
|
||||
private static bool AreVectorsEqual(v128 a, v128 b)
|
||||
{
|
||||
return a.SLong0 == b.SLong0 && a.SLong1 == b.SLong1;
|
||||
}
|
||||
|
||||
private static bool AreVectorsEqual(v256 a, v256 b)
|
||||
{
|
||||
return AreVectorsEqual(a.Lo128, b.Lo128) && AreVectorsEqual(a.Hi128, b.Hi128);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// AreEqual handling specially precision for float and intrinsic vector types
|
||||
/// </summary>
|
||||
/// <param name="expected">The expected result</param>
|
||||
/// <param name="result">the actual result</param>
|
||||
public static void AreEqual(object expected, object result, int maxUlp)
|
||||
{
|
||||
if (expected is float && result is float)
|
||||
{
|
||||
var expectedF = (float)expected;
|
||||
var resultF = (float)result;
|
||||
Assert.True(NearEqualFloat(expectedF, resultF, maxUlp, out var ulp), $"Expected: {expectedF} != Result: {resultF}, ULPs: {ulp}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is double && result is double)
|
||||
{
|
||||
var expectedF = (double)expected;
|
||||
var resultF = (double)result;
|
||||
Assert.True(NearEqualDouble(expectedF, resultF, maxUlp, out var ulp), $"Expected: {expectedF} != Result: {resultF}, ULPs: {ulp}");
|
||||
return;
|
||||
}
|
||||
|
||||
#if BURST_INTERNAL
|
||||
if (expected is float2 && result is float2)
|
||||
{
|
||||
var expectedF = (float2)expected;
|
||||
var resultF = (float2)result;
|
||||
Assert.True(NearEqualFloat(expectedF.x, resultF.x, maxUlp, out var ulp), $"Expected: {expectedF}.x != Result: {resultF}.x, ULPs: {ulp}");
|
||||
Assert.True(NearEqualFloat(expectedF.y, resultF.y, maxUlp, out ulp), $"Expected: {expectedF}.y != Result: {resultF}.y, ULPs: {ulp}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is float3 && result is float3)
|
||||
{
|
||||
var expectedF = (float3)expected;
|
||||
var resultF = (float3)result;
|
||||
Assert.True(NearEqualFloat(expectedF.x, resultF.x, maxUlp, out var ulp), $"Expected: {expectedF}.x != Result: {resultF}.x, ULPs: {ulp}");
|
||||
Assert.True(NearEqualFloat(expectedF.y, resultF.y, maxUlp, out ulp), $"Expected: {expectedF}.y != Result: {resultF}.y, ULPs: {ulp}");
|
||||
Assert.True(NearEqualFloat(expectedF.z, resultF.z, maxUlp, out ulp), $"Expected: {expectedF}.z != Result: {resultF}.z, ULPs: {ulp}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is float4 && result is float4)
|
||||
{
|
||||
var expectedF = (float4)expected;
|
||||
var resultF = (float4)result;
|
||||
Assert.True(NearEqualFloat(expectedF.x, resultF.x, maxUlp, out var ulp), $"Expected: {expectedF}.x != Result: {resultF}.x, ULPs: {ulp}");
|
||||
Assert.True(NearEqualFloat(expectedF.y, resultF.y, maxUlp, out ulp), $"Expected: {expectedF}.y != Result: {resultF}.y, ULPs: {ulp}");
|
||||
Assert.True(NearEqualFloat(expectedF.z, resultF.z, maxUlp, out ulp), $"Expected: {expectedF}.z != Result: {resultF}.z, ULPs: {ulp}");
|
||||
Assert.True(NearEqualFloat(expectedF.w, resultF.w, maxUlp, out ulp), $"Expected: {expectedF}.w != Result: {resultF}.w, ULPs: {ulp}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is float4x2 && result is float4x2)
|
||||
{
|
||||
var expectedF = (float4x2)expected;
|
||||
var resultF = (float4x2)result;
|
||||
Assert.True(NearEqualFloat(expectedF.c0.x, resultF.c0.x, maxUlp, out var ulp), $"Expected: {expectedF}.c0.x != Result: {resultF}.c0.x, ULPs: {ulp}");
|
||||
Assert.True(NearEqualFloat(expectedF.c0.y, resultF.c0.y, maxUlp, out ulp), $"Expected: {expectedF}.c0.y != Result: {resultF}.c0.y, ULPs: {ulp}");
|
||||
Assert.True(NearEqualFloat(expectedF.c0.z, resultF.c0.z, maxUlp, out ulp), $"Expected: {expectedF}.c0.z != Result: {resultF}.c0.z, ULPs: {ulp}");
|
||||
Assert.True(NearEqualFloat(expectedF.c0.w, resultF.c0.w, maxUlp, out ulp), $"Expected: {expectedF}.c0.w != Result: {resultF}.c0.w, ULPs: {ulp}");
|
||||
Assert.True(NearEqualFloat(expectedF.c1.x, resultF.c1.x, maxUlp, out ulp), $"Expected: {expectedF}.c1.x != Result: {resultF}.c1.x, ULPs: {ulp}");
|
||||
Assert.True(NearEqualFloat(expectedF.c1.y, resultF.c1.y, maxUlp, out ulp), $"Expected: {expectedF}.c1.y != Result: {resultF}.c1.y, ULPs: {ulp}");
|
||||
Assert.True(NearEqualFloat(expectedF.c1.z, resultF.c1.z, maxUlp, out ulp), $"Expected: {expectedF}.c1.z != Result: {resultF}.c1.z, ULPs: {ulp}");
|
||||
Assert.True(NearEqualFloat(expectedF.c1.w, resultF.c1.w, maxUlp, out ulp), $"Expected: {expectedF}.c1.w != Result: {resultF}.c1.w, ULPs: {ulp}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is double2 && result is double2)
|
||||
{
|
||||
var expectedF = (double2)expected;
|
||||
var resultF = (double2)result;
|
||||
Assert.True(NearEqualDouble(expectedF.x, resultF.x, maxUlp, out var ulp), $"Expected: {expectedF}.x != Result: {resultF}.x, ULPs: {ulp}");
|
||||
Assert.True(NearEqualDouble(expectedF.y, resultF.y, maxUlp, out ulp), $"Expected: {expectedF}.y != Result: {resultF}.y, ULPs: {ulp}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is double3 && result is double3)
|
||||
{
|
||||
var expectedF = (double3)expected;
|
||||
var resultF = (double3)result;
|
||||
Assert.True(NearEqualDouble(expectedF.x, resultF.x, maxUlp, out var ulp), $"Expected: {expectedF}.x != Result: {resultF}.x, ULPs: {ulp}");
|
||||
Assert.True(NearEqualDouble(expectedF.y, resultF.y, maxUlp, out ulp), $"Expected: {expectedF}.y != Result: {resultF}.y, ULPs: {ulp}");
|
||||
Assert.True(NearEqualDouble(expectedF.z, resultF.z, maxUlp, out ulp), $"Expected: {expectedF}.z != Result: {resultF}.z, ULPs: {ulp}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is double4 && result is double4)
|
||||
{
|
||||
var expectedF = (double4)expected;
|
||||
var resultF = (double4)result;
|
||||
Assert.True(NearEqualDouble(expectedF.x, resultF.x, maxUlp, out var ulp), $"Expected: {expectedF}.x != Result: {resultF}.x, ULPs: {ulp}");
|
||||
Assert.True(NearEqualDouble(expectedF.y, resultF.y, maxUlp, out ulp), $"Expected: {expectedF}.y != Result: {resultF}.y, ULPs: {ulp}");
|
||||
Assert.True(NearEqualDouble(expectedF.z, resultF.z, maxUlp, out ulp), $"Expected: {expectedF}.z != Result: {resultF}.z, ULPs: {ulp}");
|
||||
Assert.True(NearEqualDouble(expectedF.w, resultF.w, maxUlp, out ulp), $"Expected: {expectedF}.w != Result: {resultF}.w, ULPs: {ulp}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is v64 && result is v64)
|
||||
{
|
||||
if (!AreVectorsEqual((v64)expected, (v64)result))
|
||||
{
|
||||
Assert.Fail(FormatVectorFailure64((v64)expected, (v64)result));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is v128 && result is v128)
|
||||
{
|
||||
if (!AreVectorsEqual((v128)expected, (v128)result))
|
||||
{
|
||||
Assert.Fail(FormatVectorFailure128((v128)expected, (v128)result));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is v64x2 && result is v64x2)
|
||||
{
|
||||
if (!AreVectorsEqual(((v64x2)expected).v64_0, ((v64x2)result).v64_0))
|
||||
{
|
||||
Assert.Fail("First component of v64x2 differs: " + FormatVectorFailure64(((v64x2)expected).v64_0, ((v64x2)result).v64_0));
|
||||
}
|
||||
if (!AreVectorsEqual(((v64x2)expected).v64_1, ((v64x2)result).v64_1))
|
||||
{
|
||||
Assert.Fail("Second component of v64x2 differs: " + FormatVectorFailure64(((v64x2)expected).v64_1, ((v64x2)result).v64_1));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is v64x3 && result is v64x3)
|
||||
{
|
||||
if (!AreVectorsEqual(((v64x3)expected).v64_0, ((v64x3)result).v64_0))
|
||||
{
|
||||
Assert.Fail("First component of v64x3 differs: " + FormatVectorFailure64(((v64x3)expected).v64_0, ((v64x3)result).v64_0));
|
||||
}
|
||||
if (!AreVectorsEqual(((v64x3)expected).v64_1, ((v64x3)result).v64_1))
|
||||
{
|
||||
Assert.Fail("Second component of v64x3 differs: " + FormatVectorFailure64(((v64x3)expected).v64_1, ((v64x3)result).v64_1));
|
||||
}
|
||||
if (!AreVectorsEqual(((v64x3)expected).v64_2, ((v64x3)result).v64_2))
|
||||
{
|
||||
Assert.Fail("Third component of v64x3 differs: " + FormatVectorFailure64(((v64x3)expected).v64_2, ((v64x3)result).v64_2));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is v64x4 && result is v64x4)
|
||||
{
|
||||
if (!AreVectorsEqual(((v64x4)expected).v64_0, ((v64x4)result).v64_0))
|
||||
{
|
||||
Assert.Fail("First component of v64x4 differs: " + FormatVectorFailure64(((v64x4)expected).v64_0, ((v64x4)result).v64_0));
|
||||
}
|
||||
if (!AreVectorsEqual(((v64x4)expected).v64_1, ((v64x4)result).v64_1))
|
||||
{
|
||||
Assert.Fail("Second component of v64x4 differs: " + FormatVectorFailure64(((v64x4)expected).v64_1, ((v64x4)result).v64_1));
|
||||
}
|
||||
if (!AreVectorsEqual(((v64x4)expected).v64_2, ((v64x4)result).v64_2))
|
||||
{
|
||||
Assert.Fail("Third component of v64x4 differs: " + FormatVectorFailure64(((v64x4)expected).v64_2, ((v64x4)result).v64_2));
|
||||
}
|
||||
if (!AreVectorsEqual(((v64x4)expected).v64_3, ((v64x4)result).v64_3))
|
||||
{
|
||||
Assert.Fail("Fourth component of v64x4 differs: " + FormatVectorFailure64(((v64x4)expected).v64_3, ((v64x4)result).v64_3));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is v128x2 && result is v128x2)
|
||||
{
|
||||
if (!AreVectorsEqual(((v128x2)expected).v128_0, ((v128x2)result).v128_0))
|
||||
{
|
||||
Assert.Fail("First component of v128x2 differs: " + FormatVectorFailure128(((v128x2)expected).v128_0, ((v128x2)result).v128_0));
|
||||
}
|
||||
if (!AreVectorsEqual(((v128x2)expected).v128_1, ((v128x2)result).v128_1))
|
||||
{
|
||||
Assert.Fail("Second component of v128x2 differs: " + FormatVectorFailure128(((v128x2)expected).v128_1, ((v128x2)result).v128_1));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is v128x3 && result is v128x3)
|
||||
{
|
||||
if (!AreVectorsEqual(((v128x3)expected).v128_0, ((v128x3)result).v128_0))
|
||||
{
|
||||
Assert.Fail("First component of v128x3 differs: " + FormatVectorFailure128(((v128x3)expected).v128_0, ((v128x3)result).v128_0));
|
||||
}
|
||||
if (!AreVectorsEqual(((v128x3)expected).v128_1, ((v128x3)result).v128_1))
|
||||
{
|
||||
Assert.Fail("Second component of v128x3 differs: " + FormatVectorFailure128(((v128x3)expected).v128_1, ((v128x3)result).v128_1));
|
||||
}
|
||||
if (!AreVectorsEqual(((v128x3)expected).v128_2, ((v128x3)result).v128_2))
|
||||
{
|
||||
Assert.Fail("Third component of v128x3 differs: " + FormatVectorFailure128(((v128x3)expected).v128_2, ((v128x3)result).v128_2));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is v128x4 && result is v128x4)
|
||||
{
|
||||
if (!AreVectorsEqual(((v128x4)expected).v128_0, ((v128x4)result).v128_0))
|
||||
{
|
||||
Assert.Fail("First component of v128x4 differs: " + FormatVectorFailure128(((v128x4)expected).v128_0, ((v128x4)result).v128_0));
|
||||
}
|
||||
if (!AreVectorsEqual(((v128x4)expected).v128_1, ((v128x4)result).v128_1))
|
||||
{
|
||||
Assert.Fail("Second component of v128x4 differs: " + FormatVectorFailure128(((v128x4)expected).v128_1, ((v128x4)result).v128_1));
|
||||
}
|
||||
if (!AreVectorsEqual(((v128x4)expected).v128_2, ((v128x4)result).v128_2))
|
||||
{
|
||||
Assert.Fail("Third component of v128x4 differs: " + FormatVectorFailure128(((v128x4)expected).v128_2, ((v128x4)result).v128_2));
|
||||
}
|
||||
if (!AreVectorsEqual(((v128x4)expected).v128_3, ((v128x4)result).v128_3))
|
||||
{
|
||||
Assert.Fail("Fourth component of v128x4 differs: " + FormatVectorFailure128(((v128x4)expected).v128_3, ((v128x4)result).v128_3));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (expected is v256 && result is v256)
|
||||
{
|
||||
if (!AreVectorsEqual((v256)expected, (v256)result))
|
||||
{
|
||||
Assert.Fail(FormatVectorFailure256((v256)expected, (v256)result));
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
Assert.AreEqual(expected, result);
|
||||
}
|
||||
|
||||
#if BURST_INTERNAL
|
||||
private unsafe static string FormatVectorFailure64(v64 expected, v64 result)
|
||||
{
|
||||
var b = new StringBuilder();
|
||||
b.AppendLine("64-bit vectors differ!");
|
||||
b.AppendLine("Expected:");
|
||||
FormatVector(b, (void*)&expected, 8);
|
||||
b.AppendLine();
|
||||
b.AppendLine("But was :");
|
||||
FormatVector(b, (void*)&result, 8);
|
||||
b.AppendLine();
|
||||
return b.ToString();
|
||||
}
|
||||
|
||||
private unsafe static string FormatVectorFailure128(v128 expected, v128 result)
|
||||
{
|
||||
var b = new StringBuilder();
|
||||
b.AppendLine("128-bit vectors differ!");
|
||||
b.AppendLine("Expected:");
|
||||
FormatVector(b, (void*)&expected, 16);
|
||||
b.AppendLine();
|
||||
b.AppendLine("But was :");
|
||||
FormatVector(b, (void*)&result, 16);
|
||||
b.AppendLine();
|
||||
return b.ToString();
|
||||
}
|
||||
|
||||
private unsafe static string FormatVectorFailure256(v256 expected, v256 result)
|
||||
{
|
||||
var b = new StringBuilder();
|
||||
b.AppendLine("256-bit vectors differ!");
|
||||
b.AppendLine("Expected:");
|
||||
FormatVector(b, (void*)&expected, 32);
|
||||
b.AppendLine();
|
||||
b.AppendLine("But was :");
|
||||
FormatVector(b, (void*)&result, 32);
|
||||
b.AppendLine();
|
||||
return b.ToString();
|
||||
}
|
||||
|
||||
private unsafe static void FormatVector(StringBuilder b, void* v, int bytes)
|
||||
{
|
||||
b.Append("Double: ");
|
||||
for (int i = 0; i < bytes / 8; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
b.AppendFormat(" | ");
|
||||
b.AppendFormat("{0:G17}", ((double*)v)[i]);
|
||||
}
|
||||
b.AppendLine();
|
||||
b.Append("Float : ");
|
||||
for (int i = 0; i < bytes / 4; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
b.AppendFormat(" | ");
|
||||
b.AppendFormat("{0:G15}", ((float*)v)[i]);
|
||||
}
|
||||
|
||||
b.AppendLine();
|
||||
b.Append("UInt32: ");
|
||||
for (int i = 0; i < bytes / 4; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
b.AppendFormat(" | ");
|
||||
b.AppendFormat("{0:X8}", ((uint*)v)[i]);
|
||||
}
|
||||
b.AppendLine();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// The value for which all absolute numbers smaller than are considered equal to zero.
|
||||
/// </summary>
|
||||
public const float ZeroTolerance = 4 * float.Epsilon;
|
||||
|
||||
/// <summary>
|
||||
/// The value for which all absolute numbers smaller than are considered equal to zero.
|
||||
/// </summary>
|
||||
public const double ZeroToleranceDouble = 4 * double.Epsilon;
|
||||
|
||||
public static bool NearEqualFloat(float a, float b, int maxUlp, out int ulp)
|
||||
{
|
||||
ulp = 0;
|
||||
if (Math.Abs(a - b) < ZeroTolerance) return true;
|
||||
|
||||
ulp = GetUlpFloatDistance(a, b);
|
||||
return ulp <= maxUlp;
|
||||
}
|
||||
|
||||
public static unsafe int GetUlpFloatDistance(float a, float b)
|
||||
{
|
||||
// Save work if the floats are equal.
|
||||
// Also handles +0 == -0
|
||||
if (a == b)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (float.IsNaN(a) && float.IsNaN(b))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (float.IsInfinity(a) && float.IsInfinity(b))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aInt = *(int*)&a;
|
||||
int bInt = *(int*)&b;
|
||||
|
||||
if ((aInt < 0) != (bInt < 0)) return int.MaxValue;
|
||||
|
||||
// Because we would have an overflow below while trying to do -(int.MinValue)
|
||||
// We modify it here so that we don't overflow
|
||||
var ulp = (long)aInt - bInt;
|
||||
|
||||
if (ulp <= int.MinValue) return int.MaxValue;
|
||||
if (ulp > int.MaxValue) return int.MaxValue;
|
||||
|
||||
// We know for sure that numbers are in the range ]int.MinValue, int.MaxValue]
|
||||
return (int)Math.Abs(ulp);
|
||||
}
|
||||
|
||||
public static bool NearEqualDouble(double a, double b, int maxUlp, out long ulp)
|
||||
{
|
||||
ulp = 0;
|
||||
if (Math.Abs(a - b) < ZeroTolerance) return true;
|
||||
|
||||
ulp = GetUlpDoubleDistance(a, b);
|
||||
return ulp <= maxUlp;
|
||||
}
|
||||
|
||||
private static readonly long LongMinValue = long.MinValue;
|
||||
private static readonly long LongMaxValue = long.MaxValue;
|
||||
|
||||
public static unsafe long GetUlpDoubleDistance(double a, double b)
|
||||
{
|
||||
// Save work if the floats are equal.
|
||||
// Also handles +0 == -0
|
||||
if (a == b)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (double.IsNaN(a) && double.IsNaN(b))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (double.IsInfinity(a) && double.IsInfinity(b))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
long aInt = *(long*)&a;
|
||||
long bInt = *(long*)&b;
|
||||
|
||||
if ((aInt < 0) != (bInt < 0)) return long.MaxValue;
|
||||
|
||||
var ulp = aInt - bInt;
|
||||
|
||||
if (ulp <= LongMinValue) return long.MaxValue;
|
||||
if (ulp > LongMaxValue) return long.MaxValue;
|
||||
|
||||
return Math.Abs((long)ulp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified value is close to zero (0.0f).
|
||||
/// </summary>
|
||||
/// <param name="a">The floating value.</param>
|
||||
/// <returns><c>true</c> if the specified value is close to zero (0.0f); otherwise, <c>false</c>.</returns>
|
||||
public static bool IsZero(float a)
|
||||
{
|
||||
return Math.Abs(a) < ZeroTolerance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified value is close to zero (0.0f).
|
||||
/// </summary>
|
||||
/// <param name="a">The floating value.</param>
|
||||
/// <returns><c>true</c> if the specified value is close to zero (0.0f); otherwise, <c>false</c>.</returns>
|
||||
public static bool IsZero(double a)
|
||||
{
|
||||
return Math.Abs(a) < ZeroToleranceDouble;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 36b40077ff04349b8ab8ac0144483e68
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,542 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using NUnit.Framework.Internal;
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace Burst.Compiler.IL.Tests.Helpers
|
||||
{
|
||||
[Flags]
|
||||
internal enum DataRange
|
||||
{
|
||||
// Standard Test (Zero, Minus100To100, Inf, Nan)
|
||||
Standard = Zero | Minus100To100 | Inf | NaN | HighIntRange,
|
||||
|
||||
// Standard Test (Zero, ZeroExclusiveTo100, Inf, Nan)
|
||||
StandardPositive = Zero | ZeroExclusiveTo100 | Inf | NaN,
|
||||
|
||||
// Standard Between -1 and 1 (Zero, MinusOneInclusiveToOneInclusive, Inf, Nan)
|
||||
Standard11 = Zero | MinusOneInclusiveToOneInclusive | Inf | NaN,
|
||||
|
||||
Zero = 1 << 1,
|
||||
ZeroExclusiveToOneInclusive = 1 << 2,
|
||||
MinusOneInclusiveToOneInclusive = 1 << 3,
|
||||
Minus100To100 = 1 << 4,
|
||||
ZeroExclusiveTo100 = 1 << 5,
|
||||
Inf = 1 << 6,
|
||||
NaN = 1 << 7,
|
||||
HighIntRange = 1 << 8,
|
||||
}
|
||||
|
||||
internal static class DataRangeExtensions
|
||||
{
|
||||
private const int VectorsCount = 6;
|
||||
|
||||
private static bool IsIntegerType(Type type)
|
||||
{
|
||||
if (type == typeof(byte)) return true;
|
||||
if (type == typeof(sbyte)) return true;
|
||||
if (type == typeof(short)) return true;
|
||||
if (type == typeof(ushort)) return true;
|
||||
if (type == typeof(int)) return true;
|
||||
if (type == typeof(uint)) return true;
|
||||
if (type == typeof(long)) return true;
|
||||
if (type == typeof(ulong)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsSignedIntegerType(Type type)
|
||||
{
|
||||
if (type == typeof(sbyte)) return true;
|
||||
if (type == typeof(short)) return true;
|
||||
if (type == typeof(int)) return true;
|
||||
if (type == typeof(long)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static IEnumerable<object> ExpandRange(this DataRange dataRange, Type type, int seed)
|
||||
{
|
||||
if (IsIntegerType(type))
|
||||
{
|
||||
var isSigned = IsSignedIntegerType(type);
|
||||
|
||||
foreach (var value in ExpandRange(dataRange & ~(DataRange.Inf | DataRange.NaN), typeof(double), seed))
|
||||
{
|
||||
var d = (double)value;
|
||||
|
||||
if (!isSigned && (d < 0.0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return Convert.ChangeType(d, type);
|
||||
}
|
||||
|
||||
if (0 != (dataRange & DataRange.HighIntRange))
|
||||
{
|
||||
double rangeLow = 100;
|
||||
double rangeHigh = 101;
|
||||
|
||||
if (type == typeof(byte)) rangeHigh = byte.MaxValue;
|
||||
if (type == typeof(sbyte)) rangeHigh = sbyte.MaxValue;
|
||||
if (type == typeof(short)) rangeHigh = short.MaxValue;
|
||||
if (type == typeof(ushort)) rangeHigh = ushort.MaxValue;
|
||||
if (type == typeof(int)) rangeHigh = int.MaxValue;
|
||||
if (type == typeof(uint)) rangeHigh = uint.MaxValue;
|
||||
if (type == typeof(long)) rangeHigh = long.MaxValue;
|
||||
if (type == typeof(ulong)) rangeHigh = ulong.MaxValue;
|
||||
|
||||
var random = new System.Random(seed);
|
||||
|
||||
int total = 8;
|
||||
|
||||
if (!isSigned)
|
||||
{
|
||||
total *= 2;
|
||||
}
|
||||
|
||||
for (int i = 0; i < total; i++)
|
||||
{
|
||||
var next = random.NextDouble();
|
||||
var d = rangeLow + (rangeHigh - rangeLow) * next;
|
||||
|
||||
yield return Convert.ChangeType(d, type);
|
||||
|
||||
if (isSigned)
|
||||
{
|
||||
yield return Convert.ChangeType(-d, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == typeof(bool))
|
||||
{
|
||||
yield return true;
|
||||
yield return false;
|
||||
}
|
||||
else if (type == typeof(float))
|
||||
{
|
||||
foreach (var value in ExpandRange(dataRange, typeof(double), seed))
|
||||
{
|
||||
var d = (double)value;
|
||||
if (double.IsNaN(d))
|
||||
{
|
||||
yield return float.NaN;
|
||||
}
|
||||
else if (double.IsPositiveInfinity(d))
|
||||
{
|
||||
yield return float.PositiveInfinity;
|
||||
}
|
||||
else if (double.IsNegativeInfinity(d))
|
||||
{
|
||||
yield return float.NegativeInfinity;
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return (float)(double)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == typeof(double))
|
||||
{
|
||||
if ((dataRange & (DataRange.Minus100To100)) != 0)
|
||||
{
|
||||
yield return -100.0;
|
||||
yield return -77.9;
|
||||
yield return -50.0;
|
||||
yield return -36.5;
|
||||
yield return -9.1;
|
||||
|
||||
if ((dataRange & (DataRange.Zero)) != 0)
|
||||
{
|
||||
yield return 0.0;
|
||||
}
|
||||
|
||||
yield return 5.1;
|
||||
yield return 43.5;
|
||||
yield return 50.0;
|
||||
yield return 76.8;
|
||||
yield return 100.0;
|
||||
|
||||
if ((dataRange & (DataRange.NaN)) != 0)
|
||||
{
|
||||
yield return double.NaN;
|
||||
}
|
||||
|
||||
if ((dataRange & (DataRange.Inf)) != 0)
|
||||
{
|
||||
yield return double.PositiveInfinity;
|
||||
yield return double.NegativeInfinity;
|
||||
}
|
||||
}
|
||||
else if ((dataRange & DataRange.ZeroExclusiveTo100) != 0)
|
||||
{
|
||||
foreach (var value in ExpandRange(dataRange | DataRange.Minus100To100, typeof(double), seed))
|
||||
{
|
||||
var d = (double)value;
|
||||
if (double.IsNaN(d) || double.IsInfinity(d))
|
||||
{
|
||||
yield return d;
|
||||
}
|
||||
else if (d != 0.0)
|
||||
{
|
||||
d = d * 0.5 + 50.1;
|
||||
if (d > 100.0)
|
||||
{
|
||||
d = 100.0;
|
||||
}
|
||||
yield return d;
|
||||
}
|
||||
}
|
||||
|
||||
if ((dataRange & (DataRange.Zero)) != 0)
|
||||
{
|
||||
yield return 0.0;
|
||||
}
|
||||
}
|
||||
else if ((dataRange & (DataRange.MinusOneInclusiveToOneInclusive)) != 0)
|
||||
{
|
||||
foreach (var value in ExpandRange(dataRange | DataRange.Minus100To100, typeof(double), seed))
|
||||
{
|
||||
var d = (double) value;
|
||||
// Return nan/inf as-is
|
||||
if (double.IsNaN(d) || double.IsInfinity(d) || d == 0.0)
|
||||
{
|
||||
yield return d;
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return d / 100.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((dataRange & (DataRange.ZeroExclusiveToOneInclusive)) != 0)
|
||||
{
|
||||
foreach (var value in ExpandRange(dataRange | DataRange.ZeroExclusiveTo100, typeof(double), seed))
|
||||
{
|
||||
var d = (double) value;
|
||||
if (double.IsNaN(d) || double.IsInfinity(d) || d == 0.0)
|
||||
{
|
||||
yield return d;
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return d / 100.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException($"Invalid datarange `{dataRange}`: missing either Minus100To100 | MinusOneInclusiveToOneInclusive | ZeroExclusiveToOneInclusive`");
|
||||
}
|
||||
}
|
||||
else if (type.Namespace == "Unity.Mathematics")
|
||||
{
|
||||
if (type.IsByRef)
|
||||
{
|
||||
type = type.GetElementType();
|
||||
}
|
||||
|
||||
if (type.Name.StartsWith("bool"))
|
||||
{
|
||||
var size = (uint)(type.Name["bool".Length] - '0');
|
||||
var bools = ExpandRange(dataRange & ~(DataRange.NaN | DataRange.Inf), typeof(bool), seed).OfType<bool>().ToArray();
|
||||
var indices = Enumerable.Range(0, bools.Length).ToList();
|
||||
var originalIndices = new List<int>(indices);
|
||||
var random = new System.Random(seed);
|
||||
switch (size)
|
||||
{
|
||||
case 2:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = bools[NextIndex(random, indices, originalIndices)];
|
||||
var y = bools[NextIndex(random, indices, originalIndices)];
|
||||
yield return new bool2(x, y);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = bools[NextIndex(random, indices, originalIndices)];
|
||||
var y = bools[NextIndex(random, indices, originalIndices)];
|
||||
var z = bools[NextIndex(random, indices, originalIndices)];
|
||||
yield return new bool3(x, y, z);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = bools[NextIndex(random, indices, originalIndices)];
|
||||
var y = bools[NextIndex(random, indices, originalIndices)];
|
||||
var z = bools[NextIndex(random, indices, originalIndices)];
|
||||
var w = bools[NextIndex(random, indices, originalIndices)];
|
||||
yield return new bool4(x, y, z, w);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported DataRange type `{type}`");
|
||||
}
|
||||
}
|
||||
else if (type.Name.StartsWith("int"))
|
||||
{
|
||||
var size = (uint) (type.Name["int".Length] - '0');
|
||||
var ints = ExpandRange(dataRange & ~(DataRange.NaN | DataRange.Inf), typeof(int), seed).OfType<int>().ToArray();
|
||||
var indices = Enumerable.Range(0, ints.Length).ToList();
|
||||
var originalIndices = new List<int>(indices);
|
||||
var random = new System.Random(seed);
|
||||
switch (size)
|
||||
{
|
||||
case 2:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = ints[NextIndex(random, indices, originalIndices)];
|
||||
var y = ints[NextIndex(random, indices, originalIndices)];
|
||||
yield return new int2(x, y);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = ints[NextIndex(random, indices, originalIndices)];
|
||||
var y = ints[NextIndex(random, indices, originalIndices)];
|
||||
var z = ints[NextIndex(random, indices, originalIndices)];
|
||||
yield return new int3(x, y, z);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = ints[NextIndex(random, indices, originalIndices)];
|
||||
var y = ints[NextIndex(random, indices, originalIndices)];
|
||||
var z = ints[NextIndex(random, indices, originalIndices)];
|
||||
var w = ints[NextIndex(random, indices, originalIndices)];
|
||||
yield return new int4(x, y, z, w);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported DataRange type `{type}`");
|
||||
}
|
||||
}
|
||||
else if (type.Name.StartsWith("uint"))
|
||||
{
|
||||
var size = (uint)(type.Name["uint".Length] - '0');
|
||||
var uints = ExpandRange(dataRange & ~(DataRange.NaN | DataRange.Inf), typeof(uint), seed).OfType<uint>().ToArray();
|
||||
var indices = Enumerable.Range(0, uints.Length).ToList();
|
||||
var originalIndices = new List<int>(indices);
|
||||
var random = new System.Random(seed);
|
||||
switch (size)
|
||||
{
|
||||
case 2:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = uints[NextIndex(random, indices, originalIndices)];
|
||||
var y = uints[NextIndex(random, indices, originalIndices)];
|
||||
yield return new uint2(x, y);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = uints[NextIndex(random, indices, originalIndices)];
|
||||
var y = uints[NextIndex(random, indices, originalIndices)];
|
||||
var z = uints[NextIndex(random, indices, originalIndices)];
|
||||
yield return new uint3(x, y, z);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = uints[NextIndex(random, indices, originalIndices)];
|
||||
var y = uints[NextIndex(random, indices, originalIndices)];
|
||||
var z = uints[NextIndex(random, indices, originalIndices)];
|
||||
var w = uints[NextIndex(random, indices, originalIndices)];
|
||||
yield return new uint4(x, y, z, w);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported DataRange type `{type}`");
|
||||
}
|
||||
}
|
||||
else if (type.Name.StartsWith("half"))
|
||||
{
|
||||
var size = (uint)(type.Name["half".Length] - '0');
|
||||
var floats = ExpandRange(dataRange & ~(DataRange.NaN | DataRange.Inf), typeof(float), seed).OfType<float>().ToList();
|
||||
var originalIndices = Enumerable.Range(0, floats.Count).ToList();
|
||||
var indices = new List<int>(originalIndices);
|
||||
// We only put NaN and Inf in the first set of values
|
||||
if ((dataRange & DataRange.NaN) != 0)
|
||||
{
|
||||
indices.Add(floats.Count);
|
||||
floats.Add(float.NaN);
|
||||
}
|
||||
if ((dataRange & DataRange.Inf) != 0)
|
||||
{
|
||||
indices.Add(floats.Count);
|
||||
floats.Add(float.PositiveInfinity);
|
||||
}
|
||||
|
||||
var random = new System.Random(seed);
|
||||
switch (size)
|
||||
{
|
||||
case 2:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = floats[NextIndex(random, indices, originalIndices)];
|
||||
var y = floats[NextIndex(random, indices, originalIndices)];
|
||||
yield return new half2(new float2(x, y));
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = floats[NextIndex(random, indices, originalIndices)];
|
||||
var y = floats[NextIndex(random, indices, originalIndices)];
|
||||
var z = floats[NextIndex(random, indices, originalIndices)];
|
||||
yield return new half3(new float3(x, y, z));
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = floats[NextIndex(random, indices, originalIndices)];
|
||||
var y = floats[NextIndex(random, indices, originalIndices)];
|
||||
var z = floats[NextIndex(random, indices, originalIndices)];
|
||||
var w = floats[NextIndex(random, indices, originalIndices)];
|
||||
yield return new half4(new float4(x, y, z, w));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported DataRange type `{type}`");
|
||||
}
|
||||
}
|
||||
else if (type.Name.StartsWith("float"))
|
||||
{
|
||||
var size = (uint) (type.Name["float".Length] - '0');
|
||||
var floats = ExpandRange(dataRange & ~(DataRange.NaN | DataRange.Inf), typeof(float), seed).OfType<float>().ToList();
|
||||
var originalIndices = Enumerable.Range(0, floats.Count).ToList();
|
||||
var indices = new List<int>(originalIndices);
|
||||
// We only put NaN and Inf in the first set of values
|
||||
if ((dataRange & DataRange.NaN) != 0)
|
||||
{
|
||||
indices.Add(floats.Count);
|
||||
floats.Add(float.NaN);
|
||||
}
|
||||
if ((dataRange & DataRange.Inf) != 0)
|
||||
{
|
||||
indices.Add(floats.Count);
|
||||
floats.Add(float.PositiveInfinity);
|
||||
}
|
||||
|
||||
var random = new System.Random(seed);
|
||||
switch (size)
|
||||
{
|
||||
case 2:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = floats[NextIndex(random, indices, originalIndices)];
|
||||
var y = floats[NextIndex(random, indices, originalIndices)];
|
||||
yield return new float2(x, y);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = floats[NextIndex(random, indices, originalIndices)];
|
||||
var y = floats[NextIndex(random, indices, originalIndices)];
|
||||
var z = floats[NextIndex(random, indices, originalIndices)];
|
||||
yield return new float3(x, y, z);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = floats[NextIndex(random, indices, originalIndices)];
|
||||
var y = floats[NextIndex(random, indices, originalIndices)];
|
||||
var z = floats[NextIndex(random, indices, originalIndices)];
|
||||
var w = floats[NextIndex(random, indices, originalIndices)];
|
||||
yield return new float4(x, y, z, w);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported DataRange type `{type}`");
|
||||
}
|
||||
}
|
||||
else if (type.Name.StartsWith("double"))
|
||||
{
|
||||
var size = (uint)(type.Name["double".Length] - '0');
|
||||
var doubles = ExpandRange(dataRange & ~(DataRange.NaN | DataRange.Inf), typeof(double), seed).OfType<double>().ToList();
|
||||
var originalIndices = Enumerable.Range(0, doubles.Count).ToList();
|
||||
var indices = new List<int>(originalIndices);
|
||||
// We only put NaN and Inf in the first set of values
|
||||
if ((dataRange & DataRange.NaN) != 0)
|
||||
{
|
||||
indices.Add(doubles.Count);
|
||||
doubles.Add(double.NaN);
|
||||
}
|
||||
if ((dataRange & DataRange.Inf) != 0)
|
||||
{
|
||||
indices.Add(doubles.Count);
|
||||
doubles.Add(double.PositiveInfinity);
|
||||
}
|
||||
|
||||
var random = new System.Random(seed);
|
||||
switch (size)
|
||||
{
|
||||
case 2:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = doubles[NextIndex(random, indices, originalIndices)];
|
||||
var y = doubles[NextIndex(random, indices, originalIndices)];
|
||||
yield return new double2(x, y);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = doubles[NextIndex(random, indices, originalIndices)];
|
||||
var y = doubles[NextIndex(random, indices, originalIndices)];
|
||||
var z = doubles[NextIndex(random, indices, originalIndices)];
|
||||
yield return new double3(x, y, z);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (int i = 0; i < VectorsCount; i++)
|
||||
{
|
||||
var x = doubles[NextIndex(random, indices, originalIndices)];
|
||||
var y = doubles[NextIndex(random, indices, originalIndices)];
|
||||
var z = doubles[NextIndex(random, indices, originalIndices)];
|
||||
var w = doubles[NextIndex(random, indices, originalIndices)];
|
||||
yield return new double4(x, y, z, w);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported DataRange type `{type}`");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException($"Unsupported DataRange type `{type}`");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException($"Unsupported DataRange type `{type}`");
|
||||
}
|
||||
}
|
||||
|
||||
private static int NextIndex(System.Random random, List<int> indices, List<int> originalIndices)
|
||||
{
|
||||
var id = random.Next(0, indices.Count - 1);
|
||||
var index = indices[id];
|
||||
indices.RemoveAt(id);
|
||||
if (indices.Count == 0)
|
||||
{
|
||||
indices.AddRange(originalIndices);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cea7ccbebd713e1ea3ff378c516002b2
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,100 @@
|
|||
#if BURST_TESTS_ONLY
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Burst.Compiler.IL.Tests.Helpers
|
||||
{
|
||||
internal static class DelegateHelper
|
||||
{
|
||||
private static readonly Type[] _DelegateCtorSignature = new Type[2]
|
||||
{
|
||||
typeof(object),
|
||||
typeof(IntPtr)
|
||||
};
|
||||
|
||||
private static readonly Dictionary<DelegateKey, Type> DelegateTypes = new();
|
||||
|
||||
public static Type NewDelegateType(Type ret, Type[] parameters)
|
||||
{
|
||||
lock (DelegateTypes)
|
||||
{
|
||||
var key = new DelegateKey(ret, (Type[])parameters.Clone());
|
||||
Type delegateType;
|
||||
if (!DelegateTypes.TryGetValue(key, out delegateType))
|
||||
{
|
||||
var assemblyName = Guid.NewGuid().ToString();
|
||||
|
||||
var name = new AssemblyName(assemblyName);
|
||||
var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
|
||||
var moduleBuilder = assemblyBuilder.DefineDynamicModule(name.Name);
|
||||
assemblyBuilder.DefineVersionInfoResource();
|
||||
|
||||
var typeBuilder = moduleBuilder.DefineType("CustomDelegate", System.Reflection.TypeAttributes.Public | System.Reflection.TypeAttributes.Sealed | System.Reflection.TypeAttributes.AutoClass, typeof(MulticastDelegate));
|
||||
var constructor = typeof(UnmanagedFunctionPointerAttribute).GetConstructors()[0];
|
||||
|
||||
// Make sure that we setup the C calling convention on the unmanaged delegate
|
||||
var customAttribute = new CustomAttributeBuilder(constructor, new object[] { CallingConvention.Cdecl });
|
||||
typeBuilder.SetCustomAttribute(customAttribute);
|
||||
typeBuilder.DefineConstructor(System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.RTSpecialName, CallingConventions.Standard, _DelegateCtorSignature).SetImplementationFlags(System.Reflection.MethodImplAttributes.CodeTypeMask);
|
||||
typeBuilder.DefineMethod("Invoke", System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Virtual | System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.VtableLayoutMask, ret, parameters).SetImplementationFlags(System.Reflection.MethodImplAttributes.CodeTypeMask);
|
||||
delegateType = typeBuilder.CreateType();
|
||||
|
||||
DelegateTypes.Add(key, delegateType);
|
||||
}
|
||||
return delegateType;
|
||||
}
|
||||
}
|
||||
|
||||
private struct DelegateKey : IEquatable<DelegateKey>
|
||||
{
|
||||
public DelegateKey(Type returnType, Type[] arguments)
|
||||
{
|
||||
ReturnType = returnType;
|
||||
Arguments = arguments;
|
||||
}
|
||||
|
||||
public readonly Type ReturnType;
|
||||
|
||||
public readonly Type[] Arguments;
|
||||
|
||||
public bool Equals(DelegateKey other)
|
||||
{
|
||||
if (ReturnType.Equals(other.ReturnType) && Arguments.Length == other.Arguments.Length)
|
||||
{
|
||||
for (int i = 0; i < Arguments.Length; i++)
|
||||
{
|
||||
if (Arguments[i] != other.Arguments[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
return obj is DelegateKey && Equals((DelegateKey) obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
int hashcode = (ReturnType.GetHashCode() * 397) ^ Arguments.Length.GetHashCode();
|
||||
for (int i = 0; i < Arguments.Length; i++)
|
||||
{
|
||||
hashcode = (hashcode * 397) ^ Arguments[i].GetHashCode();
|
||||
}
|
||||
return hashcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ebf5c81612053b2c824c08502d93c9a1
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
using Unity.Collections;
|
||||
|
||||
namespace Burst.Compiler.IL.Tests.Helpers
|
||||
{
|
||||
// Only used to allow to call the delegate with a NativeArrayRaw
|
||||
// As we can't use a generic with pinvoke
|
||||
internal unsafe struct NativeArrayRaw : IDisposable
|
||||
{
|
||||
// MUST BE IN SYNC WITH NativeArray
|
||||
internal void* m_Buffer;
|
||||
internal int m_Length;
|
||||
|
||||
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
||||
internal int m_MinIndex;
|
||||
internal int m_MaxIndex;
|
||||
internal AtomicSafetyHandle m_Safety;
|
||||
internal DisposeSentinel m_DisposeSentinel;
|
||||
#endif
|
||||
Allocator m_AllocatorLabel;
|
||||
|
||||
public NativeArrayRaw(void* mBuffer, int mLength)
|
||||
{
|
||||
m_Buffer = mBuffer;
|
||||
m_Length = mLength;
|
||||
m_AllocatorLabel = Allocator.Persistent;
|
||||
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
||||
m_MinIndex = 0;
|
||||
m_MaxIndex = m_Length -1;
|
||||
m_Safety = AtomicSafetyHandle.Create();
|
||||
m_DisposeSentinel = null;
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
||||
DisposeSentinel.Dispose(ref m_Safety, ref m_DisposeSentinel);
|
||||
#endif
|
||||
if (m_Buffer != (void*)0)
|
||||
{
|
||||
UnsafeUtility.Free((void*)m_Buffer, m_AllocatorLabel);
|
||||
m_Buffer = (void*)0;
|
||||
m_Length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d517bbd8c0dd383c966641281f1af857
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,87 @@
|
|||
using Unity.Mathematics;
|
||||
|
||||
namespace Burst.Compiler.IL.Tests
|
||||
{
|
||||
internal static partial class Vectors
|
||||
{
|
||||
public static int ConvertToInt(bool4 result)
|
||||
{
|
||||
return ConvertToInt(result.x) + ConvertToInt(result.y) * 10 + ConvertToInt(result.z) * 100 + ConvertToInt(result.w) * 1000;
|
||||
}
|
||||
|
||||
public static int ConvertToInt(bool3 result)
|
||||
{
|
||||
return ConvertToInt(result.x) + ConvertToInt(result.y) * 10 + ConvertToInt(result.z) * 100;
|
||||
}
|
||||
|
||||
public static int ConvertToInt(bool2 result)
|
||||
{
|
||||
return ConvertToInt(result.x) + ConvertToInt(result.y) * 10;
|
||||
}
|
||||
|
||||
public static float ConvertToFloat(float4 result)
|
||||
{
|
||||
return result.x + result.y * 10.0f + result.z * 100.0f + result.w * 1000.0f;
|
||||
}
|
||||
|
||||
public static double ConvertToDouble(double4 result)
|
||||
{
|
||||
return result.x + result.y * 10.0 + result.z * 100.0 + result.w * 1000.0;
|
||||
}
|
||||
|
||||
public static float ConvertToFloat(float3 result)
|
||||
{
|
||||
return result.x + result.y * 10.0f + result.z * 100.0f;
|
||||
}
|
||||
|
||||
public static double ConvertToDouble(double3 result)
|
||||
{
|
||||
return result.x + result.y * 10.0 + result.z * 100.0;
|
||||
}
|
||||
|
||||
public static float ConvertToFloat(float2 result)
|
||||
{
|
||||
return result.x + result.y * 10.0f;
|
||||
}
|
||||
|
||||
public static double ConvertToDouble(double2 result)
|
||||
{
|
||||
return result.x + result.y * 10.0;
|
||||
}
|
||||
|
||||
public static int ConvertToInt(int4 result)
|
||||
{
|
||||
return result.x + result.y * 10 + result.z * 100 + result.w * 1000;
|
||||
}
|
||||
|
||||
public static int ConvertToInt(int3 result)
|
||||
{
|
||||
return result.x + result.y * 10 + result.z * 100;
|
||||
}
|
||||
|
||||
public static int ConvertToInt(int2 result)
|
||||
{
|
||||
return result.x + result.y * 10;
|
||||
}
|
||||
|
||||
public static int ConvertToInt(uint4 result)
|
||||
{
|
||||
return (int)(result.x + result.y * 10 + result.z * 100 + result.w * 1000);
|
||||
}
|
||||
|
||||
public static int ConvertToInt(uint3 result)
|
||||
{
|
||||
return (int)(result.x + result.y * 10 + result.z * 100);
|
||||
}
|
||||
|
||||
public static int ConvertToInt(uint2 result)
|
||||
{
|
||||
return (int)(result.x + result.y * 10);
|
||||
}
|
||||
|
||||
public static int ConvertToInt(bool value)
|
||||
{
|
||||
return value ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3cc5badcc5af3e609f1d307c13f81573
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue