95 changed files with 1591 additions and 1204 deletions
-6
View File
@@ -1,10 +1,4 @@
<Solution> <Solution>
<Configurations>
<BuildType Name="Debug" />
<BuildType Name="Debug AOT" />
<BuildType Name="Release" />
<BuildType Name="Release AOT" />
</Configurations>
<Folder Name="/Solution Items/"> <Folder Name="/Solution Items/">
<File Path=".editorconfig" /> <File Path=".editorconfig" />
<File Path="Directory.Build.props" /> <File Path="Directory.Build.props" />
-2
View File
@@ -4,8 +4,6 @@
<RuntimeIdentifiers>osx-arm64</RuntimeIdentifiers> <RuntimeIdentifiers>osx-arm64</RuntimeIdentifiers>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -406,7 +406,7 @@ namespace ARMeilleure.Instructions
{ {
Operand res = EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2); Operand res = EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2);
return EmitUnaryMathCall(context, nameof(Math.Abs), res); return EmitUnaryMathCall(context, nameof(MathHelper.Abs), res);
}); });
} }
} }
@@ -451,7 +451,7 @@ namespace ARMeilleure.Instructions
{ {
Operand res = EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2); Operand res = EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2);
return EmitUnaryMathCall(context, nameof(Math.Abs), res); return EmitUnaryMathCall(context, nameof(MathHelper.Abs), res);
}); });
} }
} }
@@ -483,7 +483,7 @@ namespace ARMeilleure.Instructions
{ {
EmitScalarUnaryOpF(context, (op1) => EmitScalarUnaryOpF(context, (op1) =>
{ {
return EmitUnaryMathCall(context, nameof(Math.Abs), op1); return EmitUnaryMathCall(context, nameof(MathHelper.Abs), op1);
}); });
} }
} }
@@ -522,7 +522,7 @@ namespace ARMeilleure.Instructions
{ {
EmitVectorUnaryOpF(context, (op1) => EmitVectorUnaryOpF(context, (op1) =>
{ {
return EmitUnaryMathCall(context, nameof(Math.Abs), op1); return EmitUnaryMathCall(context, nameof(MathHelper.Abs), op1);
}); });
} }
} }
@@ -2246,7 +2246,7 @@ namespace ARMeilleure.Instructions
{ {
EmitScalarUnaryOpF(context, (op1) => EmitScalarUnaryOpF(context, (op1) =>
{ {
return EmitUnaryMathCall(context, nameof(Math.Floor), op1); return EmitUnaryMathCall(context, nameof(MathHelper.Floor), op1);
}); });
} }
} }
@@ -2265,7 +2265,7 @@ namespace ARMeilleure.Instructions
{ {
EmitVectorUnaryOpF(context, (op1) => EmitVectorUnaryOpF(context, (op1) =>
{ {
return EmitUnaryMathCall(context, nameof(Math.Floor), op1); return EmitUnaryMathCall(context, nameof(MathHelper.Floor), op1);
}); });
} }
} }
@@ -2322,7 +2322,7 @@ namespace ARMeilleure.Instructions
{ {
EmitScalarUnaryOpF(context, (op1) => EmitScalarUnaryOpF(context, (op1) =>
{ {
return EmitUnaryMathCall(context, nameof(Math.Ceiling), op1); return EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), op1);
}); });
} }
} }
@@ -2341,7 +2341,7 @@ namespace ARMeilleure.Instructions
{ {
EmitVectorUnaryOpF(context, (op1) => EmitVectorUnaryOpF(context, (op1) =>
{ {
return EmitUnaryMathCall(context, nameof(Math.Ceiling), op1); return EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), op1);
}); });
} }
} }
@@ -2390,7 +2390,7 @@ namespace ARMeilleure.Instructions
{ {
EmitScalarUnaryOpF(context, (op1) => EmitScalarUnaryOpF(context, (op1) =>
{ {
return EmitUnaryMathCall(context, nameof(Math.Truncate), op1); return EmitUnaryMathCall(context, nameof(MathHelper.Truncate), op1);
}); });
} }
} }
@@ -2409,7 +2409,7 @@ namespace ARMeilleure.Instructions
{ {
EmitVectorUnaryOpF(context, (op1) => EmitVectorUnaryOpF(context, (op1) =>
{ {
return EmitUnaryMathCall(context, nameof(Math.Truncate), op1); return EmitUnaryMathCall(context, nameof(MathHelper.Truncate), op1);
}); });
} }
} }
@@ -43,7 +43,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
EmitScalarUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Abs), op1)); EmitScalarUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Abs), op1));
} }
} }
@@ -66,7 +66,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
EmitVectorUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Abs), op1)); EmitVectorUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Abs), op1));
} }
} }
else else
@@ -726,8 +726,8 @@ namespace ARMeilleure.Instructions
if (absolute) if (absolute)
{ {
ne = EmitUnaryMathCall(context, nameof(Math.Abs), ne); ne = EmitUnaryMathCall(context, nameof(MathHelper.Abs), ne);
me = EmitUnaryMathCall(context, nameof(Math.Abs), me); me = EmitUnaryMathCall(context, nameof(MathHelper.Abs), me);
} }
Operand e = EmitSoftFloatCall(context, name, ne, me); Operand e = EmitSoftFloatCall(context, name, ne, me);
@@ -333,7 +333,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Floor), op1)); EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Floor), op1));
} }
} }
@@ -349,7 +349,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
EmitFcvt(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Floor), op1), signed: true, scalar: false); EmitFcvt(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Floor), op1), signed: true, scalar: false);
} }
} }
@@ -365,7 +365,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Floor), op1)); EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Floor), op1));
} }
} }
@@ -538,7 +538,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Ceiling), op1)); EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), op1));
} }
} }
@@ -554,7 +554,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Ceiling), op1)); EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), op1));
} }
} }
@@ -357,10 +357,10 @@ namespace ARMeilleure.Instructions
toConvert = EmitRoundMathCall(context, MidpointRounding.ToEven, toConvert); toConvert = EmitRoundMathCall(context, MidpointRounding.ToEven, toConvert);
break; break;
case 0b10: // Towards positive infinity case 0b10: // Towards positive infinity
toConvert = EmitUnaryMathCall(context, nameof(Math.Ceiling), toConvert); toConvert = EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), toConvert);
break; break;
case 0b11: // Towards negative infinity case 0b11: // Towards negative infinity
toConvert = EmitUnaryMathCall(context, nameof(Math.Floor), toConvert); toConvert = EmitUnaryMathCall(context, nameof(MathHelper.Floor), toConvert);
break; break;
} }
@@ -494,10 +494,10 @@ namespace ARMeilleure.Instructions
toConvert = EmitRoundMathCall(context, MidpointRounding.ToEven, toConvert); toConvert = EmitRoundMathCall(context, MidpointRounding.ToEven, toConvert);
break; break;
case 0b10: // Towards positive infinity case 0b10: // Towards positive infinity
toConvert = EmitUnaryMathCall(context, nameof(Math.Ceiling), toConvert); toConvert = EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), toConvert);
break; break;
case 0b11: // Towards negative infinity case 0b11: // Towards negative infinity
toConvert = EmitUnaryMathCall(context, nameof(Math.Floor), toConvert); toConvert = EmitUnaryMathCall(context, nameof(MathHelper.Floor), toConvert);
break; break;
} }
@@ -534,7 +534,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
EmitVectorUnaryOpF32(context, (m) => EmitUnaryMathCall(context, nameof(Math.Floor), m)); EmitVectorUnaryOpF32(context, (m) => EmitUnaryMathCall(context, nameof(MathHelper.Floor), m));
} }
} }
@@ -574,7 +574,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
EmitVectorUnaryOpF32(context, (m) => EmitUnaryMathCall(context, nameof(Math.Ceiling), m)); EmitVectorUnaryOpF32(context, (m) => EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), m));
} }
} }
@@ -613,7 +613,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
EmitScalarUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Truncate), op1)); EmitScalarUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, nameof(MathHelper.Truncate), op1));
} }
} }
@@ -460,8 +460,8 @@ namespace ARMeilleure.Instructions
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp; IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
MethodInfo info = (op.Size & 1) == 0 MethodInfo info = (op.Size & 1) == 0
? typeof(MathF).GetMethod(name, [typeof(float)]) ? typeof(MathHelperF).GetMethod(name, [typeof(float)])
: typeof(Math).GetMethod(name, [typeof(double)]); : typeof(MathHelper).GetMethod(name, [typeof(double)]);
return context.Call(info, n); return context.Call(info, n);
} }
@@ -470,11 +470,11 @@ namespace ARMeilleure.Instructions
{ {
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp; IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
string name = nameof(Math.Round); string name = nameof(MathHelper.Round);
MethodInfo info = (op.Size & 1) == 0 MethodInfo info = (op.Size & 1) == 0
? typeof(MathF).GetMethod(name, [typeof(float), typeof(MidpointRounding)]) ? typeof(MathHelperF).GetMethod(name, [typeof(float), typeof(int)])
: typeof(Math).GetMethod(name, [typeof(double), typeof(MidpointRounding)]); : typeof(MathHelper).GetMethod(name, [typeof(double), typeof(int)]);
return context.Call(info, n, Const((int)roundMode)); return context.Call(info, n, Const((int)roundMode));
} }
@@ -510,16 +510,16 @@ namespace ARMeilleure.Instructions
context.MarkLabel(lbl1); context.MarkLabel(lbl1);
context.BranchIf(lbl2, rMode, rP, Comparison.NotEqual); context.BranchIf(lbl2, rMode, rP, Comparison.NotEqual);
context.Copy(res, EmitUnaryMathCall(context, nameof(Math.Ceiling), op)); context.Copy(res, EmitUnaryMathCall(context, nameof(MathHelper.Ceiling), op));
context.Branch(lblEnd); context.Branch(lblEnd);
context.MarkLabel(lbl2); context.MarkLabel(lbl2);
context.BranchIf(lbl3, rMode, rM, Comparison.NotEqual); context.BranchIf(lbl3, rMode, rM, Comparison.NotEqual);
context.Copy(res, EmitUnaryMathCall(context, nameof(Math.Floor), op)); context.Copy(res, EmitUnaryMathCall(context, nameof(MathHelper.Floor), op));
context.Branch(lblEnd); context.Branch(lblEnd);
context.MarkLabel(lbl3); context.MarkLabel(lbl3);
context.Copy(res, EmitUnaryMathCall(context, nameof(Math.Truncate), op)); context.Copy(res, EmitUnaryMathCall(context, nameof(MathHelper.Truncate), op));
context.Branch(lblEnd); context.Branch(lblEnd);
context.MarkLabel(lblEnd); context.MarkLabel(lblEnd);
@@ -0,0 +1,71 @@
using System;
using System.Runtime.InteropServices;
namespace ARMeilleure.Instructions
{
static class MathHelper
{
[UnmanagedCallersOnly]
public static double Abs(double value)
{
return Math.Abs(value);
}
[UnmanagedCallersOnly]
public static double Ceiling(double value)
{
return Math.Ceiling(value);
}
[UnmanagedCallersOnly]
public static double Floor(double value)
{
return Math.Floor(value);
}
[UnmanagedCallersOnly]
public static double Round(double value, int mode)
{
return Math.Round(value, (MidpointRounding)mode);
}
[UnmanagedCallersOnly]
public static double Truncate(double value)
{
return Math.Truncate(value);
}
}
static class MathHelperF
{
[UnmanagedCallersOnly]
public static float Abs(float value)
{
return MathF.Abs(value);
}
[UnmanagedCallersOnly]
public static float Ceiling(float value)
{
return MathF.Ceiling(value);
}
[UnmanagedCallersOnly]
public static float Floor(float value)
{
return MathF.Floor(value);
}
[UnmanagedCallersOnly]
public static float Round(float value, int mode)
{
return MathF.Round(value, (MidpointRounding)mode);
}
[UnmanagedCallersOnly]
public static float Truncate(float value)
{
return MathF.Truncate(value);
}
}
}
@@ -2,6 +2,7 @@ using ARMeilleure.Memory;
using ARMeilleure.State; using ARMeilleure.State;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using System; using System;
using System.Runtime.InteropServices;
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
@@ -34,6 +35,7 @@ namespace ARMeilleure.Instructions
Context = null; Context = null;
} }
[UnmanagedCallersOnly]
public static void Break(ulong address, int imm) public static void Break(ulong address, int imm)
{ {
Statistics.PauseTimer(); Statistics.PauseTimer();
@@ -43,6 +45,7 @@ namespace ARMeilleure.Instructions
Statistics.ResumeTimer(); Statistics.ResumeTimer();
} }
[UnmanagedCallersOnly]
public static void SupervisorCall(ulong address, int imm) public static void SupervisorCall(ulong address, int imm)
{ {
Statistics.PauseTimer(); Statistics.PauseTimer();
@@ -52,6 +55,7 @@ namespace ARMeilleure.Instructions
Statistics.ResumeTimer(); Statistics.ResumeTimer();
} }
[UnmanagedCallersOnly]
public static void Undefined(ulong address, int opCode) public static void Undefined(ulong address, int opCode)
{ {
Statistics.PauseTimer(); Statistics.PauseTimer();
@@ -62,26 +66,31 @@ namespace ARMeilleure.Instructions
} }
#region "System registers" #region "System registers"
[UnmanagedCallersOnly]
public static ulong GetCtrEl0() public static ulong GetCtrEl0()
{ {
return GetContext().CtrEl0; return GetContext().CtrEl0;
} }
[UnmanagedCallersOnly]
public static ulong GetDczidEl0() public static ulong GetDczidEl0()
{ {
return GetContext().DczidEl0; return GetContext().DczidEl0;
} }
[UnmanagedCallersOnly]
public static ulong GetCntfrqEl0() public static ulong GetCntfrqEl0()
{ {
return GetContext().CntfrqEl0; return GetContext().CntfrqEl0;
} }
[UnmanagedCallersOnly]
public static ulong GetCntpctEl0() public static ulong GetCntpctEl0()
{ {
return GetContext().CntpctEl0; return GetContext().CntpctEl0;
} }
[UnmanagedCallersOnly]
public static ulong GetCntvctEl0() public static ulong GetCntvctEl0()
{ {
return GetContext().CntvctEl0; return GetContext().CntvctEl0;
@@ -89,26 +98,31 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "Read" #region "Read"
[UnmanagedCallersOnly]
public static byte ReadByte(ulong address) public static byte ReadByte(ulong address)
{ {
return GetMemoryManager().ReadGuest<byte>(address); return GetMemoryManager().ReadGuest<byte>(address);
} }
[UnmanagedCallersOnly]
public static ushort ReadUInt16(ulong address) public static ushort ReadUInt16(ulong address)
{ {
return GetMemoryManager().ReadGuest<ushort>(address); return GetMemoryManager().ReadGuest<ushort>(address);
} }
[UnmanagedCallersOnly]
public static uint ReadUInt32(ulong address) public static uint ReadUInt32(ulong address)
{ {
return GetMemoryManager().ReadGuest<uint>(address); return GetMemoryManager().ReadGuest<uint>(address);
} }
[UnmanagedCallersOnly]
public static ulong ReadUInt64(ulong address) public static ulong ReadUInt64(ulong address)
{ {
return GetMemoryManager().ReadGuest<ulong>(address); return GetMemoryManager().ReadGuest<ulong>(address);
} }
[UnmanagedCallersOnly]
public static V128 ReadVector128(ulong address) public static V128 ReadVector128(ulong address)
{ {
return GetMemoryManager().ReadGuest<V128>(address); return GetMemoryManager().ReadGuest<V128>(address);
@@ -116,47 +130,56 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "Write" #region "Write"
[UnmanagedCallersOnly]
public static void WriteByte(ulong address, byte value) public static void WriteByte(ulong address, byte value)
{ {
GetMemoryManager().WriteGuest(address, value); GetMemoryManager().WriteGuest(address, value);
} }
[UnmanagedCallersOnly]
public static void WriteUInt16(ulong address, ushort value) public static void WriteUInt16(ulong address, ushort value)
{ {
GetMemoryManager().WriteGuest(address, value); GetMemoryManager().WriteGuest(address, value);
} }
[UnmanagedCallersOnly]
public static void WriteUInt32(ulong address, uint value) public static void WriteUInt32(ulong address, uint value)
{ {
GetMemoryManager().WriteGuest(address, value); GetMemoryManager().WriteGuest(address, value);
} }
[UnmanagedCallersOnly]
public static void WriteUInt64(ulong address, ulong value) public static void WriteUInt64(ulong address, ulong value)
{ {
GetMemoryManager().WriteGuest(address, value); GetMemoryManager().WriteGuest(address, value);
} }
[UnmanagedCallersOnly]
public static void WriteVector128(ulong address, V128 value) public static void WriteVector128(ulong address, V128 value)
{ {
GetMemoryManager().WriteGuest(address, value); GetMemoryManager().WriteGuest(address, value);
} }
#endregion #endregion
[UnmanagedCallersOnly]
public static void EnqueueForRejit(ulong address) public static void EnqueueForRejit(ulong address)
{ {
Context.Translator.EnqueueForRejit(address, GetContext().ExecutionMode); Context.Translator.EnqueueForRejit(address, GetContext().ExecutionMode);
} }
public static void SignalMemoryTracking(ulong address, ulong size, bool write) [UnmanagedCallersOnly]
public static void SignalMemoryTracking(ulong address, ulong size, byte write)
{ {
GetMemoryManager().SignalMemoryTracking(address, size, write); GetMemoryManager().SignalMemoryTracking(address, size, write == 1);
} }
[UnmanagedCallersOnly]
public static void ThrowInvalidMemoryAccess(ulong address) public static void ThrowInvalidMemoryAccess(ulong address)
{ {
throw new InvalidAccessException(address); throw new InvalidAccessException(address);
} }
[UnmanagedCallersOnly]
public static ulong GetFunctionAddress(ulong address) public static ulong GetFunctionAddress(ulong address)
{ {
TranslatedFunction function = Context.Translator.GetOrTranslate(address, GetContext().ExecutionMode); TranslatedFunction function = Context.Translator.GetOrTranslate(address, GetContext().ExecutionMode);
@@ -164,12 +187,14 @@ namespace ARMeilleure.Instructions
return (ulong)function.FuncPointer.ToInt64(); return (ulong)function.FuncPointer.ToInt64();
} }
[UnmanagedCallersOnly]
public static void InvalidateCacheLine(ulong address) public static void InvalidateCacheLine(ulong address)
{ {
Context.Translator.InvalidateJitCacheRegion(address, InstEmit.DczSizeInBytes); Context.Translator.InvalidateJitCacheRegion(address, InstEmit.DczSizeInBytes);
} }
public static bool CheckSynchronization() [UnmanagedCallersOnly]
public static byte CheckSynchronization()
{ {
Statistics.PauseTimer(); Statistics.PauseTimer();
@@ -179,7 +204,7 @@ namespace ARMeilleure.Instructions
Statistics.ResumeTimer(); Statistics.ResumeTimer();
return context.Running; return (byte)(context.Running ? 1 : 0);
} }
public static ExecutionContext GetContext() public static ExecutionContext GetContext()
@@ -1,11 +1,13 @@
using ARMeilleure.State; using ARMeilleure.State;
using System; using System;
using System.Runtime.InteropServices;
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
static class SoftFallback static class SoftFallback
{ {
#region "ShrImm64" #region "ShrImm64"
[UnmanagedCallersOnly]
public static long SignedShrImm64(long value, long roundConst, int shift) public static long SignedShrImm64(long value, long roundConst, int shift)
{ {
if (roundConst == 0L) if (roundConst == 0L)
@@ -48,6 +50,7 @@ namespace ARMeilleure.Instructions
} }
} }
[UnmanagedCallersOnly]
public static ulong UnsignedShrImm64(ulong value, long roundConst, int shift) public static ulong UnsignedShrImm64(ulong value, long roundConst, int shift)
{ {
if (roundConst == 0L) if (roundConst == 0L)
@@ -92,6 +95,7 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "Saturation" #region "Saturation"
[UnmanagedCallersOnly]
public static int SatF32ToS32(float value) public static int SatF32ToS32(float value)
{ {
if (float.IsNaN(value)) if (float.IsNaN(value))
@@ -103,6 +107,7 @@ namespace ARMeilleure.Instructions
value <= int.MinValue ? int.MinValue : (int)value; value <= int.MinValue ? int.MinValue : (int)value;
} }
[UnmanagedCallersOnly]
public static long SatF32ToS64(float value) public static long SatF32ToS64(float value)
{ {
if (float.IsNaN(value)) if (float.IsNaN(value))
@@ -114,6 +119,7 @@ namespace ARMeilleure.Instructions
value <= long.MinValue ? long.MinValue : (long)value; value <= long.MinValue ? long.MinValue : (long)value;
} }
[UnmanagedCallersOnly]
public static uint SatF32ToU32(float value) public static uint SatF32ToU32(float value)
{ {
if (float.IsNaN(value)) if (float.IsNaN(value))
@@ -125,6 +131,7 @@ namespace ARMeilleure.Instructions
value <= uint.MinValue ? uint.MinValue : (uint)value; value <= uint.MinValue ? uint.MinValue : (uint)value;
} }
[UnmanagedCallersOnly]
public static ulong SatF32ToU64(float value) public static ulong SatF32ToU64(float value)
{ {
if (float.IsNaN(value)) if (float.IsNaN(value))
@@ -136,6 +143,7 @@ namespace ARMeilleure.Instructions
value <= ulong.MinValue ? ulong.MinValue : (ulong)value; value <= ulong.MinValue ? ulong.MinValue : (ulong)value;
} }
[UnmanagedCallersOnly]
public static int SatF64ToS32(double value) public static int SatF64ToS32(double value)
{ {
if (double.IsNaN(value)) if (double.IsNaN(value))
@@ -147,6 +155,7 @@ namespace ARMeilleure.Instructions
value <= int.MinValue ? int.MinValue : (int)value; value <= int.MinValue ? int.MinValue : (int)value;
} }
[UnmanagedCallersOnly]
public static long SatF64ToS64(double value) public static long SatF64ToS64(double value)
{ {
if (double.IsNaN(value)) if (double.IsNaN(value))
@@ -158,6 +167,7 @@ namespace ARMeilleure.Instructions
value <= long.MinValue ? long.MinValue : (long)value; value <= long.MinValue ? long.MinValue : (long)value;
} }
[UnmanagedCallersOnly]
public static uint SatF64ToU32(double value) public static uint SatF64ToU32(double value)
{ {
if (double.IsNaN(value)) if (double.IsNaN(value))
@@ -169,6 +179,7 @@ namespace ARMeilleure.Instructions
value <= uint.MinValue ? uint.MinValue : (uint)value; value <= uint.MinValue ? uint.MinValue : (uint)value;
} }
[UnmanagedCallersOnly]
public static ulong SatF64ToU64(double value) public static ulong SatF64ToU64(double value)
{ {
if (double.IsNaN(value)) if (double.IsNaN(value))
@@ -182,6 +193,7 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "Count" #region "Count"
[UnmanagedCallersOnly]
public static ulong CountLeadingSigns(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.). public static ulong CountLeadingSigns(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
{ {
value ^= value >> 1; value ^= value >> 1;
@@ -201,6 +213,7 @@ namespace ARMeilleure.Instructions
private static ReadOnlySpan<byte> ClzNibbleTbl => [4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]; private static ReadOnlySpan<byte> ClzNibbleTbl => [4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0];
[UnmanagedCallersOnly]
public static ulong CountLeadingZeros(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.). public static ulong CountLeadingZeros(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
{ {
if (value == 0ul) if (value == 0ul)
@@ -224,41 +237,49 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "Table" #region "Table"
[UnmanagedCallersOnly]
public static V128 Tbl1(V128 vector, int bytes, V128 tb0) public static V128 Tbl1(V128 vector, int bytes, V128 tb0)
{ {
return TblOrTbx(default, vector, bytes, tb0); return TblOrTbx(default, vector, bytes, tb0);
} }
[UnmanagedCallersOnly]
public static V128 Tbl2(V128 vector, int bytes, V128 tb0, V128 tb1) public static V128 Tbl2(V128 vector, int bytes, V128 tb0, V128 tb1)
{ {
return TblOrTbx(default, vector, bytes, tb0, tb1); return TblOrTbx(default, vector, bytes, tb0, tb1);
} }
[UnmanagedCallersOnly]
public static V128 Tbl3(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2) public static V128 Tbl3(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2)
{ {
return TblOrTbx(default, vector, bytes, tb0, tb1, tb2); return TblOrTbx(default, vector, bytes, tb0, tb1, tb2);
} }
[UnmanagedCallersOnly]
public static V128 Tbl4(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3) public static V128 Tbl4(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3)
{ {
return TblOrTbx(default, vector, bytes, tb0, tb1, tb2, tb3); return TblOrTbx(default, vector, bytes, tb0, tb1, tb2, tb3);
} }
[UnmanagedCallersOnly]
public static V128 Tbx1(V128 dest, V128 vector, int bytes, V128 tb0) public static V128 Tbx1(V128 dest, V128 vector, int bytes, V128 tb0)
{ {
return TblOrTbx(dest, vector, bytes, tb0); return TblOrTbx(dest, vector, bytes, tb0);
} }
[UnmanagedCallersOnly]
public static V128 Tbx2(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1) public static V128 Tbx2(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1)
{ {
return TblOrTbx(dest, vector, bytes, tb0, tb1); return TblOrTbx(dest, vector, bytes, tb0, tb1);
} }
[UnmanagedCallersOnly]
public static V128 Tbx3(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2) public static V128 Tbx3(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2)
{ {
return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2); return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2);
} }
[UnmanagedCallersOnly]
public static V128 Tbx4(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3) public static V128 Tbx4(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3)
{ {
return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2, tb3); return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2, tb3);
@@ -300,14 +321,22 @@ namespace ARMeilleure.Instructions
private const uint Crc32RevPoly = 0xedb88320; private const uint Crc32RevPoly = 0xedb88320;
private const uint Crc32cRevPoly = 0x82f63b78; private const uint Crc32cRevPoly = 0x82f63b78;
[UnmanagedCallersOnly]
public static uint Crc32b(uint crc, byte value) => Crc32(crc, Crc32RevPoly, value); public static uint Crc32b(uint crc, byte value) => Crc32(crc, Crc32RevPoly, value);
[UnmanagedCallersOnly]
public static uint Crc32h(uint crc, ushort value) => Crc32h(crc, Crc32RevPoly, value); public static uint Crc32h(uint crc, ushort value) => Crc32h(crc, Crc32RevPoly, value);
[UnmanagedCallersOnly]
public static uint Crc32w(uint crc, uint value) => Crc32w(crc, Crc32RevPoly, value); public static uint Crc32w(uint crc, uint value) => Crc32w(crc, Crc32RevPoly, value);
[UnmanagedCallersOnly]
public static uint Crc32x(uint crc, ulong value) => Crc32x(crc, Crc32RevPoly, value); public static uint Crc32x(uint crc, ulong value) => Crc32x(crc, Crc32RevPoly, value);
[UnmanagedCallersOnly]
public static uint Crc32cb(uint crc, byte value) => Crc32(crc, Crc32cRevPoly, value); public static uint Crc32cb(uint crc, byte value) => Crc32(crc, Crc32cRevPoly, value);
[UnmanagedCallersOnly]
public static uint Crc32ch(uint crc, ushort value) => Crc32h(crc, Crc32cRevPoly, value); public static uint Crc32ch(uint crc, ushort value) => Crc32h(crc, Crc32cRevPoly, value);
[UnmanagedCallersOnly]
public static uint Crc32cw(uint crc, uint value) => Crc32w(crc, Crc32cRevPoly, value); public static uint Crc32cw(uint crc, uint value) => Crc32w(crc, Crc32cRevPoly, value);
[UnmanagedCallersOnly]
public static uint Crc32cx(uint crc, ulong value) => Crc32x(crc, Crc32cRevPoly, value); public static uint Crc32cx(uint crc, ulong value) => Crc32x(crc, Crc32cRevPoly, value);
private static uint Crc32h(uint crc, uint poly, ushort val) private static uint Crc32h(uint crc, uint poly, ushort val)
@@ -358,21 +387,25 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "Aes" #region "Aes"
[UnmanagedCallersOnly]
public static V128 Decrypt(V128 value, V128 roundKey) public static V128 Decrypt(V128 value, V128 roundKey)
{ {
return CryptoHelper.AesInvSubBytes(CryptoHelper.AesInvShiftRows(value ^ roundKey)); return CryptoHelper.AesInvSubBytes(CryptoHelper.AesInvShiftRows(value ^ roundKey));
} }
[UnmanagedCallersOnly]
public static V128 Encrypt(V128 value, V128 roundKey) public static V128 Encrypt(V128 value, V128 roundKey)
{ {
return CryptoHelper.AesSubBytes(CryptoHelper.AesShiftRows(value ^ roundKey)); return CryptoHelper.AesSubBytes(CryptoHelper.AesShiftRows(value ^ roundKey));
} }
[UnmanagedCallersOnly]
public static V128 InverseMixColumns(V128 value) public static V128 InverseMixColumns(V128 value)
{ {
return CryptoHelper.AesInvMixColumns(value); return CryptoHelper.AesInvMixColumns(value);
} }
[UnmanagedCallersOnly]
public static V128 MixColumns(V128 value) public static V128 MixColumns(V128 value)
{ {
return CryptoHelper.AesMixColumns(value); return CryptoHelper.AesMixColumns(value);
@@ -380,6 +413,7 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "Sha1" #region "Sha1"
[UnmanagedCallersOnly]
public static V128 HashChoose(V128 hash_abcd, uint hash_e, V128 wk) public static V128 HashChoose(V128 hash_abcd, uint hash_e, V128 wk)
{ {
for (int e = 0; e <= 3; e++) for (int e = 0; e <= 3; e++)
@@ -400,11 +434,13 @@ namespace ARMeilleure.Instructions
return hash_abcd; return hash_abcd;
} }
[UnmanagedCallersOnly]
public static uint FixedRotate(uint hash_e) public static uint FixedRotate(uint hash_e)
{ {
return hash_e.Rol(30); return hash_e.Rol(30);
} }
[UnmanagedCallersOnly]
public static V128 HashMajority(V128 hash_abcd, uint hash_e, V128 wk) public static V128 HashMajority(V128 hash_abcd, uint hash_e, V128 wk)
{ {
for (int e = 0; e <= 3; e++) for (int e = 0; e <= 3; e++)
@@ -425,6 +461,7 @@ namespace ARMeilleure.Instructions
return hash_abcd; return hash_abcd;
} }
[UnmanagedCallersOnly]
public static V128 HashParity(V128 hash_abcd, uint hash_e, V128 wk) public static V128 HashParity(V128 hash_abcd, uint hash_e, V128 wk)
{ {
for (int e = 0; e <= 3; e++) for (int e = 0; e <= 3; e++)
@@ -445,6 +482,7 @@ namespace ARMeilleure.Instructions
return hash_abcd; return hash_abcd;
} }
[UnmanagedCallersOnly]
public static V128 Sha1SchedulePart1(V128 w0_3, V128 w4_7, V128 w8_11) public static V128 Sha1SchedulePart1(V128 w0_3, V128 w4_7, V128 w8_11)
{ {
ulong t2 = w4_7.Extract<ulong>(0); ulong t2 = w4_7.Extract<ulong>(0);
@@ -455,6 +493,7 @@ namespace ARMeilleure.Instructions
return result ^ (w0_3 ^ w8_11); return result ^ (w0_3 ^ w8_11);
} }
[UnmanagedCallersOnly]
public static V128 Sha1SchedulePart2(V128 tw0_3, V128 w12_15) public static V128 Sha1SchedulePart2(V128 tw0_3, V128 w12_15)
{ {
V128 t = tw0_3 ^ (w12_15 >> 32); V128 t = tw0_3 ^ (w12_15 >> 32);
@@ -499,16 +538,19 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "Sha256" #region "Sha256"
[UnmanagedCallersOnly]
public static V128 HashLower(V128 hash_abcd, V128 hash_efgh, V128 wk) public static V128 HashLower(V128 hash_abcd, V128 hash_efgh, V128 wk)
{ {
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: true); return Sha256Hash(hash_abcd, hash_efgh, wk, part1: true);
} }
[UnmanagedCallersOnly]
public static V128 HashUpper(V128 hash_abcd, V128 hash_efgh, V128 wk) public static V128 HashUpper(V128 hash_abcd, V128 hash_efgh, V128 wk)
{ {
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: false); return Sha256Hash(hash_abcd, hash_efgh, wk, part1: false);
} }
[UnmanagedCallersOnly]
public static V128 Sha256SchedulePart1(V128 w0_3, V128 w4_7) public static V128 Sha256SchedulePart1(V128 w0_3, V128 w4_7)
{ {
V128 result = new(); V128 result = new();
@@ -527,6 +569,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static V128 Sha256SchedulePart2(V128 w0_3, V128 w8_11, V128 w12_15) public static V128 Sha256SchedulePart2(V128 w0_3, V128 w8_11, V128 w12_15)
{ {
V128 result = new(); V128 result = new();
@@ -628,6 +671,7 @@ namespace ARMeilleure.Instructions
} }
#endregion #endregion
[UnmanagedCallersOnly]
public static V128 PolynomialMult64_128(ulong op1, ulong op2) public static V128 PolynomialMult64_128(ulong op1, ulong op2)
{ {
V128 result = V128.Zero; V128 result = V128.Zero;
+295 -86
View File
@@ -1,6 +1,7 @@
using ARMeilleure.State; using ARMeilleure.State;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
@@ -312,6 +313,7 @@ namespace ARMeilleure.Instructions
static class SoftFloat16_32 static class SoftFloat16_32
{ {
[UnmanagedCallersOnly]
public static float FPConvert(ushort valueBits) public static float FPConvert(ushort valueBits)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -487,6 +489,7 @@ namespace ARMeilleure.Instructions
static class SoftFloat16_64 static class SoftFloat16_64
{ {
[UnmanagedCallersOnly]
public static double FPConvert(ushort valueBits) public static double FPConvert(ushort valueBits)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -662,6 +665,7 @@ namespace ARMeilleure.Instructions
static class SoftFloat32_16 static class SoftFloat32_16
{ {
[UnmanagedCallersOnly]
public static ushort FPConvert(float value) public static ushort FPConvert(float value)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -781,12 +785,19 @@ namespace ARMeilleure.Instructions
static class SoftFloat32 static class SoftFloat32
{ {
[UnmanagedCallersOnly]
public static float FPAdd(float value1, float value2) public static float FPAdd(float value1, float value2)
{ {
return FPAddFpscr(value1, value2, false); return FPAddFpscrImpl(value1, value2, false);
} }
public static float FPAddFpscr(float value1, float value2, bool standardFpscr) [UnmanagedCallersOnly]
public static float FPAddFpscr(float value1, float value2, byte standardFpscr)
{
return FPAddFpscrImpl(value1, value2, standardFpscr == 1);
}
private static float FPAddFpscrImpl(float value1, float value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -837,7 +848,8 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
public static int FPCompare(float value1, float value2, bool signalNaNs) [UnmanagedCallersOnly]
public static int FPCompare(float value1, float value2, byte signalNaNs)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = context.Fpcr; FPCR fpcr = context.Fpcr;
@@ -851,7 +863,7 @@ namespace ARMeilleure.Instructions
{ {
result = 0b0011; result = 0b0011;
if (type1 == FPType.SNaN || type2 == FPType.SNaN || signalNaNs) if (type1 == FPType.SNaN || type2 == FPType.SNaN || signalNaNs == 1)
{ {
SoftFloat.FPProcessException(FPException.InvalidOp, context, fpcr); SoftFloat.FPProcessException(FPException.InvalidOp, context, fpcr);
} }
@@ -875,12 +887,13 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPCompareEQ(float value1, float value2) public static float FPCompareEQ(float value1, float value2)
{ {
return FPCompareEQFpscr(value1, value2, false); return FPCompareEQFpscrImpl(value1, value2, false);
} }
public static float FPCompareEQFpscr(float value1, float value2, bool standardFpscr) private static float FPCompareEQFpscrImpl(float value1, float value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -907,12 +920,25 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
public static float FPCompareGE(float value1, float value2) [UnmanagedCallersOnly]
public static float FPCompareEQFpscr(float value1, float value2, byte standardFpscr)
{ {
return FPCompareGEFpscr(value1, value2, false); return FPCompareEQFpscrImpl(value1, value2, standardFpscr == 1);
} }
public static float FPCompareGEFpscr(float value1, float value2, bool standardFpscr) [UnmanagedCallersOnly]
public static float FPCompareGE(float value1, float value2)
{
return FPCompareGEFpscrImpl(value1, value2, false);
}
[UnmanagedCallersOnly]
public static float FPCompareGEFpscr(float value1, float value2, byte standardFpscr)
{
return FPCompareGEFpscrImpl(value1, value2, standardFpscr == 1);
}
private static float FPCompareGEFpscrImpl(float value1, float value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -936,12 +962,19 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPCompareGT(float value1, float value2) public static float FPCompareGT(float value1, float value2)
{ {
return FPCompareGTFpscr(value1, value2, false); return FPCompareGTFpscrImpl(value1, value2, false);
} }
public static float FPCompareGTFpscr(float value1, float value2, bool standardFpscr) [UnmanagedCallersOnly]
public static float FPCompareGTFpscr(float value1, float value2, byte standardFpscr)
{
return FPCompareGTFpscrImpl(value1, value2, standardFpscr == 1);
}
private static float FPCompareGTFpscrImpl(float value1, float value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -965,26 +998,31 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPCompareLE(float value1, float value2) public static float FPCompareLE(float value1, float value2)
{ {
return FPCompareGE(value2, value1); return FPCompareGEFpscrImpl(value2, value1, false);
} }
[UnmanagedCallersOnly]
public static float FPCompareLT(float value1, float value2) public static float FPCompareLT(float value1, float value2)
{ {
return FPCompareGT(value2, value1); return FPCompareGTFpscrImpl(value2, value1, false);
} }
public static float FPCompareLEFpscr(float value1, float value2, bool standardFpscr) [UnmanagedCallersOnly]
public static float FPCompareLEFpscr(float value1, float value2, byte standardFpscr)
{ {
return FPCompareGEFpscr(value2, value1, standardFpscr); return FPCompareGEFpscrImpl(value2, value1, standardFpscr == 1);
} }
public static float FPCompareLTFpscr(float value1, float value2, bool standardFpscr) [UnmanagedCallersOnly]
public static float FPCompareLTFpscr(float value1, float value2, byte standardFpscr)
{ {
return FPCompareGTFpscr(value2, value1, standardFpscr); return FPCompareGEFpscrImpl(value2, value1, standardFpscr == 1);
} }
[UnmanagedCallersOnly]
public static float FPDiv(float value1, float value2) public static float FPDiv(float value1, float value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -1037,12 +1075,19 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPMax(float value1, float value2) public static float FPMax(float value1, float value2)
{ {
return FPMaxFpscr(value1, value2, false); return FPMaxFpscrImpl(value1, value2, false);
} }
public static float FPMaxFpscr(float value1, float value2, bool standardFpscr) [UnmanagedCallersOnly]
public static float FPMaxFpscr(float value1, float value2, byte standardFpscr)
{
return FPMaxFpscrImpl(value1, value2, standardFpscr == 1);
}
private static float FPMaxFpscrImpl(float value1, float value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -1103,12 +1148,13 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPMaxNum(float value1, float value2) public static float FPMaxNum(float value1, float value2)
{ {
return FPMaxNumFpscr(value1, value2, false); return FPMaxNumFpscrImpl(value1, value2, false);
} }
public static float FPMaxNumFpscr(float value1, float value2, bool standardFpscr) private static float FPMaxNumFpscrImpl(float value1, float value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -1125,15 +1171,28 @@ namespace ARMeilleure.Instructions
value2 = FPInfinity(true); value2 = FPInfinity(true);
} }
return FPMaxFpscr(value1, value2, standardFpscr); return FPMaxFpscrImpl(value1, value2, standardFpscr);
} }
[UnmanagedCallersOnly]
public static float FPMaxNumFpscr(float value1, float value2, byte standardFpscr)
{
return FPMaxNumFpscrImpl(value1, value2, standardFpscr == 1);
}
[UnmanagedCallersOnly]
public static float FPMin(float value1, float value2) public static float FPMin(float value1, float value2)
{ {
return FPMinFpscr(value1, value2, false); return FPMinFpscrImpl(value1, value2, false);
} }
public static float FPMinFpscr(float value1, float value2, bool standardFpscr) [UnmanagedCallersOnly]
public static float FPMinFpscr(float value1, float value2, byte standardFpscr)
{
return FPMinFpscrImpl(value1, value2, standardFpscr == 1);
}
private static float FPMinFpscrImpl(float value1, float value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -1194,12 +1253,19 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPMinNum(float value1, float value2) public static float FPMinNum(float value1, float value2)
{ {
return FPMinNumFpscr(value1, value2, false); return FPMinNumFpscrImpl(value1, value2, false);
} }
public static float FPMinNumFpscr(float value1, float value2, bool standardFpscr) [UnmanagedCallersOnly]
public static float FPMinNumFpscr(float value1, float value2, byte standardFpscr)
{
return FPMinNumFpscrImpl(value1, value2, standardFpscr == 1);
}
private static float FPMinNumFpscrImpl(float value1, float value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -1216,15 +1282,22 @@ namespace ARMeilleure.Instructions
value2 = FPInfinity(false); value2 = FPInfinity(false);
} }
return FPMinFpscr(value1, value2, standardFpscr); return FPMinFpscrImpl(value1, value2, standardFpscr);
} }
[UnmanagedCallersOnly]
public static float FPMul(float value1, float value2) public static float FPMul(float value1, float value2)
{ {
return FPMulFpscr(value1, value2, false); return FPMulFpscrImpl(value1, value2, false);
} }
public static float FPMulFpscr(float value1, float value2, bool standardFpscr) [UnmanagedCallersOnly]
public static float FPMulFpscr(float value1, float value2, byte standardFpscr)
{
return FPMulFpscrImpl(value1, value2, standardFpscr == 1);
}
private static float FPMulFpscrImpl(float value1, float value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -1271,12 +1344,19 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPMulAdd(float valueA, float value1, float value2) public static float FPMulAdd(float valueA, float value1, float value2)
{ {
return FPMulAddFpscr(valueA, value1, value2, false); return FPMulAddFpscrImpl(valueA, value1, value2, false);
} }
public static float FPMulAddFpscr(float valueA, float value1, float value2, bool standardFpscr) [UnmanagedCallersOnly]
public static float FPMulAddFpscr(float valueA, float value1, float value2, byte standardFpscr)
{
return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1);
}
private static float FPMulAddFpscrImpl(float valueA, float value1, float value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -1342,20 +1422,23 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPMulSub(float valueA, float value1, float value2) public static float FPMulSub(float valueA, float value1, float value2)
{ {
value1 = value1.FPNeg(); value1 = value1.FPNeg();
return FPMulAdd(valueA, value1, value2); return FPMulAddFpscrImpl(valueA, value1, value2, false);
} }
public static float FPMulSubFpscr(float valueA, float value1, float value2, bool standardFpscr) [UnmanagedCallersOnly]
public static float FPMulSubFpscr(float valueA, float value1, float value2, byte standardFpscr)
{ {
value1 = value1.FPNeg(); value1 = value1.FPNeg();
return FPMulAddFpscr(valueA, value1, value2, standardFpscr); return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1);
} }
[UnmanagedCallersOnly]
public static float FPMulX(float value1, float value2) public static float FPMulX(float value1, float value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -1401,27 +1484,36 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPNegMulAdd(float valueA, float value1, float value2) public static float FPNegMulAdd(float valueA, float value1, float value2)
{ {
valueA = valueA.FPNeg(); valueA = valueA.FPNeg();
value1 = value1.FPNeg(); value1 = value1.FPNeg();
return FPMulAdd(valueA, value1, value2); return FPMulAddFpscrImpl(valueA, value1, value2, false);
} }
[UnmanagedCallersOnly]
public static float FPNegMulSub(float valueA, float value1, float value2) public static float FPNegMulSub(float valueA, float value1, float value2)
{ {
valueA = valueA.FPNeg(); valueA = valueA.FPNeg();
return FPMulAdd(valueA, value1, value2); return FPMulAddFpscrImpl(valueA, value1, value2, false);
} }
[UnmanagedCallersOnly]
public static float FPRecipEstimate(float value) public static float FPRecipEstimate(float value)
{ {
return FPRecipEstimateFpscr(value, false); return FPRecipEstimateFpscrImpl(value, false);
} }
public static float FPRecipEstimateFpscr(float value, bool standardFpscr) [UnmanagedCallersOnly]
public static float FPRecipEstimateFpscr(float value, byte standardFpscr)
{
return FPRecipEstimateFpscrImpl(value, standardFpscr == 1);
}
private static float FPRecipEstimateFpscrImpl(float value, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -1508,6 +1600,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPRecipStep(float value1, float value2) public static float FPRecipStep(float value1, float value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -1533,15 +1626,16 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
product = FPMulFpscr(value1, value2, true); product = FPMulFpscrImpl(value1, value2, true);
} }
result = FPSubFpscr(FPTwo(false), product, true); result = FPSubFpscrImpl(FPTwo(false), product, true);
} }
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPRecipStepFused(float value1, float value2) public static float FPRecipStepFused(float value1, float value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -1585,6 +1679,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPRecpX(float value) public static float FPRecpX(float value)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -1610,12 +1705,19 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPRSqrtEstimate(float value) public static float FPRSqrtEstimate(float value)
{ {
return FPRSqrtEstimateFpscr(value, false); return FPRSqrtEstimateFpscrImpl(value, false);
} }
public static float FPRSqrtEstimateFpscr(float value, bool standardFpscr) [UnmanagedCallersOnly]
public static float FPRSqrtEstimateFpscr(float value, byte standardFpscr)
{
return FPRSqrtEstimateFpscrImpl(value, standardFpscr == 1);
}
private static float FPRSqrtEstimateFpscrImpl(float value, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -1729,6 +1831,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPRSqrtStep(float value1, float value2) public static float FPRSqrtStep(float value1, float value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -1754,7 +1857,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
product = FPMulFpscr(value1, value2, true); product = FPMulFpscrImpl(value1, value2, true);
} }
result = FPHalvedSub(FPThree(false), product, context, fpcr); result = FPHalvedSub(FPThree(false), product, context, fpcr);
@@ -1763,6 +1866,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPRSqrtStepFused(float value1, float value2) public static float FPRSqrtStepFused(float value1, float value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -1806,6 +1910,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPSqrt(float value) public static float FPSqrt(float value)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -1848,12 +1953,13 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static float FPSub(float value1, float value2) public static float FPSub(float value1, float value2)
{ {
return FPSubFpscr(value1, value2, false); return FPSubFpscrImpl(value1, value2, false);
} }
public static float FPSubFpscr(float value1, float value2, bool standardFpscr) private static float FPSubFpscrImpl(float value1, float value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -2094,6 +2200,7 @@ namespace ARMeilleure.Instructions
static class SoftFloat64_16 static class SoftFloat64_16
{ {
[UnmanagedCallersOnly]
public static ushort FPConvert(double value) public static ushort FPConvert(double value)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -2213,12 +2320,19 @@ namespace ARMeilleure.Instructions
static class SoftFloat64 static class SoftFloat64
{ {
[UnmanagedCallersOnly]
public static double FPAdd(double value1, double value2) public static double FPAdd(double value1, double value2)
{ {
return FPAddFpscr(value1, value2, false); return FPAddFpscrImpl(value1, value2, false);
} }
public static double FPAddFpscr(double value1, double value2, bool standardFpscr) [UnmanagedCallersOnly]
public static double FPAddFpscr(double value1, double value2, byte standardFpscr)
{
return FPAddFpscrImpl(value1, value2, standardFpscr == 1);
}
private static double FPAddFpscrImpl(double value1, double value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -2269,7 +2383,8 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
public static int FPCompare(double value1, double value2, bool signalNaNs) [UnmanagedCallersOnly]
public static int FPCompare(double value1, double value2, byte signalNaNs)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = context.Fpcr; FPCR fpcr = context.Fpcr;
@@ -2283,7 +2398,7 @@ namespace ARMeilleure.Instructions
{ {
result = 0b0011; result = 0b0011;
if (type1 == FPType.SNaN || type2 == FPType.SNaN || signalNaNs) if (type1 == FPType.SNaN || type2 == FPType.SNaN || signalNaNs == 1)
{ {
SoftFloat.FPProcessException(FPException.InvalidOp, context, fpcr); SoftFloat.FPProcessException(FPException.InvalidOp, context, fpcr);
} }
@@ -2307,12 +2422,19 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPCompareEQ(double value1, double value2) public static double FPCompareEQ(double value1, double value2)
{ {
return FPCompareEQFpscr(value1, value2, false); return FPCompareEQFpscrImpl(value1, value2, false);
} }
public static double FPCompareEQFpscr(double value1, double value2, bool standardFpscr) [UnmanagedCallersOnly]
public static double FPCompareEQFpscr(double value1, double value2, byte standardFpscr)
{
return FPCompareEQFpscrImpl(value1, value2, standardFpscr == 1);
}
private static double FPCompareEQFpscrImpl(double value1, double value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -2339,12 +2461,19 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPCompareGE(double value1, double value2) public static double FPCompareGE(double value1, double value2)
{ {
return FPCompareGEFpscr(value1, value2, false); return FPCompareGEFpscrImpl(value1, value2, false);
} }
public static double FPCompareGEFpscr(double value1, double value2, bool standardFpscr) [UnmanagedCallersOnly]
public static double FPCompareGEFpscr(double value1, double value2, byte standardFpscr)
{
return FPCompareGEFpscrImpl(value1, value2, standardFpscr == 1);
}
private static double FPCompareGEFpscrImpl(double value1, double value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -2368,12 +2497,19 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPCompareGT(double value1, double value2) public static double FPCompareGT(double value1, double value2)
{ {
return FPCompareGTFpscr(value1, value2, false); return FPCompareGTFpscrImpl(value1, value2, false);
} }
public static double FPCompareGTFpscr(double value1, double value2, bool standardFpscr) [UnmanagedCallersOnly]
public static double FPCompareGTFpscr(double value1, double value2, byte standardFpscr)
{
return FPCompareGTFpscrImpl(value1, value2, standardFpscr == 1);
}
private static double FPCompareGTFpscrImpl(double value1, double value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -2397,26 +2533,31 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPCompareLE(double value1, double value2) public static double FPCompareLE(double value1, double value2)
{ {
return FPCompareGE(value2, value1); return FPCompareGEFpscrImpl(value2, value1, false);
} }
[UnmanagedCallersOnly]
public static double FPCompareLT(double value1, double value2) public static double FPCompareLT(double value1, double value2)
{ {
return FPCompareGT(value2, value1); return FPCompareGTFpscrImpl(value2, value1, false);
} }
public static double FPCompareLEFpscr(double value1, double value2, bool standardFpscr) [UnmanagedCallersOnly]
public static double FPCompareLEFpscr(double value1, double value2, byte standardFpscr)
{ {
return FPCompareGEFpscr(value2, value1, standardFpscr); return FPCompareGEFpscrImpl(value2, value1, standardFpscr == 1);
} }
public static double FPCompareLTFpscr(double value1, double value2, bool standardFpscr) [UnmanagedCallersOnly]
public static double FPCompareLTFpscr(double value1, double value2, byte standardFpscr)
{ {
return FPCompareGTFpscr(value2, value1, standardFpscr); return FPCompareGTFpscrImpl(value2, value1, standardFpscr == 1);
} }
[UnmanagedCallersOnly]
public static double FPDiv(double value1, double value2) public static double FPDiv(double value1, double value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -2469,12 +2610,19 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPMax(double value1, double value2) public static double FPMax(double value1, double value2)
{ {
return FPMaxFpscr(value1, value2, false); return FPMaxFpscrImpl(value1, value2, false);
} }
public static double FPMaxFpscr(double value1, double value2, bool standardFpscr) [UnmanagedCallersOnly]
public static double FPMaxFpscr(double value1, double value2, byte standardFpscr)
{
return FPMaxFpscrImpl(value1, value2, standardFpscr == 1);
}
private static double FPMaxFpscrImpl(double value1, double value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -2535,12 +2683,19 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPMaxNum(double value1, double value2) public static double FPMaxNum(double value1, double value2)
{ {
return FPMaxNumFpscr(value1, value2, false); return FPMaxNumFpscrImpl(value1, value2, false);
} }
public static double FPMaxNumFpscr(double value1, double value2, bool standardFpscr) [UnmanagedCallersOnly]
public static double FPMaxNumFpscr(double value1, double value2, byte standardFpscr)
{
return FPMaxNumFpscrImpl(value1, value2, standardFpscr == 1);
}
private static double FPMaxNumFpscrImpl(double value1, double value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -2557,15 +2712,22 @@ namespace ARMeilleure.Instructions
value2 = FPInfinity(true); value2 = FPInfinity(true);
} }
return FPMaxFpscr(value1, value2, standardFpscr); return FPMaxFpscrImpl(value1, value2, standardFpscr);
} }
[UnmanagedCallersOnly]
public static double FPMin(double value1, double value2) public static double FPMin(double value1, double value2)
{ {
return FPMinFpscr(value1, value2, false); return FPMinFpscrImpl(value1, value2, false);
} }
public static double FPMinFpscr(double value1, double value2, bool standardFpscr) [UnmanagedCallersOnly]
public static double FPMinFpscr(double value1, double value2, byte standardFpscr)
{
return FPMinFpscrImpl(value1, value2, standardFpscr == 1);
}
private static double FPMinFpscrImpl(double value1, double value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -2626,12 +2788,19 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPMinNum(double value1, double value2) public static double FPMinNum(double value1, double value2)
{ {
return FPMinNumFpscr(value1, value2, false); return FPMinNumFpscrImpl(value1, value2, false);
} }
public static double FPMinNumFpscr(double value1, double value2, bool standardFpscr) [UnmanagedCallersOnly]
public static double FPMinNumFpscr(double value1, double value2, byte standardFpscr)
{
return FPMinNumFpscrImpl(value1, value2, standardFpscr == 1);
}
private static double FPMinNumFpscrImpl(double value1, double value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -2648,15 +2817,22 @@ namespace ARMeilleure.Instructions
value2 = FPInfinity(false); value2 = FPInfinity(false);
} }
return FPMinFpscr(value1, value2, standardFpscr); return FPMinFpscrImpl(value1, value2, standardFpscr);
} }
[UnmanagedCallersOnly]
public static double FPMul(double value1, double value2) public static double FPMul(double value1, double value2)
{ {
return FPMulFpscr(value1, value2, false); return FPMulFpscrImpl(value1, value2, false);
} }
public static double FPMulFpscr(double value1, double value2, bool standardFpscr) [UnmanagedCallersOnly]
public static double FPMulFpscr(double value1, double value2, byte standardFpscr)
{
return FPMulFpscrImpl(value1, value2, standardFpscr == 1);
}
private static double FPMulFpscrImpl(double value1, double value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -2703,12 +2879,19 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPMulAdd(double valueA, double value1, double value2) public static double FPMulAdd(double valueA, double value1, double value2)
{ {
return FPMulAddFpscr(valueA, value1, value2, false); return FPMulAddFpscrImpl(valueA, value1, value2, false);
} }
public static double FPMulAddFpscr(double valueA, double value1, double value2, bool standardFpscr) [UnmanagedCallersOnly]
public static double FPMulAddFpscr(double valueA, double value1, double value2, byte standardFpscr)
{
return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1);
}
private static double FPMulAddFpscrImpl(double valueA, double value1, double value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -2774,20 +2957,23 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPMulSub(double valueA, double value1, double value2) public static double FPMulSub(double valueA, double value1, double value2)
{ {
value1 = value1.FPNeg(); value1 = value1.FPNeg();
return FPMulAdd(valueA, value1, value2); return FPMulAddFpscrImpl(valueA, value1, value2, false);
} }
public static double FPMulSubFpscr(double valueA, double value1, double value2, bool standardFpscr) [UnmanagedCallersOnly]
public static double FPMulSubFpscr(double valueA, double value1, double value2, byte standardFpscr)
{ {
value1 = value1.FPNeg(); value1 = value1.FPNeg();
return FPMulAddFpscr(valueA, value1, value2, standardFpscr); return FPMulAddFpscrImpl(valueA, value1, value2, standardFpscr == 1);
} }
[UnmanagedCallersOnly]
public static double FPMulX(double value1, double value2) public static double FPMulX(double value1, double value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -2833,27 +3019,36 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPNegMulAdd(double valueA, double value1, double value2) public static double FPNegMulAdd(double valueA, double value1, double value2)
{ {
valueA = valueA.FPNeg(); valueA = valueA.FPNeg();
value1 = value1.FPNeg(); value1 = value1.FPNeg();
return FPMulAdd(valueA, value1, value2); return FPMulAddFpscrImpl(valueA, value1, value2, false);
} }
[UnmanagedCallersOnly]
public static double FPNegMulSub(double valueA, double value1, double value2) public static double FPNegMulSub(double valueA, double value1, double value2)
{ {
valueA = valueA.FPNeg(); valueA = valueA.FPNeg();
return FPMulAdd(valueA, value1, value2); return FPMulAddFpscrImpl(valueA, value1, value2, false);
} }
[UnmanagedCallersOnly]
public static double FPRecipEstimate(double value) public static double FPRecipEstimate(double value)
{ {
return FPRecipEstimateFpscr(value, false); return FPRecipEstimateFpscrImpl(value, false);
} }
public static double FPRecipEstimateFpscr(double value, bool standardFpscr) [UnmanagedCallersOnly]
public static double FPRecipEstimateFpscr(double value, byte standardFpscr)
{
return FPRecipEstimateFpscrImpl(value, standardFpscr == 1);
}
private static double FPRecipEstimateFpscrImpl(double value, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -2940,6 +3135,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPRecipStep(double value1, double value2) public static double FPRecipStep(double value1, double value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -2965,7 +3161,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
product = FPMulFpscr(value1, value2, true); product = FPMulFpscrImpl(value1, value2, true);
} }
result = FPSubFpscr(FPTwo(false), product, true); result = FPSubFpscr(FPTwo(false), product, true);
@@ -2974,6 +3170,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPRecipStepFused(double value1, double value2) public static double FPRecipStepFused(double value1, double value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -3017,6 +3214,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPRecpX(double value) public static double FPRecpX(double value)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -3042,12 +3240,19 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPRSqrtEstimate(double value) public static double FPRSqrtEstimate(double value)
{ {
return FPRSqrtEstimateFpscr(value, false); return FPRSqrtEstimateFpscrImpl(value, false);
} }
public static double FPRSqrtEstimateFpscr(double value, bool standardFpscr) [UnmanagedCallersOnly]
public static double FPRSqrtEstimateFpscr(double value, byte standardFpscr)
{
return FPRSqrtEstimateFpscrImpl(value, standardFpscr == 1);
}
private static double FPRSqrtEstimateFpscrImpl(double value, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr; FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
@@ -3161,6 +3366,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPRSqrtStep(double value1, double value2) public static double FPRSqrtStep(double value1, double value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -3186,7 +3392,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
product = FPMulFpscr(value1, value2, true); product = FPMulFpscrImpl(value1, value2, true);
} }
result = FPHalvedSub(FPThree(false), product, context, fpcr); result = FPHalvedSub(FPThree(false), product, context, fpcr);
@@ -3195,6 +3401,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPRSqrtStepFused(double value1, double value2) public static double FPRSqrtStepFused(double value1, double value2)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -3238,6 +3445,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPSqrt(double value) public static double FPSqrt(double value)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -3280,6 +3488,7 @@ namespace ARMeilleure.Instructions
return result; return result;
} }
[UnmanagedCallersOnly]
public static double FPSub(double value1, double value2) public static double FPSub(double value1, double value2)
{ {
return FPSubFpscr(value1, value2, false); return FPSubFpscr(value1, value2, false);
+1 -8
View File
@@ -1,18 +1,11 @@
using System;
namespace ARMeilleure.Translation namespace ARMeilleure.Translation
{ {
class DelegateInfo class DelegateInfo
{ {
#pragma warning disable IDE0052 // Remove unread private member
private readonly Delegate _dlg; // Ensure that this delegate will not be garbage collected.
#pragma warning restore IDE0052
public nint FuncPtr { get; } public nint FuncPtr { get; }
public DelegateInfo(Delegate dlg, nint funcPtr) public DelegateInfo(nint funcPtr)
{ {
_dlg = dlg;
FuncPtr = funcPtr; FuncPtr = funcPtr;
} }
} }
+169 -534
View File
@@ -1,9 +1,7 @@
using ARMeilleure.Instructions; using ARMeilleure.Instructions;
using ARMeilleure.State;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices;
namespace ARMeilleure.Translation namespace ARMeilleure.Translation
{ {
@@ -35,20 +33,6 @@ namespace ARMeilleure.Translation
return _delegates.Values[index].FuncPtr; // O(1). return _delegates.Values[index].FuncPtr; // O(1).
} }
public static IntPtr GetDelegateFuncPtr(MethodInfo info)
{
ArgumentNullException.ThrowIfNull(info);
string key = GetKey(info);
if (!_delegates.TryGetValue(key, out DelegateInfo dlgInfo)) // O(log(n)).
{
throw new KeyNotFoundException($"({nameof(key)} = {key})");
}
return dlgInfo.FuncPtr;
}
public static int GetDelegateIndex(MethodInfo info) public static int GetDelegateIndex(MethodInfo info)
{ {
ArgumentNullException.ThrowIfNull(info); ArgumentNullException.ThrowIfNull(info);
@@ -65,11 +49,11 @@ namespace ARMeilleure.Translation
return index; return index;
} }
private static void SetDelegateInfo(Delegate dlg, IntPtr funcPtr) private static void SetDelegateInfo(MethodInfo method)
{ {
string key = GetKey(dlg.Method); string key = GetKey(method);
_delegates.Add(key, new DelegateInfo(dlg, funcPtr)); // ArgumentException (key). _delegates.Add(key, new DelegateInfo(method.MethodHandle.GetFunctionPointer())); // ArgumentException (key).
} }
private static string GetKey(MethodInfo info) private static string GetKey(MethodInfo info)
@@ -79,532 +63,183 @@ namespace ARMeilleure.Translation
private static readonly SortedList<string, DelegateInfo> _delegates; private static readonly SortedList<string, DelegateInfo> _delegates;
static Delegates() unsafe static Delegates()
{ {
_delegates = new SortedList<string, DelegateInfo>(); _delegates = new SortedList<string, DelegateInfo>();
var dlgMathAbs = new MathAbs(Math.Abs); SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Abs)));
var dlgMathCeiling = new MathCeiling(Math.Ceiling); SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Ceiling)));
var dlgMathFloor = new MathFloor(Math.Floor); SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Floor)));
var dlgMathRound = new MathRound(Math.Round); SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Round)));
var dlgMathTruncate = new MathTruncate(Math.Truncate); SetDelegateInfo(typeof(MathHelper).GetMethod(nameof(MathHelper.Truncate)));
var dlgMathFAbs = new MathFAbs(MathF.Abs); SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Abs)));
var dlgMathFCeiling = new MathFCeiling(MathF.Ceiling); SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Ceiling)));
var dlgMathFFloor = new MathFFloor(MathF.Floor); SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Floor)));
var dlgMathFRound = new MathFRound(MathF.Round); SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Round)));
var dlgMathFTruncate = new MathFTruncate(MathF.Truncate); SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Truncate)));
var dlgNativeInterfaceBreak = new NativeInterfaceBreak(NativeInterface.Break); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Break)));
var dlgNativeInterfaceCheckSynchronization = new NativeInterfaceCheckSynchronization(NativeInterface.CheckSynchronization); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.CheckSynchronization)));
var dlgNativeInterfaceEnqueueForRejit = new NativeInterfaceEnqueueForRejit(NativeInterface.EnqueueForRejit); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.EnqueueForRejit)));
var dlgNativeInterfaceGetCntfrqEl0 = new NativeInterfaceGetCntfrqEl0(NativeInterface.GetCntfrqEl0); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0)));
var dlgNativeInterfaceGetCntpctEl0 = new NativeInterfaceGetCntpctEl0(NativeInterface.GetCntpctEl0); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)));
var dlgNativeInterfaceGetCntvctEl0 = new NativeInterfaceGetCntvctEl0(NativeInterface.GetCntvctEl0); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntvctEl0)));
var dlgNativeInterfaceGetCtrEl0 = new NativeInterfaceGetCtrEl0(NativeInterface.GetCtrEl0); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCtrEl0)));
var dlgNativeInterfaceGetDczidEl0 = new NativeInterfaceGetDczidEl0(NativeInterface.GetDczidEl0); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetDczidEl0)));
var dlgNativeInterfaceGetFunctionAddress = new NativeInterfaceGetFunctionAddress(NativeInterface.GetFunctionAddress); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)));
var dlgNativeInterfaceInvalidateCacheLine = new NativeInterfaceInvalidateCacheLine(NativeInterface.InvalidateCacheLine); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.InvalidateCacheLine)));
var dlgNativeInterfaceReadByte = new NativeInterfaceReadByte(NativeInterface.ReadByte); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte)));
var dlgNativeInterfaceReadUInt16 = new NativeInterfaceReadUInt16(NativeInterface.ReadUInt16); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16)));
var dlgNativeInterfaceReadUInt32 = new NativeInterfaceReadUInt32(NativeInterface.ReadUInt32); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32)));
var dlgNativeInterfaceReadUInt64 = new NativeInterfaceReadUInt64(NativeInterface.ReadUInt64); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64)));
var dlgNativeInterfaceReadVector128 = new NativeInterfaceReadVector128(NativeInterface.ReadVector128); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128)));
var dlgNativeInterfaceSignalMemoryTracking = new NativeInterfaceSignalMemoryTracking(NativeInterface.SignalMemoryTracking); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking)));
var dlgNativeInterfaceSupervisorCall = new NativeInterfaceSupervisorCall(NativeInterface.SupervisorCall); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SupervisorCall)));
var dlgNativeInterfaceThrowInvalidMemoryAccess = new NativeInterfaceThrowInvalidMemoryAccess(NativeInterface.ThrowInvalidMemoryAccess); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess)));
var dlgNativeInterfaceUndefined = new NativeInterfaceUndefined(NativeInterface.Undefined); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Undefined)));
var dlgNativeInterfaceWriteByte = new NativeInterfaceWriteByte(NativeInterface.WriteByte); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte)));
var dlgNativeInterfaceWriteUInt16 = new NativeInterfaceWriteUInt16(NativeInterface.WriteUInt16); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16)));
var dlgNativeInterfaceWriteUInt32 = new NativeInterfaceWriteUInt32(NativeInterface.WriteUInt32); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32)));
var dlgNativeInterfaceWriteUInt64 = new NativeInterfaceWriteUInt64(NativeInterface.WriteUInt64); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)));
var dlgNativeInterfaceWriteVector128 = new NativeInterfaceWriteVector128(NativeInterface.WriteVector128); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128)));
var dlgSoftFallbackCountLeadingSigns = new SoftFallbackCountLeadingSigns(SoftFallback.CountLeadingSigns); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingSigns)));
var dlgSoftFallbackCountLeadingZeros = new SoftFallbackCountLeadingZeros(SoftFallback.CountLeadingZeros); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingZeros)));
var dlgSoftFallbackCrc32b = new SoftFallbackCrc32b(SoftFallback.Crc32b); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32b)));
var dlgSoftFallbackCrc32cb = new SoftFallbackCrc32cb(SoftFallback.Crc32cb); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cb)));
var dlgSoftFallbackCrc32ch = new SoftFallbackCrc32ch(SoftFallback.Crc32ch); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32ch)));
var dlgSoftFallbackCrc32cw = new SoftFallbackCrc32cw(SoftFallback.Crc32cw); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cw)));
var dlgSoftFallbackCrc32cx = new SoftFallbackCrc32cx(SoftFallback.Crc32cx); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cx)));
var dlgSoftFallbackCrc32h = new SoftFallbackCrc32h(SoftFallback.Crc32h); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32h)));
var dlgSoftFallbackCrc32w = new SoftFallbackCrc32w(SoftFallback.Crc32w); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32w)));
var dlgSoftFallbackCrc32x = new SoftFallbackCrc32x(SoftFallback.Crc32x); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32x)));
var dlgSoftFallbackDecrypt = new SoftFallbackDecrypt(SoftFallback.Decrypt); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Decrypt)));
var dlgSoftFallbackEncrypt = new SoftFallbackEncrypt(SoftFallback.Encrypt); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Encrypt)));
var dlgSoftFallbackFixedRotate = new SoftFallbackFixedRotate(SoftFallback.FixedRotate); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.FixedRotate)));
var dlgSoftFallbackHashChoose = new SoftFallbackHashChoose(SoftFallback.HashChoose); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashChoose)));
var dlgSoftFallbackHashLower = new SoftFallbackHashLower(SoftFallback.HashLower); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashLower)));
var dlgSoftFallbackHashMajority = new SoftFallbackHashMajority(SoftFallback.HashMajority); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashMajority)));
var dlgSoftFallbackHashParity = new SoftFallbackHashParity(SoftFallback.HashParity); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashParity)));
var dlgSoftFallbackHashUpper = new SoftFallbackHashUpper(SoftFallback.HashUpper); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashUpper)));
var dlgSoftFallbackInverseMixColumns = new SoftFallbackInverseMixColumns(SoftFallback.InverseMixColumns); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.InverseMixColumns)));
var dlgSoftFallbackMixColumns = new SoftFallbackMixColumns(SoftFallback.MixColumns); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.MixColumns)));
var dlgSoftFallbackPolynomialMult64_128 = new SoftFallbackPolynomialMult64_128(SoftFallback.PolynomialMult64_128); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.PolynomialMult64_128)));
var dlgSoftFallbackSatF32ToS32 = new SoftFallbackSatF32ToS32(SoftFallback.SatF32ToS32); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32)));
var dlgSoftFallbackSatF32ToS64 = new SoftFallbackSatF32ToS64(SoftFallback.SatF32ToS64); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS64)));
var dlgSoftFallbackSatF32ToU32 = new SoftFallbackSatF32ToU32(SoftFallback.SatF32ToU32); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)));
var dlgSoftFallbackSatF32ToU64 = new SoftFallbackSatF32ToU64(SoftFallback.SatF32ToU64); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU64)));
var dlgSoftFallbackSatF64ToS32 = new SoftFallbackSatF64ToS32(SoftFallback.SatF64ToS32); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS32)));
var dlgSoftFallbackSatF64ToS64 = new SoftFallbackSatF64ToS64(SoftFallback.SatF64ToS64); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS64)));
var dlgSoftFallbackSatF64ToU32 = new SoftFallbackSatF64ToU32(SoftFallback.SatF64ToU32); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU32)));
var dlgSoftFallbackSatF64ToU64 = new SoftFallbackSatF64ToU64(SoftFallback.SatF64ToU64); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU64)));
var dlgSoftFallbackSha1SchedulePart1 = new SoftFallbackSha1SchedulePart1(SoftFallback.Sha1SchedulePart1); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart1)));
var dlgSoftFallbackSha1SchedulePart2 = new SoftFallbackSha1SchedulePart2(SoftFallback.Sha1SchedulePart2); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart2)));
var dlgSoftFallbackSha256SchedulePart1 = new SoftFallbackSha256SchedulePart1(SoftFallback.Sha256SchedulePart1); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1)));
var dlgSoftFallbackSha256SchedulePart2 = new SoftFallbackSha256SchedulePart2(SoftFallback.Sha256SchedulePart2); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2)));
var dlgSoftFallbackSignedShrImm64 = new SoftFallbackSignedShrImm64(SoftFallback.SignedShrImm64); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShrImm64)));
var dlgSoftFallbackTbl1 = new SoftFallbackTbl1(SoftFallback.Tbl1); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl1)));
var dlgSoftFallbackTbl2 = new SoftFallbackTbl2(SoftFallback.Tbl2); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl2)));
var dlgSoftFallbackTbl3 = new SoftFallbackTbl3(SoftFallback.Tbl3); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl3)));
var dlgSoftFallbackTbl4 = new SoftFallbackTbl4(SoftFallback.Tbl4); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl4)));
var dlgSoftFallbackTbx1 = new SoftFallbackTbx1(SoftFallback.Tbx1); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx1)));
var dlgSoftFallbackTbx2 = new SoftFallbackTbx2(SoftFallback.Tbx2); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx2)));
var dlgSoftFallbackTbx3 = new SoftFallbackTbx3(SoftFallback.Tbx3); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx3)));
var dlgSoftFallbackTbx4 = new SoftFallbackTbx4(SoftFallback.Tbx4); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx4)));
var dlgSoftFallbackUnsignedShrImm64 = new SoftFallbackUnsignedShrImm64(SoftFallback.UnsignedShrImm64); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShrImm64)));
var dlgSoftFloat16_32FPConvert = new SoftFloat16_32FPConvert(SoftFloat16_32.FPConvert); SetDelegateInfo(typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert)));
var dlgSoftFloat16_64FPConvert = new SoftFloat16_64FPConvert(SoftFloat16_64.FPConvert); SetDelegateInfo(typeof(SoftFloat16_64).GetMethod(nameof(SoftFloat16_64.FPConvert)));
var dlgSoftFloat32FPAdd = new SoftFloat32FPAdd(SoftFloat32.FPAdd); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPAdd)));
var dlgSoftFloat32FPAddFpscr = new SoftFloat32FPAddFpscr(SoftFloat32.FPAddFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPAddFpscr))); // A32 only.
var dlgSoftFloat32FPCompare = new SoftFloat32FPCompare(SoftFloat32.FPCompare); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompare)));
var dlgSoftFloat32FPCompareEQ = new SoftFloat32FPCompareEQ(SoftFloat32.FPCompareEQ); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareEQ)));
var dlgSoftFloat32FPCompareEQFpscr = new SoftFloat32FPCompareEQFpscr(SoftFloat32.FPCompareEQFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareEQFpscr))); // A32 only.
var dlgSoftFloat32FPCompareGE = new SoftFloat32FPCompareGE(SoftFloat32.FPCompareGE); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGE)));
var dlgSoftFloat32FPCompareGEFpscr = new SoftFloat32FPCompareGEFpscr(SoftFloat32.FPCompareGEFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGEFpscr))); // A32 only.
var dlgSoftFloat32FPCompareGT = new SoftFloat32FPCompareGT(SoftFloat32.FPCompareGT); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGT)));
var dlgSoftFloat32FPCompareGTFpscr = new SoftFloat32FPCompareGTFpscr(SoftFloat32.FPCompareGTFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGTFpscr))); // A32 only.
var dlgSoftFloat32FPCompareLE = new SoftFloat32FPCompareLE(SoftFloat32.FPCompareLE); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLE)));
var dlgSoftFloat32FPCompareLEFpscr = new SoftFloat32FPCompareLEFpscr(SoftFloat32.FPCompareLEFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLEFpscr))); // A32 only.
var dlgSoftFloat32FPCompareLT = new SoftFloat32FPCompareLT(SoftFloat32.FPCompareLT); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLT)));
var dlgSoftFloat32FPCompareLTFpscr = new SoftFloat32FPCompareLTFpscr(SoftFloat32.FPCompareLTFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLTFpscr))); // A32 only.
var dlgSoftFloat32FPDiv = new SoftFloat32FPDiv(SoftFloat32.FPDiv); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPDiv)));
var dlgSoftFloat32FPMax = new SoftFloat32FPMax(SoftFloat32.FPMax); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMax)));
var dlgSoftFloat32FPMaxFpscr = new SoftFloat32FPMaxFpscr(SoftFloat32.FPMaxFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxFpscr))); // A32 only.
var dlgSoftFloat32FPMaxNum = new SoftFloat32FPMaxNum(SoftFloat32.FPMaxNum); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNum)));
var dlgSoftFloat32FPMaxNumFpscr = new SoftFloat32FPMaxNumFpscr(SoftFloat32.FPMaxNumFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNumFpscr))); // A32 only.
var dlgSoftFloat32FPMin = new SoftFloat32FPMin(SoftFloat32.FPMin); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMin)));
var dlgSoftFloat32FPMinFpscr = new SoftFloat32FPMinFpscr(SoftFloat32.FPMinFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinFpscr))); // A32 only.
var dlgSoftFloat32FPMinNum = new SoftFloat32FPMinNum(SoftFloat32.FPMinNum); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNum)));
var dlgSoftFloat32FPMinNumFpscr = new SoftFloat32FPMinNumFpscr(SoftFloat32.FPMinNumFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNumFpscr))); // A32 only.
var dlgSoftFloat32FPMul = new SoftFloat32FPMul(SoftFloat32.FPMul); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMul)));
var dlgSoftFloat32FPMulFpscr = new SoftFloat32FPMulFpscr(SoftFloat32.FPMulFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulFpscr))); // A32 only.
var dlgSoftFloat32FPMulAdd = new SoftFloat32FPMulAdd(SoftFloat32.FPMulAdd); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulAdd)));
var dlgSoftFloat32FPMulAddFpscr = new SoftFloat32FPMulAddFpscr(SoftFloat32.FPMulAddFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulAddFpscr))); // A32 only.
var dlgSoftFloat32FPMulSub = new SoftFloat32FPMulSub(SoftFloat32.FPMulSub); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulSub)));
var dlgSoftFloat32FPMulSubFpscr = new SoftFloat32FPMulSubFpscr(SoftFloat32.FPMulSubFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulSubFpscr))); // A32 only.
var dlgSoftFloat32FPMulX = new SoftFloat32FPMulX(SoftFloat32.FPMulX); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulX)));
var dlgSoftFloat32FPNegMulAdd = new SoftFloat32FPNegMulAdd(SoftFloat32.FPNegMulAdd); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPNegMulAdd)));
var dlgSoftFloat32FPNegMulSub = new SoftFloat32FPNegMulSub(SoftFloat32.FPNegMulSub); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPNegMulSub)));
var dlgSoftFloat32FPRecipEstimate = new SoftFloat32FPRecipEstimate(SoftFloat32.FPRecipEstimate); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipEstimate)));
var dlgSoftFloat32FPRecipEstimateFpscr = new SoftFloat32FPRecipEstimateFpscr(SoftFloat32.FPRecipEstimateFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipEstimateFpscr))); // A32 only.
var dlgSoftFloat32FPRecipStep = new SoftFloat32FPRecipStep(SoftFloat32.FPRecipStep); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipStep))); // A32 only.
var dlgSoftFloat32FPRecipStepFused = new SoftFloat32FPRecipStepFused(SoftFloat32.FPRecipStepFused); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipStepFused)));
var dlgSoftFloat32FPRecpX = new SoftFloat32FPRecpX(SoftFloat32.FPRecpX); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecpX)));
var dlgSoftFloat32FPRSqrtEstimate = new SoftFloat32FPRSqrtEstimate(SoftFloat32.FPRSqrtEstimate); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtEstimate)));
var dlgSoftFloat32FPRSqrtEstimateFpscr = new SoftFloat32FPRSqrtEstimateFpscr(SoftFloat32.FPRSqrtEstimateFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtEstimateFpscr))); // A32 only.
var dlgSoftFloat32FPRSqrtStep = new SoftFloat32FPRSqrtStep(SoftFloat32.FPRSqrtStep); // A32 only. SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtStep))); // A32 only.
var dlgSoftFloat32FPRSqrtStepFused = new SoftFloat32FPRSqrtStepFused(SoftFloat32.FPRSqrtStepFused); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtStepFused)));
var dlgSoftFloat32FPSqrt = new SoftFloat32FPSqrt(SoftFloat32.FPSqrt); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPSqrt)));
var dlgSoftFloat32FPSub = new SoftFloat32FPSub(SoftFloat32.FPSub); SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPSub)));
var dlgSoftFloat32_16FPConvert = new SoftFloat32_16FPConvert(SoftFloat32_16.FPConvert); SetDelegateInfo(typeof(SoftFloat32_16).GetMethod(nameof(SoftFloat32_16.FPConvert)));
var dlgSoftFloat64FPAdd = new SoftFloat64FPAdd(SoftFloat64.FPAdd); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPAdd)));
var dlgSoftFloat64FPAddFpscr = new SoftFloat64FPAddFpscr(SoftFloat64.FPAddFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPAddFpscr))); // A32 only.
var dlgSoftFloat64FPCompare = new SoftFloat64FPCompare(SoftFloat64.FPCompare); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompare)));
var dlgSoftFloat64FPCompareEQ = new SoftFloat64FPCompareEQ(SoftFloat64.FPCompareEQ); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareEQ)));
var dlgSoftFloat64FPCompareEQFpscr = new SoftFloat64FPCompareEQFpscr(SoftFloat64.FPCompareEQFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareEQFpscr))); // A32 only.
var dlgSoftFloat64FPCompareGE = new SoftFloat64FPCompareGE(SoftFloat64.FPCompareGE); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGE)));
var dlgSoftFloat64FPCompareGEFpscr = new SoftFloat64FPCompareGEFpscr(SoftFloat64.FPCompareGEFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGEFpscr))); // A32 only.
var dlgSoftFloat64FPCompareGT = new SoftFloat64FPCompareGT(SoftFloat64.FPCompareGT); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGT)));
var dlgSoftFloat64FPCompareGTFpscr = new SoftFloat64FPCompareGTFpscr(SoftFloat64.FPCompareGTFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGTFpscr))); // A32 only.
var dlgSoftFloat64FPCompareLE = new SoftFloat64FPCompareLE(SoftFloat64.FPCompareLE); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLE)));
var dlgSoftFloat64FPCompareLEFpscr = new SoftFloat64FPCompareLEFpscr(SoftFloat64.FPCompareLEFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLEFpscr))); // A32 only.
var dlgSoftFloat64FPCompareLT = new SoftFloat64FPCompareLT(SoftFloat64.FPCompareLT); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLT)));
var dlgSoftFloat64FPCompareLTFpscr = new SoftFloat64FPCompareLTFpscr(SoftFloat64.FPCompareLTFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLTFpscr))); // A32 only.
var dlgSoftFloat64FPDiv = new SoftFloat64FPDiv(SoftFloat64.FPDiv); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPDiv)));
var dlgSoftFloat64FPMax = new SoftFloat64FPMax(SoftFloat64.FPMax); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMax)));
var dlgSoftFloat64FPMaxFpscr = new SoftFloat64FPMaxFpscr(SoftFloat64.FPMaxFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxFpscr))); // A32 only.
var dlgSoftFloat64FPMaxNum = new SoftFloat64FPMaxNum(SoftFloat64.FPMaxNum); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxNum)));
var dlgSoftFloat64FPMaxNumFpscr = new SoftFloat64FPMaxNumFpscr(SoftFloat64.FPMaxNumFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxNumFpscr))); // A32 only.
var dlgSoftFloat64FPMin = new SoftFloat64FPMin(SoftFloat64.FPMin); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMin)));
var dlgSoftFloat64FPMinFpscr = new SoftFloat64FPMinFpscr(SoftFloat64.FPMinFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinFpscr))); // A32 only.
var dlgSoftFloat64FPMinNum = new SoftFloat64FPMinNum(SoftFloat64.FPMinNum); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinNum)));
var dlgSoftFloat64FPMinNumFpscr = new SoftFloat64FPMinNumFpscr(SoftFloat64.FPMinNumFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinNumFpscr))); // A32 only.
var dlgSoftFloat64FPMul = new SoftFloat64FPMul(SoftFloat64.FPMul); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMul)));
var dlgSoftFloat64FPMulFpscr = new SoftFloat64FPMulFpscr(SoftFloat64.FPMulFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulFpscr))); // A32 only.
var dlgSoftFloat64FPMulAdd = new SoftFloat64FPMulAdd(SoftFloat64.FPMulAdd); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulAdd)));
var dlgSoftFloat64FPMulAddFpscr = new SoftFloat64FPMulAddFpscr(SoftFloat64.FPMulAddFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulAddFpscr))); // A32 only.
var dlgSoftFloat64FPMulSub = new SoftFloat64FPMulSub(SoftFloat64.FPMulSub); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulSub)));
var dlgSoftFloat64FPMulSubFpscr = new SoftFloat64FPMulSubFpscr(SoftFloat64.FPMulSubFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulSubFpscr))); // A32 only.
var dlgSoftFloat64FPMulX = new SoftFloat64FPMulX(SoftFloat64.FPMulX); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulX)));
var dlgSoftFloat64FPNegMulAdd = new SoftFloat64FPNegMulAdd(SoftFloat64.FPNegMulAdd); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPNegMulAdd)));
var dlgSoftFloat64FPNegMulSub = new SoftFloat64FPNegMulSub(SoftFloat64.FPNegMulSub); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPNegMulSub)));
var dlgSoftFloat64FPRecipEstimate = new SoftFloat64FPRecipEstimate(SoftFloat64.FPRecipEstimate); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipEstimate)));
var dlgSoftFloat64FPRecipEstimateFpscr = new SoftFloat64FPRecipEstimateFpscr(SoftFloat64.FPRecipEstimateFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipEstimateFpscr))); // A32 only.
var dlgSoftFloat64FPRecipStep = new SoftFloat64FPRecipStep(SoftFloat64.FPRecipStep); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipStep))); // A32 only.
var dlgSoftFloat64FPRecipStepFused = new SoftFloat64FPRecipStepFused(SoftFloat64.FPRecipStepFused); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipStepFused)));
var dlgSoftFloat64FPRecpX = new SoftFloat64FPRecpX(SoftFloat64.FPRecpX); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecpX)));
var dlgSoftFloat64FPRSqrtEstimate = new SoftFloat64FPRSqrtEstimate(SoftFloat64.FPRSqrtEstimate); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtEstimate)));
var dlgSoftFloat64FPRSqrtEstimateFpscr = new SoftFloat64FPRSqrtEstimateFpscr(SoftFloat64.FPRSqrtEstimateFpscr); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtEstimateFpscr))); // A32 only.
var dlgSoftFloat64FPRSqrtStep = new SoftFloat64FPRSqrtStep(SoftFloat64.FPRSqrtStep); // A32 only. SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtStep))); // A32 only.
var dlgSoftFloat64FPRSqrtStepFused = new SoftFloat64FPRSqrtStepFused(SoftFloat64.FPRSqrtStepFused); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtStepFused)));
var dlgSoftFloat64FPSqrt = new SoftFloat64FPSqrt(SoftFloat64.FPSqrt); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPSqrt)));
var dlgSoftFloat64FPSub = new SoftFloat64FPSub(SoftFloat64.FPSub); SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPSub)));
var dlgSoftFloat64_16FPConvert = new SoftFloat64_16FPConvert(SoftFloat64_16.FPConvert); SetDelegateInfo(typeof(SoftFloat64_16).GetMethod(nameof(SoftFloat64_16.FPConvert)));
SetDelegateInfo(dlgMathAbs, Marshal.GetFunctionPointerForDelegate<MathAbs>(dlgMathAbs));
SetDelegateInfo(dlgMathCeiling, Marshal.GetFunctionPointerForDelegate<MathCeiling>(dlgMathCeiling));
SetDelegateInfo(dlgMathFloor, Marshal.GetFunctionPointerForDelegate<MathFloor>(dlgMathFloor));
SetDelegateInfo(dlgMathRound, Marshal.GetFunctionPointerForDelegate<MathRound>(dlgMathRound));
SetDelegateInfo(dlgMathTruncate, Marshal.GetFunctionPointerForDelegate<MathTruncate>(dlgMathTruncate));
SetDelegateInfo(dlgMathFAbs, Marshal.GetFunctionPointerForDelegate<MathFAbs>(dlgMathFAbs));
SetDelegateInfo(dlgMathFCeiling, Marshal.GetFunctionPointerForDelegate<MathFCeiling>(dlgMathFCeiling));
SetDelegateInfo(dlgMathFFloor, Marshal.GetFunctionPointerForDelegate<MathFFloor>(dlgMathFFloor));
SetDelegateInfo(dlgMathFRound, Marshal.GetFunctionPointerForDelegate<MathFRound>(dlgMathFRound));
SetDelegateInfo(dlgMathFTruncate, Marshal.GetFunctionPointerForDelegate<MathFTruncate>(dlgMathFTruncate));
SetDelegateInfo(dlgNativeInterfaceBreak, Marshal.GetFunctionPointerForDelegate<NativeInterfaceBreak>(dlgNativeInterfaceBreak));
SetDelegateInfo(dlgNativeInterfaceCheckSynchronization, Marshal.GetFunctionPointerForDelegate<NativeInterfaceCheckSynchronization>(dlgNativeInterfaceCheckSynchronization));
SetDelegateInfo(dlgNativeInterfaceEnqueueForRejit, Marshal.GetFunctionPointerForDelegate<NativeInterfaceEnqueueForRejit>(dlgNativeInterfaceEnqueueForRejit));
SetDelegateInfo(dlgNativeInterfaceGetCntfrqEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetCntfrqEl0>(dlgNativeInterfaceGetCntfrqEl0));
SetDelegateInfo(dlgNativeInterfaceGetCntpctEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetCntpctEl0>(dlgNativeInterfaceGetCntpctEl0));
SetDelegateInfo(dlgNativeInterfaceGetCntvctEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetCntvctEl0>(dlgNativeInterfaceGetCntvctEl0));
SetDelegateInfo(dlgNativeInterfaceGetCtrEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetCtrEl0>(dlgNativeInterfaceGetCtrEl0));
SetDelegateInfo(dlgNativeInterfaceGetDczidEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetDczidEl0>(dlgNativeInterfaceGetDczidEl0));
SetDelegateInfo(dlgNativeInterfaceGetFunctionAddress, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetFunctionAddress>(dlgNativeInterfaceGetFunctionAddress));
SetDelegateInfo(dlgNativeInterfaceInvalidateCacheLine, Marshal.GetFunctionPointerForDelegate<NativeInterfaceInvalidateCacheLine>(dlgNativeInterfaceInvalidateCacheLine));
SetDelegateInfo(dlgNativeInterfaceReadByte, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadByte>(dlgNativeInterfaceReadByte));
SetDelegateInfo(dlgNativeInterfaceReadUInt16, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadUInt16>(dlgNativeInterfaceReadUInt16));
SetDelegateInfo(dlgNativeInterfaceReadUInt32, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadUInt32>(dlgNativeInterfaceReadUInt32));
SetDelegateInfo(dlgNativeInterfaceReadUInt64, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadUInt64>(dlgNativeInterfaceReadUInt64));
SetDelegateInfo(dlgNativeInterfaceReadVector128, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadVector128>(dlgNativeInterfaceReadVector128));
SetDelegateInfo(dlgNativeInterfaceSignalMemoryTracking, Marshal.GetFunctionPointerForDelegate<NativeInterfaceSignalMemoryTracking>(dlgNativeInterfaceSignalMemoryTracking));
SetDelegateInfo(dlgNativeInterfaceSupervisorCall, Marshal.GetFunctionPointerForDelegate<NativeInterfaceSupervisorCall>(dlgNativeInterfaceSupervisorCall));
SetDelegateInfo(dlgNativeInterfaceThrowInvalidMemoryAccess, Marshal.GetFunctionPointerForDelegate<NativeInterfaceThrowInvalidMemoryAccess>(dlgNativeInterfaceThrowInvalidMemoryAccess));
SetDelegateInfo(dlgNativeInterfaceUndefined, Marshal.GetFunctionPointerForDelegate<NativeInterfaceUndefined>(dlgNativeInterfaceUndefined));
SetDelegateInfo(dlgNativeInterfaceWriteByte, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteByte>(dlgNativeInterfaceWriteByte));
SetDelegateInfo(dlgNativeInterfaceWriteUInt16, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteUInt16>(dlgNativeInterfaceWriteUInt16));
SetDelegateInfo(dlgNativeInterfaceWriteUInt32, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteUInt32>(dlgNativeInterfaceWriteUInt32));
SetDelegateInfo(dlgNativeInterfaceWriteUInt64, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteUInt64>(dlgNativeInterfaceWriteUInt64));
SetDelegateInfo(dlgNativeInterfaceWriteVector128, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteVector128>(dlgNativeInterfaceWriteVector128));
SetDelegateInfo(dlgSoftFallbackCountLeadingSigns, Marshal.GetFunctionPointerForDelegate<SoftFallbackCountLeadingSigns>(dlgSoftFallbackCountLeadingSigns));
SetDelegateInfo(dlgSoftFallbackCountLeadingZeros, Marshal.GetFunctionPointerForDelegate<SoftFallbackCountLeadingZeros>(dlgSoftFallbackCountLeadingZeros));
SetDelegateInfo(dlgSoftFallbackCrc32b, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32b>(dlgSoftFallbackCrc32b));
SetDelegateInfo(dlgSoftFallbackCrc32cb, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32cb>(dlgSoftFallbackCrc32cb));
SetDelegateInfo(dlgSoftFallbackCrc32ch, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32ch>(dlgSoftFallbackCrc32ch));
SetDelegateInfo(dlgSoftFallbackCrc32cw, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32cw>(dlgSoftFallbackCrc32cw));
SetDelegateInfo(dlgSoftFallbackCrc32cx, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32cx>(dlgSoftFallbackCrc32cx));
SetDelegateInfo(dlgSoftFallbackCrc32h, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32h>(dlgSoftFallbackCrc32h));
SetDelegateInfo(dlgSoftFallbackCrc32w, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32w>(dlgSoftFallbackCrc32w));
SetDelegateInfo(dlgSoftFallbackCrc32x, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32x>(dlgSoftFallbackCrc32x));
SetDelegateInfo(dlgSoftFallbackDecrypt, Marshal.GetFunctionPointerForDelegate<SoftFallbackDecrypt>(dlgSoftFallbackDecrypt));
SetDelegateInfo(dlgSoftFallbackEncrypt, Marshal.GetFunctionPointerForDelegate<SoftFallbackEncrypt>(dlgSoftFallbackEncrypt));
SetDelegateInfo(dlgSoftFallbackFixedRotate, Marshal.GetFunctionPointerForDelegate<SoftFallbackFixedRotate>(dlgSoftFallbackFixedRotate));
SetDelegateInfo(dlgSoftFallbackHashChoose, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashChoose>(dlgSoftFallbackHashChoose));
SetDelegateInfo(dlgSoftFallbackHashLower, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashLower>(dlgSoftFallbackHashLower));
SetDelegateInfo(dlgSoftFallbackHashMajority, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashMajority>(dlgSoftFallbackHashMajority));
SetDelegateInfo(dlgSoftFallbackHashParity, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashParity>(dlgSoftFallbackHashParity));
SetDelegateInfo(dlgSoftFallbackHashUpper, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashUpper>(dlgSoftFallbackHashUpper));
SetDelegateInfo(dlgSoftFallbackInverseMixColumns, Marshal.GetFunctionPointerForDelegate<SoftFallbackInverseMixColumns>(dlgSoftFallbackInverseMixColumns));
SetDelegateInfo(dlgSoftFallbackMixColumns, Marshal.GetFunctionPointerForDelegate<SoftFallbackMixColumns>(dlgSoftFallbackMixColumns));
SetDelegateInfo(dlgSoftFallbackPolynomialMult64_128, Marshal.GetFunctionPointerForDelegate<SoftFallbackPolynomialMult64_128>(dlgSoftFallbackPolynomialMult64_128));
SetDelegateInfo(dlgSoftFallbackSatF32ToS32, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF32ToS32>(dlgSoftFallbackSatF32ToS32));
SetDelegateInfo(dlgSoftFallbackSatF32ToS64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF32ToS64>(dlgSoftFallbackSatF32ToS64));
SetDelegateInfo(dlgSoftFallbackSatF32ToU32, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF32ToU32>(dlgSoftFallbackSatF32ToU32));
SetDelegateInfo(dlgSoftFallbackSatF32ToU64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF32ToU64>(dlgSoftFallbackSatF32ToU64));
SetDelegateInfo(dlgSoftFallbackSatF64ToS32, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF64ToS32>(dlgSoftFallbackSatF64ToS32));
SetDelegateInfo(dlgSoftFallbackSatF64ToS64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF64ToS64>(dlgSoftFallbackSatF64ToS64));
SetDelegateInfo(dlgSoftFallbackSatF64ToU32, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF64ToU32>(dlgSoftFallbackSatF64ToU32));
SetDelegateInfo(dlgSoftFallbackSatF64ToU64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF64ToU64>(dlgSoftFallbackSatF64ToU64));
SetDelegateInfo(dlgSoftFallbackSha1SchedulePart1, Marshal.GetFunctionPointerForDelegate<SoftFallbackSha1SchedulePart1>(dlgSoftFallbackSha1SchedulePart1));
SetDelegateInfo(dlgSoftFallbackSha1SchedulePart2, Marshal.GetFunctionPointerForDelegate<SoftFallbackSha1SchedulePart2>(dlgSoftFallbackSha1SchedulePart2));
SetDelegateInfo(dlgSoftFallbackSha256SchedulePart1, Marshal.GetFunctionPointerForDelegate<SoftFallbackSha256SchedulePart1>(dlgSoftFallbackSha256SchedulePart1));
SetDelegateInfo(dlgSoftFallbackSha256SchedulePart2, Marshal.GetFunctionPointerForDelegate<SoftFallbackSha256SchedulePart2>(dlgSoftFallbackSha256SchedulePart2));
SetDelegateInfo(dlgSoftFallbackSignedShrImm64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSignedShrImm64>(dlgSoftFallbackSignedShrImm64));
SetDelegateInfo(dlgSoftFallbackTbl1, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbl1>(dlgSoftFallbackTbl1));
SetDelegateInfo(dlgSoftFallbackTbl2, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbl2>(dlgSoftFallbackTbl2));
SetDelegateInfo(dlgSoftFallbackTbl3, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbl3>(dlgSoftFallbackTbl3));
SetDelegateInfo(dlgSoftFallbackTbl4, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbl4>(dlgSoftFallbackTbl4));
SetDelegateInfo(dlgSoftFallbackTbx1, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbx1>(dlgSoftFallbackTbx1));
SetDelegateInfo(dlgSoftFallbackTbx2, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbx2>(dlgSoftFallbackTbx2));
SetDelegateInfo(dlgSoftFallbackTbx3, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbx3>(dlgSoftFallbackTbx3));
SetDelegateInfo(dlgSoftFallbackTbx4, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbx4>(dlgSoftFallbackTbx4));
SetDelegateInfo(dlgSoftFallbackUnsignedShrImm64, Marshal.GetFunctionPointerForDelegate<SoftFallbackUnsignedShrImm64>(dlgSoftFallbackUnsignedShrImm64));
SetDelegateInfo(dlgSoftFloat16_32FPConvert, Marshal.GetFunctionPointerForDelegate<SoftFloat16_32FPConvert>(dlgSoftFloat16_32FPConvert));
SetDelegateInfo(dlgSoftFloat16_64FPConvert, Marshal.GetFunctionPointerForDelegate<SoftFloat16_64FPConvert>(dlgSoftFloat16_64FPConvert));
SetDelegateInfo(dlgSoftFloat32FPAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPAdd>(dlgSoftFloat32FPAdd));
SetDelegateInfo(dlgSoftFloat32FPAddFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPAddFpscr>(dlgSoftFloat32FPAddFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPCompare, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompare>(dlgSoftFloat32FPCompare));
SetDelegateInfo(dlgSoftFloat32FPCompareEQ, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareEQ>(dlgSoftFloat32FPCompareEQ));
SetDelegateInfo(dlgSoftFloat32FPCompareEQFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareEQFpscr>(dlgSoftFloat32FPCompareEQFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPCompareGE, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareGE>(dlgSoftFloat32FPCompareGE));
SetDelegateInfo(dlgSoftFloat32FPCompareGEFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareGEFpscr>(dlgSoftFloat32FPCompareGEFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPCompareGT, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareGT>(dlgSoftFloat32FPCompareGT));
SetDelegateInfo(dlgSoftFloat32FPCompareGTFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareGTFpscr>(dlgSoftFloat32FPCompareGTFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPCompareLE, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareLE>(dlgSoftFloat32FPCompareLE));
SetDelegateInfo(dlgSoftFloat32FPCompareLEFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareLEFpscr>(dlgSoftFloat32FPCompareLEFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPCompareLT, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareLT>(dlgSoftFloat32FPCompareLT));
SetDelegateInfo(dlgSoftFloat32FPCompareLTFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareLTFpscr>(dlgSoftFloat32FPCompareLTFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPDiv, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPDiv>(dlgSoftFloat32FPDiv));
SetDelegateInfo(dlgSoftFloat32FPMax, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMax>(dlgSoftFloat32FPMax));
SetDelegateInfo(dlgSoftFloat32FPMaxFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMaxFpscr>(dlgSoftFloat32FPMaxFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPMaxNum, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMaxNum>(dlgSoftFloat32FPMaxNum));
SetDelegateInfo(dlgSoftFloat32FPMaxNumFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMaxNumFpscr>(dlgSoftFloat32FPMaxNumFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPMin, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMin>(dlgSoftFloat32FPMin));
SetDelegateInfo(dlgSoftFloat32FPMinFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMinFpscr>(dlgSoftFloat32FPMinFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPMinNum, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMinNum>(dlgSoftFloat32FPMinNum));
SetDelegateInfo(dlgSoftFloat32FPMinNumFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMinNumFpscr>(dlgSoftFloat32FPMinNumFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPMul, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMul>(dlgSoftFloat32FPMul));
SetDelegateInfo(dlgSoftFloat32FPMulFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulFpscr>(dlgSoftFloat32FPMulFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPMulAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulAdd>(dlgSoftFloat32FPMulAdd));
SetDelegateInfo(dlgSoftFloat32FPMulAddFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulAddFpscr>(dlgSoftFloat32FPMulAddFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPMulSub, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulSub>(dlgSoftFloat32FPMulSub));
SetDelegateInfo(dlgSoftFloat32FPMulSubFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulSubFpscr>(dlgSoftFloat32FPMulSubFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPMulX, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulX>(dlgSoftFloat32FPMulX));
SetDelegateInfo(dlgSoftFloat32FPNegMulAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPNegMulAdd>(dlgSoftFloat32FPNegMulAdd));
SetDelegateInfo(dlgSoftFloat32FPNegMulSub, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPNegMulSub>(dlgSoftFloat32FPNegMulSub));
SetDelegateInfo(dlgSoftFloat32FPRecipEstimate, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecipEstimate>(dlgSoftFloat32FPRecipEstimate));
SetDelegateInfo(dlgSoftFloat32FPRecipEstimateFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecipEstimateFpscr>(dlgSoftFloat32FPRecipEstimateFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPRecipStep, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecipStep>(dlgSoftFloat32FPRecipStep)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPRecipStepFused, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecipStepFused>(dlgSoftFloat32FPRecipStepFused));
SetDelegateInfo(dlgSoftFloat32FPRecpX, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecpX>(dlgSoftFloat32FPRecpX));
SetDelegateInfo(dlgSoftFloat32FPRSqrtEstimate, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRSqrtEstimate>(dlgSoftFloat32FPRSqrtEstimate));
SetDelegateInfo(dlgSoftFloat32FPRSqrtEstimateFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRSqrtEstimateFpscr>(dlgSoftFloat32FPRSqrtEstimateFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPRSqrtStep, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRSqrtStep>(dlgSoftFloat32FPRSqrtStep)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPRSqrtStepFused, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRSqrtStepFused>(dlgSoftFloat32FPRSqrtStepFused));
SetDelegateInfo(dlgSoftFloat32FPSqrt, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPSqrt>(dlgSoftFloat32FPSqrt));
SetDelegateInfo(dlgSoftFloat32FPSub, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPSub>(dlgSoftFloat32FPSub));
SetDelegateInfo(dlgSoftFloat32_16FPConvert, Marshal.GetFunctionPointerForDelegate<SoftFloat32_16FPConvert>(dlgSoftFloat32_16FPConvert));
SetDelegateInfo(dlgSoftFloat64FPAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPAdd>(dlgSoftFloat64FPAdd));
SetDelegateInfo(dlgSoftFloat64FPAddFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPAddFpscr>(dlgSoftFloat64FPAddFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPCompare, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompare>(dlgSoftFloat64FPCompare));
SetDelegateInfo(dlgSoftFloat64FPCompareEQ, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareEQ>(dlgSoftFloat64FPCompareEQ));
SetDelegateInfo(dlgSoftFloat64FPCompareEQFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareEQFpscr>(dlgSoftFloat64FPCompareEQFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPCompareGE, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareGE>(dlgSoftFloat64FPCompareGE));
SetDelegateInfo(dlgSoftFloat64FPCompareGEFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareGEFpscr>(dlgSoftFloat64FPCompareGEFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPCompareGT, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareGT>(dlgSoftFloat64FPCompareGT));
SetDelegateInfo(dlgSoftFloat64FPCompareGTFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareGTFpscr>(dlgSoftFloat64FPCompareGTFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPCompareLE, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareLE>(dlgSoftFloat64FPCompareLE));
SetDelegateInfo(dlgSoftFloat64FPCompareLEFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareLEFpscr>(dlgSoftFloat64FPCompareLEFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPCompareLT, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareLT>(dlgSoftFloat64FPCompareLT));
SetDelegateInfo(dlgSoftFloat64FPCompareLTFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareLTFpscr>(dlgSoftFloat64FPCompareLTFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPDiv, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPDiv>(dlgSoftFloat64FPDiv));
SetDelegateInfo(dlgSoftFloat64FPMax, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMax>(dlgSoftFloat64FPMax));
SetDelegateInfo(dlgSoftFloat64FPMaxFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMaxFpscr>(dlgSoftFloat64FPMaxFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPMaxNum, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMaxNum>(dlgSoftFloat64FPMaxNum));
SetDelegateInfo(dlgSoftFloat64FPMaxNumFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMaxNumFpscr>(dlgSoftFloat64FPMaxNumFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPMin, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMin>(dlgSoftFloat64FPMin));
SetDelegateInfo(dlgSoftFloat64FPMinFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMinFpscr>(dlgSoftFloat64FPMinFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPMinNum, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMinNum>(dlgSoftFloat64FPMinNum));
SetDelegateInfo(dlgSoftFloat64FPMinNumFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMinNumFpscr>(dlgSoftFloat64FPMinNumFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPMul, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMul>(dlgSoftFloat64FPMul));
SetDelegateInfo(dlgSoftFloat64FPMulFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulFpscr>(dlgSoftFloat64FPMulFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPMulAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulAdd>(dlgSoftFloat64FPMulAdd));
SetDelegateInfo(dlgSoftFloat64FPMulAddFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulAddFpscr>(dlgSoftFloat64FPMulAddFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPMulSub, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulSub>(dlgSoftFloat64FPMulSub));
SetDelegateInfo(dlgSoftFloat64FPMulSubFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulSubFpscr>(dlgSoftFloat64FPMulSubFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPMulX, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulX>(dlgSoftFloat64FPMulX));
SetDelegateInfo(dlgSoftFloat64FPNegMulAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPNegMulAdd>(dlgSoftFloat64FPNegMulAdd));
SetDelegateInfo(dlgSoftFloat64FPNegMulSub, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPNegMulSub>(dlgSoftFloat64FPNegMulSub));
SetDelegateInfo(dlgSoftFloat64FPRecipEstimate, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecipEstimate>(dlgSoftFloat64FPRecipEstimate));
SetDelegateInfo(dlgSoftFloat64FPRecipEstimateFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecipEstimateFpscr>(dlgSoftFloat64FPRecipEstimateFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPRecipStep, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecipStep>(dlgSoftFloat64FPRecipStep)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPRecipStepFused, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecipStepFused>(dlgSoftFloat64FPRecipStepFused));
SetDelegateInfo(dlgSoftFloat64FPRecpX, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecpX>(dlgSoftFloat64FPRecpX));
SetDelegateInfo(dlgSoftFloat64FPRSqrtEstimate, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRSqrtEstimate>(dlgSoftFloat64FPRSqrtEstimate));
SetDelegateInfo(dlgSoftFloat64FPRSqrtEstimateFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRSqrtEstimateFpscr>(dlgSoftFloat64FPRSqrtEstimateFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPRSqrtStep, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRSqrtStep>(dlgSoftFloat64FPRSqrtStep)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPRSqrtStepFused, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRSqrtStepFused>(dlgSoftFloat64FPRSqrtStepFused));
SetDelegateInfo(dlgSoftFloat64FPSqrt, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPSqrt>(dlgSoftFloat64FPSqrt));
SetDelegateInfo(dlgSoftFloat64FPSub, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPSub>(dlgSoftFloat64FPSub));
SetDelegateInfo(dlgSoftFloat64_16FPConvert, Marshal.GetFunctionPointerForDelegate<SoftFloat64_16FPConvert>(dlgSoftFloat64_16FPConvert));
} }
private delegate double MathAbs(double value);
private delegate double MathCeiling(double a);
private delegate double MathFloor(double d);
private delegate double MathRound(double value, MidpointRounding mode);
private delegate double MathTruncate(double d);
private delegate float MathFAbs(float x);
private delegate float MathFCeiling(float x);
private delegate float MathFFloor(float x);
private delegate float MathFRound(float x, MidpointRounding mode);
private delegate float MathFTruncate(float x);
private delegate void NativeInterfaceBreak(ulong address, int imm);
private delegate bool NativeInterfaceCheckSynchronization();
private delegate void NativeInterfaceEnqueueForRejit(ulong address);
private delegate ulong NativeInterfaceGetCntfrqEl0();
private delegate ulong NativeInterfaceGetCntpctEl0();
private delegate ulong NativeInterfaceGetCntvctEl0();
private delegate ulong NativeInterfaceGetCtrEl0();
private delegate ulong NativeInterfaceGetDczidEl0();
private delegate ulong NativeInterfaceGetFunctionAddress(ulong address);
private delegate void NativeInterfaceInvalidateCacheLine(ulong address);
private delegate byte NativeInterfaceReadByte(ulong address);
private delegate ushort NativeInterfaceReadUInt16(ulong address);
private delegate uint NativeInterfaceReadUInt32(ulong address);
private delegate ulong NativeInterfaceReadUInt64(ulong address);
private delegate V128 NativeInterfaceReadVector128(ulong address);
private delegate void NativeInterfaceSignalMemoryTracking(ulong address, ulong size, bool write);
private delegate void NativeInterfaceSupervisorCall(ulong address, int imm);
private delegate void NativeInterfaceThrowInvalidMemoryAccess(ulong address);
private delegate void NativeInterfaceUndefined(ulong address, int opCode);
private delegate void NativeInterfaceWriteByte(ulong address, byte value);
private delegate void NativeInterfaceWriteUInt16(ulong address, ushort value);
private delegate void NativeInterfaceWriteUInt32(ulong address, uint value);
private delegate void NativeInterfaceWriteUInt64(ulong address, ulong value);
private delegate void NativeInterfaceWriteVector128(ulong address, V128 value);
private delegate ulong SoftFallbackCountLeadingSigns(ulong value, int size);
private delegate ulong SoftFallbackCountLeadingZeros(ulong value, int size);
private delegate uint SoftFallbackCrc32b(uint crc, byte value);
private delegate uint SoftFallbackCrc32cb(uint crc, byte value);
private delegate uint SoftFallbackCrc32ch(uint crc, ushort value);
private delegate uint SoftFallbackCrc32cw(uint crc, uint value);
private delegate uint SoftFallbackCrc32cx(uint crc, ulong value);
private delegate uint SoftFallbackCrc32h(uint crc, ushort value);
private delegate uint SoftFallbackCrc32w(uint crc, uint value);
private delegate uint SoftFallbackCrc32x(uint crc, ulong value);
private delegate V128 SoftFallbackDecrypt(V128 value, V128 roundKey);
private delegate V128 SoftFallbackEncrypt(V128 value, V128 roundKey);
private delegate uint SoftFallbackFixedRotate(uint hash_e);
private delegate V128 SoftFallbackHashChoose(V128 hash_abcd, uint hash_e, V128 wk);
private delegate V128 SoftFallbackHashLower(V128 hash_abcd, V128 hash_efgh, V128 wk);
private delegate V128 SoftFallbackHashMajority(V128 hash_abcd, uint hash_e, V128 wk);
private delegate V128 SoftFallbackHashParity(V128 hash_abcd, uint hash_e, V128 wk);
private delegate V128 SoftFallbackHashUpper(V128 hash_abcd, V128 hash_efgh, V128 wk);
private delegate V128 SoftFallbackInverseMixColumns(V128 value);
private delegate V128 SoftFallbackMixColumns(V128 value);
private delegate V128 SoftFallbackPolynomialMult64_128(ulong op1, ulong op2);
private delegate int SoftFallbackSatF32ToS32(float value);
private delegate long SoftFallbackSatF32ToS64(float value);
private delegate uint SoftFallbackSatF32ToU32(float value);
private delegate ulong SoftFallbackSatF32ToU64(float value);
private delegate int SoftFallbackSatF64ToS32(double value);
private delegate long SoftFallbackSatF64ToS64(double value);
private delegate uint SoftFallbackSatF64ToU32(double value);
private delegate ulong SoftFallbackSatF64ToU64(double value);
private delegate V128 SoftFallbackSha1SchedulePart1(V128 w0_3, V128 w4_7, V128 w8_11);
private delegate V128 SoftFallbackSha1SchedulePart2(V128 tw0_3, V128 w12_15);
private delegate V128 SoftFallbackSha256SchedulePart1(V128 w0_3, V128 w4_7);
private delegate V128 SoftFallbackSha256SchedulePart2(V128 w0_3, V128 w8_11, V128 w12_15);
private delegate long SoftFallbackSignedShrImm64(long value, long roundConst, int shift);
private delegate V128 SoftFallbackTbl1(V128 vector, int bytes, V128 tb0);
private delegate V128 SoftFallbackTbl2(V128 vector, int bytes, V128 tb0, V128 tb1);
private delegate V128 SoftFallbackTbl3(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2);
private delegate V128 SoftFallbackTbl4(V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3);
private delegate V128 SoftFallbackTbx1(V128 dest, V128 vector, int bytes, V128 tb0);
private delegate V128 SoftFallbackTbx2(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1);
private delegate V128 SoftFallbackTbx3(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2);
private delegate V128 SoftFallbackTbx4(V128 dest, V128 vector, int bytes, V128 tb0, V128 tb1, V128 tb2, V128 tb3);
private delegate ulong SoftFallbackUnsignedShrImm64(ulong value, long roundConst, int shift);
private delegate float SoftFloat16_32FPConvert(ushort valueBits);
private delegate double SoftFloat16_64FPConvert(ushort valueBits);
private delegate float SoftFloat32FPAdd(float value1, float value2);
private delegate float SoftFloat32FPAddFpscr(float value1, float value2, bool standardFpscr);
private delegate int SoftFloat32FPCompare(float value1, float value2, bool signalNaNs);
private delegate float SoftFloat32FPCompareEQ(float value1, float value2);
private delegate float SoftFloat32FPCompareEQFpscr(float value1, float value2, bool standardFpscr);
private delegate float SoftFloat32FPCompareGE(float value1, float value2);
private delegate float SoftFloat32FPCompareGEFpscr(float value1, float value2, bool standardFpscr);
private delegate float SoftFloat32FPCompareGT(float value1, float value2);
private delegate float SoftFloat32FPCompareGTFpscr(float value1, float value2, bool standardFpscr);
private delegate float SoftFloat32FPCompareLE(float value1, float value2);
private delegate float SoftFloat32FPCompareLEFpscr(float value1, float value2, bool standardFpscr);
private delegate float SoftFloat32FPCompareLT(float value1, float value2);
private delegate float SoftFloat32FPCompareLTFpscr(float value1, float value2, bool standardFpscr);
private delegate float SoftFloat32FPDiv(float value1, float value2);
private delegate float SoftFloat32FPMax(float value1, float value2);
private delegate float SoftFloat32FPMaxFpscr(float value1, float value2, bool standardFpscr);
private delegate float SoftFloat32FPMaxNum(float value1, float value2);
private delegate float SoftFloat32FPMaxNumFpscr(float value1, float value2, bool standardFpscr);
private delegate float SoftFloat32FPMin(float value1, float value2);
private delegate float SoftFloat32FPMinFpscr(float value1, float value2, bool standardFpscr);
private delegate float SoftFloat32FPMinNum(float value1, float value2);
private delegate float SoftFloat32FPMinNumFpscr(float value1, float value2, bool standardFpscr);
private delegate float SoftFloat32FPMul(float value1, float value2);
private delegate float SoftFloat32FPMulFpscr(float value1, float value2, bool standardFpscr);
private delegate float SoftFloat32FPMulAdd(float valueA, float value1, float value2);
private delegate float SoftFloat32FPMulAddFpscr(float valueA, float value1, float value2, bool standardFpscr);
private delegate float SoftFloat32FPMulSub(float valueA, float value1, float value2);
private delegate float SoftFloat32FPMulSubFpscr(float valueA, float value1, float value2, bool standardFpscr);
private delegate float SoftFloat32FPMulX(float value1, float value2);
private delegate float SoftFloat32FPNegMulAdd(float valueA, float value1, float value2);
private delegate float SoftFloat32FPNegMulSub(float valueA, float value1, float value2);
private delegate float SoftFloat32FPRecipEstimate(float value);
private delegate float SoftFloat32FPRecipEstimateFpscr(float value, bool standardFpscr);
private delegate float SoftFloat32FPRecipStep(float value1, float value2);
private delegate float SoftFloat32FPRecipStepFused(float value1, float value2);
private delegate float SoftFloat32FPRecpX(float value);
private delegate float SoftFloat32FPRSqrtEstimate(float value);
private delegate float SoftFloat32FPRSqrtEstimateFpscr(float value, bool standardFpscr);
private delegate float SoftFloat32FPRSqrtStep(float value1, float value2);
private delegate float SoftFloat32FPRSqrtStepFused(float value1, float value2);
private delegate float SoftFloat32FPSqrt(float value);
private delegate float SoftFloat32FPSub(float value1, float value2);
private delegate ushort SoftFloat32_16FPConvert(float value);
private delegate double SoftFloat64FPAdd(double value1, double value2);
private delegate double SoftFloat64FPAddFpscr(double value1, double value2, bool standardFpscr);
private delegate int SoftFloat64FPCompare(double value1, double value2, bool signalNaNs);
private delegate double SoftFloat64FPCompareEQ(double value1, double value2);
private delegate double SoftFloat64FPCompareEQFpscr(double value1, double value2, bool standardFpscr);
private delegate double SoftFloat64FPCompareGE(double value1, double value2);
private delegate double SoftFloat64FPCompareGEFpscr(double value1, double value2, bool standardFpscr);
private delegate double SoftFloat64FPCompareGT(double value1, double value2);
private delegate double SoftFloat64FPCompareGTFpscr(double value1, double value2, bool standardFpscr);
private delegate double SoftFloat64FPCompareLE(double value1, double value2);
private delegate double SoftFloat64FPCompareLEFpscr(double value1, double value2, bool standardFpscr);
private delegate double SoftFloat64FPCompareLT(double value1, double value2);
private delegate double SoftFloat64FPCompareLTFpscr(double value1, double value2, bool standardFpscr);
private delegate double SoftFloat64FPDiv(double value1, double value2);
private delegate double SoftFloat64FPMax(double value1, double value2);
private delegate double SoftFloat64FPMaxFpscr(double value1, double value2, bool standardFpscr);
private delegate double SoftFloat64FPMaxNum(double value1, double value2);
private delegate double SoftFloat64FPMaxNumFpscr(double value1, double value2, bool standardFpscr);
private delegate double SoftFloat64FPMin(double value1, double value2);
private delegate double SoftFloat64FPMinFpscr(double value1, double value2, bool standardFpscr);
private delegate double SoftFloat64FPMinNum(double value1, double value2);
private delegate double SoftFloat64FPMinNumFpscr(double value1, double value2, bool standardFpscr);
private delegate double SoftFloat64FPMul(double value1, double value2);
private delegate double SoftFloat64FPMulFpscr(double value1, double value2, bool standardFpscr);
private delegate double SoftFloat64FPMulAdd(double valueA, double value1, double value2);
private delegate double SoftFloat64FPMulAddFpscr(double valueA, double value1, double value2, bool standardFpscr);
private delegate double SoftFloat64FPMulSub(double valueA, double value1, double value2);
private delegate double SoftFloat64FPMulSubFpscr(double valueA, double value1, double value2, bool standardFpscr);
private delegate double SoftFloat64FPMulX(double value1, double value2);
private delegate double SoftFloat64FPNegMulAdd(double valueA, double value1, double value2);
private delegate double SoftFloat64FPNegMulSub(double valueA, double value1, double value2);
private delegate double SoftFloat64FPRecipEstimate(double value);
private delegate double SoftFloat64FPRecipEstimateFpscr(double value, bool standardFpscr);
private delegate double SoftFloat64FPRecipStep(double value1, double value2);
private delegate double SoftFloat64FPRecipStepFused(double value1, double value2);
private delegate double SoftFloat64FPRecpX(double value);
private delegate double SoftFloat64FPRSqrtEstimate(double value);
private delegate double SoftFloat64FPRSqrtEstimateFpscr(double value, bool standardFpscr);
private delegate double SoftFloat64FPRSqrtStep(double value1, double value2);
private delegate double SoftFloat64FPRSqrtStepFused(double value1, double value2);
private delegate double SoftFloat64FPSqrt(double value);
private delegate double SoftFloat64FPSub(double value1, double value2);
private delegate ushort SoftFloat64_16FPConvert(double value);
} }
} }
@@ -97,7 +97,7 @@ namespace ARMeilleure.Translation
public virtual Operand Call(MethodInfo info, params Operand[] callArgs) public virtual Operand Call(MethodInfo info, params Operand[] callArgs)
{ {
nint funcPtr = Delegates.GetDelegateFuncPtr(info); nint funcPtr = info.MethodHandle.GetFunctionPointer();
OperandType returnType = GetOperandType(info.ReturnType); OperandType returnType = GetOperandType(info.ReturnType);
@@ -413,6 +413,10 @@ namespace ARMeilleure.Translation
context.CurrOp = opCode; context.CurrOp = opCode;
Operand nativeContext = context.LoadArgument(OperandType.I64, 0);
Operand dispAddressAddr = context.Add(nativeContext, Const((ulong)NativeContext.GetDispatchAddressOffset()));
context.Store(dispAddressAddr, Const(opCode.Address));
bool isLastOp = opcIndex == block.OpCodes.Count - 1; bool isLastOp = opcIndex == block.OpCodes.Count - 1;
if (isLastOp) if (isLastOp)
@@ -2,8 +2,6 @@
<PropertyGroup> <PropertyGroup>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -3,8 +3,6 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -4,8 +4,6 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64;win-arm64;osx-arm64;linux-arm64</RuntimeIdentifiers> <RuntimeIdentifiers>win-x64;osx-x64;linux-x64;win-arm64;osx-arm64;linux-arm64</RuntimeIdentifiers>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
-2
View File
@@ -3,8 +3,6 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
-2
View File
@@ -3,8 +3,6 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants Condition=" '$(ExtraDefineConstants)' != '' ">$(DefineConstants);$(ExtraDefineConstants)</DefineConstants> <DefineConstants Condition=" '$(ExtraDefineConstants)' != '' ">$(DefineConstants);$(ExtraDefineConstants)</DefineConstants>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -8,7 +8,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32
{ {
static class Decoder<T> where T : IInstEmit static class Decoder<T> where T : IInstEmit
{ {
public static MultiBlock DecodeMulti(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address, bool isThumb) public static MultiBlock DecodeMulti(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address, bool singleBlock, bool isThumb)
{ {
List<Block> blocks = []; List<Block> blocks = [];
List<ulong> branchTargets = []; List<ulong> branchTargets = [];
@@ -24,7 +24,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32
blocks.Add(block); blocks.Add(block);
if (block.IsTruncated || !HasNextBlock(block, block.EndAddress - 4UL, branchTargets)) if (block.IsTruncated || (singleBlock && block.EndsWithBranch) || !HasNextBlock(block, block.EndAddress - 4UL, branchTargets))
{ {
break; break;
} }
@@ -227,7 +227,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
public static CompiledFunction Compile(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address, IAddressTable<ulong> funcTable, nint dispatchStubPtr, bool isThumb) public static CompiledFunction Compile(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address, IAddressTable<ulong> funcTable, nint dispatchStubPtr, bool isThumb)
{ {
MultiBlock multiBlock = Decoder<InstEmit>.DecodeMulti(cpuPreset, memoryManager, address, isThumb); MultiBlock multiBlock = Decoder<InstEmit>.DecodeMulti(cpuPreset, memoryManager, address, singleBlock: true, isThumb);
Dictionary<ulong, int> targets = new(); Dictionary<ulong, int> targets = new();
@@ -305,7 +305,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
public static CompiledFunction Compile(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address, IAddressTable<ulong> funcTable, nint dispatchStubPtr) public static CompiledFunction Compile(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address, IAddressTable<ulong> funcTable, nint dispatchStubPtr)
{ {
MultiBlock multiBlock = Decoder.DecodeMulti(cpuPreset, memoryManager, address); MultiBlock multiBlock = Decoder.DecodeMulti(cpuPreset, memoryManager, address, singleBlock: true);
Dictionary<ulong, int> targets = new(); Dictionary<ulong, int> targets = new();
List<PendingBranch> pendingBranches = []; List<PendingBranch> pendingBranches = [];
@@ -13,7 +13,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
private const uint NzcvFlags = 0xfu << 28; private const uint NzcvFlags = 0xfu << 28;
private const uint CFlag = 0x1u << 29; private const uint CFlag = 0x1u << 29;
public static MultiBlock DecodeMulti(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address) public static MultiBlock DecodeMulti(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address, bool singleBlock)
{ {
List<Block> blocks = []; List<Block> blocks = [];
List<ulong> branchTargets = []; List<ulong> branchTargets = [];
@@ -35,7 +35,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
blocks.Add(block); blocks.Add(block);
if (block.IsTruncated || !HasNextBlock(block, block.EndAddress - 4UL, branchTargets)) if (block.IsTruncated || (singleBlock && block.EndsWithBranch) || !HasNextBlock(block, block.EndAddress - 4UL, branchTargets))
{ {
break; break;
} }
-2
View File
@@ -3,8 +3,6 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -1,8 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
+6
View File
@@ -32,6 +32,7 @@ namespace Ryujinx.Graphics.GAL
public readonly bool SupportsGeometryShader; public readonly bool SupportsGeometryShader;
public readonly bool SupportsGeometryShaderPassthrough; public readonly bool SupportsGeometryShaderPassthrough;
public readonly bool SupportsTransformFeedback; public readonly bool SupportsTransformFeedback;
public readonly bool SupportsImageBufferPixelAlignment;
public readonly bool SupportsImageLoadFormatted; public readonly bool SupportsImageLoadFormatted;
public readonly bool SupportsLayerVertexTessellation; public readonly bool SupportsLayerVertexTessellation;
public readonly bool SupportsMismatchingViewFormat; public readonly bool SupportsMismatchingViewFormat;
@@ -43,6 +44,7 @@ namespace Ryujinx.Graphics.GAL
public readonly bool SupportsShaderBarrierDivergence; public readonly bool SupportsShaderBarrierDivergence;
public readonly bool SupportsShaderFloat64; public readonly bool SupportsShaderFloat64;
public readonly bool SupportsShaderNonUniformIndexing; public readonly bool SupportsShaderNonUniformIndexing;
public readonly bool SupportsTextureBufferPixelAlignment;
public readonly bool SupportsTextureGatherOffsets; public readonly bool SupportsTextureGatherOffsets;
public readonly bool SupportsTextureShadowLod; public readonly bool SupportsTextureShadowLod;
public readonly bool SupportsVertexStoreAndAtomics; public readonly bool SupportsVertexStoreAndAtomics;
@@ -101,6 +103,7 @@ namespace Ryujinx.Graphics.GAL
bool supportsGeometryShader, bool supportsGeometryShader,
bool supportsGeometryShaderPassthrough, bool supportsGeometryShaderPassthrough,
bool supportsTransformFeedback, bool supportsTransformFeedback,
bool supportsImageBufferPixelAlignment,
bool supportsImageLoadFormatted, bool supportsImageLoadFormatted,
bool supportsLayerVertexTessellation, bool supportsLayerVertexTessellation,
bool supportsMismatchingViewFormat, bool supportsMismatchingViewFormat,
@@ -112,6 +115,7 @@ namespace Ryujinx.Graphics.GAL
bool supportsShaderBarrierDivergence, bool supportsShaderBarrierDivergence,
bool supportsShaderFloat64, bool supportsShaderFloat64,
bool supportsShaderNonUniformIndexing, bool supportsShaderNonUniformIndexing,
bool supportsTextureBufferPixelAlignment,
bool supportsTextureGatherOffsets, bool supportsTextureGatherOffsets,
bool supportsTextureShadowLod, bool supportsTextureShadowLod,
bool supportsVertexStoreAndAtomics, bool supportsVertexStoreAndAtomics,
@@ -164,6 +168,7 @@ namespace Ryujinx.Graphics.GAL
SupportsGeometryShader = supportsGeometryShader; SupportsGeometryShader = supportsGeometryShader;
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough; SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
SupportsTransformFeedback = supportsTransformFeedback; SupportsTransformFeedback = supportsTransformFeedback;
SupportsImageBufferPixelAlignment = supportsImageBufferPixelAlignment;
SupportsImageLoadFormatted = supportsImageLoadFormatted; SupportsImageLoadFormatted = supportsImageLoadFormatted;
SupportsLayerVertexTessellation = supportsLayerVertexTessellation; SupportsLayerVertexTessellation = supportsLayerVertexTessellation;
SupportsMismatchingViewFormat = supportsMismatchingViewFormat; SupportsMismatchingViewFormat = supportsMismatchingViewFormat;
@@ -175,6 +180,7 @@ namespace Ryujinx.Graphics.GAL
SupportsShaderBarrierDivergence = supportsShaderBarrierDivergence; SupportsShaderBarrierDivergence = supportsShaderBarrierDivergence;
SupportsShaderFloat64 = supportsShaderFloat64; SupportsShaderFloat64 = supportsShaderFloat64;
SupportsShaderNonUniformIndexing = supportsShaderNonUniformIndexing; SupportsShaderNonUniformIndexing = supportsShaderNonUniformIndexing;
SupportsTextureBufferPixelAlignment = supportsTextureBufferPixelAlignment;
SupportsTextureGatherOffsets = supportsTextureGatherOffsets; SupportsTextureGatherOffsets = supportsTextureGatherOffsets;
SupportsTextureShadowLod = supportsTextureShadowLod; SupportsTextureShadowLod = supportsTextureShadowLod;
SupportsVertexStoreAndAtomics = supportsVertexStoreAndAtomics; SupportsVertexStoreAndAtomics = supportsVertexStoreAndAtomics;
@@ -1,10 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations> <Configurations>Debug;Release</Configurations>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -466,6 +466,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
engine.UpdateState(ulong.MaxValue & ~(1UL << StateUpdater.ShaderStateIndex)); engine.UpdateState(ulong.MaxValue & ~(1UL << StateUpdater.ShaderStateIndex));
_channel.TextureManager.SignalRenderTargetsModifiable();
_channel.TextureManager.UpdateRenderTargets(); _channel.TextureManager.UpdateRenderTargets();
int textureId = _state.State.DrawTextureTextureId; int textureId = _state.State.DrawTextureTextureId;
@@ -803,7 +804,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
int index = (argument >> 6) & 0xf; int index = (argument >> 6) & 0xf;
int layer = (argument >> 10) & 0x3ff; int layer = (argument >> 10) & 0x3ff;
RenderTargetUpdateFlags updateFlags = RenderTargetUpdateFlags.SingleColor; RenderTargetUpdateFlags updateFlags = RenderTargetUpdateFlags.SingleColor | RenderTargetUpdateFlags.ForClear;
if (layer != 0 || layerCount > 1) if (layer != 0 || layerCount > 1)
{ {
@@ -38,6 +38,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
/// </summary> /// </summary>
DiscardClip = 1 << 4, DiscardClip = 1 << 4,
/// <summary>
/// Indicates that the render target will be used for a clear operation.
/// </summary>
ForClear = 1 << 5,
/// <summary> /// <summary>
/// Default update flags for draw. /// Default update flags for draw.
/// </summary> /// </summary>
@@ -45,6 +45,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
private ProgramPipelineState _pipeline; private ProgramPipelineState _pipeline;
private bool _fsReadsFragCoord; private bool _fsReadsFragCoord;
private bool _fsAlwaysDiscards;
private bool _vsUsesDrawParameters; private bool _vsUsesDrawParameters;
private bool _vtgWritesRtLayer; private bool _vtgWritesRtLayer;
private byte _vsClipDistancesWritten; private byte _vsClipDistancesWritten;
@@ -491,6 +492,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
Span<RtColorState> rtColorStateSpan = _state.State.RtColorState.AsSpan(); Span<RtColorState> rtColorStateSpan = _state.State.RtColorState.AsSpan();
bool rtModifiable = updateFlags.HasFlag(RenderTargetUpdateFlags.ForClear) || !_fsAlwaysDiscards;
for (int index = 0; index < Constants.TotalRenderTargets; index++) for (int index = 0; index < Constants.TotalRenderTargets; index++)
{ {
int rtIndex = useControl ? rtControl.UnpackPermutationIndex(index) : index; int rtIndex = useControl ? rtControl.UnpackPermutationIndex(index) : index;
@@ -499,7 +502,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
if (index >= count || !IsRtEnabled(colorState) || (singleColor && index != singleUse)) if (index >= count || !IsRtEnabled(colorState) || (singleColor && index != singleUse))
{ {
changedScale |= _channel.TextureManager.SetRenderTargetColor(index, null); changedScale |= _channel.TextureManager.SetRenderTargetColor(index, null, rtModifiable);
continue; continue;
} }
@@ -518,7 +521,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
samplesInY, samplesInY,
sizeHint); sizeHint);
changedScale |= _channel.TextureManager.SetRenderTargetColor(index, color); changedScale |= _channel.TextureManager.SetRenderTargetColor(index, color, rtModifiable);
if (color != null) if (color != null)
{ {
@@ -572,7 +575,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
} }
} }
changedScale |= _channel.TextureManager.SetRenderTargetDepthStencil(depthStencil); changedScale |= _channel.TextureManager.SetRenderTargetDepthStencil(depthStencil, rtModifiable);
if (changedScale) if (changedScale)
{ {
@@ -774,6 +777,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
float width = scaleX * 2; float width = scaleX * 2;
float height = scaleY * 2; float height = scaleY * 2;
if (yNegate)
{
y += _state.State.ScreenScissorState.Height - MathF.Abs(height);
}
float scale = _channel.TextureManager.RenderTargetScale; float scale = _channel.TextureManager.RenderTargetScale;
if (scale != 1f) if (scale != 1f)
{ {
@@ -1517,20 +1525,38 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_currentProgramInfo[stageIndex] = info; _currentProgramInfo[stageIndex] = info;
} }
if (gs.Shaders[5]?.Info.UsesFragCoord == true) _fsReadsFragCoord = false;
{
// Make sure we update the viewport size on the support buffer if it will be consumed on the new shader.
if (!_fsReadsFragCoord && (_state.State.YControl & YControl.NegateY) != 0) ShaderProgramInfo fragmentShaderInfo = gs.Shaders[5]?.Info;
if (fragmentShaderInfo != null)
{
if (fragmentShaderInfo.UsesFragCoord)
{ {
UpdateSupportBufferViewportSize(); // Make sure we update the viewport size on the support buffer if it will be consumed on the new shader.
if (!_fsReadsFragCoord && (_state.State.YControl & YControl.NegateY) != 0)
{
UpdateSupportBufferViewportSize();
}
_fsReadsFragCoord = true;
} }
_fsReadsFragCoord = true; if (_fsAlwaysDiscards != fragmentShaderInfo.HasUnconditionalDiscard)
{
_fsAlwaysDiscards = fragmentShaderInfo.HasUnconditionalDiscard;
if (!_fsAlwaysDiscards)
{
_channel.TextureManager.RefreshModifiedTextures();
_channel.TextureManager.SignalRenderTargetsModifiable();
}
}
} }
else else
{ {
_fsReadsFragCoord = false; _fsAlwaysDiscards = false;
} }
if (gs.VertexAsCompute != null) if (gs.VertexAsCompute != null)
+9 -5
View File
@@ -1572,11 +1572,6 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <param name="bound">True if the texture has been bound, false if it has been unbound</param> /// <param name="bound">True if the texture has been bound, false if it has been unbound</param>
public void SignalModifying(bool bound) public void SignalModifying(bool bound)
{ {
if (bound)
{
_scaledSetScore = Math.Max(0, _scaledSetScore - 1);
}
if (_modifiedStale || Group.HasCopyDependencies || Group.HasFlushBuffer) if (_modifiedStale || Group.HasCopyDependencies || Group.HasFlushBuffer)
{ {
_modifiedStale = false; _modifiedStale = false;
@@ -1584,9 +1579,18 @@ namespace Ryujinx.Graphics.Gpu.Image
} }
_physicalMemory.TextureCache.Lift(this); _physicalMemory.TextureCache.Lift(this);
}
/// <summary>
/// Signals that a render target texture has been either bound or unbound.
/// </summary>
/// <param name="bound">True if the texture has been bound, false if it has been unbound</param>
public void SignalBindingChange(bool bound)
{
if (bound) if (bound)
{ {
_scaledSetScore = Math.Max(0, _scaledSetScore - 1);
IncrementReferenceCount(); IncrementReferenceCount();
} }
else else
@@ -4,6 +4,7 @@ using Ryujinx.Graphics.Gpu.Engine.Types;
using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Gpu.Shader; using Ryujinx.Graphics.Gpu.Shader;
using Ryujinx.Graphics.Shader; using Ryujinx.Graphics.Shader;
using Ryujinx.Memory.Range;
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@@ -67,6 +68,9 @@ namespace Ryujinx.Graphics.Gpu.Image
private int _lastFragmentTotal; private int _lastFragmentTotal;
private readonly int _bufferTextureAlignment;
private readonly int _bufferImageAlignment;
/// <summary> /// <summary>
/// Constructs a new instance of the texture bindings manager. /// Constructs a new instance of the texture bindings manager.
/// </summary> /// </summary>
@@ -108,6 +112,10 @@ namespace Ryujinx.Graphics.Gpu.Image
} }
_textureCounts = []; _textureCounts = [];
int alignment = context.Capabilities.TextureBufferOffsetAlignment;
_bufferTextureAlignment = context.Capabilities.SupportsTextureBufferPixelAlignment ? 0 : alignment;
_bufferImageAlignment = context.Capabilities.SupportsImageBufferPixelAlignment ? 0 : alignment;
} }
/// <summary> /// <summary>
@@ -521,10 +529,12 @@ namespace Ryujinx.Graphics.Gpu.Image
if (hostTexture != null && texture.Target == Target.TextureBuffer) if (hostTexture != null && texture.Target == Target.TextureBuffer)
{ {
MultiRange range = GetAlignedBufferTextureRange(texture, index, stageIndex, false);
// Ensure that the buffer texture is using the correct buffer as storage. // Ensure that the buffer texture is using the correct buffer as storage.
// Buffers are frequently re-created to accommodate larger data, so we need to re-bind // Buffers are frequently re-created to accommodate larger data, so we need to re-bind
// to ensure we're not using a old buffer that was already deleted. // to ensure we're not using a old buffer that was already deleted.
_channel.BufferManager.SetBufferTextureStorage(stage, hostTexture, texture.Range, bindingInfo, false); _channel.BufferManager.SetBufferTextureStorage(stage, hostTexture, range, bindingInfo, false);
// Cache is not used for buffer texture, it must always rebind. // Cache is not used for buffer texture, it must always rebind.
state.CachedTexture = null; state.CachedTexture = null;
@@ -659,7 +669,9 @@ namespace Ryujinx.Graphics.Gpu.Image
// Buffers are frequently re-created to accommodate larger data, so we need to re-bind // Buffers are frequently re-created to accommodate larger data, so we need to re-bind
// to ensure we're not using a old buffer that was already deleted. // to ensure we're not using a old buffer that was already deleted.
_channel.BufferManager.SetBufferTextureStorage(stage, hostTexture, texture.Range, bindingInfo, true); MultiRange range = GetAlignedBufferTextureRange(texture, index, stageIndex, true);
_channel.BufferManager.SetBufferTextureStorage(stage, hostTexture, range, bindingInfo, true);
// Cache is not used for buffer texture, it must always rebind. // Cache is not used for buffer texture, it must always rebind.
state.CachedTexture = null; state.CachedTexture = null;
@@ -692,6 +704,61 @@ namespace Ryujinx.Graphics.Gpu.Image
return specStateMatches; return specStateMatches;
} }
/// <summary>
/// Gets the aligned address of the texture according to the host requirements.
/// </summary>
/// <param name="texture">Texture to have its address aligned</param>
/// <param name="index">Index of the texture in the shader</param>
/// <param name="stageIndex">Index of the shader stage</param>
/// <param name="isImage">True if the texture is bound as image, false for sampled textures</param>
/// <returns>Aligned address and size of the buffer texture</returns>
private MultiRange GetAlignedBufferTextureRange(Texture texture, int index, int stageIndex, bool isImage)
{
MultiRange range = texture.Range;
int alignment = isImage ? _bufferImageAlignment : _bufferTextureAlignment;
if (alignment != 0)
{
MemoryRange firstRange = range.GetSubRange(0);
ulong misalign = firstRange.Address & ((ulong)alignment - 1);
int offset = misalign != 0 ? (int)misalign / texture.Info.FormatInfo.BytesPerPixel : 0;
if (misalign != 0)
{
firstRange = new MemoryRange(firstRange.Address - misalign, firstRange.Size + misalign);
if (range.Count > 1)
{
MemoryRange[] ranges = new MemoryRange[range.Count];
ranges[0] = firstRange;
for (int i = 1; i < range.Count; i++)
{
ranges[i] = range.GetSubRange(i);
}
range = new MultiRange(ranges);
}
else
{
range = new MultiRange(firstRange.Address, firstRange.Size);
}
}
if (isImage)
{
_context.SupportBufferUpdater.UpdateBufferImageOffset(stageIndex, index, offset);
}
else
{
_context.SupportBufferUpdater.UpdateBufferTextureOffset(stageIndex, index, offset);
}
}
return range;
}
/// <summary> /// <summary>
/// Gets the texture descriptor for a given texture handle. /// Gets the texture descriptor for a given texture handle.
/// </summary> /// </summary>
@@ -19,12 +19,39 @@ namespace Ryujinx.Graphics.Gpu.Image
private readonly TexturePoolCache _texturePoolCache; private readonly TexturePoolCache _texturePoolCache;
private readonly SamplerPoolCache _samplerPoolCache; private readonly SamplerPoolCache _samplerPoolCache;
/// <summary>
/// Bound render target texture modification report state.
/// </summary>
[Flags]
private enum BindState : byte
{
/// <summary>
/// Render target texture has not been signalled for modification, and can't be modified on the next render operations.
/// </summary>
None = 0,
/// <summary>
/// Render target texture has been signalled for modification.
/// </summary>
Bound = 1 << 0,
/// <summary>
/// Render target texture might be modified on the next render operations.
/// </summary>
Modified = 1 << 1,
/// <summary>
/// Render target texture has been signalled for modification and might be modified on the next render operations.
/// </summary>
BoundModified = Bound | Modified,
}
private readonly Texture[] _rtColors; private readonly Texture[] _rtColors;
private readonly ITexture[] _rtHostColors; private readonly ITexture[] _rtHostColors;
private readonly bool[] _rtColorsBound; private readonly BindState[] _rtColorsBound;
private Texture _rtDepthStencil; private Texture _rtDepthStencil;
private ITexture _rtHostDs; private ITexture _rtHostDs;
private bool _rtDsBound; private BindState _rtDsBound;
public int ClipRegionWidth { get; private set; } public int ClipRegionWidth { get; private set; }
public int ClipRegionHeight { get; private set; } public int ClipRegionHeight { get; private set; }
@@ -55,7 +82,7 @@ namespace Ryujinx.Graphics.Gpu.Image
_rtColors = new Texture[Constants.TotalRenderTargets]; _rtColors = new Texture[Constants.TotalRenderTargets];
_rtHostColors = new ITexture[Constants.TotalRenderTargets]; _rtHostColors = new ITexture[Constants.TotalRenderTargets];
_rtColorsBound = new bool[Constants.TotalRenderTargets]; _rtColorsBound = new BindState[Constants.TotalRenderTargets];
} }
/// <summary> /// <summary>
@@ -151,27 +178,39 @@ namespace Ryujinx.Graphics.Gpu.Image
/// </summary> /// </summary>
/// <param name="index">The index of the color buffer to set (up to 8)</param> /// <param name="index">The index of the color buffer to set (up to 8)</param>
/// <param name="color">The color buffer texture</param> /// <param name="color">The color buffer texture</param>
/// <param name="modified">Indicates if the following render operations will modidify <paramref name="color"/> contents</param>
/// <returns>True if render target scale must be updated.</returns> /// <returns>True if render target scale must be updated.</returns>
public bool SetRenderTargetColor(int index, Texture color) public bool SetRenderTargetColor(int index, Texture color, bool modified)
{ {
bool hasValue = color != null; bool hasValue = color != null;
bool changesScale = (hasValue != (_rtColors[index] != null)) || (hasValue && RenderTargetScale != color.ScaleFactor); bool changesScale = (hasValue != (_rtColors[index] != null)) || (hasValue && RenderTargetScale != color.ScaleFactor);
if (_rtColors[index] != color) if (_rtColors[index] != color)
{ {
if (_rtColorsBound[index]) Texture oldColor = _rtColors[index];
if (oldColor != null)
{ {
_rtColors[index]?.SignalModifying(false); if (_rtColorsBound[index].HasFlag(BindState.Bound))
} {
else oldColor.SignalModifying(false);
{ }
_rtColorsBound[index] = true;
oldColor.SignalBindingChange(false);
} }
_rtColorsBound[index] = modified ? BindState.BoundModified : BindState.None;
if (color != null) if (color != null)
{ {
color.SynchronizeMemory(); color.SynchronizeMemory();
color.SignalModifying(true);
if (modified)
{
color.SignalModifying(true);
}
color.SignalBindingChange(true);
} }
_rtColors[index] = color; _rtColors[index] = color;
@@ -184,27 +223,39 @@ namespace Ryujinx.Graphics.Gpu.Image
/// Sets the render target depth-stencil buffer. /// Sets the render target depth-stencil buffer.
/// </summary> /// </summary>
/// <param name="depthStencil">The depth-stencil buffer texture</param> /// <param name="depthStencil">The depth-stencil buffer texture</param>
/// <param name="modified">Indicates if the following render operations will modidify <paramref name="depthStencil"/> contents</param>
/// <returns>True if render target scale must be updated.</returns> /// <returns>True if render target scale must be updated.</returns>
public bool SetRenderTargetDepthStencil(Texture depthStencil) public bool SetRenderTargetDepthStencil(Texture depthStencil, bool modified)
{ {
bool hasValue = depthStencil != null; bool hasValue = depthStencil != null;
bool changesScale = (hasValue != (_rtDepthStencil != null)) || (hasValue && RenderTargetScale != depthStencil.ScaleFactor); bool changesScale = (hasValue != (_rtDepthStencil != null)) || (hasValue && RenderTargetScale != depthStencil.ScaleFactor);
if (_rtDepthStencil != depthStencil) if (_rtDepthStencil != depthStencil)
{ {
if (_rtDsBound) Texture oldDepthStencil = _rtDepthStencil;
if (oldDepthStencil != null)
{ {
_rtDepthStencil?.SignalModifying(false); if (_rtDsBound.HasFlag(BindState.Bound))
} {
else oldDepthStencil.SignalModifying(false);
{ }
_rtDsBound = true;
oldDepthStencil.SignalBindingChange(false);
} }
_rtDsBound = modified ? BindState.BoundModified : BindState.None;
if (depthStencil != null) if (depthStencil != null)
{ {
depthStencil.SynchronizeMemory(); depthStencil.SynchronizeMemory();
depthStencil.SignalModifying(true);
if (modified)
{
depthStencil.SignalModifying(true);
}
depthStencil.SignalBindingChange(true);
} }
_rtDepthStencil = depthStencil; _rtDepthStencil = depthStencil;
@@ -443,10 +494,10 @@ namespace Ryujinx.Graphics.Gpu.Image
{ {
hostDsTexture = dsTexture.HostTexture; hostDsTexture = dsTexture.HostTexture;
if (!_rtDsBound) if (_rtDsBound == BindState.Modified)
{ {
dsTexture.SignalModifying(true); dsTexture.SignalModifying(true);
_rtDsBound = true; _rtDsBound |= BindState.Bound;
} }
} }
@@ -470,10 +521,10 @@ namespace Ryujinx.Graphics.Gpu.Image
{ {
hostTexture = texture.HostTexture; hostTexture = texture.HostTexture;
if (!_rtColorsBound[index]) if (_rtColorsBound[index] == BindState.Modified)
{ {
texture.SignalModifying(true); texture.SignalModifying(true);
_rtColorsBound[index] = true; _rtColorsBound[index] |= BindState.Bound;
} }
} }
@@ -518,24 +569,37 @@ namespace Ryujinx.Graphics.Gpu.Image
{ {
Texture dsTexture = _rtDepthStencil; Texture dsTexture = _rtDepthStencil;
if (dsTexture != null && _rtDsBound) if (dsTexture != null && _rtDsBound.HasFlag(BindState.Bound))
{ {
dsTexture.SignalModifying(false); dsTexture.SignalModifying(false);
_rtDsBound = false; _rtDsBound &= ~BindState.Bound;
} }
for (int index = 0; index < _rtColors.Length; index++) for (int index = 0; index < _rtColors.Length; index++)
{ {
Texture texture = _rtColors[index]; Texture texture = _rtColors[index];
if (texture != null && _rtColorsBound[index]) if (texture != null && _rtColorsBound[index].HasFlag(BindState.Bound))
{ {
texture.SignalModifying(false); texture.SignalModifying(false);
_rtColorsBound[index] = false; _rtColorsBound[index] &= ~BindState.Bound;
} }
} }
} }
/// <summary>
/// Indicates that the currently bound render targets might be modified, if they are used on the next render operation.
/// </summary>
public void SignalRenderTargetsModifiable()
{
_rtDsBound |= BindState.Modified;
for (int index = 0; index < _rtColorsBound.Length; index++)
{
_rtColorsBound[index] |= BindState.Modified;
}
}
/// <summary> /// <summary>
/// Forces the texture and sampler pools to be re-loaded from the cache on next use. /// Forces the texture and sampler pools to be re-loaded from the cache on next use.
/// </summary> /// </summary>
@@ -572,19 +636,11 @@ namespace Ryujinx.Graphics.Gpu.Image
for (int i = 0; i < _rtColors.Length; i++) for (int i = 0; i < _rtColors.Length; i++)
{ {
if (_rtColorsBound[i]) _rtColors[i]?.DecrementReferenceCount();
{
_rtColors[i]?.DecrementReferenceCount();
}
_rtColors[i] = null; _rtColors[i] = null;
} }
if (_rtDsBound) _rtDepthStencil?.DecrementReferenceCount();
{
_rtDepthStencil?.DecrementReferenceCount();
}
_rtDepthStencil = null; _rtDepthStencil = null;
} }
} }
@@ -129,6 +129,38 @@ namespace Ryujinx.Graphics.Gpu.Memory
} }
} }
/// <summary>
/// Updates the offset used for accessing buffer textures that are not aligned to the host requirements.
/// </summary>
/// <param name="stageIndex">Index of the shader stage where the texture is used</param>
/// <param name="bindingIndex">Index of the texture binding in the shader</param>
/// <param name="offset">Offset for the misaligned part of the address</param>
public void UpdateBufferTextureOffset(int stageIndex, int bindingIndex, int offset)
{
if (_data.BufferTextureOffset[stageIndex][bindingIndex].X != offset)
{
_data.BufferTextureOffset[stageIndex][bindingIndex].X = offset;
int index = stageIndex * SupportBuffer.TextureCount + bindingIndex;
MarkDirty(SupportBuffer.BufferTextureOffsetOffset + index * sizeof(int) * 4, sizeof(int));
}
}
/// <summary>
/// Updates the offset used for accessing buffer images that are not aligned to the host requirements.
/// </summary>
/// <param name="stageIndex">Index of the shader stage where the image is used</param>
/// <param name="bindingIndex">Index of the image binding in the shader</param>
/// <param name="offset">Offset for the misaligned part of the address</param>
public void UpdateBufferImageOffset(int stageIndex, int bindingIndex, int offset)
{
if (_data.BufferTextureOffset[stageIndex][bindingIndex].Y != offset)
{
_data.BufferTextureOffset[stageIndex][bindingIndex].Y = offset;
int index = stageIndex * SupportBuffer.TextureCount + bindingIndex;
MarkDirty(SupportBuffer.BufferTextureOffsetOffset + index * sizeof(int) * 4 + sizeof(int), sizeof(int));
}
}
/// <summary> /// <summary>
/// Sets whether the format of a given render target is a BGRA format. /// Sets whether the format of a given render target is a BGRA format.
/// </summary> /// </summary>
@@ -2,8 +2,6 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2; private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
private const uint CodeGenVersion = 7354; private const uint CodeGenVersion = 6371;
private const string SharedTocFileName = "shared.toc"; private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data"; private const string SharedDataFileName = "shared.data";
@@ -170,6 +170,11 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
/// </summary> /// </summary>
public bool UsesRtLayer; public bool UsesRtLayer;
/// <summary>
/// Indicates that the fragment shader always discards the fragment, not producing any output for the bound render targets.
/// </summary>
public bool HasUnconditionalDiscard;
/// <summary> /// <summary>
/// Bit mask with the clip distances written on the vertex stage. /// Bit mask with the clip distances written on the vertex stage.
/// </summary> /// </summary>
@@ -806,6 +811,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
dataInfo.UsesInstanceId, dataInfo.UsesInstanceId,
dataInfo.UsesDrawParameters, dataInfo.UsesDrawParameters,
dataInfo.UsesRtLayer, dataInfo.UsesRtLayer,
dataInfo.HasUnconditionalDiscard,
dataInfo.ClipDistancesWritten, dataInfo.ClipDistancesWritten,
dataInfo.FragmentOutputMap); dataInfo.FragmentOutputMap);
} }
@@ -836,6 +842,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
UsesInstanceId = info.UsesInstanceId, UsesInstanceId = info.UsesInstanceId,
UsesDrawParameters = info.UsesDrawParameters, UsesDrawParameters = info.UsesDrawParameters,
UsesRtLayer = info.UsesRtLayer, UsesRtLayer = info.UsesRtLayer,
HasUnconditionalDiscard = info.HasUnconditionalDiscard,
ClipDistancesWritten = info.ClipDistancesWritten, ClipDistancesWritten = info.ClipDistancesWritten,
FragmentOutputMap = info.FragmentOutputMap, FragmentOutputMap = info.FragmentOutputMap,
}; };
@@ -207,6 +207,10 @@ namespace Ryujinx.Graphics.Gpu.Shader
public bool QueryHostSupportsBgraFormat() => _context.Capabilities.SupportsBgraFormat; public bool QueryHostSupportsBgraFormat() => _context.Capabilities.SupportsBgraFormat;
public bool QueryHostSupportsBufferImagePixelAlignment() => _context.Capabilities.SupportsImageBufferPixelAlignment;
public bool QueryHostSupportsBufferTexturePixelAlignment() => _context.Capabilities.SupportsTextureBufferPixelAlignment;
public bool QueryHostSupportsFragmentShaderInterlock() => _context.Capabilities.SupportsFragmentShaderInterlock; public bool QueryHostSupportsFragmentShaderInterlock() => _context.Capabilities.SupportsFragmentShaderInterlock;
public bool QueryHostSupportsFragmentShaderOrderingIntel() => _context.Capabilities.SupportsFragmentShaderOrderingIntel; public bool QueryHostSupportsFragmentShaderOrderingIntel() => _context.Capabilities.SupportsFragmentShaderOrderingIntel;
@@ -430,7 +430,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
TranslatorContext lastInVertexPipeline = geometryToCompute ? translatorContexts[4] ?? currentStage : currentStage; TranslatorContext lastInVertexPipeline = geometryToCompute ? translatorContexts[4] ?? currentStage : currentStage;
program = lastInVertexPipeline.GenerateVertexPassthroughForCompute(); (program, ShaderProgramInfo vacInfo) = lastInVertexPipeline.GenerateVertexPassthroughForCompute();
infoBuilder.AddStageInfoVac(vacInfo);
} }
else else
{ {
@@ -535,7 +536,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
private ShaderAsCompute CreateHostVertexAsComputeProgram(ShaderProgram program, TranslatorContext context, bool tfEnabled) private ShaderAsCompute CreateHostVertexAsComputeProgram(ShaderProgram program, TranslatorContext context, bool tfEnabled)
{ {
ShaderSource source = new(program.Code, program.BinaryCode, ShaderStage.Compute, program.Language); ShaderSource source = new(program.Code, program.BinaryCode, ShaderStage.Compute, program.Language);
ShaderInfo info = ShaderInfoBuilder.BuildForVertexAsCompute(_context, program.Info, tfEnabled); ShaderInfo info = ShaderInfoBuilder.BuildForVertexAsCompute(_context, program.Info, context.GetVertexAsComputeInfo(), tfEnabled);
return new(_context.Renderer.CreateProgram([source], info), program.Info, context.GetResourceReservations()); return new(_context.Renderer.CreateProgram([source], info), program.Info, context.GetResourceReservations());
} }
@@ -95,7 +95,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
private void PopulateDescriptorAndUsages(ResourceStages stages, ResourceType type, int setIndex, int start, int count, bool write = false) private void PopulateDescriptorAndUsages(ResourceStages stages, ResourceType type, int setIndex, int start, int count, bool write = false)
{ {
AddDescriptor(stages, type, setIndex, start, count); AddDescriptor(stages, type, setIndex, start, count);
AddUsage(stages, type, setIndex, start, count, write); // AddUsage(stages, type, setIndex, start, count, write);
} }
/// <summary> /// <summary>
@@ -159,6 +159,25 @@ namespace Ryujinx.Graphics.Gpu.Shader
AddUsage(info.Images, stages, isImage: true); AddUsage(info.Images, stages, isImage: true);
} }
public void AddStageInfoVac(ShaderProgramInfo info)
{
ResourceStages stages = info.Stage switch
{
ShaderStage.Compute => ResourceStages.Compute,
ShaderStage.Vertex => ResourceStages.Vertex,
ShaderStage.TessellationControl => ResourceStages.TessellationControl,
ShaderStage.TessellationEvaluation => ResourceStages.TessellationEvaluation,
ShaderStage.Geometry => ResourceStages.Geometry,
ShaderStage.Fragment => ResourceStages.Fragment,
_ => ResourceStages.None,
};
AddUsage(info.CBuffers, stages, isStorage: false);
AddUsage(info.SBuffers, stages, isStorage: true);
AddUsage(info.Textures, stages, isImage: false);
AddUsage(info.Images, stages, isImage: true);
}
/// <summary> /// <summary>
/// Adds a resource descriptor to the list of descriptors. /// Adds a resource descriptor to the list of descriptors.
/// </summary> /// </summary>
@@ -422,10 +441,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param> /// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
/// <param name="fromCache">True if the compute shader comes from a disk cache, false otherwise</param> /// <param name="fromCache">True if the compute shader comes from a disk cache, false otherwise</param>
/// <returns>Shader information</returns> /// <returns>Shader information</returns>
public static ShaderInfo BuildForVertexAsCompute(GpuContext context, ShaderProgramInfo info, bool tfEnabled, bool fromCache = false) public static ShaderInfo BuildForVertexAsCompute(GpuContext context, ShaderProgramInfo info, ShaderProgramInfo info2, bool tfEnabled, bool fromCache = false)
{ {
ShaderInfoBuilder builder = new(context, tfEnabled, vertexAsCompute: true); ShaderInfoBuilder builder = new(context, tfEnabled, vertexAsCompute: true);
builder.AddStageInfoVac(info2);
builder.AddStageInfo(info, vertexAsCompute: true); builder.AddStageInfo(info, vertexAsCompute: true);
return builder.Build(null, fromCache); return builder.Build(null, fromCache);
@@ -2,8 +2,6 @@
<PropertyGroup> <PropertyGroup>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -2,8 +2,6 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -2,8 +2,6 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -3,8 +3,6 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -174,6 +174,7 @@ namespace Ryujinx.Graphics.OpenGL
supportsGeometryShader: true, supportsGeometryShader: true,
supportsGeometryShaderPassthrough: HwCapabilities.SupportsGeometryShaderPassthrough, supportsGeometryShaderPassthrough: HwCapabilities.SupportsGeometryShaderPassthrough,
supportsTransformFeedback: true, supportsTransformFeedback: true,
supportsImageBufferPixelAlignment: false,
supportsImageLoadFormatted: HwCapabilities.SupportsImageLoadFormatted, supportsImageLoadFormatted: HwCapabilities.SupportsImageLoadFormatted,
supportsLayerVertexTessellation: HwCapabilities.SupportsShaderViewportLayerArray, supportsLayerVertexTessellation: HwCapabilities.SupportsShaderViewportLayerArray,
supportsMismatchingViewFormat: HwCapabilities.SupportsMismatchingViewFormat, supportsMismatchingViewFormat: HwCapabilities.SupportsMismatchingViewFormat,
@@ -185,6 +186,7 @@ namespace Ryujinx.Graphics.OpenGL
supportsShaderBarrierDivergence: !(intelWindows || intelUnix), supportsShaderBarrierDivergence: !(intelWindows || intelUnix),
supportsShaderFloat64: true, supportsShaderFloat64: true,
supportsShaderNonUniformIndexing: false, supportsShaderNonUniformIndexing: false,
supportsTextureBufferPixelAlignment: false,
supportsTextureGatherOffsets: true, supportsTextureGatherOffsets: true,
supportsTextureShadowLod: HwCapabilities.SupportsTextureShadowLod, supportsTextureShadowLod: HwCapabilities.SupportsTextureShadowLod,
supportsVertexStoreAndAtomics: true, supportsVertexStoreAndAtomics: true,
@@ -2,8 +2,6 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -522,6 +522,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
enum PMode enum PMode
{ {
Idx = 0,
F4e = 1, F4e = 1,
B4e = 2, B4e = 2,
Rc8 = 3, Rc8 = 3,
@@ -234,6 +234,24 @@ namespace Ryujinx.Graphics.Shader
return true; return true;
} }
/// <summary>
/// Queries host support for buffer image access with the buffer offset aligned to a single pixel rather than a fixed alignment.
/// </summary>
/// <returns>True if the host supports buffer image access with pixel alignment, false otherwise</returns>
bool QueryHostSupportsBufferImagePixelAlignment()
{
return true;
}
/// <summary>
/// Queries host support for buffer texture access with the buffer offset aligned to a single pixel rather than a fixed alignment.
/// </summary>
/// <returns>True if the host supports buffer texture access with pixel alignment, false otherwise</returns>
bool QueryHostSupportsBufferTexturePixelAlignment()
{
return true;
}
/// <summary> /// <summary>
/// Queries host support for fragment shader ordering critical sections on the shader code. /// Queries host support for fragment shader ordering critical sections on the shader code.
/// </summary> /// </summary>
@@ -215,34 +215,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
context.TranslatorContext.GpuAccessor.Log("Shader instruction Pret is not implemented."); context.TranslatorContext.GpuAccessor.Log("Shader instruction Pret is not implemented.");
} }
public static void PrmtR(EmitterContext context)
{
context.GetOp<InstPrmtR>();
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtR is not implemented.");
}
public static void PrmtI(EmitterContext context)
{
context.GetOp<InstPrmtI>();
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtI is not implemented.");
}
public static void PrmtC(EmitterContext context)
{
context.GetOp<InstPrmtC>();
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtC is not implemented.");
}
public static void PrmtRc(EmitterContext context)
{
context.GetOp<InstPrmtRc>();
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtRc is not implemented.");
}
public static void R2b(EmitterContext context) public static void R2b(EmitterContext context)
{ {
context.GetOp<InstR2b>(); context.GetOp<InstR2b>();
@@ -1,7 +1,7 @@
using Ryujinx.Graphics.Shader.Decoders; using Ryujinx.Graphics.Shader.Decoders;
using Ryujinx.Graphics.Shader.IntermediateRepresentation; using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using Ryujinx.Graphics.Shader.Translation; using Ryujinx.Graphics.Shader.Translation;
using System;
using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper; using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
@@ -37,6 +37,38 @@ namespace Ryujinx.Graphics.Shader.Instructions
context.Copy(GetDest(op.Dest), GetSrcImm(context, op.Imm32)); context.Copy(GetDest(op.Dest), GetSrcImm(context, op.Imm32));
} }
public static void PrmtR(EmitterContext context)
{
context.GetOp<InstPrmtR>();
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtR is not implemented.");
}
public static void PrmtI(EmitterContext context)
{
InstPrmtI op = context.GetOp<InstPrmtI>();
Operand op1 = GetSrcReg(context, op.SrcA);
Operand control = GetSrcImm(context, op.Imm20);
Operand op2 = GetSrcReg(context, op.SrcC);
EmitPrmt(context, op1, control, op2, op.PMode, op.Dest);
}
public static void PrmtC(EmitterContext context)
{
context.GetOp<InstPrmtC>();
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtC is not implemented.");
}
public static void PrmtRc(EmitterContext context)
{
context.GetOp<InstPrmtRc>();
context.TranslatorContext.GpuAccessor.Log("Shader instruction PrmtRc is not implemented.");
}
public static void R2pR(EmitterContext context) public static void R2pR(EmitterContext context)
{ {
InstR2pR op = context.GetOp<InstR2pR>(); InstR2pR op = context.GetOp<InstR2pR>();
@@ -169,6 +201,39 @@ namespace Ryujinx.Graphics.Shader.Instructions
context.Copy(GetDest(op.Dest), src); context.Copy(GetDest(op.Dest), src);
} }
public static void SelR(EmitterContext context)
{
InstSelR op = context.GetOp<InstSelR>();
Operand srcA = GetSrcReg(context, op.SrcA);
Operand srcB = GetSrcReg(context, op.SrcB);
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
EmitSel(context, srcA, srcB, srcPred, op.Dest);
}
public static void SelI(EmitterContext context)
{
InstSelI op = context.GetOp<InstSelI>();
Operand srcA = GetSrcReg(context, op.SrcA);
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
EmitSel(context, srcA, srcB, srcPred, op.Dest);
}
public static void SelC(EmitterContext context)
{
InstSelC op = context.GetOp<InstSelC>();
Operand srcA = GetSrcReg(context, op.SrcA);
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
EmitSel(context, srcA, srcB, srcPred, op.Dest);
}
private static Operand EmitLoadSubgroupLaneId(EmitterContext context) private static Operand EmitLoadSubgroupLaneId(EmitterContext context)
{ {
if (context.TranslatorContext.GpuAccessor.QueryHostSubgroupSize() <= 32) if (context.TranslatorContext.GpuAccessor.QueryHostSubgroupSize() <= 32)
@@ -215,37 +280,34 @@ namespace Ryujinx.Graphics.Shader.Instructions
} }
} }
public static void SelR(EmitterContext context) private static void EmitPrmt(EmitterContext context, Operand op1, Operand control, Operand op2, PMode pMode, int rd)
{ {
InstSelR op = context.GetOp<InstSelR>(); if (pMode == PMode.Idx)
{
Operand res = Const(0);
Operand srcA = GetSrcReg(context, op.SrcA); for (int b = 0; b < 4; b++)
Operand srcB = GetSrcReg(context, op.SrcB); {
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv); Operand sel = context.ShiftRightU32(control, Const(b * 4));
Operand byteSel = context.BitwiseAnd(sel, Const(7));
Operand copySign = context.BitwiseAnd(sel, Const(8));
EmitSel(context, srcA, srcB, srcPred, op.Dest); Operand srcOp = context.ConditionalSelect(context.BitwiseAnd(byteSel, Const(4)), op2, op1);
} Operand srcValue = context.ShiftRightU32(srcOp, context.ShiftLeft(context.BitwiseAnd(byteSel, Const(3)), Const(3)));
Operand srcSign = context.ShiftRightS32(context.ShiftLeft(srcValue, Const(24)), Const(31));
public static void SelI(EmitterContext context) srcValue = context.ConditionalSelect(copySign, srcSign, srcValue);
{ srcValue = context.BitwiseAnd(srcValue, Const(0xff));
InstSelI op = context.GetOp<InstSelI>();
Operand srcA = GetSrcReg(context, op.SrcA); res = context.BitfieldInsert(res, srcValue, Const(b * 8), Const(8));
Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20)); }
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
EmitSel(context, srcA, srcB, srcPred, op.Dest); context.Copy(GetDest(rd), res);
} }
else
public static void SelC(EmitterContext context) {
{ throw new NotImplementedException(pMode.ToString());
InstSelC op = context.GetOp<InstSelC>(); }
Operand srcA = GetSrcReg(context, op.SrcA);
Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
EmitSel(context, srcA, srcB, srcPred, op.Dest);
} }
private static void EmitR2p(EmitterContext context, Operand value, Operand mask, ByteSel byteSel, bool ccpr) private static void EmitR2p(EmitterContext context, Operand value, Operand mask, ByteSel byteSel, bool ccpr)
@@ -23,6 +23,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
set => _branch = AddSuccessor(_branch, value); set => _branch = AddSuccessor(_branch, value);
} }
public bool HasSuccessor => _branch != null || _next != null;
public bool HasBranch => _branch != null; public bool HasBranch => _branch != null;
public bool Reachable => Index == 0 || Predecessors.Count != 0; public bool Reachable => Index == 0 || Predecessors.Count != 0;
@@ -1,8 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -18,6 +18,7 @@ namespace Ryujinx.Graphics.Shader
public bool UsesInstanceId { get; } public bool UsesInstanceId { get; }
public bool UsesDrawParameters { get; } public bool UsesDrawParameters { get; }
public bool UsesRtLayer { get; } public bool UsesRtLayer { get; }
public bool HasUnconditionalDiscard { get; }
public byte ClipDistancesWritten { get; } public byte ClipDistancesWritten { get; }
public int FragmentOutputMap { get; } public int FragmentOutputMap { get; }
@@ -34,6 +35,7 @@ namespace Ryujinx.Graphics.Shader
bool usesInstanceId, bool usesInstanceId,
bool usesDrawParameters, bool usesDrawParameters,
bool usesRtLayer, bool usesRtLayer,
bool hasUnconditionalDiscard,
byte clipDistancesWritten, byte clipDistancesWritten,
int fragmentOutputMap) int fragmentOutputMap)
{ {
@@ -50,6 +52,7 @@ namespace Ryujinx.Graphics.Shader
UsesInstanceId = usesInstanceId; UsesInstanceId = usesInstanceId;
UsesDrawParameters = usesDrawParameters; UsesDrawParameters = usesDrawParameters;
UsesRtLayer = usesRtLayer; UsesRtLayer = usesRtLayer;
HasUnconditionalDiscard = hasUnconditionalDiscard;
ClipDistancesWritten = clipDistancesWritten; ClipDistancesWritten = clipDistancesWritten;
FragmentOutputMap = fragmentOutputMap; FragmentOutputMap = fragmentOutputMap;
} }
+10 -2
View File
@@ -24,6 +24,7 @@ namespace Ryujinx.Graphics.Shader
RenderScale, RenderScale,
TfeOffset, TfeOffset,
TfeVertexCount, TfeVertexCount,
BufferTextureOffset,
} }
public struct SupportBuffer public struct SupportBuffer
@@ -42,10 +43,13 @@ namespace Ryujinx.Graphics.Shader
public static readonly int ComputeRenderScaleOffset; public static readonly int ComputeRenderScaleOffset;
public static readonly int TfeOffsetOffset; public static readonly int TfeOffsetOffset;
public static readonly int TfeVertexCountOffset; public static readonly int TfeVertexCountOffset;
public static readonly int BufferTextureOffsetOffset;
public const int FragmentIsBgraCount = 8; public const int FragmentIsBgraCount = 8;
public const int TextureCount = 64;
// One for the render target, 64 for the textures, and 8 for the images. // One for the render target, 64 for the textures, and 8 for the images.
public const int RenderScaleMaxCount = 1 + 64 + 8; public const int RenderScaleMaxCount = 1 + TextureCount + 8;
private static int OffsetOf<T>(ref SupportBuffer storage, ref T target) private static int OffsetOf<T>(ref SupportBuffer storage, ref T target)
{ {
@@ -68,6 +72,7 @@ namespace Ryujinx.Graphics.Shader
ComputeRenderScaleOffset = GraphicsRenderScaleOffset + FieldSize; ComputeRenderScaleOffset = GraphicsRenderScaleOffset + FieldSize;
TfeOffsetOffset = OffsetOf(ref instance, ref instance.TfeOffset); TfeOffsetOffset = OffsetOf(ref instance, ref instance.TfeOffset);
TfeVertexCountOffset = OffsetOf(ref instance, ref instance.TfeVertexCount); TfeVertexCountOffset = OffsetOf(ref instance, ref instance.TfeVertexCount);
BufferTextureOffsetOffset = OffsetOf(ref instance, ref instance.BufferTextureOffset);
} }
internal static StructureType GetStructureType() internal static StructureType GetStructureType()
@@ -80,7 +85,8 @@ namespace Ryujinx.Graphics.Shader
new StructureField(AggregateType.S32, "frag_scale_count"), new StructureField(AggregateType.S32, "frag_scale_count"),
new StructureField(AggregateType.Array | AggregateType.FP32, "render_scale", RenderScaleMaxCount), new StructureField(AggregateType.Array | AggregateType.FP32, "render_scale", RenderScaleMaxCount),
new StructureField(AggregateType.Vector4 | AggregateType.S32, "tfe_offset"), new StructureField(AggregateType.Vector4 | AggregateType.S32, "tfe_offset"),
new StructureField(AggregateType.S32, "tfe_vertex_count") new StructureField(AggregateType.S32, "tfe_vertex_count"),
new StructureField(AggregateType.Array | AggregateType.Vector2 | AggregateType.S32, "buffer_texture_offset")
]); ]);
} }
@@ -95,5 +101,7 @@ namespace Ryujinx.Graphics.Shader
public Vector4<int> TfeOffset; public Vector4<int> TfeOffset;
public Vector4<int> TfeVertexCount; public Vector4<int> TfeVertexCount;
public Array5<Array64<Vector4<int>>> BufferTextureOffset;
} }
} }
@@ -26,5 +26,6 @@ namespace Ryujinx.Graphics.Shader.Translation
SharedMemory = 1 << 11, SharedMemory = 1 << 11,
Store = 1 << 12, Store = 1 << 12,
VtgAsCompute = 1 << 13, VtgAsCompute = 1 << 13,
UnconditionalDiscard = 1 << 14,
} }
} }
@@ -0,0 +1,38 @@
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
namespace Ryujinx.Graphics.Shader.Translation
{
static class FeatureIdentification
{
public static void RunPass(BasicBlock[] blocks, ShaderStage stage, ref FeatureFlags usedFeatures)
{
if (stage == ShaderStage.Fragment)
{
bool endsWithDiscardOnly = true;
for (int blockIndex = 0; blockIndex < blocks.Length; blockIndex++)
{
BasicBlock block = blocks[blockIndex];
if (block.HasSuccessor)
{
continue;
}
if (block.Operations.Count == 0 ||
block.Operations.Last.Value is not Operation operation ||
operation.Inst != Instruction.Discard)
{
endsWithDiscardOnly = false;
break;
}
}
if (endsWithDiscardOnly)
{
usedFeatures |= FeatureFlags.UnconditionalDiscard;
}
}
}
}
}
@@ -43,6 +43,11 @@ namespace Ryujinx.Graphics.Shader.Translation
private readonly Dictionary<TextureInfo, TextureMeta> _usedTextures; private readonly Dictionary<TextureInfo, TextureMeta> _usedTextures;
private readonly Dictionary<TextureInfo, TextureMeta> _usedImages; private readonly Dictionary<TextureInfo, TextureMeta> _usedImages;
private readonly List<BufferDefinition> _vacConstantBuffers;
private readonly List<BufferDefinition> _vacStorageBuffers;
private readonly List<TextureDefinition> _vacTextures;
private readonly List<TextureDefinition> _vacImages;
public int LocalMemoryId { get; private set; } public int LocalMemoryId { get; private set; }
public int SharedMemoryId { get; private set; } public int SharedMemoryId { get; private set; }
@@ -78,6 +83,11 @@ namespace Ryujinx.Graphics.Shader.Translation
_usedTextures = new(); _usedTextures = new();
_usedImages = new(); _usedImages = new();
_vacConstantBuffers = new();
_vacStorageBuffers = new();
_vacTextures = new();
_vacImages = new();
Properties.AddOrUpdateConstantBuffer(new(BufferLayout.Std140, 0, SupportBuffer.Binding, "support_buffer", SupportBuffer.GetStructureType())); Properties.AddOrUpdateConstantBuffer(new(BufferLayout.Std140, 0, SupportBuffer.Binding, "support_buffer", SupportBuffer.GetStructureType()));
LocalMemoryId = -1; LocalMemoryId = -1;
@@ -563,6 +573,76 @@ namespace Ryujinx.Graphics.Shader.Translation
return descriptors.ToArray(); return descriptors.ToArray();
} }
public ShaderProgramInfo GetVertexAsComputeInfo(bool isVertex = false)
{
var cbDescriptors = new BufferDescriptor[_vacConstantBuffers.Count];
int cbDescriptorIndex = 0;
foreach (BufferDefinition definition in _vacConstantBuffers)
{
cbDescriptors[cbDescriptorIndex++] = new BufferDescriptor(definition.Set, definition.Binding, 0, 0, 0, BufferUsageFlags.None);
}
var sbDescriptors = new BufferDescriptor[_vacStorageBuffers.Count];
int sbDescriptorIndex = 0;
foreach (BufferDefinition definition in _vacStorageBuffers)
{
sbDescriptors[sbDescriptorIndex++] = new BufferDescriptor(definition.Set, definition.Binding, 0, 0, 0, BufferUsageFlags.Write);
}
var tDescriptors = new TextureDescriptor[_vacTextures.Count];
int tDescriptorIndex = 0;
foreach (TextureDefinition definition in _vacTextures)
{
tDescriptors[tDescriptorIndex++] = new TextureDescriptor(
definition.Set,
definition.Binding,
definition.Type,
definition.Format,
0,
0,
definition.ArrayLength,
definition.Separate,
definition.Flags);
}
var iDescriptors = new TextureDescriptor[_vacImages.Count];
int iDescriptorIndex = 0;
foreach (TextureDefinition definition in _vacImages)
{
iDescriptors[iDescriptorIndex++] = new TextureDescriptor(
definition.Set,
definition.Binding,
definition.Type,
definition.Format,
0,
0,
definition.ArrayLength,
definition.Separate,
definition.Flags);
}
return new ShaderProgramInfo(
cbDescriptors,
sbDescriptors,
tDescriptors,
iDescriptors,
isVertex ? ShaderStage.Vertex : ShaderStage.Compute,
0,
0,
0,
false,
false,
false,
false,
false,
0,
0);
}
public bool TryGetCbufSlotAndHandleForTexture(int binding, out int cbufSlot, out int handle) public bool TryGetCbufSlotAndHandleForTexture(int binding, out int cbufSlot, out int handle)
{ {
foreach ((TextureInfo info, TextureMeta meta) in _usedTextures) foreach ((TextureInfo info, TextureMeta meta) in _usedTextures)
@@ -627,6 +707,30 @@ namespace Ryujinx.Graphics.Shader.Translation
Properties.AddOrUpdateStorageBuffer(new(BufferLayout.Std430, setIndex, binding, name, type)); Properties.AddOrUpdateStorageBuffer(new(BufferLayout.Std430, setIndex, binding, name, type));
} }
public void AddVertexAsComputeConstantBuffer(BufferDefinition definition)
{
_vacConstantBuffers.Add(definition);
Properties.AddOrUpdateConstantBuffer(definition);
}
public void AddVertexAsComputeStorageBuffer(BufferDefinition definition)
{
_vacStorageBuffers.Add(definition);
Properties.AddOrUpdateStorageBuffer(definition);
}
public void AddVertexAsComputeTexture(TextureDefinition definition)
{
_vacTextures.Add(definition);
Properties.AddOrUpdateTexture(definition);
}
public void AddVertexAsComputeImage(TextureDefinition definition)
{
_vacImages.Add(definition);
Properties.AddOrUpdateImage(definition);
}
public static string GetShaderStagePrefix(ShaderStage stage) public static string GetShaderStagePrefix(ShaderStage stage)
{ {
uint index = (uint)stage; uint index = (uint)stage;
@@ -1,4 +1,5 @@
using Ryujinx.Graphics.Shader.IntermediateRepresentation; using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using Ryujinx.Graphics.Shader.Translation.Optimizations;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
@@ -27,7 +28,19 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
if (texOp.Type == SamplerType.TextureBuffer && !context.GpuAccessor.QueryHostSupportsSnormBufferTextureFormat()) if (texOp.Type == SamplerType.TextureBuffer && !context.GpuAccessor.QueryHostSupportsSnormBufferTextureFormat())
{ {
node = InsertSnormNormalization(node, context.ResourceManager, context.GpuAccessor); if (!context.GpuAccessor.QueryHostSupportsSnormBufferTextureFormat())
{
node = InsertSnormNormalization(node, context.ResourceManager, context.GpuAccessor);
}
if (!context.GpuAccessor.QueryHostSupportsBufferTexturePixelAlignment())
{
node = InsertCoordOffset(node, context.ResourceManager, context.Stage, isImage: false);
}
}
else if (!context.GpuAccessor.QueryHostSupportsBufferTexturePixelAlignment() && texOp.Inst.IsImage())
{
node = InsertCoordOffset(node, context.ResourceManager, context.Stage, isImage: true);
} }
} }
} }
@@ -278,6 +291,87 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
return node; return node;
} }
private static LinkedListNode<INode> InsertCoordOffset(LinkedListNode<INode> node, ResourceManager resourceManager, ShaderStage stage, bool isImage)
{
// Some GPUs have fixed alignment requirements for buffer textures.
// For those cases, we bind the aligned buffer offset, and apply the remaining offset on the shader.
TextureOperation texOp = (TextureOperation)node.Value;
if ((texOp.Type & SamplerType.Mask) != SamplerType.TextureBuffer)
{
return node;
}
Operand[] sources = new Operand[texOp.SourcesCount];
for (int i = 0; i < texOp.SourcesCount; i++)
{
sources[i] = texOp.GetSource(i);
}
bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
bool isIndexed = resourceManager.IsArrayOfTexturesOrImages(texOp.Binding, isImage);
int coordsIndex = isBindless || isIndexed ? 1 : 0;
Operand[] dests = new Operand[texOp.DestsCount];
for (int i = 0; i < texOp.DestsCount; i++)
{
dests[i] = texOp.GetDest(i);
}
LinkedListNode<INode> oldNode = node;
Operand source = sources[coordsIndex];
Operand offset = Local();
Operand coordPlusOffset = Local();
int stageIndex = stage switch
{
ShaderStage.TessellationControl => 1,
ShaderStage.TessellationEvaluation => 2,
ShaderStage.Geometry => 3,
ShaderStage.Fragment => 4,
_ => 0,
};
int bindingIndex = isImage
? resourceManager.FindImageDescriptorIndex(texOp.Binding)
: resourceManager.FindTextureDescriptorIndex(texOp.Binding);
node.List.AddBefore(node, new Operation(
Instruction.Load,
StorageKind.ConstantBuffer,
offset,
Const(SupportBuffer.Binding),
Const((int)SupportBufferField.BufferTextureOffset),
Const(stageIndex * SupportBuffer.TextureCount + bindingIndex),
Const(isImage ? 1 : 0)));
node.List.AddBefore(node, new Operation(Instruction.Add, coordPlusOffset, source, offset));
sources[coordsIndex] = coordPlusOffset;
TextureOperation newTexOp = new(
texOp.Inst,
texOp.Type,
texOp.Format,
texOp.Flags,
texOp.Set,
texOp.Binding,
texOp.Index,
dests,
sources);
node = node.List.AddBefore(node, newTexOp);
Utils.DeleteNode(oldNode, texOp);
return node;
}
private static LinkedListNode<INode> InsertConstOffsets(LinkedListNode<INode> node, ResourceManager resourceManager, IGpuAccessor gpuAccessor, ShaderStage stage) private static LinkedListNode<INode> InsertConstOffsets(LinkedListNode<INode> node, ResourceManager resourceManager, IGpuAccessor gpuAccessor, ShaderStage stage)
{ {
// Non-constant texture offsets are not allowed (according to the spec), // Non-constant texture offsets are not allowed (according to the spec),
@@ -301,6 +301,11 @@ namespace Ryujinx.Graphics.Shader.Translation
Optimizer.RunPass(context); Optimizer.RunPass(context);
TransformPasses.RunPass(context); TransformPasses.RunPass(context);
if (i == 0)
{
FeatureIdentification.RunPass(cfg.Blocks, Definitions.Stage, ref usedFeatures);
}
} }
funcs[i] = new Function(cfg.Blocks, $"fun{i}", false, inArgumentsCount, outArgumentsCount); funcs[i] = new Function(cfg.Blocks, $"fun{i}", false, inArgumentsCount, outArgumentsCount);
@@ -353,6 +358,7 @@ namespace Ryujinx.Graphics.Shader.Translation
usedFeatures.HasFlag(FeatureFlags.InstanceId), usedFeatures.HasFlag(FeatureFlags.InstanceId),
usedFeatures.HasFlag(FeatureFlags.DrawParameters), usedFeatures.HasFlag(FeatureFlags.DrawParameters),
usedFeatures.HasFlag(FeatureFlags.RtLayer), usedFeatures.HasFlag(FeatureFlags.RtLayer),
usedFeatures.HasFlag(FeatureFlags.UnconditionalDiscard),
clipDistancesWritten, clipDistancesWritten,
originalDefinitions.OmapTargets); originalDefinitions.OmapTargets);
@@ -393,7 +399,7 @@ namespace Ryujinx.Graphics.Shader.Translation
{ {
int binding = resourceManager.Reservations.GetTfeBufferStorageBufferBinding(i); int binding = resourceManager.Reservations.GetTfeBufferStorageBufferBinding(i);
BufferDefinition tfeDataBuffer = new(BufferLayout.Std430, 1, binding, $"tfe_data{i}", tfeDataStruct); BufferDefinition tfeDataBuffer = new(BufferLayout.Std430, 1, binding, $"tfe_data{i}", tfeDataStruct);
resourceManager.Properties.AddOrUpdateStorageBuffer(tfeDataBuffer); resourceManager.AddVertexAsComputeStorageBuffer(tfeDataBuffer);
} }
} }
@@ -401,7 +407,7 @@ namespace Ryujinx.Graphics.Shader.Translation
{ {
int vertexInfoCbBinding = resourceManager.Reservations.VertexInfoConstantBufferBinding; int vertexInfoCbBinding = resourceManager.Reservations.VertexInfoConstantBufferBinding;
BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType()); BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType());
resourceManager.Properties.AddOrUpdateConstantBuffer(vertexInfoBuffer); resourceManager.AddVertexAsComputeConstantBuffer(vertexInfoBuffer);
StructureType vertexOutputStruct = new([ StructureType vertexOutputStruct = new([
new StructureField(AggregateType.Array | AggregateType.FP32, "data", 0) new StructureField(AggregateType.Array | AggregateType.FP32, "data", 0)
@@ -409,13 +415,13 @@ namespace Ryujinx.Graphics.Shader.Translation
int vertexOutputSbBinding = resourceManager.Reservations.VertexOutputStorageBufferBinding; int vertexOutputSbBinding = resourceManager.Reservations.VertexOutputStorageBufferBinding;
BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexOutputSbBinding, "vertex_output", vertexOutputStruct); BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexOutputSbBinding, "vertex_output", vertexOutputStruct);
resourceManager.Properties.AddOrUpdateStorageBuffer(vertexOutputBuffer); resourceManager.AddVertexAsComputeStorageBuffer(vertexOutputBuffer);
if (Stage == ShaderStage.Vertex) if (Stage == ShaderStage.Vertex)
{ {
SetBindingPair ibSetAndBinding = resourceManager.Reservations.GetIndexBufferTextureSetAndBinding(); SetBindingPair ibSetAndBinding = resourceManager.Reservations.GetIndexBufferTextureSetAndBinding();
TextureDefinition indexBuffer = new(ibSetAndBinding.SetIndex, ibSetAndBinding.Binding, "ib_data", SamplerType.TextureBuffer); TextureDefinition indexBuffer = new(ibSetAndBinding.SetIndex, ibSetAndBinding.Binding, "ib_data", SamplerType.TextureBuffer);
resourceManager.Properties.AddOrUpdateTexture(indexBuffer); resourceManager.AddVertexAsComputeTexture(indexBuffer);
int inputMap = _program.AttributeUsage.UsedInputAttributes; int inputMap = _program.AttributeUsage.UsedInputAttributes;
@@ -424,7 +430,7 @@ namespace Ryujinx.Graphics.Shader.Translation
int location = BitOperations.TrailingZeroCount(inputMap); int location = BitOperations.TrailingZeroCount(inputMap);
SetBindingPair setAndBinding = resourceManager.Reservations.GetVertexBufferTextureSetAndBinding(location); SetBindingPair setAndBinding = resourceManager.Reservations.GetVertexBufferTextureSetAndBinding(location);
TextureDefinition vaBuffer = new(setAndBinding.SetIndex, setAndBinding.Binding, $"vb_data{location}", SamplerType.TextureBuffer); TextureDefinition vaBuffer = new(setAndBinding.SetIndex, setAndBinding.Binding, $"vb_data{location}", SamplerType.TextureBuffer);
resourceManager.Properties.AddOrUpdateTexture(vaBuffer); resourceManager.AddVertexAsComputeTexture(vaBuffer);
inputMap &= ~(1 << location); inputMap &= ~(1 << location);
} }
@@ -433,11 +439,11 @@ namespace Ryujinx.Graphics.Shader.Translation
{ {
SetBindingPair trbSetAndBinding = resourceManager.Reservations.GetTopologyRemapBufferTextureSetAndBinding(); SetBindingPair trbSetAndBinding = resourceManager.Reservations.GetTopologyRemapBufferTextureSetAndBinding();
TextureDefinition remapBuffer = new(trbSetAndBinding.SetIndex, trbSetAndBinding.Binding, "trb_data", SamplerType.TextureBuffer); TextureDefinition remapBuffer = new(trbSetAndBinding.SetIndex, trbSetAndBinding.Binding, "trb_data", SamplerType.TextureBuffer);
resourceManager.Properties.AddOrUpdateTexture(remapBuffer); resourceManager.AddVertexAsComputeTexture(remapBuffer);
int geometryVbOutputSbBinding = resourceManager.Reservations.GeometryVertexOutputStorageBufferBinding; int geometryVbOutputSbBinding = resourceManager.Reservations.GeometryVertexOutputStorageBufferBinding;
BufferDefinition geometryVbOutputBuffer = new(BufferLayout.Std430, 1, geometryVbOutputSbBinding, "geometry_vb_output", vertexOutputStruct); BufferDefinition geometryVbOutputBuffer = new(BufferLayout.Std430, 1, geometryVbOutputSbBinding, "geometry_vb_output", vertexOutputStruct);
resourceManager.Properties.AddOrUpdateStorageBuffer(geometryVbOutputBuffer); resourceManager.AddVertexAsComputeStorageBuffer(geometryVbOutputBuffer);
StructureType geometryIbOutputStruct = new([ StructureType geometryIbOutputStruct = new([
new StructureField(AggregateType.Array | AggregateType.U32, "data", 0) new StructureField(AggregateType.Array | AggregateType.U32, "data", 0)
@@ -445,7 +451,7 @@ namespace Ryujinx.Graphics.Shader.Translation
int geometryIbOutputSbBinding = resourceManager.Reservations.GeometryIndexOutputStorageBufferBinding; int geometryIbOutputSbBinding = resourceManager.Reservations.GeometryIndexOutputStorageBufferBinding;
BufferDefinition geometryIbOutputBuffer = new(BufferLayout.Std430, 1, geometryIbOutputSbBinding, "geometry_ib_output", geometryIbOutputStruct); BufferDefinition geometryIbOutputBuffer = new(BufferLayout.Std430, 1, geometryIbOutputSbBinding, "geometry_ib_output", geometryIbOutputStruct);
resourceManager.Properties.AddOrUpdateStorageBuffer(geometryIbOutputBuffer); resourceManager.AddVertexAsComputeStorageBuffer(geometryIbOutputBuffer);
} }
resourceManager.SetVertexAsComputeLocalMemories(Definitions.Stage, Definitions.InputTopology); resourceManager.SetVertexAsComputeLocalMemories(Definitions.Stage, Definitions.InputTopology);
@@ -478,12 +484,17 @@ namespace Ryujinx.Graphics.Shader.Translation
return new ResourceReservations(GpuAccessor, IsTransformFeedbackEmulated, vertexAsCompute: true, _vertexOutput, ioUsage); return new ResourceReservations(GpuAccessor, IsTransformFeedbackEmulated, vertexAsCompute: true, _vertexOutput, ioUsage);
} }
public ShaderProgramInfo GetVertexAsComputeInfo()
{
return CreateResourceManager(true).GetVertexAsComputeInfo();
}
public void SetVertexOutputMapForGeometryAsCompute(TranslatorContext vertexContext) public void SetVertexOutputMapForGeometryAsCompute(TranslatorContext vertexContext)
{ {
_vertexOutput = vertexContext._program.GetIoUsage(); _vertexOutput = vertexContext._program.GetIoUsage();
} }
public ShaderProgram GenerateVertexPassthroughForCompute() public (ShaderProgram, ShaderProgramInfo) GenerateVertexPassthroughForCompute()
{ {
AttributeUsage attributeUsage = new(GpuAccessor); AttributeUsage attributeUsage = new(GpuAccessor);
ResourceManager resourceManager = new(ShaderStage.Vertex, GpuAccessor); ResourceManager resourceManager = new(ShaderStage.Vertex, GpuAccessor);
@@ -495,7 +506,7 @@ namespace Ryujinx.Graphics.Shader.Translation
if (Stage == ShaderStage.Vertex) if (Stage == ShaderStage.Vertex)
{ {
BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType()); BufferDefinition vertexInfoBuffer = new(BufferLayout.Std140, 0, vertexInfoCbBinding, "vb_info", VertexInfoBuffer.GetStructureType());
resourceManager.Properties.AddOrUpdateConstantBuffer(vertexInfoBuffer); resourceManager.AddVertexAsComputeConstantBuffer(vertexInfoBuffer);
} }
StructureType vertexInputStruct = new([ StructureType vertexInputStruct = new([
@@ -504,7 +515,7 @@ namespace Ryujinx.Graphics.Shader.Translation
int vertexDataSbBinding = reservations.VertexOutputStorageBufferBinding; int vertexDataSbBinding = reservations.VertexOutputStorageBufferBinding;
BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexDataSbBinding, "vb_input", vertexInputStruct); BufferDefinition vertexOutputBuffer = new(BufferLayout.Std430, 1, vertexDataSbBinding, "vb_input", vertexInputStruct);
resourceManager.Properties.AddOrUpdateStorageBuffer(vertexOutputBuffer); resourceManager.AddVertexAsComputeStorageBuffer(vertexOutputBuffer);
EmitterContext context = new(); EmitterContext context = new();
@@ -562,14 +573,14 @@ namespace Ryujinx.Graphics.Shader.Translation
LastInVertexPipeline = true LastInVertexPipeline = true
}; };
return Generate( return (Generate(
[function], [function],
attributeUsage, attributeUsage,
definitions, definitions,
definitions, definitions,
resourceManager, resourceManager,
FeatureFlags.None, FeatureFlags.None,
0); 0), resourceManager.GetVertexAsComputeInfo(isVertex: true));
} }
public ShaderProgram GenerateGeometryPassthrough() public ShaderProgram GenerateGeometryPassthrough()
@@ -2,8 +2,6 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -2,8 +2,6 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -1,8 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -36,6 +36,7 @@ namespace Ryujinx.Graphics.Vulkan
queueLock, queueLock,
_gd.QueueFamilyIndex, _gd.QueueFamilyIndex,
_gd.IsQualcommProprietary, _gd.IsQualcommProprietary,
_gd.IsTurnip,
isLight: true); isLight: true);
} }
} }
@@ -19,6 +19,7 @@ namespace Ryujinx.Graphics.Vulkan
private readonly Queue _queue; private readonly Queue _queue;
private readonly Lock _queueLock; private readonly Lock _queueLock;
private readonly bool _concurrentFenceWaitUnsupported; private readonly bool _concurrentFenceWaitUnsupported;
private readonly bool _fenceAlwaysWaits;
private readonly CommandPool _pool; private readonly CommandPool _pool;
private readonly Thread _owner; private readonly Thread _owner;
@@ -66,6 +67,7 @@ namespace Ryujinx.Graphics.Vulkan
Lock queueLock, Lock queueLock,
uint queueFamilyIndex, uint queueFamilyIndex,
bool concurrentFenceWaitUnsupported, bool concurrentFenceWaitUnsupported,
bool fenceAlwaysWaits,
bool isLight = false) bool isLight = false)
{ {
_api = api; _api = api;
@@ -73,6 +75,7 @@ namespace Ryujinx.Graphics.Vulkan
_queue = queue; _queue = queue;
_queueLock = queueLock; _queueLock = queueLock;
_concurrentFenceWaitUnsupported = concurrentFenceWaitUnsupported; _concurrentFenceWaitUnsupported = concurrentFenceWaitUnsupported;
_fenceAlwaysWaits = fenceAlwaysWaits;
_owner = Thread.CurrentThread; _owner = Thread.CurrentThread;
CommandPoolCreateInfo commandPoolCreateInfo = new() CommandPoolCreateInfo commandPoolCreateInfo = new()
@@ -207,7 +210,7 @@ namespace Ryujinx.Graphics.Vulkan
ref ReservedCommandBuffer entry = ref _commandBuffers[index]; ref ReservedCommandBuffer entry = ref _commandBuffers[index];
if (wait || !entry.InConsumption || entry.Fence.IsSignaled()) if (wait || !entry.InConsumption || entry.Fence.IsSignaledLazy())
{ {
WaitAndDecrementRef(index); WaitAndDecrementRef(index);
@@ -349,7 +352,7 @@ namespace Ryujinx.Graphics.Vulkan
if (refreshFence) if (refreshFence)
{ {
entry.Fence = new FenceHolder(_api, _device, _concurrentFenceWaitUnsupported); entry.Fence = new FenceHolder(_api, _device, _concurrentFenceWaitUnsupported, _fenceAlwaysWaits);
} }
else else
{ {
+13 -1
View File
@@ -12,13 +12,15 @@ namespace Ryujinx.Graphics.Vulkan
private int _referenceCount; private int _referenceCount;
private int _lock; private int _lock;
private readonly bool _concurrentWaitUnsupported; private readonly bool _concurrentWaitUnsupported;
private readonly bool _alwaysWaits;
private bool _disposed; private bool _disposed;
public unsafe FenceHolder(Vk api, Device device, bool concurrentWaitUnsupported) public unsafe FenceHolder(Vk api, Device device, bool concurrentWaitUnsupported, bool alwaysWaits)
{ {
_api = api; _api = api;
_device = device; _device = device;
_concurrentWaitUnsupported = concurrentWaitUnsupported; _concurrentWaitUnsupported = concurrentWaitUnsupported;
_alwaysWaits = alwaysWaits;
FenceCreateInfo fenceCreateInfo = new() FenceCreateInfo fenceCreateInfo = new()
{ {
@@ -123,6 +125,16 @@ namespace Ryujinx.Graphics.Vulkan
} }
} }
public bool IsSignaledLazy()
{
if (_alwaysWaits)
{
return false;
}
return IsSignaled();
}
public bool IsSignaled() public bool IsSignaled()
{ {
if (_concurrentWaitUnsupported) if (_concurrentWaitUnsupported)
@@ -2,8 +2,7 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations> <Configurations>Debug;Release</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -60,7 +60,7 @@ namespace Ryujinx.Graphics.Vulkan
private ProgramPipelineState _state; private ProgramPipelineState _state;
private DisposableRenderPass _dummyRenderPass; private DisposableRenderPass _dummyRenderPass;
private readonly Task _compileTask; private ShaderCompilationRequest _compileRequest;
private bool _firstBackgroundUse; private bool _firstBackgroundUse;
public ShaderCollection( public ShaderCollection(
@@ -139,7 +139,7 @@ namespace Ryujinx.Graphics.Vulkan
// Updating buffer texture bindings using template updates crashes the Adreno driver on Windows. // Updating buffer texture bindings using template updates crashes the Adreno driver on Windows.
UpdateTexturesWithoutTemplate = gd.IsQualcommProprietary && usesBufferTextures; UpdateTexturesWithoutTemplate = gd.IsQualcommProprietary && usesBufferTextures;
_compileTask = Task.CompletedTask; _compileRequest = new ShaderCompilationRequest(Task.CompletedTask);
_firstBackgroundUse = false; _firstBackgroundUse = false;
} }
@@ -153,7 +153,9 @@ namespace Ryujinx.Graphics.Vulkan
{ {
_state = state; _state = state;
_compileTask = BackgroundCompilation(); _compileRequest = gd.ShaderCompilationQueue != null
? gd.ShaderCompilationQueue.Add(BackgroundCompilation)
: new ShaderCompilationRequest(BackgroundCompilationAsync());
_firstBackgroundUse = !fromCache; _firstBackgroundUse = !fromCache;
} }
@@ -458,10 +460,25 @@ namespace Ryujinx.Graphics.Vulkan
return (buffer, texture); return (buffer, texture);
} }
private async Task BackgroundCompilation() private async Task BackgroundCompilationAsync()
{ {
await Task.WhenAll(_shaders.Select(shader => shader.CompileTask)); await Task.WhenAll(_shaders.Select(shader => shader.CompileTask));
BackgroundCompilationImpl();
}
private void BackgroundCompilation()
{
foreach (var shader in _shaders)
{
shader.CompileTask.Wait();
}
BackgroundCompilationImpl();
}
private void BackgroundCompilationImpl()
{
if (Array.Exists(_shaders, shader => shader.CompileStatus == ProgramLinkStatus.Failure)) if (Array.Exists(_shaders, shader => shader.CompileStatus == ProgramLinkStatus.Failure))
{ {
LinkStatus = ProgramLinkStatus.Failure; LinkStatus = ProgramLinkStatus.Failure;
@@ -604,11 +621,11 @@ namespace Ryujinx.Graphics.Vulkan
} }
} }
if (!_compileTask.IsCompleted) if (!_compileRequest.IsCompleted)
{ {
if (blocking) if (blocking)
{ {
_compileTask.Wait(); _compileRequest.Wait();
if (LinkStatus == ProgramLinkStatus.Failure) if (LinkStatus == ProgramLinkStatus.Failure)
{ {
@@ -0,0 +1,131 @@
using System;
using System.Collections.Concurrent;
using System.Threading;
namespace Ryujinx.Graphics.Vulkan
{
class ShaderCompilationQueue
{
private const int MaxParallelCompilations = 8;
private const int MaxThreadStackSize = 2 * 1024 * 1024; // MB
private struct Request
{
public readonly ulong Id;
public readonly Action Callback;
public Request(ulong id, Action callback)
{
Id = id;
Callback = callback;
}
}
private readonly Thread[] _workerThreads;
private readonly CancellationTokenSource _cts;
private readonly BlockingCollection<Request>[] _queues;
private readonly ulong[] _finishedIds;
private ulong _currentId;
private int _currentQueueIndex;
public ShaderCompilationQueue()
{
_workerThreads = new Thread[MaxParallelCompilations];
_queues = new BlockingCollection<Request>[MaxParallelCompilations];
_finishedIds = new ulong[MaxParallelCompilations];
_cts = new CancellationTokenSource();
for (int i = 0; i < MaxParallelCompilations; i++)
{
_queues[i] = new BlockingCollection<Request>();
Thread thread = new Thread(DoWork, MaxThreadStackSize) { Name = $"BackgroundShaderCompiler.{i}" };
thread.IsBackground = true;
thread.Start(i);
_workerThreads[i] = thread;
}
}
private void DoWork(object threadId)
{
int queueIndex = (int)threadId;
try
{
var queue = _queues[queueIndex];
foreach (var request in queue.GetConsumingEnumerable(_cts.Token))
{
request.Callback();
lock (queue)
{
_finishedIds[queueIndex] = request.Id;
Monitor.PulseAll(queue);
}
}
}
catch (OperationCanceledException)
{
}
}
public ShaderCompilationRequest Add(Action callback)
{
ulong newId = Interlocked.Increment(ref _currentId);
// Let's keep rotating between the queues to increase the chances
// that the selected queue thread is currently idle.
int queueIndex = Interlocked.Increment(ref _currentQueueIndex) % MaxParallelCompilations;
_queues[queueIndex].Add(new Request(newId, callback));
return new ShaderCompilationRequest(this, queueIndex, newId);
}
public void Wait(int queueIndex, ulong id)
{
var queue = _queues[queueIndex];
lock (queue)
{
while (_finishedIds[queueIndex] < id)
{
Monitor.Wait(queue);
}
}
}
public bool IsCompleted(int queueIndex, ulong id)
{
var queue = _queues[queueIndex];
lock (queue)
{
return _finishedIds[queueIndex] >= id;
}
}
public void Dispose()
{
for (int i = 0; i < MaxParallelCompilations; i++)
{
_queues[i].CompleteAdding();
}
_cts.Cancel();
for (int i = 0; i < MaxParallelCompilations; i++)
{
_workerThreads[i].Join();
_queues[i].Dispose();
}
_cts.Dispose();
}
}
}
@@ -0,0 +1,55 @@
using System.Threading.Tasks;
namespace Ryujinx.Graphics.Vulkan
{
struct ShaderCompilationRequest
{
private readonly Task _task;
private readonly ShaderCompilationQueue _queue;
private readonly int _queueIndex;
private readonly ulong _requestId;
public bool IsCompleted
{
get
{
if (_task != null)
{
return _task.IsCompleted;
}
else
{
return _queue.IsCompleted(_queueIndex, _requestId);
}
}
}
public ShaderCompilationRequest(Task task)
{
_task = task;
_queue = null;
_queueIndex = 0;
_requestId = 0;
}
public ShaderCompilationRequest(ShaderCompilationQueue queue, int queueIndex, ulong requestId)
{
_task = null;
_queue = queue;
_queueIndex = queueIndex;
_requestId = requestId;
}
public void Wait()
{
if (_task != null)
{
_task.Wait();
}
else
{
_queue.Wait(_queueIndex, _requestId);
}
}
}
}
+1 -1
View File
@@ -266,7 +266,7 @@ namespace Ryujinx.Graphics.Vulkan
public void FreeCompleted() public void FreeCompleted()
{ {
FenceHolder signalledFence = null; FenceHolder signalledFence = null;
while (_pendingCopies.TryPeek(out PendingCopy pc) && pc.Fence != null && (pc.Fence == signalledFence || pc.Fence.IsSignaled())) while (_pendingCopies.TryPeek(out PendingCopy pc) && pc.Fence != null && (pc.Fence == signalledFence || pc.Fence.IsSignaledLazy()))
{ {
signalledFence = pc.Fence; // Already checked - don't need to do it again. signalledFence = pc.Fence; // Already checked - don't need to do it again.
PendingCopy dequeued = _pendingCopies.Dequeue(); PendingCopy dequeued = _pendingCopies.Dequeue();
+15 -1
View File
@@ -55,6 +55,7 @@ namespace Ryujinx.Graphics.Vulkan
internal CommandBufferPool CommandBufferPool { get; private set; } internal CommandBufferPool CommandBufferPool { get; private set; }
internal PipelineLayoutCache PipelineLayoutCache { get; private set; } internal PipelineLayoutCache PipelineLayoutCache { get; private set; }
internal BackgroundResources BackgroundResources { get; private set; } internal BackgroundResources BackgroundResources { get; private set; }
internal ShaderCompilationQueue ShaderCompilationQueue { get; private set; }
internal Action<Action> InterruptAction { get; private set; } internal Action<Action> InterruptAction { get; private set; }
internal SyncManager SyncManager { get; private set; } internal SyncManager SyncManager { get; private set; }
@@ -96,6 +97,7 @@ namespace Ryujinx.Graphics.Vulkan
internal bool IsNvidiaPreTuring { get; private set; } internal bool IsNvidiaPreTuring { get; private set; }
internal bool IsIntelArc { get; private set; } internal bool IsIntelArc { get; private set; }
internal bool IsQualcommProprietary { get; private set; } internal bool IsQualcommProprietary { get; private set; }
internal bool IsTurnip { get; private set; }
internal bool IsMoltenVk { get; private set; } internal bool IsMoltenVk { get; private set; }
internal bool SupportsMTL31 { get; private set; } internal bool SupportsMTL31 { get; private set; }
internal bool IsTBDR { get; private set; } internal bool IsTBDR { get; private set; }
@@ -127,6 +129,12 @@ namespace Ryujinx.Graphics.Vulkan
// Any device running on MacOS is using MoltenVK, even Intel and AMD vendors. // Any device running on MacOS is using MoltenVK, even Intel and AMD vendors.
IsMoltenVk = true; IsMoltenVk = true;
// The default thread stack size on MacOS is low, and can cause stack overflow
// on SPIR-V Cross during shader compilation.
// As a workaround, we use this custom queue which allows us to specify the stack
// size of the threads used for compilation.
ShaderCompilationQueue = new ShaderCompilationQueue();
} }
SupportsMTL31 = OperatingSystem.IsMacOSVersionAtLeast(14); SupportsMTL31 = OperatingSystem.IsMacOSVersionAtLeast(14);
@@ -396,6 +404,8 @@ namespace Ryujinx.Graphics.Vulkan
IsFeedbackLoopDevice = IsAmdRdna3; IsFeedbackLoopDevice = IsAmdRdna3;
IsTurnip = GpuRenderer.StartsWith("Turnip");
if (Vendor == Vendor.Nvidia) if (Vendor == Vendor.Nvidia)
{ {
Match match = VendorUtils.NvidiaConsumerClassRegex().Match(GpuRenderer); Match match = VendorUtils.NvidiaConsumerClassRegex().Match(GpuRenderer);
@@ -476,7 +486,7 @@ namespace Ryujinx.Graphics.Vulkan
Api.TryGetDeviceExtension(_instance.Instance, _device, out ExtExternalMemoryHost hostMemoryApi); Api.TryGetDeviceExtension(_instance.Instance, _device, out ExtExternalMemoryHost hostMemoryApi);
HostMemoryAllocator = new HostMemoryAllocator(MemoryAllocator, Api, hostMemoryApi, _device); HostMemoryAllocator = new HostMemoryAllocator(MemoryAllocator, Api, hostMemoryApi, _device);
CommandBufferPool = new CommandBufferPool(Api, _device, Queue, QueueLock, queueFamilyIndex, IsQualcommProprietary); CommandBufferPool = new CommandBufferPool(Api, _device, Queue, QueueLock, queueFamilyIndex, IsQualcommProprietary, IsTurnip);
PipelineLayoutCache = new PipelineLayoutCache(); PipelineLayoutCache = new PipelineLayoutCache();
@@ -777,6 +787,7 @@ namespace Ryujinx.Graphics.Vulkan
supportsGeometryShader: Capabilities.SupportsGeometryShader, supportsGeometryShader: Capabilities.SupportsGeometryShader,
supportsGeometryShaderPassthrough: Capabilities.SupportsGeometryShaderPassthrough, supportsGeometryShaderPassthrough: Capabilities.SupportsGeometryShaderPassthrough,
supportsTransformFeedback: Capabilities.SupportsTransformFeedback, supportsTransformFeedback: Capabilities.SupportsTransformFeedback,
supportsImageBufferPixelAlignment: false,
supportsImageLoadFormatted: features2.Features.ShaderStorageImageReadWithoutFormat, supportsImageLoadFormatted: features2.Features.ShaderStorageImageReadWithoutFormat,
supportsLayerVertexTessellation: featuresVk12.ShaderOutputLayer, supportsLayerVertexTessellation: featuresVk12.ShaderOutputLayer,
supportsMismatchingViewFormat: true, supportsMismatchingViewFormat: true,
@@ -790,6 +801,7 @@ namespace Ryujinx.Graphics.Vulkan
supportsShaderNonUniformIndexing: supportsShaderNonUniformIndexing:
featuresVk12.ShaderSampledImageArrayNonUniformIndexing && featuresVk12.ShaderSampledImageArrayNonUniformIndexing &&
featuresVk12.ShaderStorageImageArrayNonUniformIndexing, featuresVk12.ShaderStorageImageArrayNonUniformIndexing,
supportsTextureBufferPixelAlignment: false,
supportsTextureGatherOffsets: features2.Features.ShaderImageGatherExtended, supportsTextureGatherOffsets: features2.Features.ShaderImageGatherExtended,
supportsTextureShadowLod: false, supportsTextureShadowLod: false,
supportsVertexStoreAndAtomics: features2.Features.VertexPipelineStoresAndAtomics, supportsVertexStoreAndAtomics: features2.Features.VertexPipelineStoresAndAtomics,
@@ -1112,6 +1124,8 @@ namespace Ryujinx.Graphics.Vulkan
SurfaceApi.DestroySurface(_instance.Instance, _surface, null); SurfaceApi.DestroySurface(_instance.Instance, _surface, null);
ShaderCompilationQueue?.Dispose();
Api.DestroyDevice(_device, null); Api.DestroyDevice(_device, null);
_debugMessenger.Dispose(); _debugMessenger.Dispose();
@@ -6,8 +6,6 @@
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath> <CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
<IsRoslynComponent>true</IsRoslynComponent> <IsRoslynComponent>true</IsRoslynComponent>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
-2
View File
@@ -2,8 +2,6 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -1,8 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -4,8 +4,6 @@
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules> <EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -3,8 +3,6 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules> <EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -1,8 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -2,8 +2,6 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
-2
View File
@@ -2,8 +2,6 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
-2
View File
@@ -3,8 +3,6 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -2,8 +2,6 @@
<PropertyGroup> <PropertyGroup>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
+1 -1
View File
@@ -116,7 +116,7 @@ namespace Ryujinx.ShaderTools
if (options.VertexPassthrough) if (options.VertexPassthrough)
{ {
program = translatorContext.GenerateVertexPassthroughForCompute(); (program, _) = translatorContext.GenerateVertexPassthroughForCompute();
} }
else else
{ {
@@ -2,8 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations> <Configurations>Debug;Release</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -2,8 +2,6 @@
<PropertyGroup> <PropertyGroup>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -2,8 +2,7 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations> <Configurations>Debug;Release</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
+1 -2
View File
@@ -7,10 +7,9 @@
<TargetOS Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">windows</TargetOS> <TargetOS Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">windows</TargetOS>
<TargetOS Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">osx</TargetOS> <TargetOS Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">osx</TargetOS>
<TargetOS Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">linux</TargetOS> <TargetOS Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">linux</TargetOS>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations> <Configurations>Debug;Release</Configurations>
<RunSettingsFilePath>$(MSBuildProjectDirectory)\.runsettings</RunSettingsFilePath> <RunSettingsFilePath>$(MSBuildProjectDirectory)\.runsettings</RunSettingsFilePath>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
@@ -86,7 +86,7 @@ namespace Ryujinx.UI.App.Common
private static byte[] GetResourceBytes(string resourceName) private static byte[] GetResourceBytes(string resourceName)
{ {
Stream resourceStream = typeof(ApplicationLibrary).Assembly.GetManifestResourceStream(resourceName); Stream resourceStream = Assembly.GetCallingAssembly().GetManifestResourceStream(resourceName);
if (resourceStream != null) if (resourceStream != null)
{ {
byte[] resourceByteArray = new byte[resourceStream.Length]; byte[] resourceByteArray = new byte[resourceStream.Length];
@@ -2,8 +2,6 @@
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -4,8 +4,6 @@
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules> <EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
-14
View File
@@ -11,8 +11,6 @@
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
<IncludeSourceRevisionInInformationalVersion Condition="'$(Configuration)'=='Release'">false</IncludeSourceRevisionInInformationalVersion> <IncludeSourceRevisionInInformationalVersion Condition="'$(Configuration)'=='Release'">false</IncludeSourceRevisionInInformationalVersion>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
<Target Name="RemoveNativePackagePdbs" AfterTargets="ResolvePackageAssets"> <Target Name="RemoveNativePackagePdbs" AfterTargets="ResolvePackageAssets">
@@ -170,16 +168,4 @@
<ItemGroup> <ItemGroup>
<TrimmerRootDescriptor Include="TrimmerRootDescriptor.xml" /> <TrimmerRootDescriptor Include="TrimmerRootDescriptor.xml" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="$(Configuration.EndsWith('AOT'))">
<RdXmlFile Include="rd.xml" />
</ItemGroup>
<PropertyGroup Condition="$(Configuration.EndsWith('AOT'))">
<PublishAot>true</PublishAot>
<IsAotCompatible>true</IsAotCompatible>
<TrimmerSingleWarn>false</TrimmerSingleWarn>
<InvariantGlobalization>false</InvariantGlobalization>
<OptimizationPreference>Speed</OptimizationPreference>
<PublishSingleFile>false</PublishSingleFile>
<TrimMode>full</TrimMode>
</PropertyGroup>
</Project> </Project>
@@ -40,12 +40,13 @@ namespace Ryujinx.Ava.UI.Views.Main
{ {
List<CheckBox> checkBoxes = []; List<CheckBox> checkBoxes = [];
foreach (FileTypes fileName in Enum.GetValues<FileTypes>()) foreach (object item in Enum.GetValues(typeof(FileTypes)))
{ {
string fileName = Enum.GetName(typeof(FileTypes), item);
checkBoxes.Add(new CheckBox checkBoxes.Add(new CheckBox
{ {
Content = $".{fileName}", Content = $".{fileName}",
IsChecked = fileName.GetConfigValue(ConfigurationState.Instance.UI.ShownFileTypes), IsChecked = ((FileTypes)item).GetConfigValue(ConfigurationState.Instance.UI.ShownFileTypes),
Command = MiniCommand.Create(() => Window.ToggleFileType(fileName)), Command = MiniCommand.Create(() => Window.ToggleFileType(fileName)),
}); });
} }
+8 -10
View File
@@ -30,7 +30,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning; using System.Runtime.Versioning;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -582,7 +581,6 @@ namespace Ryujinx.Ava.UI.Windows
GraphicsConfig.TextureDumpFormatPng = ConfigurationState.Instance.Graphics.TexturesDumpFileFormat == TextureFileFormat.Png; GraphicsConfig.TextureDumpFormatPng = ConfigurationState.Instance.Graphics.TexturesDumpFileFormat == TextureFileFormat.Png;
GraphicsConfig.EnableTextureDump = ConfigurationState.Instance.Graphics.EnableTextureDump; GraphicsConfig.EnableTextureDump = ConfigurationState.Instance.Graphics.EnableTextureDump;
GraphicsConfig.EnableTextureRealTimeEdit = ConfigurationState.Instance.Graphics.EnableTextureRealTimeEdit; GraphicsConfig.EnableTextureRealTimeEdit = ConfigurationState.Instance.Graphics.EnableTextureRealTimeEdit;
GraphicsConfig.EnableMacroJit = RuntimeFeature.IsDynamicCodeSupported ? ConfigurationState.Instance.Graphics.EnableMacroHLE : false;
#pragma warning restore IDE0055 #pragma warning restore IDE0055
} }
@@ -678,18 +676,18 @@ namespace Ryujinx.Ava.UI.Windows
ReloadGameList(); ReloadGameList();
} }
public void ToggleFileType(FileTypes fileType) public void ToggleFileType(string fileType)
{ {
_ = fileType switch _ = fileType switch
{ {
#pragma warning disable IDE0055 // Disable formatting #pragma warning disable IDE0055 // Disable formatting
FileTypes.NSP => ConfigurationState.Instance.UI.ShownFileTypes.NSP.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NSP, "NSP" => ConfigurationState.Instance.UI.ShownFileTypes.NSP.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NSP,
FileTypes.PFS0 => ConfigurationState.Instance.UI.ShownFileTypes.PFS0.Value = !ConfigurationState.Instance.UI.ShownFileTypes.PFS0, "PFS0" => ConfigurationState.Instance.UI.ShownFileTypes.PFS0.Value = !ConfigurationState.Instance.UI.ShownFileTypes.PFS0,
FileTypes.XCI => ConfigurationState.Instance.UI.ShownFileTypes.XCI.Value = !ConfigurationState.Instance.UI.ShownFileTypes.XCI, "XCI" => ConfigurationState.Instance.UI.ShownFileTypes.XCI.Value = !ConfigurationState.Instance.UI.ShownFileTypes.XCI,
FileTypes.NCA => ConfigurationState.Instance.UI.ShownFileTypes.NCA.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NCA, "NCA" => ConfigurationState.Instance.UI.ShownFileTypes.NCA.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NCA,
FileTypes.NRO => ConfigurationState.Instance.UI.ShownFileTypes.NRO.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NRO, "NRO" => ConfigurationState.Instance.UI.ShownFileTypes.NRO.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NRO,
FileTypes.NSO => ConfigurationState.Instance.UI.ShownFileTypes.NSO.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NSO, "NSO" => ConfigurationState.Instance.UI.ShownFileTypes.NSO.Value = !ConfigurationState.Instance.UI.ShownFileTypes.NSO,
_ => throw new ArgumentOutOfRangeException(fileType.ToString()), _ => throw new ArgumentOutOfRangeException(fileType),
#pragma warning restore IDE0055 #pragma warning restore IDE0055
}; };
-281
View File
@@ -1,281 +0,0 @@
<Directives>
<Application>
<Assembly Name="Silk.NET.Vulkan.Extensions.EXT">
<Type Name="Silk.NET.Vulkan.Extensions.EXT.ExtAttachmentFeedbackLoopDynamicState" Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.EXT.ExtConditionalRendering" Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.EXT.ExtDebugUtils" Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.EXT.ExtExtendedDynamicState" Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.EXT.ExtExternalMemoryHost" Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.EXT.ExtTransformFeedback" Dynamic="Required All"/>
</Assembly>
<Assembly Name="Silk.NET.Vulkan.Extensions.KHR">
<Type Name="Silk.NET.Vulkan.Extensions.KHR.KhrAndroidSurface" Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.KHR.KhrDrawIndirectCount" Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.KHR.KhrPushDescriptor" Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.KHR.KhrSurface" Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.KHR.KhrSwapchain" Dynamic="Required All"/>
</Assembly>
<Assembly Name="Ryujinx.HLE">
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.AccountService.IManagerForApplication" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.AccountService.IManagerForSystemService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.AccountService.IProfile" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.AccountService.IProfileEditor" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.IAccountServiceForAdministrator" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.IAccountServiceForApplication" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.IAccountServiceForSystemService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.IAsyncContext" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.IAsyncNetworkServiceLicenseKindContext" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.IBaasAccessTokenAccessor" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.ProfilesJsonSerializerContext" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Dauth.IService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.ILibraryAppletProxy" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.ISystemAppletProxy" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletCreator.ILibraryAppletAccessor" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy.ILibraryAppletSelfAccessor" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy.IProcessWindingController" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.IAppletCommonFunctions" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.IApplicationCreator" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.IAudioController" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.ICommonStateGetter" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.IDebugFunctions" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.IDisplayController" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.IGlobalStateController" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.IHomeMenuFunctions" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.ILibraryAppletCreator" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.ISelfController" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.IWindowController" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AppletFifo`1" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.IAllSystemAppletProxiesService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.IStorage" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.IStorageAccessor" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.IApplicationFunctions" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.IApplicationProxy" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.IApplicationProxyService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.Idle.IPolicyManagerSystem" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.Omm.IOperationModeManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.Spsm.IPowerStateInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.Tcap.IAvmService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.Tcap.IFactorySettingsServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.Tcap.IManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Apm.IManagerPrivileged" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Apm.ManagerServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Apm.SessionServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Apm.SystemManagerServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Arp.LibHacArpServiceObject" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Arp.LibHacIReader" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Bgct.IStateControlService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Bgct.ITaskService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Bluetooth.IBluetoothDriver" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Bluetooth.IBluetoothUser" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.BluetoothManager.BtmUser.IBtmUserCore" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.BluetoothManager.IBtm" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.BluetoothManager.IBtmDebug" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.BluetoothManager.IBtmSystem" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.BluetoothManager.IBtmUser" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Caps.IAlbumAccessorService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Caps.IAlbumApplicationService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Caps.IAlbumControlService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Caps.IScreenShotApplicationService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Caps.IScreenShotControlService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Caps.IScreenshotService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Cec.ICecManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.CommandCmifAttribute" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.CommandTipcAttribute" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.DummyService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ectx.IReaderForSystem" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ectx.IWriterForApplication" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ectx.IWriterForSystem" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Erpt.IContext" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Erpt.ISession" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Es.IETicketService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Eupld.IControl" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Eupld.IRequest" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fatal.IPrivateService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fatal.IService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy.IDirectory" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy.IFile" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy.IFileSystem" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy.IStorage" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.IDeviceOperator" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.IFileSystemProxy" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.IFileSystemProxyForLoader" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.IMultiCommitManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.IProgramRegistry" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.ISaveDataInfoReader" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Grc.IGrcService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Grc.IRemoteVideoTransfer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.DebugPadDevice" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.HidServer.IActiveApplicationDeviceList" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.HidServer.IAppletResource" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.IHidbusServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.IHidDebugServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.IHidServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.IHidSystemServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.Irs.IIrSensorServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.Irs.IIrSensorSystemServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.ISystemServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.KeyboardDevice" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.MouseDevice" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.NpadDevices" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.TouchDevice" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ldn.IMonitorServiceCreator" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ldn.ISystemServiceCreator" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ldn.IUserServiceCreator" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ldn.Lp2p.IServiceCreator" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.IUserLocalCommunicationService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Loader.IDebugMonitorInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Loader.IProcessManagerInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Loader.IShellInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Mig.IService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Mii.IImageDatabaseService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Mii.IStaticService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Mii.StaticService.DatabaseServiceImpl" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Mnpp.IServiceForApplication" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ncm.IContentManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ncm.Lr.ILocationResolverManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager.ILocationResolver" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.News.IServiceCreator" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption.AmiiboBinReader" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption.AmiiboDecryptor" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption.AmiiboDump" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption.AmiiboMasterKey" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.IAmManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.ISystemManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.IUserManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.Mifare.IUserManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.NfcManager.INfc" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.Nfp.AmiiboJsonSerializerContext" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.Nfp.IAmManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.Nfp.INfp" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.Nfp.ISystemManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.Nfp.IUserManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ngct.IService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ngct.IServiceWithManagementApi" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nifm.IStaticService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nifm.StaticService.IGeneralService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nifm.StaticService.IRequest" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.INetworkInstallManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.IShopServiceAccessServerInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.IShopServiceAccessSystemInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.IShopServiceManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.Ntc.IStaticService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.Ntc.StaticService.IEnsureNetworkClockAvailabilityService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface.IShopServiceAccessServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface.ShopServiceAccessServer.IShopServiceAccessor" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface.ShopServiceAccessServer.ShopServiceAccessor.IShopServiceAsync" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Notification.INotificationServicesForApplication" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Notification.INotificationServicesForSystem" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Npns.INpnsSystem" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Npns.INpnsUser" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.Aoc.IAddOnContentManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.Aoc.IContentsServiceManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.Aoc.IPurchaseEventManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.IApplicationManagerInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.IDevelopInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.IReadOnlyApplicationControlDataInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.IServiceGetterInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.ISystemUpdateInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.IVulnerabilityManagerInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.Host1xContext" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.INvDrvDebugFSServices" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.INvDrvServices" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.INvGemControl" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.INvGemCoreDump" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.NvHostAsGpuDeviceFile" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.NvHostChannelDeviceFile" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.NvHostGpuDeviceFile" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl.NvHostCtrlDeviceFile" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu.NvHostCtrlGpuDeviceFile" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostDbgGpu.NvHostDbgGpuDeviceFile" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostProfGpu.NvHostProfGpuDeviceFile" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap.NvMapDeviceFile" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.Types.NvIoctlNotImplementedException" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.Types.NvQueryEventNotImplementedException" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Olsc.IOlscServiceForApplication" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Olsc.IOlscServiceForSystemService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcie.ILogManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcie.IManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pctl.IParentalControlServiceFactory" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory.IParentalControlService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcv.Bpc.IBoardPowerControlManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcv.Bpc.IRtcManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcv.Clkrst.ClkrstManager.IClkrstSession" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcv.Clkrst.IArbitrationManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcv.Clkrst.IClkrstManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcv.IPcvService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcv.Rgltr.IRegulatorManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcv.Rtc.IRtcManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pm.IBootModeInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pm.IDebugMonitorInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pm.IInformationInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pm.IShellInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ptm.Fan.IManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ptm.Fgm.IDebugger" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ptm.Fgm.ISession" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ptm.Pcm.IManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ptm.Psm.IPsmServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ptm.Psm.IPsmSession" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ptm.Tc.IManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ro.IRoInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sdb.Pdm.INotifyService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sdb.Pdm.IQueryService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sdb.Pl.ISharedFontManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.ServerBase" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.ServiceAttribute" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Settings.IFirmwareDebugSettingsServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Settings.ISettingsServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Settings.ISystemSettingsServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sm.IManagerInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sm.IUserInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Bsd.IClient" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl.EventFileDescriptor" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl.EventFileDescriptorPollManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl.ManagedSocket" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl.ManagedSocketPollManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Bsd.ServerInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Ethc.IEthInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Ethc.IEthInterfaceGroup" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Nsd.IManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.IResolver" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Spl.IGeneralInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Spl.IRandomInterface" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ssl.ISslService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ssl.SslService.ISslConnection" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ssl.SslService.ISslContext" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ssl.SslService.SslManagedSocketConnection" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.SurfaceFlinger.BufferItem" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.SurfaceFlinger.BufferItemConsumer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.SurfaceFlinger.BufferQueueProducer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.SurfaceFlinger.ConsumerBase" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.SurfaceFlinger.HOSBinderDriverServer" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.SurfaceFlinger.SurfaceFlinger" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.EphemeralNetworkSystemClockContextWriter" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.EphemeralNetworkSystemClockCore" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.LocalSystemClockContextWriter" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.NetworkSystemClockContextWriter" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.StandardLocalSystemClockCore" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.StandardNetworkSystemClockCore" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.StandardSteadyClockCore" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.StandardUserSystemClockCore" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.TickBasedSteadyClockCore" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.IAlarmService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.IPowerStateRequestHandler" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.IStaticServiceForGlue" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.IStaticServiceForPsc" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.ITimeServiceManager" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.StaticService.ISteadyClock" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.StaticService.ISystemClock" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.StaticService.ITimeZoneServiceForGlue" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.StaticService.ITimeZoneServiceForPsc" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Vi.IApplicationRootService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Vi.IManagerRootService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Vi.ISystemRootService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService.IManagerDisplayService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService.ISystemDisplayService" Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Vi.RootService.IApplicationDisplayService" Dynamic="Required All" />
</Assembly>
<Assembly Name="Ryujinx.Graphics.Gpu">
<Type Name="Ryujinx.Graphics.Gpu.Engine.MME.MacroJitCompiler" Dynamic="Required All"/>
</Assembly>
</Application>
</Directives>
-2
View File
@@ -1,8 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Configurations>Debug;Release;Debug AOT;Release AOT</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup> </PropertyGroup>
</Project> </Project>