Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
32d21ddf17 | ||
|
82f90704a0 | ||
|
f978d3726a | ||
|
6f28c4abad | ||
|
105c9712c1 | ||
|
4d804ed45e | ||
|
4a27d29412 | ||
|
5bd2c58ad6 | ||
|
cf4c78b9c8 | ||
|
52aa4b6c22 | ||
|
5a02433080 | ||
|
915a0f7173 | ||
|
0cc266ff19 | ||
|
9a1b74799d | ||
|
638f3761f3 | ||
|
193ca3c9a2 |
8
.github/assign/audio.yml
vendored
Normal file
8
.github/assign/audio.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- marysaka
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- audio
|
11
.github/assign/cpu.yml
vendored
Normal file
11
.github/assign/cpu.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- gdkchan
|
||||
- riperiperi
|
||||
- marysaka
|
||||
- LDj3SNuD
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- cpu
|
4
.github/assign/global.yml
vendored
Normal file
4
.github/assign/global.yml
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- Ryujinx/developers
|
10
.github/assign/gpu.yml
vendored
Normal file
10
.github/assign/gpu.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- gdkchan
|
||||
- riperiperi
|
||||
- marysaka
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- gpu
|
11
.github/assign/gui.yml
vendored
Normal file
11
.github/assign/gui.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- Ack77
|
||||
- emmauss
|
||||
- TSRBerry
|
||||
- marysaka
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- gui
|
11
.github/assign/horizon.yml
vendored
Normal file
11
.github/assign/horizon.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- gdkchan
|
||||
- Ack77
|
||||
- marysaka
|
||||
- TSRBerry
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- horizon
|
9
.github/assign/infra.yml
vendored
Normal file
9
.github/assign/infra.yml
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
addReviewers: true
|
||||
|
||||
reviewers:
|
||||
- marysaka
|
||||
- TSRBerry
|
||||
|
||||
filterLabels:
|
||||
include:
|
||||
- infra
|
33
.github/labeler.yml
vendored
Normal file
33
.github/labeler.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
audio: 'src/Ryujinx.Audio*/**'
|
||||
|
||||
cpu:
|
||||
- 'src/ARMeilleure/**'
|
||||
- 'src/Ryujinx.Cpu/**'
|
||||
- 'src/Ryujinx.Memory/**'
|
||||
|
||||
gpu:
|
||||
- 'src/Ryujinx.Graphics.*/**'
|
||||
- 'src/Spv.Generator/**'
|
||||
- 'src/Ryujinx.ShaderTools/**'
|
||||
|
||||
'graphics-backend:opengl': 'src/Ryujinx.Graphics.OpenGL/**'
|
||||
'graphics-backend:vulkan':
|
||||
- 'src/Ryujinx.Graphics.Vulkan/**'
|
||||
- 'src/Spv.Generator/**'
|
||||
|
||||
gui:
|
||||
- 'src/Ryujinx/**'
|
||||
- 'src/Ryujinx.Ui.Common/**'
|
||||
- 'src/Ryujinx.Ui.LocaleGenerator/**'
|
||||
- 'src/Ryujinx.Ava/**'
|
||||
|
||||
horizon:
|
||||
- 'src/Ryujinx.HLE/**'
|
||||
- 'src/Ryujinx.Horizon*/**'
|
||||
|
||||
kernel: 'src/Ryujinx.HLE/HOS/Kernel/**'
|
||||
|
||||
infra:
|
||||
- '.github/**'
|
||||
- 'distribution/**'
|
||||
- 'Directory.Packages.props'
|
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@@ -3,19 +3,13 @@ name: Build job
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs: {}
|
||||
#push:
|
||||
# branches: [ master ]
|
||||
# paths-ignore:
|
||||
# - '.github/*'
|
||||
# - '.github/ISSUE_TEMPLATE/**'
|
||||
# - '*.yml'
|
||||
# - 'README.md'
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
paths-ignore:
|
||||
- '.github/*'
|
||||
- '.github/ISSUE_TEMPLATE/**'
|
||||
- '.github/**'
|
||||
- '*.yml'
|
||||
- '*.json'
|
||||
- '*.config'
|
||||
- 'README.md'
|
||||
|
||||
concurrency:
|
||||
|
54
.github/workflows/pr_triage.yml
vendored
Normal file
54
.github/workflows/pr_triage.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
name: "Pull Request Triage"
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, ready_for_review]
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Update labels based on changes
|
||||
uses: actions/labeler@v4
|
||||
with:
|
||||
sync-labels: true
|
||||
dot: true
|
||||
|
||||
- name: Auto Assign [Audio]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/audio.yml'
|
||||
|
||||
- name: Auto Assign [CPU]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/cpu.yml'
|
||||
|
||||
- name: Auto Assign [GPU]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/gpu.yml'
|
||||
|
||||
- name: Auto Assign [GUI]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/gui.yml'
|
||||
|
||||
- name: Auto Assign [Horizon]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/horizon.yml'
|
||||
|
||||
- name: Auto Assign [Infra]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/infra.yml'
|
||||
|
||||
- name: Auto Assign [Global]
|
||||
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||
with:
|
||||
configuration-path: '.github/assign/global.yml'
|
5
.github/workflows/release.yml
vendored
5
.github/workflows/release.yml
vendored
@@ -6,9 +6,10 @@ on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
paths-ignore:
|
||||
- '.github/*'
|
||||
- '.github/ISSUE_TEMPLATE/**'
|
||||
- '.github/**'
|
||||
- '*.yml'
|
||||
- '*.json'
|
||||
- '*.config'
|
||||
- 'README.md'
|
||||
|
||||
concurrency: release
|
||||
|
@@ -46,7 +46,7 @@
|
||||
<PackageVersion Include="System.Drawing.Common" Version="7.0.0" />
|
||||
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.31.0" />
|
||||
<PackageVersion Include="System.IO.Hashing" Version="7.0.0" />
|
||||
<PackageVersion Include="System.Management" Version="7.0.1" />
|
||||
<PackageVersion Include="System.Management" Version="7.0.2" />
|
||||
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
||||
<PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" />
|
||||
</ItemGroup>
|
||||
|
@@ -168,8 +168,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
|
||||
Logger.StartPass(PassName.CodeGeneration);
|
||||
|
||||
//Console.Error.WriteLine(IRDumper.GetDump(cfg));
|
||||
|
||||
bool relocatable = (cctx.Options & CompilerOptions.Relocatable) != 0;
|
||||
|
||||
CodeGenContext context = new(allocResult, maxCallArgs, cfg.Blocks.Count, relocatable);
|
||||
|
@@ -179,6 +179,35 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
(uint)operation.GetSource(2).AsInt32());
|
||||
break;
|
||||
|
||||
case IntrinsicType.Vector128Unary:
|
||||
GenerateVectorUnary(
|
||||
context,
|
||||
1,
|
||||
0,
|
||||
info.Inst,
|
||||
operation.Destination,
|
||||
operation.GetSource(0));
|
||||
break;
|
||||
case IntrinsicType.Vector128Binary:
|
||||
GenerateVectorBinary(
|
||||
context,
|
||||
1,
|
||||
0,
|
||||
info.Inst,
|
||||
operation.Destination,
|
||||
operation.GetSource(0),
|
||||
operation.GetSource(1));
|
||||
break;
|
||||
case IntrinsicType.Vector128BinaryRd:
|
||||
GenerateVectorUnary(
|
||||
context,
|
||||
1,
|
||||
0,
|
||||
info.Inst,
|
||||
operation.Destination,
|
||||
operation.GetSource(1));
|
||||
break;
|
||||
|
||||
case IntrinsicType.VectorUnary:
|
||||
GenerateVectorUnary(
|
||||
context,
|
||||
|
@@ -19,8 +19,8 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
Add(Intrinsic.Arm64AddvV, new IntrinsicInfo(0x0e31b800u, IntrinsicType.VectorUnary));
|
||||
Add(Intrinsic.Arm64AddS, new IntrinsicInfo(0x5e208400u, IntrinsicType.ScalarBinary));
|
||||
Add(Intrinsic.Arm64AddV, new IntrinsicInfo(0x0e208400u, IntrinsicType.VectorBinary));
|
||||
Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128Unary));
|
||||
Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128Unary));
|
||||
Add(Intrinsic.Arm64AesdV, new IntrinsicInfo(0x4e285800u, IntrinsicType.Vector128BinaryRd));
|
||||
Add(Intrinsic.Arm64AeseV, new IntrinsicInfo(0x4e284800u, IntrinsicType.Vector128BinaryRd));
|
||||
Add(Intrinsic.Arm64AesimcV, new IntrinsicInfo(0x4e287800u, IntrinsicType.Vector128Unary));
|
||||
Add(Intrinsic.Arm64AesmcV, new IntrinsicInfo(0x4e286800u, IntrinsicType.Vector128Unary));
|
||||
Add(Intrinsic.Arm64AndV, new IntrinsicInfo(0x0e201c00u, IntrinsicType.VectorBinaryBitwise));
|
||||
|
@@ -23,6 +23,10 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
ScalarTernaryShlRd,
|
||||
ScalarTernaryShrRd,
|
||||
|
||||
Vector128Unary,
|
||||
Vector128Binary,
|
||||
Vector128BinaryRd,
|
||||
|
||||
VectorUnary,
|
||||
VectorUnaryBitwise,
|
||||
VectorUnaryByElem,
|
||||
@@ -50,9 +54,6 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
VectorTernaryShlRd,
|
||||
VectorTernaryShrRd,
|
||||
|
||||
Vector128Unary,
|
||||
Vector128Binary,
|
||||
|
||||
GetRegister,
|
||||
SetRegister
|
||||
}
|
||||
|
@@ -746,6 +746,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
info.Type == IntrinsicType.ScalarTernaryFPRdByElem ||
|
||||
info.Type == IntrinsicType.ScalarTernaryShlRd ||
|
||||
info.Type == IntrinsicType.ScalarTernaryShrRd ||
|
||||
info.Type == IntrinsicType.Vector128BinaryRd ||
|
||||
info.Type == IntrinsicType.VectorBinaryRd ||
|
||||
info.Type == IntrinsicType.VectorInsertByElem ||
|
||||
info.Type == IntrinsicType.VectorTernaryRd ||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
enum OpCode32SimdSelMode : int
|
||||
enum OpCode32SimdSelMode
|
||||
{
|
||||
Eq = 0,
|
||||
Vs,
|
||||
|
@@ -17,7 +17,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AesdV, d, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.X86Aesdeclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
||||
}
|
||||
@@ -38,7 +42,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AeseV, d, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.X86Aesenclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
||||
}
|
||||
@@ -58,7 +66,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AesimcV, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.X86Aesimc, n);
|
||||
}
|
||||
@@ -78,7 +90,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AesmcV, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
Operand roundKey = context.VectorZero();
|
||||
|
||||
|
@@ -17,7 +17,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AesdV, d, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.X86Aesdeclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
||||
}
|
||||
@@ -38,7 +42,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AeseV, d, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.X86Aesenclast, context.AddIntrinsic(Intrinsic.X86Xorpd, d, n), context.VectorZero());
|
||||
}
|
||||
@@ -58,7 +66,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AesimcV, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.X86Aesimc, n);
|
||||
}
|
||||
@@ -78,7 +90,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res;
|
||||
|
||||
if (Optimizations.UseAesni)
|
||||
if (Optimizations.UseArm64Aes)
|
||||
{
|
||||
res = context.AddIntrinsic(Intrinsic.Arm64AesmcV, n);
|
||||
}
|
||||
else if (Optimizations.UseAesni)
|
||||
{
|
||||
Operand roundKey = context.VectorZero();
|
||||
|
||||
|
@@ -165,7 +165,7 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
Operand m = GetVecA32(op.Vm >> 1);
|
||||
|
||||
Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, doubleSize);
|
||||
Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, true);
|
||||
|
||||
Intrinsic inst = (unsigned ? Intrinsic.Arm64FcvtzuGp : Intrinsic.Arm64FcvtzsGp) | Intrinsic.Arm64VDouble;
|
||||
|
||||
@@ -175,7 +175,7 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
else
|
||||
{
|
||||
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, unsigned ? Intrinsic.Arm64FcvtzuS : Intrinsic.Arm64FcvtzsS);
|
||||
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, unsigned ? Intrinsic.Arm64FcvtzuS : Intrinsic.Arm64FcvtzsS, false);
|
||||
}
|
||||
}
|
||||
else if (!roundWithFpscr && Optimizations.UseSse41)
|
||||
@@ -260,28 +260,64 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
if (Optimizations.UseAdvSimd)
|
||||
{
|
||||
if (unsigned)
|
||||
bool doubleSize = floatSize == OperandType.FP64;
|
||||
|
||||
if (doubleSize)
|
||||
{
|
||||
inst = rm switch {
|
||||
0b00 => Intrinsic.Arm64FcvtauS,
|
||||
0b01 => Intrinsic.Arm64FcvtnuS,
|
||||
0b10 => Intrinsic.Arm64FcvtpuS,
|
||||
0b11 => Intrinsic.Arm64FcvtmuS,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
||||
};
|
||||
Operand m = GetVecA32(op.Vm >> 1);
|
||||
|
||||
Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, true);
|
||||
|
||||
if (unsigned)
|
||||
{
|
||||
inst = rm switch {
|
||||
0b00 => Intrinsic.Arm64FcvtauGp,
|
||||
0b01 => Intrinsic.Arm64FcvtnuGp,
|
||||
0b10 => Intrinsic.Arm64FcvtpuGp,
|
||||
0b11 => Intrinsic.Arm64FcvtmuGp,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
inst = rm switch {
|
||||
0b00 => Intrinsic.Arm64FcvtasGp,
|
||||
0b01 => Intrinsic.Arm64FcvtnsGp,
|
||||
0b10 => Intrinsic.Arm64FcvtpsGp,
|
||||
0b11 => Intrinsic.Arm64FcvtmsGp,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
||||
};
|
||||
}
|
||||
|
||||
Operand asInteger = context.AddIntrinsicInt(inst | Intrinsic.Arm64VDouble, toConvert);
|
||||
|
||||
InsertScalar(context, op.Vd, asInteger);
|
||||
}
|
||||
else
|
||||
{
|
||||
inst = rm switch {
|
||||
0b00 => Intrinsic.Arm64FcvtasS,
|
||||
0b01 => Intrinsic.Arm64FcvtnsS,
|
||||
0b10 => Intrinsic.Arm64FcvtpsS,
|
||||
0b11 => Intrinsic.Arm64FcvtmsS,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
||||
};
|
||||
}
|
||||
if (unsigned)
|
||||
{
|
||||
inst = rm switch {
|
||||
0b00 => Intrinsic.Arm64FcvtauS,
|
||||
0b01 => Intrinsic.Arm64FcvtnuS,
|
||||
0b10 => Intrinsic.Arm64FcvtpuS,
|
||||
0b11 => Intrinsic.Arm64FcvtmuS,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
inst = rm switch {
|
||||
0b00 => Intrinsic.Arm64FcvtasS,
|
||||
0b01 => Intrinsic.Arm64FcvtnsS,
|
||||
0b10 => Intrinsic.Arm64FcvtpsS,
|
||||
0b11 => Intrinsic.Arm64FcvtmsS,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(rm))
|
||||
};
|
||||
}
|
||||
|
||||
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst);
|
||||
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst);
|
||||
}
|
||||
}
|
||||
else if (Optimizations.UseSse41)
|
||||
{
|
||||
|
@@ -192,11 +192,10 @@ namespace ARMeilleure.Instructions
|
||||
EmitVectorTernaryOpSimd32(context, (d, n, m) => context.AddIntrinsic(inst, d, n, m));
|
||||
}
|
||||
|
||||
public static void EmitScalarUnaryOpSimd32(ArmEmitterContext context, Func1I scalarFunc)
|
||||
public static void EmitScalarUnaryOpSimd32(ArmEmitterContext context, Func1I scalarFunc, bool doubleSize)
|
||||
{
|
||||
OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;
|
||||
|
||||
bool doubleSize = (op.Size & 1) != 0;
|
||||
int shift = doubleSize ? 1 : 2;
|
||||
Operand m = GetVecA32(op.Vm >> shift);
|
||||
Operand d = GetVecA32(op.Vd >> shift);
|
||||
@@ -215,8 +214,13 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;
|
||||
|
||||
inst |= ((op.Size & 1) != 0 ? Intrinsic.Arm64VDouble : Intrinsic.Arm64VFloat) | Intrinsic.Arm64V128;
|
||||
EmitScalarUnaryOpSimd32(context, (m) => (inst == 0) ? m : context.AddIntrinsic(inst, m));
|
||||
EmitScalarUnaryOpF32(context, inst, (op.Size & 1) != 0);
|
||||
}
|
||||
|
||||
public static void EmitScalarUnaryOpF32(ArmEmitterContext context, Intrinsic inst, bool doubleSize)
|
||||
{
|
||||
inst |= (doubleSize ? Intrinsic.Arm64VDouble : Intrinsic.Arm64VFloat) | Intrinsic.Arm64V128;
|
||||
EmitScalarUnaryOpSimd32(context, (m) => (inst == 0) ? m : context.AddIntrinsic(inst, m), doubleSize);
|
||||
}
|
||||
|
||||
public static void EmitScalarBinaryOpSimd32(ArmEmitterContext context, Func2I scalarFunc)
|
||||
|
@@ -13,6 +13,7 @@ namespace ARMeilleure
|
||||
public static bool UseUnmanagedDispatchLoop { get; set; } = true;
|
||||
|
||||
public static bool UseAdvSimdIfAvailable { get; set; } = true;
|
||||
public static bool UseArm64AesIfAvailable { get; set; } = true;
|
||||
public static bool UseArm64PmullIfAvailable { get; set; } = true;
|
||||
|
||||
public static bool UseSseIfAvailable { get; set; } = true;
|
||||
@@ -41,6 +42,7 @@ namespace ARMeilleure
|
||||
}
|
||||
|
||||
internal static bool UseAdvSimd => UseAdvSimdIfAvailable && Arm64HardwareCapabilities.SupportsAdvSimd;
|
||||
internal static bool UseArm64Aes => UseArm64AesIfAvailable && Arm64HardwareCapabilities.SupportsAes;
|
||||
internal static bool UseArm64Pmull => UseArm64PmullIfAvailable && Arm64HardwareCapabilities.SupportsPmull;
|
||||
|
||||
internal static bool UseSse => UseSseIfAvailable && X86HardwareCapabilities.SupportsSse;
|
||||
|
@@ -78,7 +78,7 @@ namespace ARMeilleure.Signal
|
||||
private static IntPtr _signalHandlerPtr;
|
||||
private static IntPtr _signalHandlerHandle;
|
||||
|
||||
private static readonly object _lock = new object();
|
||||
private static readonly object _lock = new();
|
||||
private static bool _initialized;
|
||||
|
||||
static NativeSignalHandler()
|
||||
|
@@ -1,6 +1,6 @@
|
||||
namespace ARMeilleure.State
|
||||
{
|
||||
enum ExecutionMode : int
|
||||
enum ExecutionMode
|
||||
{
|
||||
Aarch32Arm = 0,
|
||||
Aarch32Thumb = 1,
|
||||
|
@@ -2,6 +2,7 @@ using ARMeilleure.CodeGen;
|
||||
using ARMeilleure.CodeGen.Unwinding;
|
||||
using ARMeilleure.Memory;
|
||||
using ARMeilleure.Native;
|
||||
using Ryujinx.Memory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@@ -12,8 +13,8 @@ namespace ARMeilleure.Translation.Cache
|
||||
{
|
||||
static partial class JitCache
|
||||
{
|
||||
private const int PageSize = 4 * 1024;
|
||||
private const int PageMask = PageSize - 1;
|
||||
private static readonly int PageSize = (int)MemoryBlock.GetPageSize();
|
||||
private static readonly int PageMask = PageSize - 1;
|
||||
|
||||
private const int CodeAlignment = 4; // Bytes.
|
||||
private const int CacheSize = 2047 * 1024 * 1024;
|
||||
@@ -25,7 +26,7 @@ namespace ARMeilleure.Translation.Cache
|
||||
|
||||
private static readonly List<CacheEntry> _cacheEntries = new List<CacheEntry>();
|
||||
|
||||
private static readonly object _lock = new object();
|
||||
private static readonly object _lock = new();
|
||||
private static bool _initialized;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
|
@@ -30,7 +30,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||
|
||||
private const uint InternalVersion = 4661; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
private const uint InternalVersion = 5292; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
|
||||
private const string ActualDir = "0";
|
||||
private const string BackupDir = "1";
|
||||
|
@@ -17,7 +17,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
|
||||
private Queue<OpenALAudioBuffer> _queuedBuffers;
|
||||
private ulong _playedSampleCount;
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
public OpenALHardwareDeviceSession(OpenALHardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, float requestedVolume) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount)
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
namespace Ryujinx.Audio.Backends.SoundIo.Native
|
||||
{
|
||||
public enum SoundIoBackend : int
|
||||
public enum SoundIoBackend
|
||||
{
|
||||
None = 0,
|
||||
Jack = 1,
|
||||
|
@@ -11,7 +11,7 @@ namespace Ryujinx.Audio
|
||||
/// <summary>
|
||||
/// Lock used to control the waiters registration.
|
||||
/// </summary>
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
/// <summary>
|
||||
/// Events signaled when the driver played audio buffers.
|
||||
|
@@ -10,7 +10,7 @@ namespace Ryujinx.Audio.Backends.Common
|
||||
{
|
||||
private const int RingBufferAlignment = 2048;
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
private byte[] _buffer;
|
||||
private int _size;
|
||||
|
@@ -14,12 +14,12 @@ namespace Ryujinx.Audio.Input
|
||||
/// </summary>
|
||||
public class AudioInputManager : IDisposable
|
||||
{
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
/// <summary>
|
||||
/// Lock used for session allocation.
|
||||
/// </summary>
|
||||
private object _sessionLock = new object();
|
||||
private readonly object _sessionLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// The session ids allocation table.
|
||||
|
@@ -48,7 +48,7 @@ namespace Ryujinx.Audio.Input
|
||||
/// <summary>
|
||||
/// The lock of the parent.
|
||||
/// </summary>
|
||||
private object _parentLock;
|
||||
private readonly object _parentLock;
|
||||
|
||||
/// <summary>
|
||||
/// The dispose state.
|
||||
|
@@ -14,12 +14,12 @@ namespace Ryujinx.Audio.Output
|
||||
/// </summary>
|
||||
public class AudioOutputManager : IDisposable
|
||||
{
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
/// <summary>
|
||||
/// Lock used for session allocation.
|
||||
/// </summary>
|
||||
private object _sessionLock = new object();
|
||||
private readonly object _sessionLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// The session ids allocation table.
|
||||
|
@@ -48,7 +48,7 @@ namespace Ryujinx.Audio.Output
|
||||
/// <summary>
|
||||
/// THe lock of the parent.
|
||||
/// </summary>
|
||||
private object _parentLock;
|
||||
private readonly object _parentLock;
|
||||
|
||||
/// <summary>
|
||||
/// The dispose state.
|
||||
|
@@ -26,7 +26,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||
{
|
||||
public class AudioRenderSystem : IDisposable
|
||||
{
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
private AudioRendererRenderingDevice _renderingDevice;
|
||||
private AudioRendererExecutionMode _executionMode;
|
||||
|
@@ -19,12 +19,12 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||
/// <summary>
|
||||
/// Lock used for session allocation.
|
||||
/// </summary>
|
||||
private object _sessionLock = new object();
|
||||
private readonly object _sessionLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// Lock used to control the <see cref="AudioProcessor"/> running state.
|
||||
/// </summary>
|
||||
private object _audioProcessorLock = new object();
|
||||
private readonly object _audioProcessorLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// The session ids allocation table.
|
||||
|
@@ -16,7 +16,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
|
||||
/// <summary>
|
||||
/// Global lock of the object.
|
||||
/// </summary>
|
||||
private object Lock = new object();
|
||||
private readonly object Lock = new();
|
||||
|
||||
/// <summary>
|
||||
/// The upsamplers instances.
|
||||
|
@@ -40,6 +40,7 @@ using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Formats.Png;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using SPB.Graphics.Exceptions;
|
||||
using SPB.Graphics.Vulkan;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -475,11 +476,20 @@ namespace Ryujinx.Ava
|
||||
_windowsMultimediaTimerResolution = null;
|
||||
}
|
||||
|
||||
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent();
|
||||
if (_rendererHost.EmbeddedWindow is EmbeddedWindowOpenGL openGlWindow)
|
||||
{
|
||||
// Try to bind the OpenGL context before calling the shutdown event.
|
||||
openGlWindow.MakeCurrent(false, false);
|
||||
|
||||
Device.DisposeGpu();
|
||||
Device.DisposeGpu();
|
||||
|
||||
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(null);
|
||||
// Unbind context and destroy everything.
|
||||
openGlWindow.MakeCurrent(true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Device.DisposeGpu();
|
||||
}
|
||||
}
|
||||
|
||||
private void HideCursorState_Changed(object sender, ReactiveEventArgs<HideCursorMode> state)
|
||||
@@ -930,7 +940,7 @@ namespace Ryujinx.Ava
|
||||
_gpuDoneEvent.Set();
|
||||
});
|
||||
|
||||
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(null);
|
||||
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(true);
|
||||
}
|
||||
|
||||
public void UpdateStatus()
|
||||
@@ -1044,7 +1054,7 @@ namespace Ryujinx.Ava
|
||||
ScreenshotRequested = true;
|
||||
break;
|
||||
case KeyboardHotkeyState.ShowUi:
|
||||
_viewModel.ShowMenuAndStatusBar = true;
|
||||
_viewModel.ShowMenuAndStatusBar = !_viewModel.ShowMenuAndStatusBar;
|
||||
break;
|
||||
case KeyboardHotkeyState.Pause:
|
||||
if (_viewModel.IsPaused)
|
||||
|
@@ -123,7 +123,7 @@ namespace Ryujinx.Ava.UI.Renderer
|
||||
}
|
||||
else
|
||||
{
|
||||
X11Window = PlatformHelper.CreateOpenGLWindow(FramebufferFormat.Default, 0, 0, 100, 100) as GLXWindow;
|
||||
X11Window = PlatformHelper.CreateOpenGLWindow(new FramebufferFormat(new ColorFormat(8, 8, 8, 0), 16, 0, ColorFormat.Zero, 0, 2, false), 0, 0, 100, 100) as GLXWindow;
|
||||
}
|
||||
|
||||
WindowHandle = X11Window.WindowHandle.RawHandle;
|
||||
|
@@ -1,9 +1,11 @@
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.OpenGL;
|
||||
using Ryujinx.Ui.Common.Configuration;
|
||||
using SPB.Graphics;
|
||||
using SPB.Graphics.Exceptions;
|
||||
using SPB.Graphics.OpenGL;
|
||||
using SPB.Platform;
|
||||
using SPB.Platform.WGL;
|
||||
@@ -18,8 +20,6 @@ namespace Ryujinx.Ava.UI.Renderer
|
||||
|
||||
public OpenGLContextBase Context { get; set; }
|
||||
|
||||
public EmbeddedWindowOpenGL() { }
|
||||
|
||||
protected override void OnWindowDestroying()
|
||||
{
|
||||
Context.Dispose();
|
||||
@@ -62,14 +62,21 @@ namespace Ryujinx.Ava.UI.Renderer
|
||||
Context.MakeCurrent(null);
|
||||
}
|
||||
|
||||
public void MakeCurrent()
|
||||
public void MakeCurrent(bool unbind = false, bool shouldThrow = true)
|
||||
{
|
||||
Context?.MakeCurrent(_window);
|
||||
}
|
||||
try
|
||||
{
|
||||
Context?.MakeCurrent(!unbind ? _window : null);
|
||||
}
|
||||
catch (ContextException e)
|
||||
{
|
||||
if (shouldThrow)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
public void MakeCurrent(NativeWindowBase window)
|
||||
{
|
||||
Context?.MakeCurrent(window);
|
||||
Logger.Warning?.Print(LogClass.Ui, $"Failed to {(!unbind ? "bind" : "unbind")} OpenGL context: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
public void SwapBuffers()
|
||||
|
@@ -7,7 +7,7 @@ namespace Ryujinx.Common.Configuration.Hid
|
||||
// This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
|
||||
[Flags]
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<ControllerType>))]
|
||||
public enum ControllerType : int
|
||||
public enum ControllerType
|
||||
{
|
||||
None,
|
||||
ProController = 1 << 0,
|
||||
|
@@ -5,7 +5,7 @@ namespace Ryujinx.Common.Configuration.Hid
|
||||
{
|
||||
// This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<PlayerIndex>))]
|
||||
public enum PlayerIndex : int
|
||||
public enum PlayerIndex
|
||||
{
|
||||
Player1 = 0,
|
||||
Player2 = 1,
|
||||
|
@@ -24,6 +24,24 @@ namespace Ryujinx.Common.Memory
|
||||
return value;
|
||||
}
|
||||
|
||||
public bool TryRead<T>(out T value) where T : unmanaged
|
||||
{
|
||||
int valueSize = Unsafe.SizeOf<T>();
|
||||
|
||||
if (valueSize > _input.Length)
|
||||
{
|
||||
value = default;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
value = MemoryMarshal.Cast<byte, T>(_input)[0];
|
||||
|
||||
_input = _input.Slice(valueSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ReadOnlySpan<byte> GetSpan(int size)
|
||||
{
|
||||
ReadOnlySpan<byte> data = _input.Slice(0, size);
|
||||
|
@@ -56,7 +56,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||
private int _refConsumerPtr;
|
||||
|
||||
private Action _interruptAction;
|
||||
private object _interruptLock = new();
|
||||
private readonly object _interruptLock = new();
|
||||
|
||||
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;
|
||||
|
||||
|
@@ -78,7 +78,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
private List<BufferMigration> _sources;
|
||||
private BufferMigration _migrationTarget;
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
/// <summary>
|
||||
/// Whether the modified range list has any entries or not.
|
||||
@@ -125,7 +125,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
BufferModifiedRange overlap = overlaps[i];
|
||||
|
||||
|
||||
if (overlap.Address > address)
|
||||
{
|
||||
// The start of the remaining region is uncovered by this overlap. Call the action for it.
|
||||
|
@@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
||||
private ulong _accumulatedCounter;
|
||||
private int _waiterCount;
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
private Queue<BufferedQuery> _queryPool;
|
||||
private AutoResetEvent _queuedEvent = new AutoResetEvent(false);
|
||||
|
@@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
||||
private bool _hostAccessReserved = false;
|
||||
private int _refCount = 1; // Starts with a reference from the counter queue.
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
private ulong _result = ulong.MaxValue;
|
||||
private double _divisor = 1f;
|
||||
|
||||
|
@@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||
{
|
||||
private const int DisposedLiveFrames = 2;
|
||||
|
||||
private readonly object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
private readonly Dictionary<TextureCreateInfo, List<DisposedTexture>> _textures = new Dictionary<TextureCreateInfo, List<DisposedTexture>>();
|
||||
|
||||
/// <summary>
|
||||
|
@@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
{
|
||||
enum MVKConfigLogLevel : int
|
||||
enum MVKConfigLogLevel
|
||||
{
|
||||
None = 0,
|
||||
Error = 1,
|
||||
@@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
Debug = 4
|
||||
}
|
||||
|
||||
enum MVKConfigTraceVulkanCalls : int
|
||||
enum MVKConfigTraceVulkanCalls
|
||||
{
|
||||
None = 0,
|
||||
Enter = 1,
|
||||
@@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
Duration = 3
|
||||
}
|
||||
|
||||
enum MVKConfigAutoGPUCaptureScope : int
|
||||
enum MVKConfigAutoGPUCaptureScope
|
||||
{
|
||||
None = 0,
|
||||
Device = 1,
|
||||
@@ -28,7 +28,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
}
|
||||
|
||||
[Flags]
|
||||
enum MVKConfigAdvertiseExtensions : int
|
||||
enum MVKConfigAdvertiseExtensions
|
||||
{
|
||||
All = 0x00000001,
|
||||
MoltenVK = 0x00000002,
|
||||
@@ -36,7 +36,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
Portability = 0x00000008
|
||||
}
|
||||
|
||||
enum MVKVkSemaphoreSupportStyle : int
|
||||
enum MVKVkSemaphoreSupportStyle
|
||||
{
|
||||
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE = 0,
|
||||
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE = 1,
|
||||
|
@@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
private ulong _accumulatedCounter;
|
||||
private int _waiterCount;
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
private Queue<BufferedQuery> _queryPool;
|
||||
private AutoResetEvent _queuedEvent = new AutoResetEvent(false);
|
||||
|
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
private bool _hostAccessReserved = false;
|
||||
private int _refCount = 1; // Starts with a reference from the counter queue.
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
private ulong _result = ulong.MaxValue;
|
||||
private double _divisor = 1f;
|
||||
|
||||
|
@@ -60,7 +60,7 @@ namespace Ryujinx.HLE.HOS.Applets
|
||||
private bool _canAcceptController = false;
|
||||
private KeyboardInputMode _inputMode = KeyboardInputMode.ControllerAndKeyboard;
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
public event EventHandler AppletStateChanged;
|
||||
|
||||
|
@@ -13,7 +13,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
||||
private const int TextBoxBlinkSleepMilliseconds = 100;
|
||||
private const int RendererWaitTimeoutMilliseconds = 100;
|
||||
|
||||
private readonly object _stateLock = new object();
|
||||
private readonly object _stateLock = new();
|
||||
|
||||
private SoftwareKeyboardUiState _state = new SoftwareKeyboardUiState();
|
||||
private SoftwareKeyboardRendererBase _renderer;
|
||||
|
@@ -26,7 +26,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
||||
const string CancelText = "Cancel";
|
||||
const string ControllerToggleText = "Toggle input";
|
||||
|
||||
private readonly object _bufferLock = new object();
|
||||
private readonly object _bufferLock = new();
|
||||
|
||||
private RenderingSurfaceInfo _surfaceInfo = null;
|
||||
private Image<Argb32> _surface = null;
|
||||
@@ -311,7 +311,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
||||
private static RectangleF MeasureString(ReadOnlySpan<char> text, Font font)
|
||||
{
|
||||
RendererOptions options = new RendererOptions(font);
|
||||
|
||||
|
||||
if (text == "")
|
||||
{
|
||||
FontRectangle emptyRectangle = TextMeasurer.Measure(" ", options);
|
||||
|
@@ -26,8 +26,8 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
|
||||
}
|
||||
|
||||
private TRef<bool> _cancelled = null;
|
||||
private Thread _thread = null;
|
||||
private object _lock = new object();
|
||||
private Thread _thread = null;
|
||||
private readonly object _lock = new();
|
||||
|
||||
public bool IsRunning
|
||||
{
|
||||
|
@@ -40,8 +40,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
|
||||
public ProcessState State { get; private set; }
|
||||
|
||||
private object _processLock;
|
||||
private object _threadingLock;
|
||||
private readonly object _processLock = new();
|
||||
private readonly object _threadingLock = new();
|
||||
|
||||
public KAddressArbiter AddressArbiter { get; private set; }
|
||||
|
||||
@@ -94,9 +94,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
|
||||
public KProcess(KernelContext context, bool allowCodeMemoryForJit = false) : base(context)
|
||||
{
|
||||
_processLock = new object();
|
||||
_threadingLock = new object();
|
||||
|
||||
AddressArbiter = new KAddressArbiter(context);
|
||||
|
||||
_fullTlsPages = new SortedDictionary<ulong, KTlsPageInfo>();
|
||||
|
@@ -112,7 +112,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
|
||||
public bool WaitingInArbitration { get; set; }
|
||||
|
||||
private object _activityOperationLock;
|
||||
private readonly object _activityOperationLock = new();
|
||||
|
||||
public KThread(KernelContext context) : base(context)
|
||||
{
|
||||
@@ -123,8 +123,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
|
||||
_mutexWaiters = new LinkedList<KThread>();
|
||||
_pinnedWaiters = new LinkedList<KThread>();
|
||||
|
||||
_activityOperationLock = new object();
|
||||
}
|
||||
|
||||
public Result Initialize(
|
||||
|
@@ -154,7 +154,7 @@ namespace Ryujinx.HLE.HOS
|
||||
}
|
||||
|
||||
private static DirectoryInfo FindTitleDir(DirectoryInfo contentsDir, string titleId)
|
||||
=> contentsDir.EnumerateDirectories($"{titleId}*", DirEnumOptions).FirstOrDefault();
|
||||
=> contentsDir.EnumerateDirectories(titleId, DirEnumOptions).FirstOrDefault();
|
||||
|
||||
private static void AddModsFromDirectory(ModCache mods, DirectoryInfo dir, string titleId)
|
||||
{
|
||||
|
@@ -17,8 +17,8 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
|
||||
private KEvent _accumulatedSuspendedTickChangedEvent;
|
||||
private int _accumulatedSuspendedTickChangedEventHandle;
|
||||
|
||||
private object _fatalSectionLock = new object();
|
||||
private int _fatalSectionCount;
|
||||
private readonly object _fatalSectionLock = new();
|
||||
private int _fatalSectionCount;
|
||||
|
||||
// TODO: Set this when the game goes in suspension (go back to home menu ect), we currently don't support that so we can keep it set to 0.
|
||||
private ulong _accumulatedSuspendedTickValue = 0;
|
||||
@@ -429,4 +429,4 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
|
||||
return ResultCode.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@ namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator
|
||||
private readonly UserId _userId;
|
||||
private readonly FriendServicePermissionLevel _permissionLevel;
|
||||
|
||||
private readonly object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
private KEvent _notificationEvent;
|
||||
private int _notificationEventHandle = 0;
|
||||
|
@@ -1,8 +1,29 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Logging;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
{
|
||||
[Service("hidbus")]
|
||||
class IHidbusServer : IpcService
|
||||
{
|
||||
public IHidbusServer(ServiceCtx context) { }
|
||||
|
||||
[CommandCmif(1)]
|
||||
// GetBusHandle(nn::hid::NpadIdType, nn::hidbus::BusType, nn::applet::AppletResourceUserId) -> (bool HasHandle, nn::hidbus::BusHandle)
|
||||
public ResultCode GetBusHandle(ServiceCtx context)
|
||||
{
|
||||
NpadIdType npadIdType = (NpadIdType)context.RequestData.ReadInt32();
|
||||
context.RequestData.BaseStream.Position += 4; // Padding
|
||||
BusType busType = (BusType)context.RequestData.ReadInt64();
|
||||
long appletResourceUserId = context.RequestData.ReadInt64();
|
||||
|
||||
context.ResponseData.Write(false);
|
||||
context.ResponseData.BaseStream.Position += 7; // Padding
|
||||
context.ResponseData.WriteStruct(new BusHandle());
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { npadIdType, busType, appletResourceUserId });
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
}
|
||||
}
|
14
src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs
Normal file
14
src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct BusHandle
|
||||
{
|
||||
public int AbstractedPadId;
|
||||
public byte InternalIndex;
|
||||
public byte PlayerNumber;
|
||||
public byte BusTypeId;
|
||||
public byte IsValid;
|
||||
}
|
||||
}
|
9
src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs
Normal file
9
src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
{
|
||||
public enum BusType : long
|
||||
{
|
||||
LeftJoyRail = 0,
|
||||
RightJoyRail = 1,
|
||||
InternalBus = 2
|
||||
}
|
||||
}
|
@@ -3,7 +3,7 @@ using System;
|
||||
namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
{
|
||||
[Flags]
|
||||
public enum ControllerType : int
|
||||
public enum ControllerType
|
||||
{
|
||||
None,
|
||||
ProController = 1 << 0,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
{
|
||||
public enum NpadIdType : int
|
||||
public enum NpadIdType
|
||||
{
|
||||
Player1 = 0,
|
||||
Player2 = 1,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Hid
|
||||
{
|
||||
public enum PlayerIndex : int
|
||||
public enum PlayerIndex
|
||||
{
|
||||
Player1 = 0,
|
||||
Player2 = 1,
|
||||
|
@@ -3,7 +3,7 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad
|
||||
{
|
||||
[Flags]
|
||||
enum DeviceType : int
|
||||
enum DeviceType
|
||||
{
|
||||
None = 0,
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad
|
||||
{
|
||||
enum NpadBatteryLevel : int
|
||||
enum NpadBatteryLevel
|
||||
{
|
||||
Percent0,
|
||||
Percent25,
|
||||
|
@@ -775,7 +775,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii.Types
|
||||
|
||||
private static ReadOnlySpan<ElementInfo> ElementInfos => MemoryMarshal.Cast<byte, ElementInfo>(ElementInfoArray);
|
||||
|
||||
private enum ElementInfoIndex : int
|
||||
private enum ElementInfoIndex
|
||||
{
|
||||
HairType,
|
||||
Height,
|
||||
|
@@ -21,7 +21,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii.Types
|
||||
};
|
||||
|
||||
[Flags]
|
||||
public enum BeardAndMustacheFlag : int
|
||||
public enum BeardAndMustacheFlag
|
||||
{
|
||||
Beard = 1,
|
||||
Mustache
|
||||
|
@@ -1,6 +1,6 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Mii.Types
|
||||
{
|
||||
enum Source : int
|
||||
enum Source
|
||||
{
|
||||
Database,
|
||||
Default
|
||||
|
@@ -3,7 +3,7 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Mii.Types
|
||||
{
|
||||
[Flags]
|
||||
enum SourceFlag : int
|
||||
enum SourceFlag
|
||||
{
|
||||
Database = 1 << Source.Database,
|
||||
Default = 1 << Source.Default,
|
||||
|
@@ -24,7 +24,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl
|
||||
private NvFence _previousFailingFence;
|
||||
private uint _failingCount;
|
||||
|
||||
public readonly object Lock = new object();
|
||||
public readonly object Lock = new();
|
||||
|
||||
/// <summary>
|
||||
/// Max failing count until waiting on CPU.
|
||||
|
@@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl
|
||||
|
||||
private Switch _device;
|
||||
|
||||
private object _syncpointAllocatorLock = new object();
|
||||
private readonly object _syncpointAllocatorLock = new();
|
||||
|
||||
public NvHostSyncpt(Switch device)
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices
|
||||
{
|
||||
enum NvInternalResult : int
|
||||
enum NvInternalResult
|
||||
{
|
||||
Success = 0,
|
||||
OperationNotPermitted = -1,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
|
||||
{
|
||||
enum NvMapHandleParam : int
|
||||
enum NvMapHandleParam
|
||||
{
|
||||
Size = 1,
|
||||
Align = 2,
|
||||
|
@@ -10,7 +10,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||
{
|
||||
private static ConcurrentDictionary<ulong, BsdContext> _registry = new ConcurrentDictionary<ulong, BsdContext>();
|
||||
|
||||
private readonly object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
private List<IFileDescriptor> _fds;
|
||||
|
||||
|
@@ -5,7 +5,7 @@ using System.Net.Sockets;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||
{
|
||||
interface ISocket : IDisposable, IFileDescriptor
|
||||
interface ISocket : IFileDescriptor
|
||||
{
|
||||
IPEndPoint RemoteEndPoint { get; }
|
||||
IPEndPoint LocalEndPoint { get; }
|
||||
|
@@ -10,7 +10,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl
|
||||
private ulong _value;
|
||||
private readonly EventFdFlags _flags;
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
public bool Blocking { get => !_flags.HasFlag(EventFdFlags.NonBlocking); set => throw new NotSupportedException(); }
|
||||
|
||||
|
@@ -7,7 +7,7 @@ namespace Ryujinx.HLE.HOS.Services.Spl
|
||||
{
|
||||
private RandomNumberGenerator _rng;
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
public IRandomInterface(ServiceCtx context)
|
||||
{
|
||||
|
@@ -40,13 +40,13 @@ namespace Ryujinx.HLE.HOS.Services.Ssl
|
||||
}
|
||||
}
|
||||
|
||||
private VirtualFileSystem _virtualFileSystem;
|
||||
private VirtualFileSystem _virtualFileSystem;
|
||||
private IntegrityCheckLevel _fsIntegrityCheckLevel;
|
||||
private ContentManager _contentManager;
|
||||
private bool _initialized;
|
||||
private ContentManager _contentManager;
|
||||
private bool _initialized;
|
||||
private Dictionary<CaCertificateId, CertStoreEntry> _certificates;
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
private struct CertStoreFileHeader
|
||||
{
|
||||
|
@@ -34,7 +34,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
public bool EnableExternalEvent;
|
||||
public int MaxBufferCountCached;
|
||||
|
||||
public readonly object Lock = new object();
|
||||
public readonly object Lock = new();
|
||||
|
||||
private KEvent _waitBufferFreeEvent;
|
||||
private KEvent _frameAvailableEvent;
|
||||
|
@@ -21,7 +21,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
private uint _currentCallbackTicket;
|
||||
private uint _callbackTicket;
|
||||
|
||||
private readonly object _callbackLock = new object();
|
||||
private readonly object _callbackLock = new();
|
||||
|
||||
public BufferQueueProducer(BufferQueueCore core, ITickSource tickSource)
|
||||
{
|
||||
|
@@ -23,7 +23,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
|
||||
protected BufferQueueConsumer Consumer;
|
||||
|
||||
protected readonly object Lock = new object();
|
||||
protected readonly object Lock = new();
|
||||
|
||||
private IConsumerListener _listener;
|
||||
|
||||
@@ -168,7 +168,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
|
||||
Slot slot = Slots[slotIndex];
|
||||
|
||||
// TODO: Check this. On Android, this checks the "handle". I assume NvMapHandle is the handle, but it might not be.
|
||||
// TODO: Check this. On Android, this checks the "handle". I assume NvMapHandle is the handle, but it might not be.
|
||||
return !slot.GraphicBuffer.IsNull && slot.GraphicBuffer.Object.Buffer.Surfaces[0].NvMapHandle == graphicBuffer.Object.Buffer.Surfaces[0].NvMapHandle;
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
{
|
||||
enum NativeWindowApi : int
|
||||
enum NativeWindowApi
|
||||
{
|
||||
NoApi = 0,
|
||||
NVN = 1,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
{
|
||||
enum Status : int
|
||||
enum Status
|
||||
{
|
||||
Success = 0,
|
||||
WouldBlock = -11,
|
||||
|
@@ -37,7 +37,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
private int _swapInterval;
|
||||
private int _swapIntervalDelay;
|
||||
|
||||
private readonly object Lock = new object();
|
||||
private readonly object Lock = new();
|
||||
|
||||
public long RenderLayerId { get; private set; }
|
||||
|
||||
|
@@ -13,14 +13,13 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
||||
private UInt128 _timeZoneRuleVersion;
|
||||
private uint _totalLocationNameCount;
|
||||
private SteadyClockTimePoint _timeZoneUpdateTimePoint;
|
||||
private object _lock;
|
||||
private readonly object _lock = new();
|
||||
|
||||
public TimeZoneManager()
|
||||
{
|
||||
_isInitialized = false;
|
||||
_deviceLocationName = "UTC";
|
||||
_timeZoneRuleVersion = new UInt128();
|
||||
_lock = new object();
|
||||
_myRules = new Box<TimeZoneRule>();
|
||||
|
||||
_timeZoneUpdateTimePoint = SteadyClockTimePoint.GetRandom();
|
||||
|
@@ -17,7 +17,7 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
||||
private const int MessageLengthLimit = 5000;
|
||||
|
||||
private readonly LogService _log;
|
||||
private readonly ulong _pid;
|
||||
private readonly ulong _pid;
|
||||
|
||||
private LogPacket _logPacket;
|
||||
|
||||
@@ -74,8 +74,12 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
||||
|
||||
private bool LogImpl(ReadOnlySpan<byte> message)
|
||||
{
|
||||
SpanReader reader = new(message);
|
||||
LogPacketHeader header = reader.Read<LogPacketHeader>();
|
||||
SpanReader reader = new(message);
|
||||
|
||||
if (!reader.TryRead(out LogPacketHeader header))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isHeadPacket = (header.Flags & LogPacketFlags.IsHead) != 0;
|
||||
bool isTailPacket = (header.Flags & LogPacketFlags.IsTail) != 0;
|
||||
@@ -84,8 +88,10 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
||||
|
||||
while (reader.Length > 0)
|
||||
{
|
||||
int type = ReadUleb128(ref reader);
|
||||
int size = ReadUleb128(ref reader);
|
||||
if (!TryReadUleb128(ref reader, out int type) || !TryReadUleb128(ref reader, out int size))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
LogDataChunkKey key = (LogDataChunkKey)type;
|
||||
|
||||
@@ -101,15 +107,24 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
||||
}
|
||||
else if (key == LogDataChunkKey.Line)
|
||||
{
|
||||
_logPacket.Line = reader.Read<int>();
|
||||
if (!reader.TryRead<int>(out _logPacket.Line))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (key == LogDataChunkKey.DropCount)
|
||||
{
|
||||
_logPacket.DropCount = reader.Read<long>();
|
||||
if (!reader.TryRead<long>(out _logPacket.DropCount))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (key == LogDataChunkKey.Time)
|
||||
{
|
||||
_logPacket.Time = reader.Read<long>();
|
||||
if (!reader.TryRead<long>(out _logPacket.Time))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (key == LogDataChunkKey.Message)
|
||||
{
|
||||
@@ -154,23 +169,25 @@ namespace Ryujinx.Horizon.LogManager.Ipc
|
||||
return isTailPacket;
|
||||
}
|
||||
|
||||
private static int ReadUleb128(ref SpanReader reader)
|
||||
private static bool TryReadUleb128(ref SpanReader reader, out int result)
|
||||
{
|
||||
int result = 0;
|
||||
int count = 0;
|
||||
|
||||
result = 0;
|
||||
int count = 0;
|
||||
byte encoded;
|
||||
|
||||
do
|
||||
{
|
||||
encoded = reader.Read<byte>();
|
||||
if (!reader.TryRead<byte>(out encoded))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
result += (encoded & 0x7F) << (7 * count);
|
||||
|
||||
count++;
|
||||
} while ((encoded & 0x80) != 0);
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -13,7 +13,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
|
||||
|
||||
private readonly List<MultiWaitHolderBase> _multiWaits;
|
||||
|
||||
private object _lock;
|
||||
private readonly object _lock = new();
|
||||
|
||||
private int _waitingThreadHandle;
|
||||
|
||||
@@ -24,8 +24,6 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
|
||||
public MultiWaitImpl()
|
||||
{
|
||||
_multiWaits = new List<MultiWaitHolderBase>();
|
||||
|
||||
_lock = new object();
|
||||
}
|
||||
|
||||
public void LinkMultiWaitHolder(MultiWaitHolderBase multiWaitHolder)
|
||||
|
@@ -46,7 +46,7 @@ namespace Ryujinx.Input.SDL2
|
||||
SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_PADDLE2,
|
||||
SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_PADDLE3,
|
||||
SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_PADDLE4,
|
||||
SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_TOUCHPAD,
|
||||
SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_TOUCHPAD,
|
||||
|
||||
// Virtual buttons are invalid, ignored.
|
||||
SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_INVALID,
|
||||
@@ -55,7 +55,7 @@ namespace Ryujinx.Input.SDL2
|
||||
SDL_GameControllerButton.SDL_CONTROLLER_BUTTON_INVALID,
|
||||
};
|
||||
|
||||
private object _userMappingLock = new object();
|
||||
private readonly object _userMappingLock = new();
|
||||
|
||||
private List<ButtonMappingEntry> _buttonsUserMapping;
|
||||
|
||||
|
@@ -24,7 +24,7 @@ namespace Ryujinx.Input.SDL2
|
||||
}
|
||||
}
|
||||
|
||||
private object _userMappingLock = new object();
|
||||
private readonly object _userMappingLock = new();
|
||||
|
||||
private readonly SDL2KeyboardDriver _driver;
|
||||
private StandardKeyboardInputConfig _configuration;
|
||||
|
@@ -15,7 +15,7 @@ namespace Ryujinx.Input.HLE
|
||||
{
|
||||
private CemuHookClient _cemuHookClient;
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
private bool _blockInputUpdates;
|
||||
|
||||
@@ -271,7 +271,7 @@ namespace Ryujinx.Input.HLE
|
||||
|
||||
_device.Hid.Mouse.Update((int)position.X, (int)position.Y, buttons, (int)mouseInput.Scroll.X, (int)mouseInput.Scroll.Y, true);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
_device.Hid.Mouse.Update(0, 0);
|
||||
}
|
||||
|
@@ -52,7 +52,7 @@ namespace Ryujinx.Memory.Tracking
|
||||
|
||||
private event Action _onDirty;
|
||||
|
||||
private object _preActionLock = new object();
|
||||
private readonly object _preActionLock = new();
|
||||
private RegionSignal _preAction; // Action to perform before a read or write. This will block the memory access.
|
||||
private PreciseRegionSignal _preciseAction; // Action to perform on a precise read or write.
|
||||
private readonly List<VirtualRegion> _regions;
|
||||
|
@@ -41,7 +41,7 @@ namespace Ryujinx.SDL2.Common
|
||||
|
||||
private ConcurrentDictionary<uint, Action<SDL_Event>> _registeredWindowHandlers;
|
||||
|
||||
private object _lock = new object();
|
||||
private readonly object _lock = new();
|
||||
|
||||
private SDL2Driver() {}
|
||||
|
||||
|
@@ -7,7 +7,7 @@ namespace Ryujinx.Tests.Memory
|
||||
{
|
||||
public class Tests
|
||||
{
|
||||
private const ulong MemorySize = 0x8000;
|
||||
private static readonly ulong MemorySize = MemoryBlock.GetPageSize() * 8;
|
||||
|
||||
private MemoryBlock _memoryBlock;
|
||||
|
||||
@@ -44,14 +44,17 @@ namespace Ryujinx.Tests.Memory
|
||||
[Platform(Exclude = "MacOsX")]
|
||||
public void Test_Alias()
|
||||
{
|
||||
using MemoryBlock backing = new MemoryBlock(0x10000, MemoryAllocationFlags.Mirrorable);
|
||||
using MemoryBlock toAlias = new MemoryBlock(0x10000, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
|
||||
ulong pageSize = MemoryBlock.GetPageSize();
|
||||
ulong blockSize = MemoryBlock.GetPageSize() * 16;
|
||||
|
||||
toAlias.MapView(backing, 0x1000, 0, 0x4000);
|
||||
toAlias.UnmapView(backing, 0x3000, 0x1000);
|
||||
using MemoryBlock backing = new MemoryBlock(blockSize, MemoryAllocationFlags.Mirrorable);
|
||||
using MemoryBlock toAlias = new MemoryBlock(blockSize, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
|
||||
|
||||
toAlias.MapView(backing, pageSize, 0, pageSize * 4);
|
||||
toAlias.UnmapView(backing, pageSize * 3, pageSize);
|
||||
|
||||
toAlias.Write(0, 0xbadc0de);
|
||||
Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, 0x1000), 0xbadc0de);
|
||||
Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (int)pageSize), 0xbadc0de);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -59,8 +62,12 @@ namespace Ryujinx.Tests.Memory
|
||||
[Platform(Exclude = "MacOsX")]
|
||||
public void Test_AliasRandom()
|
||||
{
|
||||
using MemoryBlock backing = new MemoryBlock(0x80000, MemoryAllocationFlags.Mirrorable);
|
||||
using MemoryBlock toAlias = new MemoryBlock(0x80000, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
|
||||
ulong pageSize = MemoryBlock.GetPageSize();
|
||||
int pageBits = (int)ulong.Log2(pageSize);
|
||||
ulong blockSize = MemoryBlock.GetPageSize() * 128;
|
||||
|
||||
using MemoryBlock backing = new MemoryBlock(blockSize, MemoryAllocationFlags.Mirrorable);
|
||||
using MemoryBlock toAlias = new MemoryBlock(blockSize, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
|
||||
|
||||
Random rng = new Random(123);
|
||||
|
||||
@@ -72,16 +79,16 @@ namespace Ryujinx.Tests.Memory
|
||||
|
||||
if ((rng.Next() & 1) != 0)
|
||||
{
|
||||
toAlias.MapView(backing, (ulong)srcPage << 12, (ulong)dstPage << 12, (ulong)pages << 12);
|
||||
toAlias.MapView(backing, (ulong)srcPage << pageBits, (ulong)dstPage << pageBits, (ulong)pages << pageBits);
|
||||
|
||||
int offset = rng.Next(0, 0x1000 - sizeof(int));
|
||||
int offset = rng.Next(0, (int)pageSize - sizeof(int));
|
||||
|
||||
toAlias.Write((ulong)((dstPage << 12) + offset), 0xbadc0de);
|
||||
Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (srcPage << 12) + offset), 0xbadc0de);
|
||||
toAlias.Write((ulong)((dstPage << pageBits) + offset), 0xbadc0de);
|
||||
Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (srcPage << pageBits) + offset), 0xbadc0de);
|
||||
}
|
||||
else
|
||||
{
|
||||
toAlias.UnmapView(backing, (ulong)dstPage << 12, (ulong)pages << 12);
|
||||
toAlias.UnmapView(backing, (ulong)dstPage << pageBits, (ulong)pages << pageBits);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,7 +98,7 @@ namespace Ryujinx.Tests.Memory
|
||||
[Platform(Exclude = "MacOsX")]
|
||||
public void Test_AliasMapLeak()
|
||||
{
|
||||
ulong pageSize = 4096;
|
||||
ulong pageSize = MemoryBlock.GetPageSize();
|
||||
ulong size = 100000 * pageSize; // The mappings limit on Linux is usually around 65K, so let's make sure we are above that.
|
||||
|
||||
using MemoryBlock backing = new MemoryBlock(pageSize, MemoryAllocationFlags.Mirrorable);
|
||||
|
@@ -13,9 +13,9 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestFixture]
|
||||
public class CpuTest
|
||||
{
|
||||
protected const ulong Size = 0x1000;
|
||||
protected const ulong CodeBaseAddress = 0x1000;
|
||||
protected const ulong DataBaseAddress = CodeBaseAddress + Size;
|
||||
protected static readonly ulong Size = MemoryBlock.GetPageSize();
|
||||
protected static ulong CodeBaseAddress = Size;
|
||||
protected static ulong DataBaseAddress = CodeBaseAddress + Size;
|
||||
|
||||
private static bool Ignore_FpcrFz = false;
|
||||
private static bool Ignore_FpcrDn = false;
|
||||
@@ -39,12 +39,24 @@ namespace Ryujinx.Tests.Cpu
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_currAddress = CodeBaseAddress;
|
||||
int pageBits = (int)ulong.Log2(Size);
|
||||
|
||||
_ram = new MemoryBlock(Size * 2);
|
||||
_memory = new MemoryManager(_ram, 1ul << 16);
|
||||
_memory = new MemoryManager(_ram, 1ul << (pageBits + 4));
|
||||
_memory.IncrementReferenceCount();
|
||||
_memory.Map(CodeBaseAddress, 0, Size * 2, MemoryMapFlags.Private);
|
||||
|
||||
// Some tests depends on hardcoded address that were computed for 4KiB.
|
||||
// We change the layout on non 4KiB platforms to keep compat here.
|
||||
if (Size > 0x1000)
|
||||
{
|
||||
DataBaseAddress = 0;
|
||||
CodeBaseAddress = Size;
|
||||
}
|
||||
|
||||
_currAddress = CodeBaseAddress;
|
||||
|
||||
_memory.Map(CodeBaseAddress, 0, Size, MemoryMapFlags.Private);
|
||||
_memory.Map(DataBaseAddress, Size, Size, MemoryMapFlags.Private);
|
||||
|
||||
_context = CpuContext.CreateExecutionContext();
|
||||
Translator.IsReadyForTranslation.Set();
|
||||
|
@@ -13,9 +13,9 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestFixture]
|
||||
public class CpuTest32
|
||||
{
|
||||
protected const uint Size = 0x1000;
|
||||
protected const uint CodeBaseAddress = 0x1000;
|
||||
protected const uint DataBaseAddress = CodeBaseAddress + Size;
|
||||
protected static readonly uint Size = (uint)MemoryBlock.GetPageSize();
|
||||
protected static uint CodeBaseAddress = Size;
|
||||
protected static uint DataBaseAddress = CodeBaseAddress + Size;
|
||||
|
||||
private uint _currAddress;
|
||||
|
||||
@@ -33,12 +33,24 @@ namespace Ryujinx.Tests.Cpu
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_currAddress = CodeBaseAddress;
|
||||
int pageBits = (int)ulong.Log2(Size);
|
||||
|
||||
_ram = new MemoryBlock(Size * 2);
|
||||
_memory = new MemoryManager(_ram, 1ul << 16);
|
||||
_memory = new MemoryManager(_ram, 1ul << (pageBits + 4));
|
||||
_memory.IncrementReferenceCount();
|
||||
_memory.Map(CodeBaseAddress, 0, Size * 2, MemoryMapFlags.Private);
|
||||
|
||||
// Some tests depends on hardcoded address that were computed for 4KiB.
|
||||
// We change the layout on non 4KiB platforms to keep compat here.
|
||||
if (Size > 0x1000)
|
||||
{
|
||||
DataBaseAddress = 0;
|
||||
CodeBaseAddress = Size;
|
||||
}
|
||||
|
||||
_currAddress = CodeBaseAddress;
|
||||
|
||||
_memory.Map(CodeBaseAddress, 0, Size, MemoryMapFlags.Private);
|
||||
_memory.Map(DataBaseAddress, Size, Size, MemoryMapFlags.Private);
|
||||
|
||||
_context = CpuContext.CreateExecutionContext();
|
||||
_context.IsAarch32 = true;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#define SimdMemory32
|
||||
|
||||
using ARMeilleure.State;
|
||||
using Ryujinx.Memory;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
|
||||
@@ -9,6 +10,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
[Category("SimdMemory32")]
|
||||
public sealed class CpuTestSimdMemory32 : CpuTest32
|
||||
{
|
||||
private static readonly uint TestOffset = DataBaseAddress + 0x500;
|
||||
#if SimdMemory32
|
||||
|
||||
private uint[] _ldStModes =
|
||||
@@ -42,7 +44,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
[Range(0u, 3u)] uint n,
|
||||
[Values(0x0u)] uint offset)
|
||||
{
|
||||
var data = GenerateVectorSequence(0x1000);
|
||||
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
|
||||
SetWorkingMemory(0, data);
|
||||
|
||||
uint opcode = 0xf4a00000u; // VLD1.8 {D0[0]}, [R0], R0
|
||||
@@ -58,7 +60,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
|
||||
opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc.
|
||||
|
||||
SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500);
|
||||
SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset);
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
@@ -72,7 +74,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
[Values] bool t,
|
||||
[Values(0x0u)] uint offset)
|
||||
{
|
||||
var data = GenerateVectorSequence(0x1000);
|
||||
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
|
||||
SetWorkingMemory(0, data);
|
||||
|
||||
uint opcode = 0xf4a00c00u; // VLD1.8 {D0[0]}, [R0], R0
|
||||
@@ -85,7 +87,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc.
|
||||
if (t) opcode |= 1 << 5;
|
||||
|
||||
SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500);
|
||||
SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset);
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
@@ -98,7 +100,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
[Range(0u, 10u)] uint mode,
|
||||
[Values(0x0u)] uint offset)
|
||||
{
|
||||
var data = GenerateVectorSequence(0x1000);
|
||||
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
|
||||
SetWorkingMemory(0, data);
|
||||
|
||||
uint opcode = 0xf4200000u; // VLD4.8 {D0, D1, D2, D3}, [R0], R0
|
||||
@@ -114,7 +116,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
opcode |= ((vd & 0x10) << 18);
|
||||
opcode |= ((vd & 0xf) << 12);
|
||||
|
||||
SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500);
|
||||
SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset);
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
@@ -128,7 +130,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
[Range(0u, 3u)] uint n,
|
||||
[Values(0x0u)] uint offset)
|
||||
{
|
||||
var data = GenerateVectorSequence(0x1000);
|
||||
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
|
||||
SetWorkingMemory(0, data);
|
||||
|
||||
(V128 vec1, V128 vec2, V128 vec3, V128 vec4) = GenerateTestVectors();
|
||||
@@ -146,7 +148,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
|
||||
opcode |= (n & 3) << 8; // ST1 is 0, ST2 is 1 etc.
|
||||
|
||||
SingleOpcode(opcode, r0: 0x2500, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: 0x2500);
|
||||
SingleOpcode(opcode, r0: TestOffset, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: TestOffset);
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
@@ -159,7 +161,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
[Range(0u, 10u)] uint mode,
|
||||
[Values(0x0u)] uint offset)
|
||||
{
|
||||
var data = GenerateVectorSequence(0x1000);
|
||||
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
|
||||
SetWorkingMemory(0, data);
|
||||
|
||||
(V128 vec1, V128 vec2, V128 vec3, V128 vec4) = GenerateTestVectors();
|
||||
@@ -177,7 +179,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
opcode |= ((vd & 0x10) << 18);
|
||||
opcode |= ((vd & 0xf) << 12);
|
||||
|
||||
SingleOpcode(opcode, r0: 0x2500, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: 0x2500);
|
||||
SingleOpcode(opcode, r0: TestOffset, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: TestOffset);
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
@@ -189,7 +191,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
[Values(0x1u, 0x32u)] uint regs,
|
||||
[Values] bool single)
|
||||
{
|
||||
var data = GenerateVectorSequence(0x1000);
|
||||
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
|
||||
SetWorkingMemory(0, data);
|
||||
|
||||
uint opcode = 0xec100a00u; // VST4.8 {D0, D1, D2, D3}, [R0], R0
|
||||
@@ -225,7 +227,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
|
||||
opcode |= regs & 0xff;
|
||||
|
||||
SingleOpcode(opcode, r0: 0x2500, sp: 0x2500);
|
||||
SingleOpcode(opcode, r0: TestOffset, sp: TestOffset);
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
@@ -237,7 +239,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
[Values(0x0u)] uint imm,
|
||||
[Values] bool sub)
|
||||
{
|
||||
var data = GenerateVectorSequence(0x1000);
|
||||
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
|
||||
SetWorkingMemory(0, data);
|
||||
|
||||
uint opcode = 0xed900a00u; // VLDR.32 S0, [R0, #0]
|
||||
@@ -260,7 +262,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
}
|
||||
opcode |= imm & 0xff;
|
||||
|
||||
SingleOpcode(opcode, r0: 0x2500);
|
||||
SingleOpcode(opcode, r0: TestOffset);
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
@@ -272,7 +274,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
[Values(0x0u)] uint imm,
|
||||
[Values] bool sub)
|
||||
{
|
||||
var data = GenerateVectorSequence(0x1000);
|
||||
var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
|
||||
SetWorkingMemory(0, data);
|
||||
|
||||
uint opcode = 0xed800a00u; // VSTR.32 S0, [R0, #0]
|
||||
@@ -297,7 +299,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
|
||||
(V128 vec1, V128 vec2, _, _) = GenerateTestVectors();
|
||||
|
||||
SingleOpcode(opcode, r0: 0x2500, v0: vec1, v1: vec2);
|
||||
SingleOpcode(opcode, r0: TestOffset, v0: vec1, v1: vec2);
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user