Compare commits

...

5 Commits

Author SHA1 Message Date
dd2e851e95 OpenTK (#6143) 2024-01-25 19:25:47 +01:00
2ca70eb9a0 Implement SQSHL (immediate) CPU instruction (#6155)
* Implement SQSHL (immediate) CPU instruction

* Fix test
2024-01-24 23:50:43 +01:00
6575952432 Vulkan: Enumerate Query Pool properly (#6167)
Turns out that ElementAt for Queue<T> runs the default implementation as it doesn't implement IList, which enumerates elements of the queue up to the given index. This code was creating `count` enumerators and iterating way more queue items than it needed to at higher counts. The solution is just to use one enumerator and break out of the loop when we get the count that we need.

3.5% of backend time was being spent _just_ enumerating at the usual spot in SMO.
2024-01-24 19:33:52 -03:00
9a28ba72b1 Use unix timestamps on GetFileTimeStampRaw (#6169) 2024-01-24 19:26:59 -03:00
34a9922b57 Fix architecture preference for MacOS game shortcuts (#6145)
* Fix architecture preference for MacOS game shortcuts

* Detect arch and then pass it to script

Co-authored-by: jcm <john.moody@coloradocollege.edu>

* Remove old script write call in `CreateShortcutMacos`

* Turn launch script into EmbeddedResource

* Added final newline

---------

Co-authored-by: jcm <john.moody@coloradocollege.edu>
2024-01-22 23:10:25 +01:00
10 changed files with 292 additions and 10 deletions

View File

@ -28,10 +28,10 @@
<PackageVersion Include="NetCoreServer" Version="7.0.0" />
<PackageVersion Include="NUnit" Version="3.13.3" />
<PackageVersion Include="NUnit3TestAdapter" Version="4.1.0" />
<PackageVersion Include="OpenTK.Core" Version="4.8.1" />
<PackageVersion Include="OpenTK.Graphics" Version="4.8.1" />
<PackageVersion Include="OpenTK.Audio.OpenAL" Version="4.8.1" />
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.8.1" />
<PackageVersion Include="OpenTK.Core" Version="4.8.2" />
<PackageVersion Include="OpenTK.Graphics" Version="4.8.2" />
<PackageVersion Include="OpenTK.Audio.OpenAL" Version="4.8.2" />
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.8.2" />
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" />
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />

View File

@ -0,0 +1,8 @@
#!/bin/sh
launch_arch="$(uname -m)"
if [ "$(sysctl -in sysctl.proc_translated)" = "1" ]
then
launch_arch="arm64"
fi
arch -$launch_arch {0} {1}

View File

@ -517,7 +517,10 @@ namespace ARMeilleure.Decoders
SetA64("0x00111100>>>xxx100111xxxxxxxxxx", InstName.Sqrshrn_V, InstEmit.Sqrshrn_V, OpCodeSimdShImm.Create);
SetA64("0111111100>>>xxx100011xxxxxxxxxx", InstName.Sqrshrun_S, InstEmit.Sqrshrun_S, OpCodeSimdShImm.Create);
SetA64("0x10111100>>>xxx100011xxxxxxxxxx", InstName.Sqrshrun_V, InstEmit.Sqrshrun_V, OpCodeSimdShImm.Create);
SetA64("010111110>>>>xxx011101xxxxxxxxxx", InstName.Sqshl_Si, InstEmit.Sqshl_Si, OpCodeSimdShImm.Create);
SetA64("0>001110<<1xxxxx010011xxxxxxxxxx", InstName.Sqshl_V, InstEmit.Sqshl_V, OpCodeSimdReg.Create);
SetA64("0000111100>>>xxx011101xxxxxxxxxx", InstName.Sqshl_Vi, InstEmit.Sqshl_Vi, OpCodeSimdShImm.Create);
SetA64("010011110>>>>xxx011101xxxxxxxxxx", InstName.Sqshl_Vi, InstEmit.Sqshl_Vi, OpCodeSimdShImm.Create);
SetA64("0101111100>>>xxx100101xxxxxxxxxx", InstName.Sqshrn_S, InstEmit.Sqshrn_S, OpCodeSimdShImm.Create);
SetA64("0x00111100>>>xxx100101xxxxxxxxxx", InstName.Sqshrn_V, InstEmit.Sqshrn_V, OpCodeSimdShImm.Create);
SetA64("0111111100>>>xxx100001xxxxxxxxxx", InstName.Sqshrun_S, InstEmit.Sqshrun_S, OpCodeSimdShImm.Create);

View File

@ -116,7 +116,7 @@ namespace ARMeilleure.Instructions
}
else if (shift >= eSize)
{
if ((op.RegisterSize == RegisterSize.Simd64))
if (op.RegisterSize == RegisterSize.Simd64)
{
Operand res = context.VectorZeroUpper64(GetVec(op.Rd));
@ -359,6 +359,16 @@ namespace ARMeilleure.Instructions
}
}
public static void Sqshl_Si(ArmEmitterContext context)
{
EmitShlImmOp(context, signedDst: true, ShlRegFlags.Signed | ShlRegFlags.Scalar | ShlRegFlags.Saturating);
}
public static void Sqshl_Vi(ArmEmitterContext context)
{
EmitShlImmOp(context, signedDst: true, ShlRegFlags.Signed | ShlRegFlags.Saturating);
}
public static void Sqshrn_S(ArmEmitterContext context)
{
if (Optimizations.UseAdvSimd)
@ -1593,6 +1603,99 @@ namespace ARMeilleure.Instructions
Saturating = 1 << 3,
}
private static void EmitShlImmOp(ArmEmitterContext context, bool signedDst, ShlRegFlags flags = ShlRegFlags.None)
{
bool scalar = flags.HasFlag(ShlRegFlags.Scalar);
bool signed = flags.HasFlag(ShlRegFlags.Signed);
bool saturating = flags.HasFlag(ShlRegFlags.Saturating);
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
Operand res = context.VectorZero();
int elems = !scalar ? op.GetBytesCount() >> op.Size : 1;
for (int index = 0; index < elems; index++)
{
Operand ne = EmitVectorExtract(context, op.Rn, index, op.Size, signed);
Operand e = !saturating
? EmitShlImm(context, ne, GetImmShl(op), op.Size)
: EmitShlImmSatQ(context, ne, GetImmShl(op), op.Size, signed, signedDst);
res = EmitVectorInsert(context, res, e, index, op.Size);
}
context.Copy(GetVec(op.Rd), res);
}
private static Operand EmitShlImm(ArmEmitterContext context, Operand op, int shiftLsB, int size)
{
int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
Operand res = context.AllocateLocal(OperandType.I64);
if (shiftLsB >= eSize)
{
Operand shl = context.ShiftLeft(op, Const(shiftLsB));
context.Copy(res, shl);
}
else
{
Operand zeroL = Const(0L);
context.Copy(res, zeroL);
}
return res;
}
private static Operand EmitShlImmSatQ(ArmEmitterContext context, Operand op, int shiftLsB, int size, bool signedSrc, bool signedDst)
{
int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
Operand lblEnd = Label();
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
if (shiftLsB >= eSize)
{
context.Copy(res, signedSrc
? EmitSignedSignSatQ(context, op, size)
: EmitUnsignedSignSatQ(context, op, size));
}
else
{
Operand shl = context.ShiftLeft(op, Const(shiftLsB));
if (eSize == 64)
{
Operand sarOrShr = signedSrc
? context.ShiftRightSI(shl, Const(shiftLsB))
: context.ShiftRightUI(shl, Const(shiftLsB));
context.Copy(res, shl);
context.BranchIf(lblEnd, sarOrShr, op, Comparison.Equal);
context.Copy(res, signedSrc
? EmitSignedSignSatQ(context, op, size)
: EmitUnsignedSignSatQ(context, op, size));
}
else
{
context.Copy(res, signedSrc
? EmitSignedSrcSatQ(context, shl, size, signedDst)
: EmitUnsignedSrcSatQ(context, shl, size, signedDst));
}
}
context.MarkLabel(lblEnd);
return res;
}
private static void EmitShlRegOp(ArmEmitterContext context, ShlRegFlags flags = ShlRegFlags.None)
{
bool scalar = flags.HasFlag(ShlRegFlags.Scalar);

View File

@ -384,7 +384,9 @@ namespace ARMeilleure.Instructions
Sqrshrn_V,
Sqrshrun_S,
Sqrshrun_V,
Sqshl_Si,
Sqshl_V,
Sqshl_Vi,
Sqshrn_S,
Sqshrn_V,
Sqshrun_S,

View File

@ -67,9 +67,18 @@ namespace Ryujinx.Graphics.Vulkan.Queries
lock (_queryPool)
{
count = Math.Min(count, _queryPool.Count);
for (int i = 0; i < count; i++)
if (count > 0)
{
_queryPool.ElementAt(i).PoolReset(cmd, ResetSequence);
foreach (BufferedQuery query in _queryPool)
{
query.PoolReset(cmd, ResetSequence);
if (--count == 0)
{
break;
}
}
}
}
}

View File

@ -186,7 +186,12 @@ namespace Ryujinx.HLE.FileSystem
public void InitializeFsServer(LibHac.Horizon horizon, out HorizonClient fsServerClient)
{
LocalFileSystem serverBaseFs = new(AppDataManager.BaseDirPath);
LocalFileSystem serverBaseFs = new(useUnixTimeStamps: true);
Result result = serverBaseFs.Initialize(AppDataManager.BaseDirPath, LocalFileSystem.PathMode.DefaultCaseSensitivity, ensurePathExists: true);
if (result.IsFailure())
{
throw new HorizonResultException(result, "Error creating LocalFileSystem.");
}
fsServerClient = horizon.CreatePrivilegedHorizonClient();
var fsServer = new FileSystemServer(fsServerClient);

View File

@ -311,6 +311,46 @@ namespace Ryujinx.Tests.Cpu
};
}
private static uint[] _ShlImm_S_D_()
{
return new[]
{
0x5F407400u, // SQSHL D0, D0, #0
};
}
private static uint[] _ShlImm_V_8B_16B_()
{
return new[]
{
0x0F087400u, // SQSHL V0.8B, V0.8B, #0
};
}
private static uint[] _ShlImm_V_4H_8H_()
{
return new[]
{
0x0F107400u, // SQSHL V0.4H, V0.4H, #0
};
}
private static uint[] _ShlImm_V_2S_4S_()
{
return new[]
{
0x0F207400u, // SQSHL V0.2S, V0.2S, #0
};
}
private static uint[] _ShlImm_V_2D_()
{
return new[]
{
0x4F407400u, // SQSHL V0.2D, V0.2D, #0
};
}
private static uint[] _ShrImm_Sri_S_D_()
{
return new[]
@ -813,6 +853,117 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise]
public void ShlImm_S_D([ValueSource(nameof(_ShlImm_S_D_))] uint opcodes,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a,
[Values(1u, 64u)] uint shift)
{
uint immHb = (64 + shift) & 0x7F;
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
opcodes |= (immHb << 16);
V128 v0 = MakeVectorE0E1(z, z);
V128 v1 = MakeVectorE0(a);
SingleOpcode(opcodes, v0: v0, v1: v1);
CompareAgainstUnicorn();
}
[Test, Pairwise]
public void ShlImm_V_8B_16B([ValueSource(nameof(_ShlImm_V_8B_16B_))] uint opcodes,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_8B_))] ulong z,
[ValueSource(nameof(_8B_))] ulong a,
[Values(1u, 8u)] uint shift,
[Values(0b0u, 0b1u)] uint q) // <8B, 16B>
{
uint immHb = (8 + shift) & 0x7F;
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
opcodes |= (immHb << 16);
opcodes |= ((q & 1) << 30);
V128 v0 = MakeVectorE0E1(z, z);
V128 v1 = MakeVectorE0E1(a, a * q);
SingleOpcode(opcodes, v0: v0, v1: v1);
CompareAgainstUnicorn();
}
[Test, Pairwise]
public void ShlImm_V_4H_8H([ValueSource(nameof(_ShlImm_V_4H_8H_))] uint opcodes,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_4H_))] ulong z,
[ValueSource(nameof(_4H_))] ulong a,
[Values(1u, 16u)] uint shift,
[Values(0b0u, 0b1u)] uint q) // <4H, 8H>
{
uint immHb = (16 + shift) & 0x7F;
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
opcodes |= (immHb << 16);
opcodes |= ((q & 1) << 30);
V128 v0 = MakeVectorE0E1(z, z);
V128 v1 = MakeVectorE0E1(a, a * q);
SingleOpcode(opcodes, v0: v0, v1: v1);
CompareAgainstUnicorn();
}
[Test, Pairwise]
public void ShlImm_V_2S_4S([ValueSource(nameof(_ShlImm_V_2S_4S_))] uint opcodes,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_))] ulong z,
[ValueSource(nameof(_2S_))] ulong a,
[Values(1u, 32u)] uint shift,
[Values(0b0u, 0b1u)] uint q) // <2S, 4S>
{
uint immHb = (32 + shift) & 0x7F;
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
opcodes |= (immHb << 16);
opcodes |= (((q | (immHb >> 6)) & 1) << 30);
V128 v0 = MakeVectorE0E1(z, z);
V128 v1 = MakeVectorE0E1(a, a * q);
SingleOpcode(opcodes, v0: v0, v1: v1);
CompareAgainstUnicorn();
}
[Test, Pairwise]
public void ShlImm_V_2D([ValueSource(nameof(_ShlImm_V_2D_))] uint opcodes,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a,
[Values(1u, 64u)] uint shift)
{
uint immHb = (64 + shift) & 0x7F;
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
opcodes |= (immHb << 16);
V128 v0 = MakeVectorE0E1(z, z);
V128 v1 = MakeVectorE0E1(a, a);
SingleOpcode(opcodes, v0: v0, v1: v1);
CompareAgainstUnicorn();
}
[Test, Pairwise]
public void ShrImm_Sri_S_D([ValueSource(nameof(_ShrImm_Sri_S_D_))] uint opcodes,
[Values(0u)] uint rd,

View File

@ -54,6 +54,7 @@ namespace Ryujinx.Ui.Common.Helper
{
string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx");
var plistFile = EmbeddedResources.ReadAllText("Ryujinx.Ui.Common/shortcut-template.plist");
var shortcutScript = EmbeddedResources.ReadAllText("Ryujinx.Ui.Common/shortcut-launch-script.sh");
// Macos .App folder
string contentFolderPath = Path.Combine("/Applications", cleanedAppName + ".app", "Contents");
string scriptFolderPath = Path.Combine(contentFolderPath, "MacOS");
@ -68,8 +69,7 @@ namespace Ryujinx.Ui.Common.Helper
string scriptPath = Path.Combine(scriptFolderPath, ScriptName);
using StreamWriter scriptFile = new(scriptPath);
scriptFile.WriteLine("#!/bin/sh");
scriptFile.WriteLine($"{basePath} {GetArgsString(appFilePath)}");
scriptFile.Write(shortcutScript, basePath, GetArgsString(appFilePath));
// Set execute permission
FileInfo fileInfo = new(scriptPath);

View File

@ -51,6 +51,7 @@
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'osx-x64' OR '$(RuntimeIdentifier)' == 'osx-arm64' OR '$(RuntimeIdentifier)' == ''">
<EmbeddedResource Include="..\..\distribution\macos\shortcut-template.plist" />
<EmbeddedResource Include="..\..\distribution\macos\shortcut-launch-script.sh" />
</ItemGroup>
<ItemGroup>