diff --git a/.github/assign/audio.yml b/.github/assign/audio.yml
new file mode 100644
index 000000000..337007d39
--- /dev/null
+++ b/.github/assign/audio.yml
@@ -0,0 +1,8 @@
+addReviewers: true
+
+reviewers:
+ - marysaka
+
+filterLabels:
+ include:
+ - audio
\ No newline at end of file
diff --git a/.github/assign/cpu.yml b/.github/assign/cpu.yml
new file mode 100644
index 000000000..da824bdc3
--- /dev/null
+++ b/.github/assign/cpu.yml
@@ -0,0 +1,11 @@
+addReviewers: true
+
+reviewers:
+ - gdkchan
+ - riperiperi
+ - marysaka
+ - LDj3SNuD
+
+filterLabels:
+ include:
+ - cpu
\ No newline at end of file
diff --git a/.github/assign/global.yml b/.github/assign/global.yml
new file mode 100644
index 000000000..53a9af429
--- /dev/null
+++ b/.github/assign/global.yml
@@ -0,0 +1,4 @@
+addReviewers: true
+
+reviewers:
+ - Ryujinx/developers
\ No newline at end of file
diff --git a/.github/assign/gpu.yml b/.github/assign/gpu.yml
new file mode 100644
index 000000000..b96d9d87d
--- /dev/null
+++ b/.github/assign/gpu.yml
@@ -0,0 +1,10 @@
+addReviewers: true
+
+reviewers:
+ - gdkchan
+ - riperiperi
+ - marysaka
+
+filterLabels:
+ include:
+ - gpu
\ No newline at end of file
diff --git a/.github/assign/gui.yml b/.github/assign/gui.yml
new file mode 100644
index 000000000..9731ea5bd
--- /dev/null
+++ b/.github/assign/gui.yml
@@ -0,0 +1,11 @@
+addReviewers: true
+
+reviewers:
+ - Ack77
+ - emmauss
+ - TSRBerry
+ - marysaka
+
+filterLabels:
+ include:
+ - gui
\ No newline at end of file
diff --git a/.github/assign/horizon.yml b/.github/assign/horizon.yml
new file mode 100644
index 000000000..966382b29
--- /dev/null
+++ b/.github/assign/horizon.yml
@@ -0,0 +1,11 @@
+addReviewers: true
+
+reviewers:
+ - gdkchan
+ - Ack77
+ - marysaka
+ - TSRBerry
+
+filterLabels:
+ include:
+ - horizon
\ No newline at end of file
diff --git a/.github/assign/infra.yml b/.github/assign/infra.yml
new file mode 100644
index 000000000..d319fef19
--- /dev/null
+++ b/.github/assign/infra.yml
@@ -0,0 +1,9 @@
+addReviewers: true
+
+reviewers:
+ - marysaka
+ - TSRBerry
+
+filterLabels:
+ include:
+ - infra
\ No newline at end of file
diff --git a/.github/labeler.yml b/.github/labeler.yml
new file mode 100644
index 000000000..587830be1
--- /dev/null
+++ b/.github/labeler.yml
@@ -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'
\ No newline at end of file
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 97db387f0..bf8fd000a 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -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:
diff --git a/.github/workflows/pr_triage.yml b/.github/workflows/pr_triage.yml
new file mode 100644
index 000000000..e32dd27ad
--- /dev/null
+++ b/.github/workflows/pr_triage.yml
@@ -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'
\ No newline at end of file
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 98ba34822..63e6d0187 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -6,9 +6,10 @@ on:
push:
branches: [ master ]
paths-ignore:
- - '.github/*'
- - '.github/ISSUE_TEMPLATE/**'
+ - '.github/**'
- '*.yml'
+ - '*.json'
+ - '*.config'
- 'README.md'
concurrency: release
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 9922f0719..a100f8261 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -21,7 +21,7 @@
-
+
@@ -44,9 +44,9 @@
-
+
-
+
diff --git a/src/ARMeilleure/CodeGen/Arm64/CodeGenerator.cs b/src/ARMeilleure/CodeGen/Arm64/CodeGenerator.cs
index fc4fa976e..927198505 100644
--- a/src/ARMeilleure/CodeGen/Arm64/CodeGenerator.cs
+++ b/src/ARMeilleure/CodeGen/Arm64/CodeGenerator.cs
@@ -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);
diff --git a/src/ARMeilleure/CodeGen/Arm64/CodeGeneratorIntrinsic.cs b/src/ARMeilleure/CodeGen/Arm64/CodeGeneratorIntrinsic.cs
index aaa00bb65..1309404a8 100644
--- a/src/ARMeilleure/CodeGen/Arm64/CodeGeneratorIntrinsic.cs
+++ b/src/ARMeilleure/CodeGen/Arm64/CodeGeneratorIntrinsic.cs
@@ -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,
diff --git a/src/ARMeilleure/CodeGen/Arm64/IntrinsicTable.cs b/src/ARMeilleure/CodeGen/Arm64/IntrinsicTable.cs
index a309d56d9..c2bd0bd51 100644
--- a/src/ARMeilleure/CodeGen/Arm64/IntrinsicTable.cs
+++ b/src/ARMeilleure/CodeGen/Arm64/IntrinsicTable.cs
@@ -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));
diff --git a/src/ARMeilleure/CodeGen/Arm64/IntrinsicType.cs b/src/ARMeilleure/CodeGen/Arm64/IntrinsicType.cs
index 800eca93c..df61ea1eb 100644
--- a/src/ARMeilleure/CodeGen/Arm64/IntrinsicType.cs
+++ b/src/ARMeilleure/CodeGen/Arm64/IntrinsicType.cs
@@ -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
}
diff --git a/src/ARMeilleure/CodeGen/Arm64/PreAllocator.cs b/src/ARMeilleure/CodeGen/Arm64/PreAllocator.cs
index 6ea9d2397..74f80e0fb 100644
--- a/src/ARMeilleure/CodeGen/Arm64/PreAllocator.cs
+++ b/src/ARMeilleure/CodeGen/Arm64/PreAllocator.cs
@@ -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 ||
diff --git a/src/ARMeilleure/Decoders/OpCode32SimdSel.cs b/src/ARMeilleure/Decoders/OpCode32SimdSel.cs
index 37fd714a4..bd4865ea5 100644
--- a/src/ARMeilleure/Decoders/OpCode32SimdSel.cs
+++ b/src/ARMeilleure/Decoders/OpCode32SimdSel.cs
@@ -13,7 +13,7 @@
}
}
- enum OpCode32SimdSelMode : int
+ enum OpCode32SimdSelMode
{
Eq = 0,
Vs,
diff --git a/src/ARMeilleure/Instructions/InstEmitSimdCrypto.cs b/src/ARMeilleure/Instructions/InstEmitSimdCrypto.cs
index db24e0290..6226e35ae 100644
--- a/src/ARMeilleure/Instructions/InstEmitSimdCrypto.cs
+++ b/src/ARMeilleure/Instructions/InstEmitSimdCrypto.cs
@@ -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();
diff --git a/src/ARMeilleure/Instructions/InstEmitSimdCrypto32.cs b/src/ARMeilleure/Instructions/InstEmitSimdCrypto32.cs
index f713a388c..24fd7c87e 100644
--- a/src/ARMeilleure/Instructions/InstEmitSimdCrypto32.cs
+++ b/src/ARMeilleure/Instructions/InstEmitSimdCrypto32.cs
@@ -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();
diff --git a/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs b/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs
index 33ae83df6..bec36e2d6 100644
--- a/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs
+++ b/src/ARMeilleure/Instructions/InstEmitSimdCvt32.cs
@@ -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)
{
diff --git a/src/ARMeilleure/Instructions/InstEmitSimdHelper32Arm64.cs b/src/ARMeilleure/Instructions/InstEmitSimdHelper32Arm64.cs
index 98236be6d..804d915c4 100644
--- a/src/ARMeilleure/Instructions/InstEmitSimdHelper32Arm64.cs
+++ b/src/ARMeilleure/Instructions/InstEmitSimdHelper32Arm64.cs
@@ -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)
diff --git a/src/ARMeilleure/IntermediateRepresentation/Intrinsic.cs b/src/ARMeilleure/IntermediateRepresentation/Intrinsic.cs
index f5a776fa2..df5d39ae4 100644
--- a/src/ARMeilleure/IntermediateRepresentation/Intrinsic.cs
+++ b/src/ARMeilleure/IntermediateRepresentation/Intrinsic.cs
@@ -1,5 +1,8 @@
+using System;
+
namespace ARMeilleure.IntermediateRepresentation
{
+ [Flags]
enum Intrinsic : ushort
{
// X86 (SSE and AVX)
diff --git a/src/ARMeilleure/Optimizations.cs b/src/ARMeilleure/Optimizations.cs
index a84a4dc4f..13348cec2 100644
--- a/src/ARMeilleure/Optimizations.cs
+++ b/src/ARMeilleure/Optimizations.cs
@@ -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;
diff --git a/src/ARMeilleure/Signal/NativeSignalHandler.cs b/src/ARMeilleure/Signal/NativeSignalHandler.cs
index cddeb8174..5da0c7726 100644
--- a/src/ARMeilleure/Signal/NativeSignalHandler.cs
+++ b/src/ARMeilleure/Signal/NativeSignalHandler.cs
@@ -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()
diff --git a/src/ARMeilleure/State/ExecutionMode.cs b/src/ARMeilleure/State/ExecutionMode.cs
index 29154a255..f43c5569f 100644
--- a/src/ARMeilleure/State/ExecutionMode.cs
+++ b/src/ARMeilleure/State/ExecutionMode.cs
@@ -1,6 +1,6 @@
namespace ARMeilleure.State
{
- enum ExecutionMode : int
+ enum ExecutionMode
{
Aarch32Arm = 0,
Aarch32Thumb = 1,
diff --git a/src/ARMeilleure/Translation/Cache/JitCache.cs b/src/ARMeilleure/Translation/Cache/JitCache.cs
index daa2eeac2..03cba5ade 100644
--- a/src/ARMeilleure/Translation/Cache/JitCache.cs
+++ b/src/ARMeilleure/Translation/Cache/JitCache.cs
@@ -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 _cacheEntries = new List();
- private static readonly object _lock = new object();
+ private static readonly object _lock = new();
private static bool _initialized;
[SupportedOSPlatform("windows")]
diff --git a/src/ARMeilleure/Translation/PTC/Ptc.cs b/src/ARMeilleure/Translation/PTC/Ptc.cs
index ea4e715b5..3c697bffe 100644
--- a/src/ARMeilleure/Translation/PTC/Ptc.cs
+++ b/src/ARMeilleure/Translation/PTC/Ptc.cs
@@ -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";
diff --git a/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceSession.cs b/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceSession.cs
index ac3319e0d..8d7d0d6a2 100644
--- a/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceSession.cs
+++ b/src/Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceSession.cs
@@ -17,7 +17,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
private Queue _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)
{
diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs
index 92f8ea375..4e9123a0f 100644
--- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs
+++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs
@@ -1,6 +1,6 @@
namespace Ryujinx.Audio.Backends.SoundIo.Native
{
- public enum SoundIoBackend : int
+ public enum SoundIoBackend
{
None = 0,
Jack = 1,
diff --git a/src/Ryujinx.Audio/AudioManager.cs b/src/Ryujinx.Audio/AudioManager.cs
index c37ca4a3d..9f2a05b09 100644
--- a/src/Ryujinx.Audio/AudioManager.cs
+++ b/src/Ryujinx.Audio/AudioManager.cs
@@ -11,7 +11,7 @@ namespace Ryujinx.Audio
///
/// Lock used to control the waiters registration.
///
- private object _lock = new object();
+ private readonly object _lock = new();
///
/// Events signaled when the driver played audio buffers.
diff --git a/src/Ryujinx.Audio/Backends/Common/DynamicRingBuffer.cs b/src/Ryujinx.Audio/Backends/Common/DynamicRingBuffer.cs
index 9bf20d4b5..d17303cd3 100644
--- a/src/Ryujinx.Audio/Backends/Common/DynamicRingBuffer.cs
+++ b/src/Ryujinx.Audio/Backends/Common/DynamicRingBuffer.cs
@@ -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;
diff --git a/src/Ryujinx.Audio/Input/AudioInputManager.cs b/src/Ryujinx.Audio/Input/AudioInputManager.cs
index ac012c4a9..63cbe031f 100644
--- a/src/Ryujinx.Audio/Input/AudioInputManager.cs
+++ b/src/Ryujinx.Audio/Input/AudioInputManager.cs
@@ -14,12 +14,12 @@ namespace Ryujinx.Audio.Input
///
public class AudioInputManager : IDisposable
{
- private object _lock = new object();
+ private readonly object _lock = new();
///
/// Lock used for session allocation.
///
- private object _sessionLock = new object();
+ private readonly object _sessionLock = new();
///
/// The session ids allocation table.
diff --git a/src/Ryujinx.Audio/Input/AudioInputSystem.cs b/src/Ryujinx.Audio/Input/AudioInputSystem.cs
index b3ca0fd68..33364e28a 100644
--- a/src/Ryujinx.Audio/Input/AudioInputSystem.cs
+++ b/src/Ryujinx.Audio/Input/AudioInputSystem.cs
@@ -48,7 +48,7 @@ namespace Ryujinx.Audio.Input
///
/// The lock of the parent.
///
- private object _parentLock;
+ private readonly object _parentLock;
///
/// The dispose state.
diff --git a/src/Ryujinx.Audio/Output/AudioOutputManager.cs b/src/Ryujinx.Audio/Output/AudioOutputManager.cs
index 8c21f76a1..bc2fc6f43 100644
--- a/src/Ryujinx.Audio/Output/AudioOutputManager.cs
+++ b/src/Ryujinx.Audio/Output/AudioOutputManager.cs
@@ -14,12 +14,12 @@ namespace Ryujinx.Audio.Output
///
public class AudioOutputManager : IDisposable
{
- private object _lock = new object();
+ private readonly object _lock = new();
///
/// Lock used for session allocation.
///
- private object _sessionLock = new object();
+ private readonly object _sessionLock = new();
///
/// The session ids allocation table.
diff --git a/src/Ryujinx.Audio/Output/AudioOutputSystem.cs b/src/Ryujinx.Audio/Output/AudioOutputSystem.cs
index 93df87aab..8378f33f8 100644
--- a/src/Ryujinx.Audio/Output/AudioOutputSystem.cs
+++ b/src/Ryujinx.Audio/Output/AudioOutputSystem.cs
@@ -48,7 +48,7 @@ namespace Ryujinx.Audio.Output
///
/// THe lock of the parent.
///
- private object _parentLock;
+ private readonly object _parentLock;
///
/// The dispose state.
diff --git a/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs b/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs
index 1ad7b8590..8485fb4c5 100644
--- a/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs
@@ -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;
diff --git a/src/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs b/src/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs
index 4de0ad166..e41d5cc50 100644
--- a/src/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs
@@ -19,12 +19,12 @@ namespace Ryujinx.Audio.Renderer.Server
///
/// Lock used for session allocation.
///
- private object _sessionLock = new object();
+ private readonly object _sessionLock = new();
///
/// Lock used to control the running state.
///
- private object _audioProcessorLock = new object();
+ private readonly object _audioProcessorLock = new();
///
/// The session ids allocation table.
diff --git a/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerManager.cs b/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerManager.cs
index b37988fed..0fee00001 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerManager.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerManager.cs
@@ -16,7 +16,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
///
/// Global lock of the object.
///
- private object Lock = new object();
+ private readonly object Lock = new();
///
/// The upsamplers instances.
diff --git a/src/Ryujinx.Ava/AppHost.cs b/src/Ryujinx.Ava/AppHost.cs
index d7e6c3655..d8b485193 100644
--- a/src/Ryujinx.Ava/AppHost.cs
+++ b/src/Ryujinx.Ava/AppHost.cs
@@ -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 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)
diff --git a/src/Ryujinx.Ava/Assets/Locales/en_US.json b/src/Ryujinx.Ava/Assets/Locales/en_US.json
index 79765db16..4065a1dfb 100644
--- a/src/Ryujinx.Ava/Assets/Locales/en_US.json
+++ b/src/Ryujinx.Ava/Assets/Locales/en_US.json
@@ -545,7 +545,7 @@
"SwkbdMinRangeCharacters": "Must be {0}-{1} characters long",
"SoftwareKeyboard": "Software Keyboard",
"SoftwareKeyboardModeNumbersOnly": "Must be numbers only",
- "SoftwareKeyboardModeAlphabet": "Must be alphabets only",
+ "SoftwareKeyboardModeAlphabet": "Must be non CJK-characters only",
"SoftwareKeyboardModeASCII": "Must be ASCII text only",
"DialogControllerAppletMessagePlayerRange": "Application requests {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
"DialogControllerAppletMessage": "Application requests exactly {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
diff --git a/src/Ryujinx.Ava/Modules/Updater/Updater.cs b/src/Ryujinx.Ava/Modules/Updater/Updater.cs
index 839526c4e..71d978c67 100644
--- a/src/Ryujinx.Ava/Modules/Updater/Updater.cs
+++ b/src/Ryujinx.Ava/Modules/Updater/Updater.cs
@@ -741,7 +741,7 @@ namespace Ryujinx.Modules
var files = Directory.EnumerateFiles(HomeDir); // All files directly in base dir.
// Determine and exclude user files only when the updater is running, not when cleaning old files
- if (_running)
+ if (_running && !OperatingSystem.IsMacOS())
{
// Compare the loose files in base directory against the loose files from the incoming update, and store foreign ones in a user list.
var oldFiles = Directory.EnumerateFiles(HomeDir, "*", SearchOption.TopDirectoryOnly).Select(Path.GetFileName);
diff --git a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs b/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs
index 04bc46193..81258b448 100644
--- a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs
@@ -146,7 +146,7 @@ namespace Ryujinx.Ava.UI.Controls
case KeyboardMode.Alphabet:
localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeAlphabet);
validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText);
- _checkInput = text => text.All(char.IsAsciiLetter);
+ _checkInput = text => text.All(value => !CJKCharacterValidation.IsCJK(value));
break;
case KeyboardMode.ASCII:
localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeASCII);
diff --git a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs b/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs
index a5c8b0031..3b2c32e3f 100644
--- a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs
+++ b/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs
@@ -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;
diff --git a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowOpenGL.cs b/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowOpenGL.cs
index 305e891a1..d427ab88c 100644
--- a/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowOpenGL.cs
+++ b/src/Ryujinx.Ava/UI/Renderer/EmbeddedWindowOpenGL.cs
@@ -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()
diff --git a/src/Ryujinx.Common/Configuration/AppDataManager.cs b/src/Ryujinx.Common/Configuration/AppDataManager.cs
index d6e778430..b685e7064 100644
--- a/src/Ryujinx.Common/Configuration/AppDataManager.cs
+++ b/src/Ryujinx.Common/Configuration/AppDataManager.cs
@@ -96,7 +96,7 @@ namespace Ryujinx.Common.Configuration
if (OperatingSystem.IsMacOS() && Mode == LaunchMode.UserProfile)
{
string oldConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir);
- if (Path.Exists(oldConfigPath) && !Path.Exists(BaseDirPath))
+ if (Path.Exists(oldConfigPath) && !IsPathSymlink(oldConfigPath) && !Path.Exists(BaseDirPath))
{
CopyDirectory(oldConfigPath, BaseDirPath);
Directory.Delete(oldConfigPath, true);
@@ -115,6 +115,14 @@ namespace Ryujinx.Common.Configuration
Directory.CreateDirectory(KeysDirPath = Path.Combine(BaseDirPath, KeysDir));
}
+ // Check if existing old baseDirPath is a symlink, to prevent possible errors.
+ // Should be removed, when the existance of the old directory isn't checked anymore.
+ private static bool IsPathSymlink(string path)
+ {
+ FileAttributes attributes = File.GetAttributes(path);
+ return (attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint;
+ }
+
private static void CopyDirectory(string sourceDir, string destinationDir)
{
var dir = new DirectoryInfo(sourceDir);
diff --git a/src/Ryujinx.Common/Configuration/Hid/ControllerType.cs b/src/Ryujinx.Common/Configuration/Hid/ControllerType.cs
index 70f811c89..1c273537c 100644
--- a/src/Ryujinx.Common/Configuration/Hid/ControllerType.cs
+++ b/src/Ryujinx.Common/Configuration/Hid/ControllerType.cs
@@ -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))]
- public enum ControllerType : int
+ public enum ControllerType
{
None,
ProController = 1 << 0,
diff --git a/src/Ryujinx.Common/Configuration/Hid/PlayerIndex.cs b/src/Ryujinx.Common/Configuration/Hid/PlayerIndex.cs
index dd6495d4d..4e9a0434d 100644
--- a/src/Ryujinx.Common/Configuration/Hid/PlayerIndex.cs
+++ b/src/Ryujinx.Common/Configuration/Hid/PlayerIndex.cs
@@ -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))]
- public enum PlayerIndex : int
+ public enum PlayerIndex
{
Player1 = 0,
Player2 = 1,
diff --git a/src/Ryujinx.Common/Memory/SpanReader.cs b/src/Ryujinx.Common/Memory/SpanReader.cs
index 673932d0b..9a1a0a3f0 100644
--- a/src/Ryujinx.Common/Memory/SpanReader.cs
+++ b/src/Ryujinx.Common/Memory/SpanReader.cs
@@ -24,6 +24,24 @@ namespace Ryujinx.Common.Memory
return value;
}
+ public bool TryRead(out T value) where T : unmanaged
+ {
+ int valueSize = Unsafe.SizeOf();
+
+ if (valueSize > _input.Length)
+ {
+ value = default;
+
+ return false;
+ }
+
+ value = MemoryMarshal.Cast(_input)[0];
+
+ _input = _input.Slice(valueSize);
+
+ return true;
+ }
+
public ReadOnlySpan GetSpan(int size)
{
ReadOnlySpan data = _input.Slice(0, size);
diff --git a/src/Ryujinx.Graphics.GAL/Capabilities.cs b/src/Ryujinx.Graphics.GAL/Capabilities.cs
index 48b37d35d..ef2da0b77 100644
--- a/src/Ryujinx.Graphics.GAL/Capabilities.cs
+++ b/src/Ryujinx.Graphics.GAL/Capabilities.cs
@@ -28,12 +28,15 @@ namespace Ryujinx.Graphics.GAL
public readonly bool SupportsFragmentShaderOrderingIntel;
public readonly bool SupportsGeometryShader;
public readonly bool SupportsGeometryShaderPassthrough;
+ public readonly bool SupportsTransformFeedback;
public readonly bool SupportsImageLoadFormatted;
public readonly bool SupportsLayerVertexTessellation;
public readonly bool SupportsMismatchingViewFormat;
public readonly bool SupportsCubemapView;
public readonly bool SupportsNonConstantTextureOffset;
public readonly bool SupportsShaderBallot;
+ public readonly bool SupportsShaderBarrierDivergence;
+ public readonly bool SupportsShaderFloat64;
public readonly bool SupportsTextureShadowLod;
public readonly bool SupportsViewportIndexVertexTessellation;
public readonly bool SupportsViewportMask;
@@ -75,12 +78,15 @@ namespace Ryujinx.Graphics.GAL
bool supportsFragmentShaderOrderingIntel,
bool supportsGeometryShader,
bool supportsGeometryShaderPassthrough,
+ bool supportsTransformFeedback,
bool supportsImageLoadFormatted,
bool supportsLayerVertexTessellation,
bool supportsMismatchingViewFormat,
bool supportsCubemapView,
bool supportsNonConstantTextureOffset,
bool supportsShaderBallot,
+ bool supportsShaderBarrierDivergence,
+ bool supportsShaderFloat64,
bool supportsTextureShadowLod,
bool supportsViewportIndexVertexTessellation,
bool supportsViewportMask,
@@ -118,12 +124,15 @@ namespace Ryujinx.Graphics.GAL
SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
SupportsGeometryShader = supportsGeometryShader;
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
+ SupportsTransformFeedback = supportsTransformFeedback;
SupportsImageLoadFormatted = supportsImageLoadFormatted;
SupportsLayerVertexTessellation = supportsLayerVertexTessellation;
SupportsMismatchingViewFormat = supportsMismatchingViewFormat;
SupportsCubemapView = supportsCubemapView;
SupportsNonConstantTextureOffset = supportsNonConstantTextureOffset;
SupportsShaderBallot = supportsShaderBallot;
+ SupportsShaderBarrierDivergence = supportsShaderBarrierDivergence;
+ SupportsShaderFloat64 = supportsShaderFloat64;
SupportsTextureShadowLod = supportsTextureShadowLod;
SupportsViewportIndexVertexTessellation = supportsViewportIndexVertexTessellation;
SupportsViewportMask = supportsViewportMask;
diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs
index e6169d895..bc96f2225 100644
--- a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs
+++ b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs
@@ -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 ScreenCaptured;
diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClassState.cs b/src/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClassState.cs
index 5d81de5de..73dd31b23 100644
--- a/src/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClassState.cs
+++ b/src/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClassState.cs
@@ -100,22 +100,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
{
#pragma warning disable CS0649
public uint SetObject;
- public int SetObjectClassId => (int)((SetObject >> 0) & 0xFFFF);
+ public int SetObjectClassId => (int)(SetObject & 0xFFFF);
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
public fixed uint Reserved04[63];
public uint NoOperation;
public uint SetNotifyA;
- public int SetNotifyAAddressUpper => (int)((SetNotifyA >> 0) & 0xFF);
+ public int SetNotifyAAddressUpper => (int)(SetNotifyA & 0xFF);
public uint SetNotifyB;
public uint Notify;
public NotifyType NotifyType => (NotifyType)(Notify);
public uint WaitForIdle;
public fixed uint Reserved114[7];
public uint SetGlobalRenderEnableA;
- public int SetGlobalRenderEnableAOffsetUpper => (int)((SetGlobalRenderEnableA >> 0) & 0xFF);
+ public int SetGlobalRenderEnableAOffsetUpper => (int)(SetGlobalRenderEnableA & 0xFF);
public uint SetGlobalRenderEnableB;
public uint SetGlobalRenderEnableC;
- public int SetGlobalRenderEnableCMode => (int)((SetGlobalRenderEnableC >> 0) & 0x7);
+ public int SetGlobalRenderEnableCMode => (int)(SetGlobalRenderEnableC & 0x7);
public uint SendGoIdle;
public uint PmTrigger;
public uint PmTriggerWfi;
@@ -126,11 +126,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
public uint LineLengthIn;
public uint LineCount;
public uint OffsetOutUpper;
- public int OffsetOutUpperValue => (int)((OffsetOutUpper >> 0) & 0xFF);
+ public int OffsetOutUpperValue => (int)(OffsetOutUpper & 0xFF);
public uint OffsetOut;
public uint PitchOut;
public uint SetDstBlockSize;
- public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)((SetDstBlockSize >> 0) & 0xF);
+ public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)(SetDstBlockSize & 0xF);
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
public uint SetDstWidth;
@@ -138,11 +138,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
public uint SetDstDepth;
public uint SetDstLayer;
public uint SetDstOriginBytesX;
- public int SetDstOriginBytesXV => (int)((SetDstOriginBytesX >> 0) & 0xFFFFF);
+ public int SetDstOriginBytesXV => (int)(SetDstOriginBytesX & 0xFFFFF);
public uint SetDstOriginSamplesY;
- public int SetDstOriginSamplesYV => (int)((SetDstOriginSamplesY >> 0) & 0xFFFF);
+ public int SetDstOriginSamplesYV => (int)(SetDstOriginSamplesY & 0xFFFF);
public uint LaunchDma;
- public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)((LaunchDma >> 0) & 0x1);
+ public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)(LaunchDma & 0x1);
public LaunchDmaCompletionType LaunchDmaCompletionType => (LaunchDmaCompletionType)((LaunchDma >> 4) & 0x3);
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 8) & 0x3);
public LaunchDmaSemaphoreStructSize LaunchDmaSemaphoreStructSize => (LaunchDmaSemaphoreStructSize)((LaunchDma >> 12) & 0x1);
@@ -153,7 +153,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
public uint LoadInlineData;
public fixed uint Reserved1B8[9];
public uint SetI2mSemaphoreA;
- public int SetI2mSemaphoreAOffsetUpper => (int)((SetI2mSemaphoreA >> 0) & 0xFF);
+ public int SetI2mSemaphoreAOffsetUpper => (int)(SetI2mSemaphoreA & 0xFF);
public uint SetI2mSemaphoreB;
public uint SetI2mSemaphoreC;
public fixed uint Reserved1E8[2];
@@ -162,7 +162,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
public uint SetI2mSpareNoop02;
public uint SetI2mSpareNoop03;
public uint SetValidSpanOverflowAreaA;
- public int SetValidSpanOverflowAreaAAddressUpper => (int)((SetValidSpanOverflowAreaA >> 0) & 0xFF);
+ public int SetValidSpanOverflowAreaAAddressUpper => (int)(SetValidSpanOverflowAreaA & 0xFF);
public uint SetValidSpanOverflowAreaB;
public uint SetValidSpanOverflowAreaC;
public uint SetCoalesceWaitingPeriodUnit;
@@ -185,12 +185,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
public uint SetReservedSwMethod06;
public uint SetReservedSwMethod07;
public uint SetCwdControl;
- public SetCwdControlSmSelection SetCwdControlSmSelection => (SetCwdControlSmSelection)((SetCwdControl >> 0) & 0x1);
+ public SetCwdControlSmSelection SetCwdControlSmSelection => (SetCwdControlSmSelection)(SetCwdControl & 0x1);
public uint InvalidateTextureHeaderCacheNoWfi;
- public InvalidateCacheLines InvalidateTextureHeaderCacheNoWfiLines => (InvalidateCacheLines)((InvalidateTextureHeaderCacheNoWfi >> 0) & 0x1);
+ public InvalidateCacheLines InvalidateTextureHeaderCacheNoWfiLines => (InvalidateCacheLines)(InvalidateTextureHeaderCacheNoWfi & 0x1);
public int InvalidateTextureHeaderCacheNoWfiTag => (int)((InvalidateTextureHeaderCacheNoWfi >> 4) & 0x3FFFFF);
public uint SetCwdRefCounter;
- public int SetCwdRefCounterSelect => (int)((SetCwdRefCounter >> 0) & 0x3F);
+ public int SetCwdRefCounterSelect => (int)(SetCwdRefCounter & 0x3F);
public int SetCwdRefCounterValue => (int)((SetCwdRefCounter >> 8) & 0xFFFF);
public uint SetReservedSwMethod08;
public uint SetReservedSwMethod09;
@@ -201,28 +201,28 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
public uint SetReservedSwMethod14;
public uint SetReservedSwMethod15;
public uint SetGwcScgType;
- public SetGwcScgTypeScgType SetGwcScgTypeScgType => (SetGwcScgTypeScgType)((SetGwcScgType >> 0) & 0x1);
+ public SetGwcScgTypeScgType SetGwcScgTypeScgType => (SetGwcScgTypeScgType)(SetGwcScgType & 0x1);
public uint SetScgControl;
- public int SetScgControlCompute1MaxSmCount => (int)((SetScgControl >> 0) & 0x1FF);
+ public int SetScgControlCompute1MaxSmCount => (int)(SetScgControl & 0x1FF);
public uint InvalidateConstantBufferCacheA;
- public int InvalidateConstantBufferCacheAAddressUpper => (int)((InvalidateConstantBufferCacheA >> 0) & 0xFF);
+ public int InvalidateConstantBufferCacheAAddressUpper => (int)(InvalidateConstantBufferCacheA & 0xFF);
public uint InvalidateConstantBufferCacheB;
public uint InvalidateConstantBufferCacheC;
- public int InvalidateConstantBufferCacheCByteCount => (int)((InvalidateConstantBufferCacheC >> 0) & 0x1FFFF);
+ public int InvalidateConstantBufferCacheCByteCount => (int)(InvalidateConstantBufferCacheC & 0x1FFFF);
public bool InvalidateConstantBufferCacheCThruL2 => (InvalidateConstantBufferCacheC & 0x80000000) != 0;
public uint SetComputeClassVersion;
- public int SetComputeClassVersionCurrent => (int)((SetComputeClassVersion >> 0) & 0xFFFF);
+ public int SetComputeClassVersionCurrent => (int)(SetComputeClassVersion & 0xFFFF);
public int SetComputeClassVersionOldestSupported => (int)((SetComputeClassVersion >> 16) & 0xFFFF);
public uint CheckComputeClassVersion;
- public int CheckComputeClassVersionCurrent => (int)((CheckComputeClassVersion >> 0) & 0xFFFF);
+ public int CheckComputeClassVersionCurrent => (int)(CheckComputeClassVersion & 0xFFFF);
public int CheckComputeClassVersionOldestSupported => (int)((CheckComputeClassVersion >> 16) & 0xFFFF);
public uint SetQmdVersion;
- public int SetQmdVersionCurrent => (int)((SetQmdVersion >> 0) & 0xFFFF);
+ public int SetQmdVersionCurrent => (int)(SetQmdVersion & 0xFFFF);
public int SetQmdVersionOldestSupported => (int)((SetQmdVersion >> 16) & 0xFFFF);
public uint SetWfiConfig;
public bool SetWfiConfigEnableScgTypeWfi => (SetWfiConfig & 0x1) != 0;
public uint CheckQmdVersion;
- public int CheckQmdVersionCurrent => (int)((CheckQmdVersion >> 0) & 0xFFFF);
+ public int CheckQmdVersionCurrent => (int)(CheckQmdVersion & 0xFFFF);
public int CheckQmdVersionOldestSupported => (int)((CheckQmdVersion >> 16) & 0xFFFF);
public uint WaitForIdleScgType;
public uint InvalidateSkedCaches;
@@ -231,28 +231,28 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
public bool SetScgRenderEnableControlCompute1UsesRenderEnable => (SetScgRenderEnableControl & 0x1) != 0;
public fixed uint Reserved2A0[4];
public uint SetCwdSlotCount;
- public int SetCwdSlotCountV => (int)((SetCwdSlotCount >> 0) & 0xFF);
+ public int SetCwdSlotCountV => (int)(SetCwdSlotCount & 0xFF);
public uint SendPcasA;
public uint SendPcasB;
- public int SendPcasBFrom => (int)((SendPcasB >> 0) & 0xFFFFFF);
+ public int SendPcasBFrom => (int)(SendPcasB & 0xFFFFFF);
public int SendPcasBDelta => (int)((SendPcasB >> 24) & 0xFF);
public uint SendSignalingPcasB;
public bool SendSignalingPcasBInvalidate => (SendSignalingPcasB & 0x1) != 0;
public bool SendSignalingPcasBSchedule => (SendSignalingPcasB & 0x2) != 0;
public fixed uint Reserved2C0[9];
public uint SetShaderLocalMemoryNonThrottledA;
- public int SetShaderLocalMemoryNonThrottledASizeUpper => (int)((SetShaderLocalMemoryNonThrottledA >> 0) & 0xFF);
+ public int SetShaderLocalMemoryNonThrottledASizeUpper => (int)(SetShaderLocalMemoryNonThrottledA & 0xFF);
public uint SetShaderLocalMemoryNonThrottledB;
public uint SetShaderLocalMemoryNonThrottledC;
- public int SetShaderLocalMemoryNonThrottledCMaxSmCount => (int)((SetShaderLocalMemoryNonThrottledC >> 0) & 0x1FF);
+ public int SetShaderLocalMemoryNonThrottledCMaxSmCount => (int)(SetShaderLocalMemoryNonThrottledC & 0x1FF);
public uint SetShaderLocalMemoryThrottledA;
- public int SetShaderLocalMemoryThrottledASizeUpper => (int)((SetShaderLocalMemoryThrottledA >> 0) & 0xFF);
+ public int SetShaderLocalMemoryThrottledASizeUpper => (int)(SetShaderLocalMemoryThrottledA & 0xFF);
public uint SetShaderLocalMemoryThrottledB;
public uint SetShaderLocalMemoryThrottledC;
- public int SetShaderLocalMemoryThrottledCMaxSmCount => (int)((SetShaderLocalMemoryThrottledC >> 0) & 0x1FF);
+ public int SetShaderLocalMemoryThrottledCMaxSmCount => (int)(SetShaderLocalMemoryThrottledC & 0x1FF);
public fixed uint Reserved2FC[5];
public uint SetSpaVersion;
- public int SetSpaVersionMinor => (int)((SetSpaVersion >> 0) & 0xFF);
+ public int SetSpaVersionMinor => (int)(SetSpaVersion & 0xFF);
public int SetSpaVersionMajor => (int)((SetSpaVersion >> 8) & 0xFF);
public fixed uint Reserved314[123];
public uint SetFalcon00;
@@ -291,14 +291,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
public uint SetShaderLocalMemoryWindow;
public fixed uint Reserved780[4];
public uint SetShaderLocalMemoryA;
- public int SetShaderLocalMemoryAAddressUpper => (int)((SetShaderLocalMemoryA >> 0) & 0xFF);
+ public int SetShaderLocalMemoryAAddressUpper => (int)(SetShaderLocalMemoryA & 0xFF);
public uint SetShaderLocalMemoryB;
public fixed uint Reserved798[383];
public uint SetShaderCacheControl;
public bool SetShaderCacheControlIcachePrefetchEnable => (SetShaderCacheControl & 0x1) != 0;
public fixed uint ReservedD98[19];
public uint SetSmTimeoutInterval;
- public int SetSmTimeoutIntervalCounterBit => (int)((SetSmTimeoutInterval >> 0) & 0x3F);
+ public int SetSmTimeoutIntervalCounterBit => (int)(SetSmTimeoutInterval & 0x3F);
public fixed uint ReservedDE8[87];
public uint SetSpareNoop12;
public uint SetSpareNoop13;
@@ -324,48 +324,48 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
public bool InvalidateTextureHeaderCacheAllV => (InvalidateTextureHeaderCacheAll & 0x1) != 0;
public fixed uint Reserved1214[29];
public uint InvalidateTextureDataCacheNoWfi;
- public InvalidateCacheLines InvalidateTextureDataCacheNoWfiLines => (InvalidateCacheLines)((InvalidateTextureDataCacheNoWfi >> 0) & 0x1);
+ public InvalidateCacheLines InvalidateTextureDataCacheNoWfiLines => (InvalidateCacheLines)(InvalidateTextureDataCacheNoWfi & 0x1);
public int InvalidateTextureDataCacheNoWfiTag => (int)((InvalidateTextureDataCacheNoWfi >> 4) & 0x3FFFFF);
public fixed uint Reserved128C[7];
public uint ActivatePerfSettingsForComputeContext;
public bool ActivatePerfSettingsForComputeContextAll => (ActivatePerfSettingsForComputeContext & 0x1) != 0;
public fixed uint Reserved12AC[33];
public uint InvalidateSamplerCache;
- public InvalidateCacheLines InvalidateSamplerCacheLines => (InvalidateCacheLines)((InvalidateSamplerCache >> 0) & 0x1);
+ public InvalidateCacheLines InvalidateSamplerCacheLines => (InvalidateCacheLines)(InvalidateSamplerCache & 0x1);
public int InvalidateSamplerCacheTag => (int)((InvalidateSamplerCache >> 4) & 0x3FFFFF);
public uint InvalidateTextureHeaderCache;
- public InvalidateCacheLines InvalidateTextureHeaderCacheLines => (InvalidateCacheLines)((InvalidateTextureHeaderCache >> 0) & 0x1);
+ public InvalidateCacheLines InvalidateTextureHeaderCacheLines => (InvalidateCacheLines)(InvalidateTextureHeaderCache & 0x1);
public int InvalidateTextureHeaderCacheTag => (int)((InvalidateTextureHeaderCache >> 4) & 0x3FFFFF);
public uint InvalidateTextureDataCache;
- public InvalidateCacheLines InvalidateTextureDataCacheLines => (InvalidateCacheLines)((InvalidateTextureDataCache >> 0) & 0x1);
+ public InvalidateCacheLines InvalidateTextureDataCacheLines => (InvalidateCacheLines)(InvalidateTextureDataCache & 0x1);
public int InvalidateTextureDataCacheTag => (int)((InvalidateTextureDataCache >> 4) & 0x3FFFFF);
public fixed uint Reserved133C[58];
public uint InvalidateSamplerCacheNoWfi;
- public InvalidateCacheLines InvalidateSamplerCacheNoWfiLines => (InvalidateCacheLines)((InvalidateSamplerCacheNoWfi >> 0) & 0x1);
+ public InvalidateCacheLines InvalidateSamplerCacheNoWfiLines => (InvalidateCacheLines)(InvalidateSamplerCacheNoWfi & 0x1);
public int InvalidateSamplerCacheNoWfiTag => (int)((InvalidateSamplerCacheNoWfi >> 4) & 0x3FFFFF);
public fixed uint Reserved1428[64];
public uint SetShaderExceptions;
public bool SetShaderExceptionsEnable => (SetShaderExceptions & 0x1) != 0;
public fixed uint Reserved152C[9];
public uint SetRenderEnableA;
- public int SetRenderEnableAOffsetUpper => (int)((SetRenderEnableA >> 0) & 0xFF);
+ public int SetRenderEnableAOffsetUpper => (int)(SetRenderEnableA & 0xFF);
public uint SetRenderEnableB;
public uint SetRenderEnableC;
- public int SetRenderEnableCMode => (int)((SetRenderEnableC >> 0) & 0x7);
+ public int SetRenderEnableCMode => (int)(SetRenderEnableC & 0x7);
public uint SetTexSamplerPoolA;
- public int SetTexSamplerPoolAOffsetUpper => (int)((SetTexSamplerPoolA >> 0) & 0xFF);
+ public int SetTexSamplerPoolAOffsetUpper => (int)(SetTexSamplerPoolA & 0xFF);
public uint SetTexSamplerPoolB;
public uint SetTexSamplerPoolC;
- public int SetTexSamplerPoolCMaximumIndex => (int)((SetTexSamplerPoolC >> 0) & 0xFFFFF);
+ public int SetTexSamplerPoolCMaximumIndex => (int)(SetTexSamplerPoolC & 0xFFFFF);
public fixed uint Reserved1568[3];
public uint SetTexHeaderPoolA;
- public int SetTexHeaderPoolAOffsetUpper => (int)((SetTexHeaderPoolA >> 0) & 0xFF);
+ public int SetTexHeaderPoolAOffsetUpper => (int)(SetTexHeaderPoolA & 0xFF);
public uint SetTexHeaderPoolB;
public uint SetTexHeaderPoolC;
- public int SetTexHeaderPoolCMaximumIndex => (int)((SetTexHeaderPoolC >> 0) & 0x3FFFFF);
+ public int SetTexHeaderPoolCMaximumIndex => (int)(SetTexHeaderPoolC & 0x3FFFFF);
public fixed uint Reserved1580[34];
public uint SetProgramRegionA;
- public int SetProgramRegionAAddressUpper => (int)((SetProgramRegionA >> 0) & 0xFF);
+ public int SetProgramRegionAAddressUpper => (int)(SetProgramRegionA & 0xFF);
public uint SetProgramRegionB;
public fixed uint Reserved1610[34];
public uint InvalidateShaderCachesNoWfi;
@@ -374,7 +374,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
public bool InvalidateShaderCachesNoWfiConstant => (InvalidateShaderCachesNoWfi & 0x1000) != 0;
public fixed uint Reserved169C[170];
public uint SetRenderEnableOverride;
- public SetRenderEnableOverrideMode SetRenderEnableOverrideMode => (SetRenderEnableOverrideMode)((SetRenderEnableOverride >> 0) & 0x3);
+ public SetRenderEnableOverrideMode SetRenderEnableOverrideMode => (SetRenderEnableOverrideMode)(SetRenderEnableOverride & 0x3);
public fixed uint Reserved1948[57];
public uint PipeNop;
public uint SetSpare00;
@@ -383,11 +383,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
public uint SetSpare03;
public fixed uint Reserved1A40[48];
public uint SetReportSemaphoreA;
- public int SetReportSemaphoreAOffsetUpper => (int)((SetReportSemaphoreA >> 0) & 0xFF);
+ public int SetReportSemaphoreAOffsetUpper => (int)(SetReportSemaphoreA & 0xFF);
public uint SetReportSemaphoreB;
public uint SetReportSemaphoreC;
public uint SetReportSemaphoreD;
- public SetReportSemaphoreDOperation SetReportSemaphoreDOperation => (SetReportSemaphoreDOperation)((SetReportSemaphoreD >> 0) & 0x3);
+ public SetReportSemaphoreDOperation SetReportSemaphoreDOperation => (SetReportSemaphoreDOperation)(SetReportSemaphoreD & 0x3);
public bool SetReportSemaphoreDAwakenEnable => (SetReportSemaphoreD & 0x100000) != 0;
public SetReportSemaphoreDStructureSize SetReportSemaphoreDStructureSize => (SetReportSemaphoreDStructureSize)((SetReportSemaphoreD >> 28) & 0x1);
public bool SetReportSemaphoreDFlushDisable => (SetReportSemaphoreD & 0x4) != 0;
@@ -396,7 +396,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
public SetReportSemaphoreDReductionFormat SetReportSemaphoreDReductionFormat => (SetReportSemaphoreDReductionFormat)((SetReportSemaphoreD >> 17) & 0x3);
public fixed uint Reserved1B10[702];
public uint SetBindlessTexture;
- public int SetBindlessTextureConstantBufferSlotSelect => (int)((SetBindlessTexture >> 0) & 0x7);
+ public int SetBindlessTextureConstantBufferSlotSelect => (int)(SetBindlessTexture & 0x7);
public uint SetTrapHandler;
public fixed uint Reserved2610[843];
public Array8 SetShaderPerformanceCounterValueUpper;
@@ -423,11 +423,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
public bool SetShaderPerformanceCounterControlBWindowed(int i) => (SetShaderPerformanceCounterControlB[i] & 0x8) != 0;
public int SetShaderPerformanceCounterControlBFunc(int i) => (int)((SetShaderPerformanceCounterControlB[i] >> 4) & 0xFFFF);
public uint SetShaderPerformanceCounterTrapControl;
- public int SetShaderPerformanceCounterTrapControlMask => (int)((SetShaderPerformanceCounterTrapControl >> 0) & 0xFF);
+ public int SetShaderPerformanceCounterTrapControlMask => (int)(SetShaderPerformanceCounterTrapControl & 0xFF);
public uint StartShaderPerformanceCounter;
- public int StartShaderPerformanceCounterCounterMask => (int)((StartShaderPerformanceCounter >> 0) & 0xFF);
+ public int StartShaderPerformanceCounterCounterMask => (int)(StartShaderPerformanceCounter & 0xFF);
public uint StopShaderPerformanceCounter;
- public int StopShaderPerformanceCounterCounterMask => (int)((StopShaderPerformanceCounter >> 0) & 0xFF);
+ public int StopShaderPerformanceCounterCounterMask => (int)(StopShaderPerformanceCounter & 0xFF);
public fixed uint Reserved33E8[6];
public MmeShadowScratch SetMmeShadowScratch;
#pragma warning restore CS0649
diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClassState.cs b/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClassState.cs
index 7de4d5f08..6f3b91f2c 100644
--- a/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClassState.cs
+++ b/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClassState.cs
@@ -186,22 +186,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
public uint PmTrigger;
public fixed uint Reserved144[63];
public uint SetSemaphoreA;
- public int SetSemaphoreAUpper => (int)((SetSemaphoreA >> 0) & 0xFF);
+ public int SetSemaphoreAUpper => (int)(SetSemaphoreA & 0xFF);
public uint SetSemaphoreB;
public uint SetSemaphorePayload;
public fixed uint Reserved24C[2];
public uint SetRenderEnableA;
- public int SetRenderEnableAUpper => (int)((SetRenderEnableA >> 0) & 0xFF);
+ public int SetRenderEnableAUpper => (int)(SetRenderEnableA & 0xFF);
public uint SetRenderEnableB;
public uint SetRenderEnableC;
- public int SetRenderEnableCMode => (int)((SetRenderEnableC >> 0) & 0x7);
+ public int SetRenderEnableCMode => (int)(SetRenderEnableC & 0x7);
public uint SetSrcPhysMode;
- public SetPhysModeTarget SetSrcPhysModeTarget => (SetPhysModeTarget)((SetSrcPhysMode >> 0) & 0x3);
+ public SetPhysModeTarget SetSrcPhysModeTarget => (SetPhysModeTarget)(SetSrcPhysMode & 0x3);
public uint SetDstPhysMode;
- public SetPhysModeTarget SetDstPhysModeTarget => (SetPhysModeTarget)((SetDstPhysMode >> 0) & 0x3);
+ public SetPhysModeTarget SetDstPhysModeTarget => (SetPhysModeTarget)(SetDstPhysMode & 0x3);
public fixed uint Reserved268[38];
public uint LaunchDma;
- public LaunchDmaDataTransferType LaunchDmaDataTransferType => (LaunchDmaDataTransferType)((LaunchDma >> 0) & 0x3);
+ public LaunchDmaDataTransferType LaunchDmaDataTransferType => (LaunchDmaDataTransferType)(LaunchDma & 0x3);
public bool LaunchDmaFlushEnable => (LaunchDma & 0x4) != 0;
public LaunchDmaSemaphoreType LaunchDmaSemaphoreType => (LaunchDmaSemaphoreType)((LaunchDma >> 3) & 0x3);
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 5) & 0x3);
@@ -218,10 +218,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
public LaunchDmaBypassL2 LaunchDmaBypassL2 => (LaunchDmaBypassL2)((LaunchDma >> 20) & 0x1);
public fixed uint Reserved304[63];
public uint OffsetInUpper;
- public int OffsetInUpperUpper => (int)((OffsetInUpper >> 0) & 0xFF);
+ public int OffsetInUpperUpper => (int)(OffsetInUpper & 0xFF);
public uint OffsetInLower;
public uint OffsetOutUpper;
- public int OffsetOutUpperUpper => (int)((OffsetOutUpper >> 0) & 0xFF);
+ public int OffsetOutUpperUpper => (int)(OffsetOutUpper & 0xFF);
public uint OffsetOutLower;
public uint PitchIn;
public uint PitchOut;
@@ -231,7 +231,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
public uint SetRemapConstA;
public uint SetRemapConstB;
public uint SetRemapComponents;
- public SetRemapComponentsDst SetRemapComponentsDstX => (SetRemapComponentsDst)((SetRemapComponents >> 0) & 0x7);
+ public SetRemapComponentsDst SetRemapComponentsDstX => (SetRemapComponentsDst)(SetRemapComponents & 0x7);
public SetRemapComponentsDst SetRemapComponentsDstY => (SetRemapComponentsDst)((SetRemapComponents >> 4) & 0x7);
public SetRemapComponentsDst SetRemapComponentsDstZ => (SetRemapComponentsDst)((SetRemapComponents >> 8) & 0x7);
public SetRemapComponentsDst SetRemapComponentsDstW => (SetRemapComponentsDst)((SetRemapComponents >> 12) & 0x7);
@@ -239,7 +239,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
public SetRemapComponentsNumComponents SetRemapComponentsNumSrcComponents => (SetRemapComponentsNumComponents)((SetRemapComponents >> 20) & 0x3);
public SetRemapComponentsNumComponents SetRemapComponentsNumDstComponents => (SetRemapComponentsNumComponents)((SetRemapComponents >> 24) & 0x3);
public uint SetDstBlockSize;
- public SetBlockSizeWidth SetDstBlockSizeWidth => (SetBlockSizeWidth)((SetDstBlockSize >> 0) & 0xF);
+ public SetBlockSizeWidth SetDstBlockSizeWidth => (SetBlockSizeWidth)(SetDstBlockSize & 0xF);
public SetBlockSizeHeight SetDstBlockSizeHeight => (SetBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
public SetBlockSizeDepth SetDstBlockSizeDepth => (SetBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
public SetBlockSizeGobHeight SetDstBlockSizeGobHeight => (SetBlockSizeGobHeight)((SetDstBlockSize >> 12) & 0xF);
@@ -248,11 +248,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
public uint SetDstDepth;
public uint SetDstLayer;
public uint SetDstOrigin;
- public int SetDstOriginX => (int)((SetDstOrigin >> 0) & 0xFFFF);
+ public int SetDstOriginX => (int)(SetDstOrigin & 0xFFFF);
public int SetDstOriginY => (int)((SetDstOrigin >> 16) & 0xFFFF);
public uint Reserved724;
public uint SetSrcBlockSize;
- public SetBlockSizeWidth SetSrcBlockSizeWidth => (SetBlockSizeWidth)((SetSrcBlockSize >> 0) & 0xF);
+ public SetBlockSizeWidth SetSrcBlockSizeWidth => (SetBlockSizeWidth)(SetSrcBlockSize & 0xF);
public SetBlockSizeHeight SetSrcBlockSizeHeight => (SetBlockSizeHeight)((SetSrcBlockSize >> 4) & 0xF);
public SetBlockSizeDepth SetSrcBlockSizeDepth => (SetBlockSizeDepth)((SetSrcBlockSize >> 8) & 0xF);
public SetBlockSizeGobHeight SetSrcBlockSizeGobHeight => (SetBlockSizeGobHeight)((SetSrcBlockSize >> 12) & 0xF);
@@ -261,7 +261,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
public uint SetSrcDepth;
public uint SetSrcLayer;
public uint SetSrcOrigin;
- public int SetSrcOriginX => (int)((SetSrcOrigin >> 0) & 0xFFFF);
+ public int SetSrcOriginX => (int)(SetSrcOrigin & 0xFFFF);
public int SetSrcOriginY => (int)((SetSrcOrigin >> 16) & 0xFFFF);
public fixed uint Reserved740[629];
public uint PmTriggerEnd;
diff --git a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/CompressedMethod.cs b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/CompressedMethod.cs
index 458dc8f6f..d082ee9dd 100644
--- a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/CompressedMethod.cs
+++ b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/CompressedMethod.cs
@@ -29,7 +29,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
public uint Method;
#pragma warning restore CS0649
public int MethodAddressOld => (int)((Method >> 2) & 0x7FF);
- public int MethodAddress => (int)((Method >> 0) & 0xFFF);
+ public int MethodAddress => (int)(Method & 0xFFF);
public int SubdeviceMask => (int)((Method >> 4) & 0xFFF);
public int MethodSubchannel => (int)((Method >> 13) & 0x7);
public TertOp TertOp => (TertOp)((Method >> 16) & 0x3);
diff --git a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPEntry.cs b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPEntry.cs
index b1b236e77..31ba3217d 100644
--- a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPEntry.cs
+++ b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPEntry.cs
@@ -39,17 +39,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
#pragma warning disable CS0649
public uint Entry0;
#pragma warning restore CS0649
- public Entry0Fetch Entry0Fetch => (Entry0Fetch)((Entry0 >> 0) & 0x1);
+ public Entry0Fetch Entry0Fetch => (Entry0Fetch)(Entry0 & 0x1);
public int Entry0Get => (int)((Entry0 >> 2) & 0x3FFFFFFF);
public int Entry0Operand => (int)(Entry0);
#pragma warning disable CS0649
public uint Entry1;
#pragma warning restore CS0649
- public int Entry1GetHi => (int)((Entry1 >> 0) & 0xFF);
+ public int Entry1GetHi => (int)(Entry1 & 0xFF);
public Entry1Priv Entry1Priv => (Entry1Priv)((Entry1 >> 8) & 0x1);
public Entry1Level Entry1Level => (Entry1Level)((Entry1 >> 9) & 0x1);
public int Entry1Length => (int)((Entry1 >> 10) & 0x1FFFFF);
public Entry1Sync Entry1Sync => (Entry1Sync)((Entry1 >> 31) & 0x1);
- public Entry1Opcode Entry1Opcode => (Entry1Opcode)((Entry1 >> 0) & 0xFF);
+ public Entry1Opcode Entry1Opcode => (Entry1Opcode)(Entry1 & 0xFF);
}
}
diff --git a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClassState.cs b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClassState.cs
index 07d062eb6..ebfe15664 100644
--- a/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClassState.cs
+++ b/src/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClassState.cs
@@ -153,7 +153,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
{
#pragma warning disable CS0649
public uint SetObject;
- public int SetObjectNvclass => (int)((SetObject >> 0) & 0xFFFF);
+ public int SetObjectNvclass => (int)(SetObject & 0xFFFF);
public int SetObjectEngine => (int)((SetObject >> 16) & 0x1F);
public uint Illegal;
public int IllegalHandle => (int)(Illegal);
@@ -161,13 +161,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
public int NopHandle => (int)(Nop);
public uint Reserved0C;
public uint Semaphorea;
- public int SemaphoreaOffsetUpper => (int)((Semaphorea >> 0) & 0xFF);
+ public int SemaphoreaOffsetUpper => (int)(Semaphorea & 0xFF);
public uint Semaphoreb;
public int SemaphorebOffsetLower => (int)((Semaphoreb >> 2) & 0x3FFFFFFF);
public uint Semaphorec;
public int SemaphorecPayload => (int)(Semaphorec);
public uint Semaphored;
- public SemaphoredOperation SemaphoredOperation => (SemaphoredOperation)((Semaphored >> 0) & 0x1F);
+ public SemaphoredOperation SemaphoredOperation => (SemaphoredOperation)(Semaphored & 0x1F);
public SemaphoredAcquireSwitch SemaphoredAcquireSwitch => (SemaphoredAcquireSwitch)((Semaphored >> 12) & 0x1);
public SemaphoredReleaseWfi SemaphoredReleaseWfi => (SemaphoredReleaseWfi)((Semaphored >> 20) & 0x1);
public SemaphoredReleaseSize SemaphoredReleaseSize => (SemaphoredReleaseSize)((Semaphored >> 24) & 0x1);
@@ -181,14 +181,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
public uint Reserved2C;
public uint MemOpC;
public int MemOpCOperandLow => (int)((MemOpC >> 2) & 0x3FFFFFFF);
- public MemOpCTlbInvalidatePdb MemOpCTlbInvalidatePdb => (MemOpCTlbInvalidatePdb)((MemOpC >> 0) & 0x1);
+ public MemOpCTlbInvalidatePdb MemOpCTlbInvalidatePdb => (MemOpCTlbInvalidatePdb)(MemOpC & 0x1);
public MemOpCTlbInvalidateGpc MemOpCTlbInvalidateGpc => (MemOpCTlbInvalidateGpc)((MemOpC >> 1) & 0x1);
public MemOpCTlbInvalidateTarget MemOpCTlbInvalidateTarget => (MemOpCTlbInvalidateTarget)((MemOpC >> 10) & 0x3);
public int MemOpCTlbInvalidateAddrLo => (int)((MemOpC >> 12) & 0xFFFFF);
public uint MemOpD;
- public int MemOpDOperandHigh => (int)((MemOpD >> 0) & 0xFF);
+ public int MemOpDOperandHigh => (int)(MemOpD & 0xFF);
public MemOpDOperation MemOpDOperation => (MemOpDOperation)((MemOpD >> 27) & 0x1F);
- public int MemOpDTlbInvalidateAddrHi => (int)((MemOpD >> 0) & 0xFF);
+ public int MemOpDTlbInvalidateAddrHi => (int)(MemOpD & 0xFF);
public uint Reserved38;
public uint Reserved3C;
public uint Reserved40;
@@ -207,15 +207,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
public uint Syncpointa;
public int SyncpointaPayload => (int)(Syncpointa);
public uint Syncpointb;
- public SyncpointbOperation SyncpointbOperation => (SyncpointbOperation)((Syncpointb >> 0) & 0x1);
+ public SyncpointbOperation SyncpointbOperation => (SyncpointbOperation)(Syncpointb & 0x1);
public SyncpointbWaitSwitch SyncpointbWaitSwitch => (SyncpointbWaitSwitch)((Syncpointb >> 4) & 0x1);
public int SyncpointbSyncptIndex => (int)((Syncpointb >> 8) & 0xFFF);
public uint Wfi;
- public WfiScope WfiScope => (WfiScope)((Wfi >> 0) & 0x1);
+ public WfiScope WfiScope => (WfiScope)(Wfi & 0x1);
public uint CrcCheck;
public int CrcCheckValue => (int)(CrcCheck);
public uint Yield;
- public YieldOp YieldOp => (YieldOp)((Yield >> 0) & 0x3);
+ public YieldOp YieldOp => (YieldOp)(Yield & 0x3);
// TODO: Eventually move this to per-engine state.
public Array31 Reserved84;
public uint NoOperation;
diff --git a/src/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClassState.cs b/src/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClassState.cs
index d0c82a5e4..f6d9602a6 100644
--- a/src/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClassState.cs
+++ b/src/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClassState.cs
@@ -113,22 +113,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
{
#pragma warning disable CS0649
public uint SetObject;
- public int SetObjectClassId => (int)((SetObject >> 0) & 0xFFFF);
+ public int SetObjectClassId => (int)(SetObject & 0xFFFF);
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
public fixed uint Reserved04[63];
public uint NoOperation;
public uint SetNotifyA;
- public int SetNotifyAAddressUpper => (int)((SetNotifyA >> 0) & 0xFF);
+ public int SetNotifyAAddressUpper => (int)(SetNotifyA & 0xFF);
public uint SetNotifyB;
public uint Notify;
public NotifyType NotifyType => (NotifyType)(Notify);
public uint WaitForIdle;
public fixed uint Reserved114[7];
public uint SetGlobalRenderEnableA;
- public int SetGlobalRenderEnableAOffsetUpper => (int)((SetGlobalRenderEnableA >> 0) & 0xFF);
+ public int SetGlobalRenderEnableAOffsetUpper => (int)(SetGlobalRenderEnableA & 0xFF);
public uint SetGlobalRenderEnableB;
public uint SetGlobalRenderEnableC;
- public int SetGlobalRenderEnableCMode => (int)((SetGlobalRenderEnableC >> 0) & 0x7);
+ public int SetGlobalRenderEnableCMode => (int)(SetGlobalRenderEnableC & 0x7);
public uint SendGoIdle;
public uint PmTrigger;
public uint PmTriggerWfi;
@@ -139,11 +139,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
public uint LineLengthIn;
public uint LineCount;
public uint OffsetOutUpper;
- public int OffsetOutUpperValue => (int)((OffsetOutUpper >> 0) & 0xFF);
+ public int OffsetOutUpperValue => (int)(OffsetOutUpper & 0xFF);
public uint OffsetOut;
public uint PitchOut;
public uint SetDstBlockSize;
- public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)((SetDstBlockSize >> 0) & 0xF);
+ public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)(SetDstBlockSize & 0xF);
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
public uint SetDstWidth;
@@ -151,11 +151,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
public uint SetDstDepth;
public uint SetDstLayer;
public uint SetDstOriginBytesX;
- public int SetDstOriginBytesXV => (int)((SetDstOriginBytesX >> 0) & 0xFFFFF);
+ public int SetDstOriginBytesXV => (int)(SetDstOriginBytesX & 0xFFFFF);
public uint SetDstOriginSamplesY;
- public int SetDstOriginSamplesYV => (int)((SetDstOriginSamplesY >> 0) & 0xFFFF);
+ public int SetDstOriginSamplesYV => (int)(SetDstOriginSamplesY & 0xFFFF);
public uint LaunchDma;
- public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)((LaunchDma >> 0) & 0x1);
+ public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)(LaunchDma & 0x1);
public LaunchDmaCompletionType LaunchDmaCompletionType => (LaunchDmaCompletionType)((LaunchDma >> 4) & 0x3);
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 8) & 0x3);
public LaunchDmaSemaphoreStructSize LaunchDmaSemaphoreStructSize => (LaunchDmaSemaphoreStructSize)((LaunchDma >> 12) & 0x1);
@@ -166,7 +166,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
public uint LoadInlineData;
public fixed uint Reserved1B8[9];
public uint SetI2mSemaphoreA;
- public int SetI2mSemaphoreAOffsetUpper => (int)((SetI2mSemaphoreA >> 0) & 0xFF);
+ public int SetI2mSemaphoreAOffsetUpper => (int)(SetI2mSemaphoreA & 0xFF);
public uint SetI2mSemaphoreB;
public uint SetI2mSemaphoreC;
public fixed uint Reserved1E8[2];
diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs
index 7438ba03b..9c4921c8b 100644
--- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs
+++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs
@@ -539,6 +539,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
engine.UpdateState();
+ if (instanceCount > 1)
+ {
+ // Must be called after UpdateState as it assumes the shader state
+ // has already been set, and that bindings have been updated already.
+
+ _channel.BufferManager.SetInstancedDrawVertexCount(count);
+ }
+
if (indexed)
{
_context.Renderer.Pipeline.DrawIndexed(count, instanceCount, firstIndex, firstVertex, firstInstance);
@@ -676,6 +684,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_channel.BufferManager.SetIndexBuffer(br, IndexType.UInt);
}
+ _channel.BufferManager.SetInstancedDrawVertexCount(_instancedIndexCount);
+
_context.Renderer.Pipeline.DrawIndexed(
_instancedIndexCount,
_instanceIndex + 1,
@@ -685,6 +695,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
}
else
{
+ _channel.BufferManager.SetInstancedDrawVertexCount(_instancedDrawStateCount);
+
_context.Renderer.Pipeline.Draw(
_instancedDrawStateCount,
_instanceIndex + 1,
diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
index 5fa4702b8..92e980ced 100644
--- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
+++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
@@ -269,7 +269,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_prevFirstVertex = _state.State.FirstVertex;
}
- bool tfEnable = _state.State.TfEnable;
+ bool tfEnable = _state.State.TfEnable && _context.Capabilities.SupportsTransformFeedback;
if (!tfEnable && _prevTfEnable)
{
@@ -1367,6 +1367,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_vsUsesDrawParameters = gs.Shaders[1]?.Info.UsesDrawParameters ?? false;
_vsClipDistancesWritten = gs.Shaders[1]?.Info.ClipDistancesWritten ?? 0;
+ bool hasTransformFeedback = gs.SpecializationState.TransformFeedbackDescriptors != null;
+ if (hasTransformFeedback != _channel.BufferManager.HasTransformFeedbackOutputs)
+ {
+ if (!_context.Capabilities.SupportsTransformFeedback)
+ {
+ // If host does not support transform feedback, and the shader changed,
+ // we might need to update bindings as transform feedback emulation
+ // uses storage buffer bindings that might have been used for something
+ // else in a previous draw.
+
+ _channel.BufferManager.ForceTransformFeedbackAndStorageBuffersDirty();
+ }
+
+ _channel.BufferManager.HasTransformFeedbackOutputs = hasTransformFeedback;
+ }
+
if (oldVsClipDistancesWritten != _vsClipDistancesWritten)
{
UpdateUserClipState();
diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs
index 8f26f38ff..beda2dbfe 100644
--- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs
+++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs
@@ -746,12 +746,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
{
#pragma warning disable CS0649
public uint SetObject;
- public int SetObjectClassId => (int)((SetObject >> 0) & 0xFFFF);
+ public int SetObjectClassId => (int)(SetObject & 0xFFFF);
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
public fixed uint Reserved04[63];
public uint NoOperation;
public uint SetNotifyA;
- public int SetNotifyAAddressUpper => (int)((SetNotifyA >> 0) & 0xFF);
+ public int SetNotifyAAddressUpper => (int)(SetNotifyA & 0xFF);
public uint SetNotifyB;
public uint Notify;
public NotifyType NotifyType => (NotifyType)(Notify);
@@ -761,13 +761,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
public uint LoadMmeStartAddressRamPointer;
public uint LoadMmeStartAddressRam;
public uint SetMmeShadowRamControl;
- public SetMmeShadowRamControlMode SetMmeShadowRamControlMode => (SetMmeShadowRamControlMode)((SetMmeShadowRamControl >> 0) & 0x3);
+ public SetMmeShadowRamControlMode SetMmeShadowRamControlMode => (SetMmeShadowRamControlMode)(SetMmeShadowRamControl & 0x3);
public fixed uint Reserved128[2];
public uint SetGlobalRenderEnableA;
- public int SetGlobalRenderEnableAOffsetUpper => (int)((SetGlobalRenderEnableA >> 0) & 0xFF);
+ public int SetGlobalRenderEnableAOffsetUpper => (int)(SetGlobalRenderEnableA & 0xFF);
public uint SetGlobalRenderEnableB;
public uint SetGlobalRenderEnableC;
- public int SetGlobalRenderEnableCMode => (int)((SetGlobalRenderEnableC >> 0) & 0x7);
+ public int SetGlobalRenderEnableCMode => (int)(SetGlobalRenderEnableC & 0x7);
public uint SendGoIdle;
public uint PmTrigger;
public uint PmTriggerWfi;
@@ -778,11 +778,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
public uint LineLengthIn;
public uint LineCount;
public uint OffsetOutUpper;
- public int OffsetOutUpperValue => (int)((OffsetOutUpper >> 0) & 0xFF);
+ public int OffsetOutUpperValue => (int)(OffsetOutUpper & 0xFF);
public uint OffsetOut;
public uint PitchOut;
public uint SetDstBlockSize;
- public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)((SetDstBlockSize >> 0) & 0xF);
+ public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)(SetDstBlockSize & 0xF);
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
public uint SetDstWidth;
@@ -790,11 +790,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
public uint SetDstDepth;
public uint SetDstLayer;
public uint SetDstOriginBytesX;
- public int SetDstOriginBytesXV => (int)((SetDstOriginBytesX >> 0) & 0xFFFFF);
+ public int SetDstOriginBytesXV => (int)(SetDstOriginBytesX & 0xFFFFF);
public uint SetDstOriginSamplesY;
- public int SetDstOriginSamplesYV => (int)((SetDstOriginSamplesY >> 0) & 0xFFFF);
+ public int SetDstOriginSamplesYV => (int)(SetDstOriginSamplesY & 0xFFFF);
public uint LaunchDma;
- public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)((LaunchDma >> 0) & 0x1);
+ public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)(LaunchDma & 0x1);
public LaunchDmaCompletionType LaunchDmaCompletionType => (LaunchDmaCompletionType)((LaunchDma >> 4) & 0x3);
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 8) & 0x3);
public LaunchDmaSemaphoreStructSize LaunchDmaSemaphoreStructSize => (LaunchDmaSemaphoreStructSize)((LaunchDma >> 12) & 0x1);
diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodClassState.cs b/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodClassState.cs
index 46fddb04c..55e5019fc 100644
--- a/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodClassState.cs
+++ b/src/Ryujinx.Graphics.Gpu/Engine/Twod/TwodClassState.cs
@@ -499,12 +499,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
{
#pragma warning disable CS0649
public uint SetObject;
- public int SetObjectClassId => (int)((SetObject >> 0) & 0xFFFF);
+ public int SetObjectClassId => (int)(SetObject & 0xFFFF);
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
public fixed uint Reserved04[63];
public uint NoOperation;
public uint SetNotifyA;
- public int SetNotifyAAddressUpper => (int)((SetNotifyA >> 0) & 0x1FFFFFF);
+ public int SetNotifyAAddressUpper => (int)(SetNotifyA & 0x1FFFFFF);
public uint SetNotifyB;
public uint Notify;
public NotifyType NotifyType => (NotifyType)(Notify);
@@ -514,13 +514,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
public uint LoadMmeStartAddressRamPointer;
public uint LoadMmeStartAddressRam;
public uint SetMmeShadowRamControl;
- public SetMmeShadowRamControlMode SetMmeShadowRamControlMode => (SetMmeShadowRamControlMode)((SetMmeShadowRamControl >> 0) & 0x3);
+ public SetMmeShadowRamControlMode SetMmeShadowRamControlMode => (SetMmeShadowRamControlMode)(SetMmeShadowRamControl & 0x3);
public fixed uint Reserved128[2];
public uint SetGlobalRenderEnableA;
- public int SetGlobalRenderEnableAOffsetUpper => (int)((SetGlobalRenderEnableA >> 0) & 0xFF);
+ public int SetGlobalRenderEnableAOffsetUpper => (int)(SetGlobalRenderEnableA & 0xFF);
public uint SetGlobalRenderEnableB;
public uint SetGlobalRenderEnableC;
- public int SetGlobalRenderEnableCMode => (int)((SetGlobalRenderEnableC >> 0) & 0x7);
+ public int SetGlobalRenderEnableCMode => (int)(SetGlobalRenderEnableC & 0x7);
public uint SendGoIdle;
public uint PmTrigger;
public fixed uint Reserved144[3];
@@ -533,9 +533,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
public int SetMmeSwitchStateRestoreMacro => (int)((SetMmeSwitchState >> 12) & 0xFF);
public fixed uint Reserved1F0[4];
public uint SetDstFormat;
- public SetDstFormatV SetDstFormatV => (SetDstFormatV)((SetDstFormat >> 0) & 0xFF);
+ public SetDstFormatV SetDstFormatV => (SetDstFormatV)(SetDstFormat & 0xFF);
public uint SetDstMemoryLayout;
- public SetDstMemoryLayoutV SetDstMemoryLayoutV => (SetDstMemoryLayoutV)((SetDstMemoryLayout >> 0) & 0x1);
+ public SetDstMemoryLayoutV SetDstMemoryLayoutV => (SetDstMemoryLayoutV)(SetDstMemoryLayout & 0x1);
public uint SetDstBlockSize;
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0x7);
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0x7);
@@ -545,37 +545,37 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
public uint SetDstWidth;
public uint SetDstHeight;
public uint SetDstOffsetUpper;
- public int SetDstOffsetUpperV => (int)((SetDstOffsetUpper >> 0) & 0xFF);
+ public int SetDstOffsetUpperV => (int)(SetDstOffsetUpper & 0xFF);
public uint SetDstOffsetLower;
public uint FlushAndInvalidateRopMiniCache;
public bool FlushAndInvalidateRopMiniCacheV => (FlushAndInvalidateRopMiniCache & 0x1) != 0;
public uint SetSpareNoop06;
public uint SetSrcFormat;
- public SetSrcFormatV SetSrcFormatV => (SetSrcFormatV)((SetSrcFormat >> 0) & 0xFF);
+ public SetSrcFormatV SetSrcFormatV => (SetSrcFormatV)(SetSrcFormat & 0xFF);
public uint SetSrcMemoryLayout;
- public SetSrcMemoryLayoutV SetSrcMemoryLayoutV => (SetSrcMemoryLayoutV)((SetSrcMemoryLayout >> 0) & 0x1);
+ public SetSrcMemoryLayoutV SetSrcMemoryLayoutV => (SetSrcMemoryLayoutV)(SetSrcMemoryLayout & 0x1);
public uint SetSrcBlockSize;
public SetSrcBlockSizeHeight SetSrcBlockSizeHeight => (SetSrcBlockSizeHeight)((SetSrcBlockSize >> 4) & 0x7);
public SetSrcBlockSizeDepth SetSrcBlockSizeDepth => (SetSrcBlockSizeDepth)((SetSrcBlockSize >> 8) & 0x7);
public uint SetSrcDepth;
public uint TwodInvalidateTextureDataCache;
- public TwodInvalidateTextureDataCacheV TwodInvalidateTextureDataCacheV => (TwodInvalidateTextureDataCacheV)((TwodInvalidateTextureDataCache >> 0) & 0x3);
+ public TwodInvalidateTextureDataCacheV TwodInvalidateTextureDataCacheV => (TwodInvalidateTextureDataCacheV)(TwodInvalidateTextureDataCache & 0x3);
public uint SetSrcPitch;
public uint SetSrcWidth;
public uint SetSrcHeight;
public uint SetSrcOffsetUpper;
- public int SetSrcOffsetUpperV => (int)((SetSrcOffsetUpper >> 0) & 0xFF);
+ public int SetSrcOffsetUpperV => (int)(SetSrcOffsetUpper & 0xFF);
public uint SetSrcOffsetLower;
public uint SetPixelsFromMemorySectorPromotion;
- public SetPixelsFromMemorySectorPromotionV SetPixelsFromMemorySectorPromotionV => (SetPixelsFromMemorySectorPromotionV)((SetPixelsFromMemorySectorPromotion >> 0) & 0x3);
+ public SetPixelsFromMemorySectorPromotionV SetPixelsFromMemorySectorPromotionV => (SetPixelsFromMemorySectorPromotionV)(SetPixelsFromMemorySectorPromotion & 0x3);
public uint SetSpareNoop12;
public uint SetNumProcessingClusters;
- public SetNumProcessingClustersV SetNumProcessingClustersV => (SetNumProcessingClustersV)((SetNumProcessingClusters >> 0) & 0x1);
+ public SetNumProcessingClustersV SetNumProcessingClustersV => (SetNumProcessingClustersV)(SetNumProcessingClusters & 0x1);
public uint SetRenderEnableA;
- public int SetRenderEnableAOffsetUpper => (int)((SetRenderEnableA >> 0) & 0xFF);
+ public int SetRenderEnableAOffsetUpper => (int)(SetRenderEnableA & 0xFF);
public uint SetRenderEnableB;
public uint SetRenderEnableC;
- public int SetRenderEnableCMode => (int)((SetRenderEnableC >> 0) & 0x7);
+ public int SetRenderEnableCMode => (int)(SetRenderEnableC & 0x7);
public uint SetSpareNoop08;
public uint SetSpareNoop01;
public uint SetSpareNoop11;
@@ -587,25 +587,25 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
public uint SetClipEnable;
public bool SetClipEnableV => (SetClipEnable & 0x1) != 0;
public uint SetColorKeyFormat;
- public SetColorKeyFormatV SetColorKeyFormatV => (SetColorKeyFormatV)((SetColorKeyFormat >> 0) & 0x7);
+ public SetColorKeyFormatV SetColorKeyFormatV => (SetColorKeyFormatV)(SetColorKeyFormat & 0x7);
public uint SetColorKey;
public uint SetColorKeyEnable;
public bool SetColorKeyEnableV => (SetColorKeyEnable & 0x1) != 0;
public uint SetRop;
- public int SetRopV => (int)((SetRop >> 0) & 0xFF);
+ public int SetRopV => (int)(SetRop & 0xFF);
public uint SetBeta1;
public uint SetBeta4;
- public int SetBeta4B => (int)((SetBeta4 >> 0) & 0xFF);
+ public int SetBeta4B => (int)(SetBeta4 & 0xFF);
public int SetBeta4G => (int)((SetBeta4 >> 8) & 0xFF);
public int SetBeta4R => (int)((SetBeta4 >> 16) & 0xFF);
public int SetBeta4A => (int)((SetBeta4 >> 24) & 0xFF);
public uint SetOperation;
- public SetOperationV SetOperationV => (SetOperationV)((SetOperation >> 0) & 0x7);
+ public SetOperationV SetOperationV => (SetOperationV)(SetOperation & 0x7);
public uint SetPatternOffset;
- public int SetPatternOffsetX => (int)((SetPatternOffset >> 0) & 0x3F);
+ public int SetPatternOffsetX => (int)(SetPatternOffset & 0x3F);
public int SetPatternOffsetY => (int)((SetPatternOffset >> 8) & 0x3F);
public uint SetPatternSelect;
- public SetPatternSelectV SetPatternSelectV => (SetPatternSelectV)((SetPatternSelect >> 0) & 0x3);
+ public SetPatternSelectV SetPatternSelectV => (SetPatternSelectV)(SetPatternSelect & 0x3);
public uint SetDstColorRenderToZetaSurface;
public bool SetDstColorRenderToZetaSurfaceV => (SetDstColorRenderToZetaSurface & 0x1) != 0;
public uint SetSpareNoop04;
@@ -618,15 +618,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
public bool SetCompressionEnable => (SetCompression & 0x1) != 0;
public uint SetSpareNoop09;
public uint SetRenderEnableOverride;
- public SetRenderEnableOverrideMode SetRenderEnableOverrideMode => (SetRenderEnableOverrideMode)((SetRenderEnableOverride >> 0) & 0x3);
+ public SetRenderEnableOverrideMode SetRenderEnableOverrideMode => (SetRenderEnableOverrideMode)(SetRenderEnableOverride & 0x3);
public uint SetPixelsFromMemoryDirection;
- public SetPixelsFromMemoryDirectionHorizontal SetPixelsFromMemoryDirectionHorizontal => (SetPixelsFromMemoryDirectionHorizontal)((SetPixelsFromMemoryDirection >> 0) & 0x3);
+ public SetPixelsFromMemoryDirectionHorizontal SetPixelsFromMemoryDirectionHorizontal => (SetPixelsFromMemoryDirectionHorizontal)(SetPixelsFromMemoryDirection & 0x3);
public SetPixelsFromMemoryDirectionVertical SetPixelsFromMemoryDirectionVertical => (SetPixelsFromMemoryDirectionVertical)((SetPixelsFromMemoryDirection >> 4) & 0x3);
public uint SetSpareNoop10;
public uint SetMonochromePatternColorFormat;
- public SetMonochromePatternColorFormatV SetMonochromePatternColorFormatV => (SetMonochromePatternColorFormatV)((SetMonochromePatternColorFormat >> 0) & 0x7);
+ public SetMonochromePatternColorFormatV SetMonochromePatternColorFormatV => (SetMonochromePatternColorFormatV)(SetMonochromePatternColorFormat & 0x7);
public uint SetMonochromePatternFormat;
- public SetMonochromePatternFormatV SetMonochromePatternFormatV => (SetMonochromePatternFormatV)((SetMonochromePatternFormat >> 0) & 0x1);
+ public SetMonochromePatternFormatV SetMonochromePatternFormatV => (SetMonochromePatternFormatV)(SetMonochromePatternFormat & 0x1);
public uint SetMonochromePatternColor0;
public uint SetMonochromePatternColor1;
public uint SetMonochromePattern0;
@@ -662,26 +662,26 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
public uint SetRenderSolidPrimColor2;
public uint SetRenderSolidPrimColor3;
public uint SetMmeMemAddressA;
- public int SetMmeMemAddressAUpper => (int)((SetMmeMemAddressA >> 0) & 0x1FFFFFF);
+ public int SetMmeMemAddressAUpper => (int)(SetMmeMemAddressA & 0x1FFFFFF);
public uint SetMmeMemAddressB;
public uint SetMmeDataRamAddress;
public uint MmeDmaRead;
public uint MmeDmaReadFifoed;
public uint MmeDmaWrite;
public uint MmeDmaReduction;
- public MmeDmaReductionReductionOp MmeDmaReductionReductionOp => (MmeDmaReductionReductionOp)((MmeDmaReduction >> 0) & 0x7);
+ public MmeDmaReductionReductionOp MmeDmaReductionReductionOp => (MmeDmaReductionReductionOp)(MmeDmaReduction & 0x7);
public MmeDmaReductionReductionFormat MmeDmaReductionReductionFormat => (MmeDmaReductionReductionFormat)((MmeDmaReduction >> 4) & 0x3);
public MmeDmaReductionReductionSize MmeDmaReductionReductionSize => (MmeDmaReductionReductionSize)((MmeDmaReduction >> 8) & 0x1);
public uint MmeDmaSysmembar;
public bool MmeDmaSysmembarV => (MmeDmaSysmembar & 0x1) != 0;
public uint MmeDmaSync;
public uint SetMmeDataFifoConfig;
- public SetMmeDataFifoConfigFifoSize SetMmeDataFifoConfigFifoSize => (SetMmeDataFifoConfigFifoSize)((SetMmeDataFifoConfig >> 0) & 0x7);
+ public SetMmeDataFifoConfigFifoSize SetMmeDataFifoConfigFifoSize => (SetMmeDataFifoConfigFifoSize)(SetMmeDataFifoConfig & 0x7);
public fixed uint Reserved578[2];
public uint RenderSolidPrimMode;
- public RenderSolidPrimModeV RenderSolidPrimModeV => (RenderSolidPrimModeV)((RenderSolidPrimMode >> 0) & 0x7);
+ public RenderSolidPrimModeV RenderSolidPrimModeV => (RenderSolidPrimModeV)(RenderSolidPrimMode & 0x7);
public uint SetRenderSolidPrimColorFormat;
- public SetRenderSolidPrimColorFormatV SetRenderSolidPrimColorFormatV => (SetRenderSolidPrimColorFormatV)((SetRenderSolidPrimColorFormat >> 0) & 0xFF);
+ public SetRenderSolidPrimColorFormatV SetRenderSolidPrimColorFormatV => (SetRenderSolidPrimColorFormatV)(SetRenderSolidPrimColorFormat & 0xFF);
public uint SetRenderSolidPrimColor;
public uint SetRenderSolidLineTieBreakBits;
public bool SetRenderSolidLineTieBreakBitsXmajXincYinc => (SetRenderSolidLineTieBreakBits & 0x1) != 0;
@@ -690,24 +690,24 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
public bool SetRenderSolidLineTieBreakBitsYmajXdecYinc => (SetRenderSolidLineTieBreakBits & 0x1000) != 0;
public fixed uint Reserved590[20];
public uint RenderSolidPrimPointXY;
- public int RenderSolidPrimPointXYX => (int)((RenderSolidPrimPointXY >> 0) & 0xFFFF);
+ public int RenderSolidPrimPointXYX => (int)(RenderSolidPrimPointXY & 0xFFFF);
public int RenderSolidPrimPointXYY => (int)((RenderSolidPrimPointXY >> 16) & 0xFFFF);
public fixed uint Reserved5E4[7];
public Array64 RenderSolidPrimPoint;
public uint SetPixelsFromCpuDataType;
- public SetPixelsFromCpuDataTypeV SetPixelsFromCpuDataTypeV => (SetPixelsFromCpuDataTypeV)((SetPixelsFromCpuDataType >> 0) & 0x1);
+ public SetPixelsFromCpuDataTypeV SetPixelsFromCpuDataTypeV => (SetPixelsFromCpuDataTypeV)(SetPixelsFromCpuDataType & 0x1);
public uint SetPixelsFromCpuColorFormat;
- public SetPixelsFromCpuColorFormatV SetPixelsFromCpuColorFormatV => (SetPixelsFromCpuColorFormatV)((SetPixelsFromCpuColorFormat >> 0) & 0xFF);
+ public SetPixelsFromCpuColorFormatV SetPixelsFromCpuColorFormatV => (SetPixelsFromCpuColorFormatV)(SetPixelsFromCpuColorFormat & 0xFF);
public uint SetPixelsFromCpuIndexFormat;
- public SetPixelsFromCpuIndexFormatV SetPixelsFromCpuIndexFormatV => (SetPixelsFromCpuIndexFormatV)((SetPixelsFromCpuIndexFormat >> 0) & 0x3);
+ public SetPixelsFromCpuIndexFormatV SetPixelsFromCpuIndexFormatV => (SetPixelsFromCpuIndexFormatV)(SetPixelsFromCpuIndexFormat & 0x3);
public uint SetPixelsFromCpuMonoFormat;
- public SetPixelsFromCpuMonoFormatV SetPixelsFromCpuMonoFormatV => (SetPixelsFromCpuMonoFormatV)((SetPixelsFromCpuMonoFormat >> 0) & 0x1);
+ public SetPixelsFromCpuMonoFormatV SetPixelsFromCpuMonoFormatV => (SetPixelsFromCpuMonoFormatV)(SetPixelsFromCpuMonoFormat & 0x1);
public uint SetPixelsFromCpuWrap;
- public SetPixelsFromCpuWrapV SetPixelsFromCpuWrapV => (SetPixelsFromCpuWrapV)((SetPixelsFromCpuWrap >> 0) & 0x3);
+ public SetPixelsFromCpuWrapV SetPixelsFromCpuWrapV => (SetPixelsFromCpuWrapV)(SetPixelsFromCpuWrap & 0x3);
public uint SetPixelsFromCpuColor0;
public uint SetPixelsFromCpuColor1;
public uint SetPixelsFromCpuMonoOpacity;
- public SetPixelsFromCpuMonoOpacityV SetPixelsFromCpuMonoOpacityV => (SetPixelsFromCpuMonoOpacityV)((SetPixelsFromCpuMonoOpacity >> 0) & 0x1);
+ public SetPixelsFromCpuMonoOpacityV SetPixelsFromCpuMonoOpacityV => (SetPixelsFromCpuMonoOpacityV)(SetPixelsFromCpuMonoOpacity & 0x1);
public fixed uint Reserved820[6];
public uint SetPixelsFromCpuSrcWidth;
public uint SetPixelsFromCpuSrcHeight;
@@ -753,13 +753,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
public bool SetBigEndianControlOverride => (SetBigEndianControl & 0x10000000) != 0;
public fixed uint Reserved874[3];
public uint SetPixelsFromMemoryBlockShape;
- public SetPixelsFromMemoryBlockShapeV SetPixelsFromMemoryBlockShapeV => (SetPixelsFromMemoryBlockShapeV)((SetPixelsFromMemoryBlockShape >> 0) & 0x7);
+ public SetPixelsFromMemoryBlockShapeV SetPixelsFromMemoryBlockShapeV => (SetPixelsFromMemoryBlockShapeV)(SetPixelsFromMemoryBlockShape & 0x7);
public uint SetPixelsFromMemoryCorralSize;
- public int SetPixelsFromMemoryCorralSizeV => (int)((SetPixelsFromMemoryCorralSize >> 0) & 0x3FF);
+ public int SetPixelsFromMemoryCorralSizeV => (int)(SetPixelsFromMemoryCorralSize & 0x3FF);
public uint SetPixelsFromMemorySafeOverlap;
public bool SetPixelsFromMemorySafeOverlapV => (SetPixelsFromMemorySafeOverlap & 0x1) != 0;
public uint SetPixelsFromMemorySampleMode;
- public SetPixelsFromMemorySampleModeOrigin SetPixelsFromMemorySampleModeOrigin => (SetPixelsFromMemorySampleModeOrigin)((SetPixelsFromMemorySampleMode >> 0) & 0x1);
+ public SetPixelsFromMemorySampleModeOrigin SetPixelsFromMemorySampleModeOrigin => (SetPixelsFromMemorySampleModeOrigin)(SetPixelsFromMemorySampleMode & 0x1);
public SetPixelsFromMemorySampleModeFilter SetPixelsFromMemorySampleModeFilter => (SetPixelsFromMemorySampleModeFilter)((SetPixelsFromMemorySampleMode >> 4) & 0x1);
public fixed uint Reserved890[8];
public uint SetPixelsFromMemoryDstX0;
diff --git a/src/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs b/src/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs
index 48cb33b4d..07429cfe8 100644
--- a/src/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs
+++ b/src/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs
@@ -6,6 +6,7 @@ using Ryujinx.Graphics.Shader;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
namespace Ryujinx.Graphics.Gpu.Memory
{
@@ -14,12 +15,17 @@ namespace Ryujinx.Graphics.Gpu.Memory
///
class BufferManager
{
+ private const int TfInfoVertexCountOffset = Constants.TotalTransformFeedbackBuffers * sizeof(int);
+ private const int TfInfoBufferSize = TfInfoVertexCountOffset + sizeof(int);
+
private readonly GpuContext _context;
private readonly GpuChannel _channel;
private int _unalignedStorageBuffers;
public bool HasUnalignedStorageBuffers => _unalignedStorageBuffers > 0;
+ public bool HasTransformFeedbackOutputs { get; set; }
+
private IndexBuffer _indexBuffer;
private readonly VertexBuffer[] _vertexBuffers;
private readonly BufferBounds[] _transformFeedbackBuffers;
@@ -98,6 +104,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
private readonly BuffersPerStage[] _gpStorageBuffers;
private readonly BuffersPerStage[] _gpUniformBuffers;
+ private BufferHandle _tfInfoBuffer;
+ private int[] _tfInfoData;
+
private bool _gpStorageBuffersDirty;
private bool _gpUniformBuffersDirty;
@@ -137,6 +146,11 @@ namespace Ryujinx.Graphics.Gpu.Memory
_bufferTextures = new List();
_ranges = new BufferAssignment[Constants.TotalGpUniformBuffers * Constants.ShaderStages];
+
+ if (!context.Capabilities.SupportsTransformFeedback)
+ {
+ _tfInfoData = new int[Constants.TotalTransformFeedbackBuffers];
+ }
}
@@ -319,6 +333,31 @@ namespace Ryujinx.Graphics.Gpu.Memory
_gpUniformBuffersDirty = true;
}
+ ///
+ /// Sets the number of vertices per instance on a instanced draw. Used for transform feedback emulation.
+ ///
+ /// Vertex count per instance
+ public void SetInstancedDrawVertexCount(int vertexCount)
+ {
+ if (!_context.Capabilities.SupportsTransformFeedback &&
+ HasTransformFeedbackOutputs &&
+ _tfInfoBuffer != BufferHandle.Null)
+ {
+ Span data = stackalloc byte[sizeof(int)];
+ MemoryMarshal.Cast(data)[0] = vertexCount;
+ _context.Renderer.SetBufferData(_tfInfoBuffer, TfInfoVertexCountOffset, data);
+ }
+ }
+
+ ///
+ /// Forces transform feedback and storage buffers to be updated on the next draw.
+ ///
+ public void ForceTransformFeedbackAndStorageBuffersDirty()
+ {
+ _transformFeedbackBuffersDirty = true;
+ _gpStorageBuffersDirty = true;
+ }
+
///
/// Sets the binding points for the storage buffers bound on the compute pipeline.
///
@@ -537,22 +576,75 @@ namespace Ryujinx.Graphics.Gpu.Memory
{
_transformFeedbackBuffersDirty = false;
- Span tfbs = stackalloc BufferRange[Constants.TotalTransformFeedbackBuffers];
-
- for (int index = 0; index < Constants.TotalTransformFeedbackBuffers; index++)
+ if (_context.Capabilities.SupportsTransformFeedback)
{
- BufferBounds tfb = _transformFeedbackBuffers[index];
+ Span tfbs = stackalloc BufferRange[Constants.TotalTransformFeedbackBuffers];
- if (tfb.Address == 0)
+ for (int index = 0; index < Constants.TotalTransformFeedbackBuffers; index++)
{
- tfbs[index] = BufferRange.Empty;
- continue;
+ BufferBounds tfb = _transformFeedbackBuffers[index];
+
+ if (tfb.Address == 0)
+ {
+ tfbs[index] = BufferRange.Empty;
+ continue;
+ }
+
+ tfbs[index] = bufferCache.GetBufferRange(tfb.Address, tfb.Size, write: true);
}
- tfbs[index] = bufferCache.GetBufferRange(tfb.Address, tfb.Size, write: true);
+ _context.Renderer.Pipeline.SetTransformFeedbackBuffers(tfbs);
}
+ else if (HasTransformFeedbackOutputs)
+ {
+ Span info = _tfInfoData.AsSpan();
+ Span buffers = stackalloc BufferAssignment[Constants.TotalTransformFeedbackBuffers + 1];
- _context.Renderer.Pipeline.SetTransformFeedbackBuffers(tfbs);
+ bool needsDataUpdate = false;
+
+ if (_tfInfoBuffer == BufferHandle.Null)
+ {
+ _tfInfoBuffer = _context.Renderer.CreateBuffer(TfInfoBufferSize);
+ }
+
+ buffers[0] = new BufferAssignment(0, new BufferRange(_tfInfoBuffer, 0, TfInfoBufferSize));
+
+ int alignment = _context.Capabilities.StorageBufferOffsetAlignment;
+
+ for (int index = 0; index < Constants.TotalTransformFeedbackBuffers; index++)
+ {
+ BufferBounds tfb = _transformFeedbackBuffers[index];
+
+ if (tfb.Address == 0)
+ {
+ buffers[1 + index] = new BufferAssignment(1 + index, BufferRange.Empty);
+ }
+ else
+ {
+ ulong endAddress = tfb.Address + tfb.Size;
+ ulong address = BitUtils.AlignDown(tfb.Address, (ulong)alignment);
+ ulong size = endAddress - address;
+
+ int tfeOffset = ((int)tfb.Address & (alignment - 1)) / 4;
+
+ if (info[index] != tfeOffset)
+ {
+ info[index] = tfeOffset;
+ needsDataUpdate = true;
+ }
+
+ buffers[1 + index] = new BufferAssignment(1 + index, bufferCache.GetBufferRange(address, size, write: true));
+ }
+ }
+
+ if (needsDataUpdate)
+ {
+ Span infoData = MemoryMarshal.Cast(info);
+ _context.Renderer.SetBufferData(_tfInfoBuffer, 0, infoData);
+ }
+
+ _context.Renderer.Pipeline.SetStorageBuffers(buffers);
+ }
}
else
{
diff --git a/src/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs b/src/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs
index d0230b629..03504b11f 100644
--- a/src/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs
+++ b/src/Ryujinx.Graphics.Gpu/Memory/BufferModifiedRangeList.cs
@@ -78,7 +78,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
private List _sources;
private BufferMigration _migrationTarget;
- private object _lock = new object();
+ private readonly object _lock = new();
///
/// 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.
diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheGpuAccessor.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheGpuAccessor.cs
index 17639ca17..537cead0e 100644
--- a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheGpuAccessor.cs
+++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheGpuAccessor.cs
@@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
ShaderSpecializationState oldSpecState,
ShaderSpecializationState newSpecState,
ResourceCounts counts,
- int stageIndex) : base(context, counts, stageIndex)
+ int stageIndex) : base(context, counts, stageIndex, oldSpecState.TransformFeedbackDescriptors != null)
{
_data = data;
_cb1Data = cb1Data;
diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
index 4b828080d..153a2e8c1 100644
--- a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
+++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
- private const uint CodeGenVersion = 4992;
+ private const uint CodeGenVersion = 5080;
private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data";
@@ -368,7 +368,11 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
if (hostCode != null)
{
- ShaderInfo shaderInfo = ShaderInfoBuilder.BuildForCache(context, shaders, specState.PipelineState);
+ ShaderInfo shaderInfo = ShaderInfoBuilder.BuildForCache(
+ context,
+ shaders,
+ specState.PipelineState,
+ specState.TransformFeedbackDescriptors != null);
IProgram hostProgram;
diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs
index d80518b10..8df89824b 100644
--- a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs
+++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs
@@ -491,7 +491,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
{
ShaderSource[] shaderSources = new ShaderSource[compilation.TranslatedStages.Length];
- ShaderInfoBuilder shaderInfoBuilder = new ShaderInfoBuilder(_context);
+ ShaderInfoBuilder shaderInfoBuilder = new ShaderInfoBuilder(_context, compilation.SpecializationState.TransformFeedbackDescriptors != null);
for (int index = 0; index < compilation.TranslatedStages.Length; index++)
{
diff --git a/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs b/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs
index 3e8167331..5e18e61f2 100644
--- a/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs
+++ b/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs
@@ -30,7 +30,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
GpuContext context,
GpuChannel channel,
GpuAccessorState state,
- int stageIndex) : base(context, state.ResourceCounts, stageIndex)
+ int stageIndex) : base(context, state.ResourceCounts, stageIndex, state.TransformFeedbackDescriptors != null)
{
_isVulkan = context.Capabilities.Api == TargetApi.Vulkan;
_channel = channel;
@@ -44,7 +44,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// GPU context
/// GPU channel
/// Current GPU state
- public GpuAccessor(GpuContext context, GpuChannel channel, GpuAccessorState state) : base(context, state.ResourceCounts, 0)
+ public GpuAccessor(GpuContext context, GpuChannel channel, GpuAccessorState state) : base(context, state.ResourceCounts, 0, false)
{
_channel = channel;
_state = state;
diff --git a/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs b/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs
index 0001243d4..2dd7c631c 100644
--- a/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs
+++ b/src/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs
@@ -17,40 +17,56 @@ namespace Ryujinx.Graphics.Gpu.Shader
private readonly ResourceCounts _resourceCounts;
private readonly int _stageIndex;
+ private readonly int _reservedConstantBuffers;
+ private readonly int _reservedStorageBuffers;
+
///
/// Creates a new GPU accessor.
///
/// GPU context
- public GpuAccessorBase(GpuContext context, ResourceCounts resourceCounts, int stageIndex)
+ /// Counter of GPU resources used by the shader
+ /// Index of the shader stage, 0 for compute
+ /// Indicates if the current graphics shader is used with transform feedback enabled
+ public GpuAccessorBase(GpuContext context, ResourceCounts resourceCounts, int stageIndex, bool tfEnabled)
{
_context = context;
_resourceCounts = resourceCounts;
_stageIndex = stageIndex;
+
+ _reservedConstantBuffers = 1; // For the support buffer.
+ _reservedStorageBuffers = !context.Capabilities.SupportsTransformFeedback && tfEnabled ? 5 : 0;
}
public int QueryBindingConstantBuffer(int index)
{
+ int binding;
+
if (_context.Capabilities.Api == TargetApi.Vulkan)
{
- // We need to start counting from 1 since binding 0 is reserved for the support uniform buffer.
- return GetBindingFromIndex(index, _context.Capabilities.MaximumUniformBuffersPerStage, "Uniform buffer") + 1;
+ binding = GetBindingFromIndex(index, _context.Capabilities.MaximumUniformBuffersPerStage, "Uniform buffer");
}
else
{
- return _resourceCounts.UniformBuffersCount++;
+ binding = _resourceCounts.UniformBuffersCount++;
}
+
+ return binding + _reservedConstantBuffers;
}
public int QueryBindingStorageBuffer(int index)
{
+ int binding;
+
if (_context.Capabilities.Api == TargetApi.Vulkan)
{
- return GetBindingFromIndex(index, _context.Capabilities.MaximumStorageBuffersPerStage, "Storage buffer");
+ binding = GetBindingFromIndex(index, _context.Capabilities.MaximumStorageBuffersPerStage, "Storage buffer");
}
else
{
- return _resourceCounts.StorageBuffersCount++;
+ binding = _resourceCounts.StorageBuffersCount++;
}
+
+ return binding + _reservedStorageBuffers;
}
public int QueryBindingTexture(int index, bool isBuffer)
@@ -141,10 +157,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
public bool QueryHostSupportsShaderBallot() => _context.Capabilities.SupportsShaderBallot;
+ public bool QueryHostSupportsShaderBarrierDivergence() => _context.Capabilities.SupportsShaderBarrierDivergence;
+
+ public bool QueryHostSupportsShaderFloat64() => _context.Capabilities.SupportsShaderFloat64;
+
public bool QueryHostSupportsSnormBufferTextureFormat() => _context.Capabilities.SupportsSnormBufferTextureFormat;
public bool QueryHostSupportsTextureShadowLod() => _context.Capabilities.SupportsTextureShadowLod;
+ public bool QueryHostSupportsTransformFeedback() => _context.Capabilities.SupportsTransformFeedback;
+
public bool QueryHostSupportsViewportIndexVertexTessellation() => _context.Capabilities.SupportsViewportIndexVertexTessellation;
public bool QueryHostSupportsViewportMask() => _context.Capabilities.SupportsViewportMask;
diff --git a/src/Ryujinx.Graphics.Gpu/Shader/ResourceCounts.cs b/src/Ryujinx.Graphics.Gpu/Shader/ResourceCounts.cs
index b85423cb3..f495229ff 100644
--- a/src/Ryujinx.Graphics.Gpu/Shader/ResourceCounts.cs
+++ b/src/Ryujinx.Graphics.Gpu/Shader/ResourceCounts.cs
@@ -24,13 +24,5 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// Total of images used by the shaders.
///
public int ImagesCount;
-
- ///
- /// Creates a new instance of the shader resource counts class.
- ///
- public ResourceCounts()
- {
- UniformBuffersCount = 1; // The first binding is reserved for the support buffer.
- }
}
}
\ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
index b7ba159a5..913f6e9ec 100644
--- a/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
+++ b/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
@@ -362,7 +362,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
TranslatorContext previousStage = null;
- ShaderInfoBuilder infoBuilder = new ShaderInfoBuilder(_context);
+ ShaderInfoBuilder infoBuilder = new ShaderInfoBuilder(_context, transformFeedbackDescriptors != null);
for (int stageIndex = 0; stageIndex < Constants.ShaderStages; stageIndex++)
{
diff --git a/src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs b/src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs
index 3fc32d711..83d92edc3 100644
--- a/src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs
+++ b/src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs
@@ -16,15 +16,24 @@ namespace Ryujinx.Graphics.Gpu.Shader
private const int TextureSetIndex = 2;
private const int ImageSetIndex = 3;
- private const ResourceStages SupportBufferStags =
+ private const ResourceStages SupportBufferStages =
ResourceStages.Compute |
ResourceStages.Vertex |
ResourceStages.Fragment;
+ private const ResourceStages VtgStages =
+ ResourceStages.Vertex |
+ ResourceStages.TessellationControl |
+ ResourceStages.TessellationEvaluation |
+ ResourceStages.Geometry;
+
private readonly GpuContext _context;
private int _fragmentOutputMap;
+ private readonly int _reservedConstantBuffers;
+ private readonly int _reservedStorageBuffers;
+
private readonly List[] _resourceDescriptors;
private readonly List[] _resourceUsages;
@@ -32,7 +41,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// Creates a new shader info builder.
///
/// GPU context that owns the shaders that will be added to the builder
- public ShaderInfoBuilder(GpuContext context)
+ /// Indicates if the graphics shader is used with transform feedback enabled
+ public ShaderInfoBuilder(GpuContext context, bool tfEnabled)
{
_context = context;
@@ -47,7 +57,22 @@ namespace Ryujinx.Graphics.Gpu.Shader
_resourceUsages[index] = new();
}
- AddDescriptor(SupportBufferStags, ResourceType.UniformBuffer, UniformSetIndex, 0, 1);
+ AddDescriptor(SupportBufferStages, ResourceType.UniformBuffer, UniformSetIndex, 0, 1);
+
+ _reservedConstantBuffers = 1; // For the support buffer.
+
+ if (!context.Capabilities.SupportsTransformFeedback && tfEnabled)
+ {
+ _reservedStorageBuffers = 5;
+
+ AddDescriptor(VtgStages, ResourceType.StorageBuffer, StorageSetIndex, 0, 5);
+ AddUsage(VtgStages, ResourceType.StorageBuffer, ResourceAccess.Read, StorageSetIndex, 0, 1);
+ AddUsage(VtgStages, ResourceType.StorageBuffer, ResourceAccess.Write, StorageSetIndex, 1, 4);
+ }
+ else
+ {
+ _reservedStorageBuffers = 0;
+ }
}
///
@@ -86,8 +111,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
int texturesPerStage = (int)_context.Capabilities.MaximumTexturesPerStage;
int imagesPerStage = (int)_context.Capabilities.MaximumImagesPerStage;
- int uniformBinding = 1 + stageIndex * uniformsPerStage;
- int storageBinding = stageIndex * storagesPerStage;
+ int uniformBinding = _reservedConstantBuffers + stageIndex * uniformsPerStage;
+ int storageBinding = _reservedStorageBuffers + stageIndex * storagesPerStage;
int textureBinding = stageIndex * texturesPerStage * 2;
int imageBinding = stageIndex * imagesPerStage * 2;
@@ -133,6 +158,23 @@ namespace Ryujinx.Graphics.Gpu.Shader
AddDescriptor(stages, type2, setIndex, binding + count, count);
}
+ ///
+ /// Adds buffer usage information to the list of usages.
+ ///
+ /// Shader stages where the resource is used
+ /// Type of the resource
+ /// How the resource is accessed by the shader stages where it is used
+ /// Descriptor set number where the resource will be bound
+ /// Binding number where the resource will be bound
+ /// Number of resources bound at the binding location
+ private void AddUsage(ResourceStages stages, ResourceType type, ResourceAccess access, int setIndex, int binding, int count)
+ {
+ for (int index = 0; index < count; index++)
+ {
+ _resourceUsages[setIndex].Add(new ResourceUsage(binding + index, type, stages, access));
+ }
+ }
+
///
/// Adds buffer usage information to the list of usages.
///
@@ -212,10 +254,15 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// GPU context that owns the shaders
/// Shaders from the disk cache
/// Optional pipeline for background compilation
+ /// Indicates if the graphics shader is used with transform feedback enabled
/// Shader information
- public static ShaderInfo BuildForCache(GpuContext context, IEnumerable programs, ProgramPipelineState? pipeline)
+ public static ShaderInfo BuildForCache(
+ GpuContext context,
+ IEnumerable programs,
+ ProgramPipelineState? pipeline,
+ bool tfEnabled)
{
- ShaderInfoBuilder builder = new ShaderInfoBuilder(context);
+ ShaderInfoBuilder builder = new ShaderInfoBuilder(context, tfEnabled);
foreach (CachedShaderStage program in programs)
{
@@ -237,7 +284,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// Shader information
public static ShaderInfo BuildForCompute(GpuContext context, ShaderProgramInfo info, bool fromCache = false)
{
- ShaderInfoBuilder builder = new ShaderInfoBuilder(context);
+ ShaderInfoBuilder builder = new ShaderInfoBuilder(context, tfEnabled: false);
builder.AddStageInfo(info);
diff --git a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
index 161191b85..c7c01a37b 100644
--- a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
+++ b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
@@ -127,6 +127,7 @@ namespace Ryujinx.Graphics.OpenGL
public Capabilities GetCapabilities()
{
bool intelWindows = HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows;
+ bool intelUnix = HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelUnix;
bool amdWindows = HwCapabilities.Vendor == HwCapabilities.GpuVendor.AmdWindows;
return new Capabilities(
@@ -152,12 +153,15 @@ namespace Ryujinx.Graphics.OpenGL
supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering,
supportsGeometryShader: true,
supportsGeometryShaderPassthrough: HwCapabilities.SupportsGeometryShaderPassthrough,
+ supportsTransformFeedback: true,
supportsImageLoadFormatted: HwCapabilities.SupportsImageLoadFormatted,
supportsLayerVertexTessellation: HwCapabilities.SupportsShaderViewportLayerArray,
supportsMismatchingViewFormat: HwCapabilities.SupportsMismatchingViewFormat,
supportsCubemapView: true,
supportsNonConstantTextureOffset: HwCapabilities.SupportsNonConstantTextureOffset,
supportsShaderBallot: HwCapabilities.SupportsShaderBallot,
+ supportsShaderBarrierDivergence: !(intelWindows || intelUnix),
+ supportsShaderFloat64: true,
supportsTextureShadowLod: HwCapabilities.SupportsTextureShadowLod,
supportsViewportIndexVertexTessellation: HwCapabilities.SupportsShaderViewportLayerArray,
supportsViewportMask: HwCapabilities.SupportsViewportArray2,
diff --git a/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs b/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs
index e0aafa6fa..648600bc2 100644
--- a/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs
+++ b/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs
@@ -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 _queryPool;
private AutoResetEvent _queuedEvent = new AutoResetEvent(false);
diff --git a/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs b/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs
index 7297baab5..ffe1f774f 100644
--- a/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs
+++ b/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs
@@ -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;
diff --git a/src/Ryujinx.Graphics.OpenGL/ResourcePool.cs b/src/Ryujinx.Graphics.OpenGL/ResourcePool.cs
index 57231cd65..69d2a78e1 100644
--- a/src/Ryujinx.Graphics.OpenGL/ResourcePool.cs
+++ b/src/Ryujinx.Graphics.OpenGL/ResourcePool.cs
@@ -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> _textures = new Dictionary>();
///
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/GlslGenerator.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/GlslGenerator.cs
index 751d03507..fe0d275b6 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/GlslGenerator.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/GlslGenerator.cs
@@ -28,18 +28,18 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
for (int i = 1; i < info.Functions.Count; i++)
{
- PrintFunction(context, info, info.Functions[i]);
+ PrintFunction(context, info.Functions[i]);
context.AppendLine();
}
}
- PrintFunction(context, info, info.Functions[0], MainFunctionName);
+ PrintFunction(context, info.Functions[0], MainFunctionName);
return context.GetCode();
}
- private static void PrintFunction(CodeGenContext context, StructuredProgramInfo info, StructuredFunction function, string funcName = null)
+ private static void PrintFunction(CodeGenContext context, StructuredFunction function, string funcName = null)
{
context.CurrentFunction = function;
@@ -48,7 +48,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
Declarations.DeclareLocals(context, function);
- PrintBlock(context, function.MainBlock);
+ PrintBlock(context, function.MainBlock, funcName == MainFunctionName);
context.LeaveScope();
}
@@ -72,7 +72,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
return $"{Declarations.GetVarTypeName(context, function.ReturnType)} {funcName ?? function.Name}({string.Join(", ", args)})";
}
- private static void PrintBlock(CodeGenContext context, AstBlock block)
+ private static void PrintBlock(CodeGenContext context, AstBlock block, bool isMainFunction)
{
AstBlockVisitor visitor = new AstBlockVisitor(block);
@@ -112,10 +112,32 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
}
};
+ bool supportsBarrierDivergence = context.Config.GpuAccessor.QueryHostSupportsShaderBarrierDivergence();
+ bool mayHaveReturned = false;
+
foreach (IAstNode node in visitor.Visit())
{
if (node is AstOperation operation)
{
+ if (!supportsBarrierDivergence)
+ {
+ if (operation.Inst == IntermediateRepresentation.Instruction.Barrier)
+ {
+ // Barrier on divergent control flow paths may cause the GPU to hang,
+ // so skip emitting the barrier for those cases.
+ if (visitor.Block.Type != AstBlockType.Main || mayHaveReturned || !isMainFunction)
+ {
+ context.Config.GpuAccessor.Log($"Shader has barrier on potentially divergent block, the barrier will be removed.");
+
+ continue;
+ }
+ }
+ else if (operation.Inst == IntermediateRepresentation.Instruction.Return)
+ {
+ mayHaveReturned = true;
+ }
+ }
+
string expr = InstGen.GetExpression(context, operation);
if (expr != null)
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs
index c1bfa0883..1f5167e66 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs
@@ -76,6 +76,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
public SpirvDelegates Delegates { get; }
+ public bool IsMainFunction { get; private set; }
+ public bool MayHaveReturned { get; set; }
+
public CodeGenContext(
StructuredProgramInfo info,
ShaderConfig config,
@@ -108,8 +111,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
Delegates = new SpirvDelegates(this);
}
- public void StartFunction()
+ public void StartFunction(bool isMainFunction)
{
+ IsMainFunction = isMainFunction;
+ MayHaveReturned = false;
_locals.Clear();
_localForArgs.Clear();
_funcArgs.Clear();
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
index 4be0c62be..6c1157525 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
@@ -242,6 +242,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
private static OperationResult GenerateBarrier(CodeGenContext context, AstOperation operation)
{
+ // Barrier on divergent control flow paths may cause the GPU to hang,
+ // so skip emitting the barrier for those cases.
+ if (!context.Config.GpuAccessor.QueryHostSupportsShaderBarrierDivergence() &&
+ (context.CurrentBlock.Type != AstBlockType.Main || context.MayHaveReturned || !context.IsMainFunction))
+ {
+ context.Config.GpuAccessor.Log($"Shader has barrier on potentially divergent block, the barrier will be removed.");
+
+ return OperationResult.Invalid;
+ }
+
context.ControlBarrier(
context.Constant(context.TypeU32(), Scope.Workgroup),
context.Constant(context.TypeU32(), Scope.Workgroup),
@@ -1092,6 +1102,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
private static OperationResult GenerateReturn(CodeGenContext context, AstOperation operation)
{
+ context.MayHaveReturned = true;
+
if (operation.SourcesCount != 0)
{
context.ReturnValue(context.Get(context.CurrentFunction.ReturnType, operation.GetSource(0)));
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs
index a55e09fd3..5c736b605 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/SpirvGenerator.cs
@@ -148,7 +148,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
context.CurrentFunction = function;
context.AddFunction(spvFunc);
- context.StartFunction();
+ context.StartFunction(isMainFunction: funcIndex == 0);
Declarations.DeclareParameters(context, function);
diff --git a/src/Ryujinx.Graphics.Shader/Constants.cs b/src/Ryujinx.Graphics.Shader/Constants.cs
index 7f1445ed0..39d6b2381 100644
--- a/src/Ryujinx.Graphics.Shader/Constants.cs
+++ b/src/Ryujinx.Graphics.Shader/Constants.cs
@@ -10,5 +10,11 @@ namespace Ryujinx.Graphics.Shader
public const int NvnBaseVertexByteOffset = 0x640;
public const int NvnBaseInstanceByteOffset = 0x644;
public const int NvnDrawIndexByteOffset = 0x648;
+
+ // Transform Feedback emulation.
+
+ public const int TfeInfoBinding = 0;
+ public const int TfeBufferBaseBinding = 1;
+ public const int TfeBuffersCount = 4;
}
}
\ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs b/src/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs
index 0c22ddc05..c7c506ec4 100644
--- a/src/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs
+++ b/src/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs
@@ -1,3 +1,5 @@
+using System;
+
namespace Ryujinx.Graphics.Shader.Decoders
{
enum AlSize
@@ -711,6 +713,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
TexSamplerBorderColor = 22,
}
+ [Flags]
enum VectorSelect
{
U8B0 = 0,
@@ -851,14 +854,14 @@ namespace Ryujinx.Graphics.Shader.Decoders
public InstConditional(ulong opcode) => _opcode = opcode;
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
- public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+ public Ccc Ccc => (Ccc)(_opcode & 0x1F);
}
struct InstAl2p
{
private ulong _opcode;
public InstAl2p(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -872,7 +875,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstAld(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 39) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -889,7 +892,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
private ulong _opcode;
public InstAst(ulong opcode) => _opcode = opcode;
public int SrcA => (int)((_opcode >> 8) & 0xFF);
- public int SrcB => (int)((_opcode >> 0) & 0xFF);
+ public int SrcB => (int)(_opcode & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -903,7 +906,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstAtom(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -918,7 +921,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstAtomCas(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -931,7 +934,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstAtoms(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -945,7 +948,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstAtomsCas(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -957,7 +960,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstB2r(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int DestPred => (int)((_opcode >> 45) & 0x7);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -985,7 +988,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstBfeR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -999,7 +1002,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstBfeI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -1013,7 +1016,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstBfeC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -1028,7 +1031,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstBfiR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -1041,7 +1044,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstBfiI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -1054,7 +1057,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstBfiC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -1068,7 +1071,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstBfiRc(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
@@ -1092,7 +1095,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public InstBra(ulong opcode) => _opcode = opcode;
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
- public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+ public Ccc Ccc => (Ccc)(_opcode & 0x1F);
public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
public bool Ca => (_opcode & 0x20) != 0;
public bool Lmt => (_opcode & 0x40) != 0;
@@ -1105,7 +1108,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public InstBrk(ulong opcode) => _opcode = opcode;
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
- public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+ public Ccc Ccc => (Ccc)(_opcode & 0x1F);
}
struct InstBrx
@@ -1115,7 +1118,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
- public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+ public Ccc Ccc => (Ccc)(_opcode & 0x1F);
public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
public bool Ca => (_opcode & 0x20) != 0;
public bool Lmt => (_opcode & 0x40) != 0;
@@ -1140,7 +1143,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public int Imm30 => (int)((_opcode >> 22) & 0x3FFFFFFF);
public bool E => (_opcode & 0x10000000000000) != 0;
public CacheType Cache => (CacheType)((_opcode >> 4) & 0x7);
- public CctlOp CctlOp => (CctlOp)((_opcode >> 0) & 0xF);
+ public CctlOp CctlOp => (CctlOp)(_opcode & 0xF);
}
struct InstCctll
@@ -1152,7 +1155,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public bool PredInv => (_opcode & 0x80000) != 0;
public int Imm22 => (int)((_opcode >> 22) & 0x3FFFFF);
public int Cache => (int)((_opcode >> 4) & 0x3);
- public CctlOp CctlOp => (CctlOp)((_opcode >> 0) & 0xF);
+ public CctlOp CctlOp => (CctlOp)(_opcode & 0xF);
}
struct InstCctlt
@@ -1162,7 +1165,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
public int TsIdx13 => (int)((_opcode >> 36) & 0x1FFF);
- public CctltOp CctltOp => (CctltOp)((_opcode >> 0) & 0x3);
+ public CctltOp CctltOp => (CctltOp)(_opcode & 0x3);
}
struct InstCctltR
@@ -1170,7 +1173,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
private ulong _opcode;
public InstCctltR(ulong opcode) => _opcode = opcode;
public int SrcC => (int)((_opcode >> 39) & 0xFF);
- public CctltOp CctltOp => (CctltOp)((_opcode >> 0) & 0x3);
+ public CctltOp CctltOp => (CctltOp)(_opcode & 0x3);
}
struct InstCont
@@ -1179,14 +1182,14 @@ namespace Ryujinx.Graphics.Shader.Decoders
public InstCont(ulong opcode) => _opcode = opcode;
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
- public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+ public Ccc Ccc => (Ccc)(_opcode & 0x1F);
}
struct InstCset
{
private ulong _opcode;
public InstCset(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
public bool WriteCC => (_opcode & 0x800000000000) != 0;
@@ -1206,7 +1209,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public bool WriteCC => (_opcode & 0x800000000000) != 0;
public Ccc Ccc => (Ccc)((_opcode >> 8) & 0x1F);
public int DestPred => (int)((_opcode >> 3) & 0x7);
- public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+ public int DestPredInv => (int)(_opcode & 0x7);
public int SrcPred => (int)((_opcode >> 39) & 0x7);
public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
@@ -1216,7 +1219,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstCs2r(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
public SReg SReg => (SReg)((_opcode >> 20) & 0xFF);
@@ -1226,7 +1229,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstDaddR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -1243,7 +1246,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstDaddI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -1260,7 +1263,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstDaddC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -1283,14 +1286,14 @@ namespace Ryujinx.Graphics.Shader.Decoders
public bool Le => (_opcode & 0x20000000) != 0;
public int Sbid => (int)((_opcode >> 26) & 0x7);
public int PendCnt => (int)((_opcode >> 20) & 0x3F);
- public int Imm6 => (int)((_opcode >> 0) & 0x3F);
+ public int Imm6 => (int)(_opcode & 0x3F);
}
struct InstDfmaR
{
private ulong _opcode;
public InstDfmaR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -1306,7 +1309,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstDfmaI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -1322,7 +1325,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstDfmaC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -1339,7 +1342,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstDfmaRc(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
@@ -1356,7 +1359,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstDmnmxR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -1374,7 +1377,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstDmnmxI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -1392,7 +1395,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstDmnmxC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -1411,7 +1414,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstDmulR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -1425,7 +1428,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstDmulI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -1439,7 +1442,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstDmulC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -1454,7 +1457,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstDsetR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -1475,7 +1478,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstDsetI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -1496,7 +1499,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstDsetC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -1531,7 +1534,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public bool AbsA => (_opcode & 0x80) != 0;
public bool NegB => (_opcode & 0x40) != 0;
public int DestPred => (int)((_opcode >> 3) & 0x7);
- public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+ public int DestPredInv => (int)(_opcode & 0x7);
}
struct InstDsetpI
@@ -1551,7 +1554,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public bool AbsA => (_opcode & 0x80) != 0;
public bool NegB => (_opcode & 0x40) != 0;
public int DestPred => (int)((_opcode >> 3) & 0x7);
- public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+ public int DestPredInv => (int)(_opcode & 0x7);
}
struct InstDsetpC
@@ -1572,7 +1575,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public bool AbsA => (_opcode & 0x80) != 0;
public bool NegB => (_opcode & 0x40) != 0;
public int DestPred => (int)((_opcode >> 3) & 0x7);
- public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+ public int DestPredInv => (int)(_opcode & 0x7);
}
struct InstExit
@@ -1581,7 +1584,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public InstExit(ulong opcode) => _opcode = opcode;
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
- public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+ public Ccc Ccc => (Ccc)(_opcode & 0x1F);
public bool KeepRefCnt => (_opcode & 0x20) != 0;
}
@@ -1589,7 +1592,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstF2fR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -1608,7 +1611,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstF2fI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -1627,7 +1630,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstF2fC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -1647,7 +1650,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstF2iR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -1665,7 +1668,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstF2iI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -1683,7 +1686,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstF2iC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -1702,7 +1705,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFaddR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -1721,7 +1724,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFaddI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -1740,7 +1743,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFaddC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -1760,7 +1763,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFadd32i(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -1826,7 +1829,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFcmpR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -1840,7 +1843,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFcmpI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -1854,7 +1857,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFcmpC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -1869,7 +1872,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFcmpRc(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
@@ -1884,7 +1887,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFfmaR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -1902,7 +1905,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFfmaI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -1920,7 +1923,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFfmaC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -1939,7 +1942,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFfmaRc(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
@@ -1958,7 +1961,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFfma32i(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm32 => (int)(_opcode >> 20);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -1974,7 +1977,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFloR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -1988,7 +1991,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFloI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -2002,7 +2005,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFloC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -2017,7 +2020,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFmnmxR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -2036,7 +2039,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFmnmxI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -2055,7 +2058,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFmnmxC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -2075,7 +2078,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFmulR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -2092,7 +2095,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFmulI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -2109,7 +2112,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFmulC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -2127,7 +2130,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFmul32i(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -2141,7 +2144,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFsetR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -2163,7 +2166,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFsetC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -2186,7 +2189,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFsetI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -2209,7 +2212,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
private ulong _opcode;
public InstFsetpR(ulong opcode) => _opcode = opcode;
public int DestPred => (int)((_opcode >> 3) & 0x7);
- public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+ public int DestPredInv => (int)(_opcode & 0x7);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -2231,7 +2234,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
private ulong _opcode;
public InstFsetpI(ulong opcode) => _opcode = opcode;
public int DestPred => (int)((_opcode >> 3) & 0x7);
- public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+ public int DestPredInv => (int)(_opcode & 0x7);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -2253,7 +2256,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
private ulong _opcode;
public InstFsetpC(ulong opcode) => _opcode = opcode;
public int DestPred => (int)((_opcode >> 3) & 0x7);
- public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+ public int DestPredInv => (int)(_opcode & 0x7);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -2275,7 +2278,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstFswzadd(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -2291,21 +2294,21 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstGetcrsptr(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
}
struct InstGetlmembase
{
private ulong _opcode;
public InstGetlmembase(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
}
struct InstHadd2R
{
private ulong _opcode;
public InstHadd2R(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public OFmt OFmt => (OFmt)((_opcode >> 49) & 0x3);
@@ -2325,7 +2328,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstHadd2I(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int BimmH0 => (int)((_opcode >> 20) & 0x3FF);
public int BimmH1 => (int)((_opcode >> 47) & 0x200) | (int)((_opcode >> 30) & 0x1FF);
@@ -2343,7 +2346,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstHadd2C(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -2363,7 +2366,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstHadd232i(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm => (int)(_opcode >> 20);
public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 53) & 0x3);
@@ -2378,7 +2381,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstHfma2R(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -2398,7 +2401,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstHfma2I(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int BimmH0 => (int)((_opcode >> 20) & 0x3FF);
public int BimmH1 => (int)((_opcode >> 47) & 0x200) | (int)((_opcode >> 30) & 0x1FF);
@@ -2417,7 +2420,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstHfma2C(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -2437,7 +2440,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstHfma2Rc(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -2457,7 +2460,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstHfma232i(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm => (int)(_opcode >> 20);
public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
@@ -2471,7 +2474,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstHmul2R(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public OFmt OFmt => (OFmt)((_opcode >> 49) & 0x3);
@@ -2490,7 +2493,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstHmul2I(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int BimmH0 => (int)((_opcode >> 20) & 0x3FF);
public int BimmH1 => (int)((_opcode >> 47) & 0x200) | (int)((_opcode >> 30) & 0x1FF);
@@ -2508,7 +2511,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstHmul2C(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -2527,7 +2530,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstHmul232i(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm32 => (int)(_opcode >> 20);
public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 53) & 0x3);
@@ -2541,7 +2544,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstHset2R(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
@@ -2564,7 +2567,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstHset2I(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int BimmH0 => (int)((_opcode >> 20) & 0x3FF);
public int BimmH1 => (int)((_opcode >> 47) & 0x200) | (int)((_opcode >> 30) & 0x1FF);
@@ -2585,7 +2588,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstHset2C(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -2608,7 +2611,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
private ulong _opcode;
public InstHsetp2R(ulong opcode) => _opcode = opcode;
public int DestPred => (int)((_opcode >> 3) & 0x7);
- public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+ public int DestPredInv => (int)(_opcode & 0x7);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -2632,7 +2635,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
private ulong _opcode;
public InstHsetp2I(ulong opcode) => _opcode = opcode;
public int DestPred => (int)((_opcode >> 3) & 0x7);
- public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+ public int DestPredInv => (int)(_opcode & 0x7);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -2654,7 +2657,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
private ulong _opcode;
public InstHsetp2C(ulong opcode) => _opcode = opcode;
public int DestPred => (int)((_opcode >> 3) & 0x7);
- public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+ public int DestPredInv => (int)(_opcode & 0x7);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -2677,7 +2680,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstI2fR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -2694,7 +2697,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstI2fI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -2711,7 +2714,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstI2fC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -2729,7 +2732,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstI2iR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -2746,7 +2749,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstI2iI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -2763,7 +2766,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstI2iC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -2781,7 +2784,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIaddR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -2796,7 +2799,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIaddI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -2811,7 +2814,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIaddC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -2827,7 +2830,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIadd32i(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -2842,7 +2845,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIadd3R(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -2863,7 +2866,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIadd3I(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -2880,7 +2883,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIadd3C(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -2898,7 +2901,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIcmpR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -2912,7 +2915,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIcmpI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -2926,7 +2929,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIcmpC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -2941,7 +2944,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIcmpRc(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
@@ -2964,7 +2967,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIdpR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -2980,7 +2983,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIdpC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -2997,7 +3000,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstImadR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -3016,7 +3019,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstImadI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -3035,7 +3038,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstImadC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -3055,7 +3058,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstImadRc(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
@@ -3075,7 +3078,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstImad32i(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -3091,7 +3094,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstImadspR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -3106,7 +3109,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstImadspI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -3121,7 +3124,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstImadspC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -3137,7 +3140,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstImadspRc(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
@@ -3153,7 +3156,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstImnmxR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3169,7 +3172,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstImnmxI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3185,7 +3188,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstImnmxC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -3202,7 +3205,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstImulR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3217,7 +3220,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstImulI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3232,7 +3235,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstImulC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -3248,7 +3251,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstImul32i(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -3263,7 +3266,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIpa(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -3282,7 +3285,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIsberd(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -3296,7 +3299,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIscaddR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3310,7 +3313,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIscaddI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3324,7 +3327,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIscaddC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -3339,7 +3342,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIscadd32i(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -3352,7 +3355,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIsetR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3371,7 +3374,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIsetI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3390,7 +3393,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstIsetC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -3421,7 +3424,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public int SrcPred => (int)((_opcode >> 39) & 0x7);
public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
public int DestPred => (int)((_opcode >> 3) & 0x7);
- public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+ public int DestPredInv => (int)(_opcode & 0x7);
}
struct InstIsetpI
@@ -3439,7 +3442,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public int SrcPred => (int)((_opcode >> 39) & 0x7);
public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
public int DestPred => (int)((_opcode >> 3) & 0x7);
- public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+ public int DestPredInv => (int)(_opcode & 0x7);
}
struct InstIsetpC
@@ -3458,7 +3461,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public int SrcPred => (int)((_opcode >> 39) & 0x7);
public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
public int DestPred => (int)((_opcode >> 3) & 0x7);
- public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+ public int DestPredInv => (int)(_opcode & 0x7);
}
struct InstJcal
@@ -3477,7 +3480,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
- public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+ public Ccc Ccc => (Ccc)(_opcode & 0x1F);
public bool Ca => (_opcode & 0x20) != 0;
public int Imm32 => (int)(_opcode >> 20);
public bool Lmt => (_opcode & 0x40) != 0;
@@ -3491,7 +3494,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
- public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+ public Ccc Ccc => (Ccc)(_opcode & 0x1F);
public bool Ca => (_opcode & 0x20) != 0;
public int Imm32 => (int)(_opcode >> 20);
public bool Lmt => (_opcode & 0x40) != 0;
@@ -3503,14 +3506,14 @@ namespace Ryujinx.Graphics.Shader.Decoders
public InstKil(ulong opcode) => _opcode = opcode;
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
- public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+ public Ccc Ccc => (Ccc)(_opcode & 0x1F);
}
struct InstLd
{
private ulong _opcode;
public InstLd(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -3525,7 +3528,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstLdc(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -3539,7 +3542,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstLdg(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -3553,7 +3556,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstLdl(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -3566,7 +3569,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstLds(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -3579,7 +3582,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstLeaR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3595,7 +3598,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstLeaI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3611,7 +3614,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstLeaC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -3628,7 +3631,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstLeaHiR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -3645,7 +3648,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstLeaHiC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -3669,14 +3672,14 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstLongjmp(ulong opcode) => _opcode = opcode;
- public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+ public Ccc Ccc => (Ccc)(_opcode & 0x1F);
}
struct InstLopR
{
private ulong _opcode;
public InstLopR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3694,7 +3697,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstLopI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3712,7 +3715,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstLopC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -3731,7 +3734,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstLop3R(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -3748,7 +3751,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstLop3I(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -3763,7 +3766,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstLop3C(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -3779,7 +3782,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstLop32i(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -3798,14 +3801,14 @@ namespace Ryujinx.Graphics.Shader.Decoders
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
public Membar Membar => (Membar)((_opcode >> 8) & 0x3);
- public Ivall Ivall => (Ivall)((_opcode >> 0) & 0x3);
+ public Ivall Ivall => (Ivall)(_opcode & 0x3);
}
struct InstMovR
{
private ulong _opcode;
public InstMovR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -3816,7 +3819,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstMovI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -3827,7 +3830,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstMovC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3839,7 +3842,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstMov32i(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int Imm32 => (int)(_opcode >> 20);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -3850,7 +3853,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstMufu(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -3875,7 +3878,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstOutR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3887,7 +3890,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstOutI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3899,7 +3902,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstOutC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -3912,7 +3915,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstP2rR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3925,7 +3928,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstP2rI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -3938,7 +3941,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstP2rC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -3975,7 +3978,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstPixld(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -3996,7 +3999,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstPopcR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -4007,7 +4010,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstPopcI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -4018,7 +4021,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstPopcC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4039,7 +4042,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstPrmtR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -4052,7 +4055,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstPrmtI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -4065,7 +4068,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstPrmtC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -4079,7 +4082,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstPrmtRc(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
@@ -4093,7 +4096,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstPset(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
public bool WriteCC => (_opcode & 0x800000000000) != 0;
@@ -4115,7 +4118,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public int DestPred => (int)((_opcode >> 3) & 0x7);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
- public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+ public int DestPredInv => (int)(_opcode & 0x7);
public int Src2Pred => (int)((_opcode >> 12) & 0x7);
public bool Src2PredInv => (_opcode & 0x8000) != 0;
public int Src1Pred => (int)((_opcode >> 29) & 0x7);
@@ -4185,7 +4188,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
private ulong _opcode;
public InstRed(ulong opcode) => _opcode = opcode;
public int SrcA => (int)((_opcode >> 8) & 0xFF);
- public int SrcB => (int)((_opcode >> 0) & 0xFF);
+ public int SrcB => (int)(_opcode & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
public int Imm20 => (int)((_opcode >> 28) & 0xFFFFF);
@@ -4200,14 +4203,14 @@ namespace Ryujinx.Graphics.Shader.Decoders
public InstRet(ulong opcode) => _opcode = opcode;
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
- public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+ public Ccc Ccc => (Ccc)(_opcode & 0x1F);
}
struct InstRroR
{
private ulong _opcode;
public InstRroR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -4220,7 +4223,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstRroI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -4233,7 +4236,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstRroC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4253,7 +4256,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstS2r(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
public SReg SReg => (SReg)((_opcode >> 20) & 0xFF);
@@ -4269,7 +4272,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSelR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4282,7 +4285,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSelI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4295,7 +4298,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSelC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -4323,7 +4326,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstShfLR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -4339,7 +4342,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstShfRR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -4355,7 +4358,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstShfLI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4371,7 +4374,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstShfRI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4387,7 +4390,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstShfl(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -4405,7 +4408,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstShlR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4419,7 +4422,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstShlI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4433,7 +4436,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstShlC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -4448,7 +4451,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstShrR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4464,7 +4467,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstShrI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4480,7 +4483,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstShrC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -4505,7 +4508,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSt(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -4520,7 +4523,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstStg(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -4534,7 +4537,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstStl(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -4555,7 +4558,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSts(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -4567,7 +4570,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSuatomB(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -4584,7 +4587,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSuatom(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4601,7 +4604,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSuatomB2(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -4619,7 +4622,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSuatomCasB(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -4636,7 +4639,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSuatomCas(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4653,7 +4656,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSuldDB(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4670,7 +4673,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSuldD(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -4687,7 +4690,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSuldB(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4703,7 +4706,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSuld(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -4719,7 +4722,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSuredB(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4735,7 +4738,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSured(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -4751,7 +4754,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSustDB(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4767,7 +4770,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSustD(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -4783,7 +4786,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSustB(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4798,7 +4801,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstSust(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -4815,14 +4818,14 @@ namespace Ryujinx.Graphics.Shader.Decoders
public InstSync(ulong opcode) => _opcode = opcode;
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
- public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+ public Ccc Ccc => (Ccc)(_opcode & 0x1F);
}
struct InstTex
{
private ulong _opcode;
public InstTex(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4843,7 +4846,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstTexB(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4863,7 +4866,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstTexs(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4879,7 +4882,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstTld(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4899,7 +4902,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstTldB(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4918,7 +4921,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstTlds(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4934,7 +4937,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstTld4(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4955,7 +4958,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstTld4B(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4975,7 +4978,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstTld4s(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -4992,7 +4995,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstTmml(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -5008,7 +5011,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstTmmlB(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -5023,7 +5026,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstTxa(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -5037,7 +5040,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstTxd(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -5055,7 +5058,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstTxdB(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -5072,7 +5075,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstTxq(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -5086,7 +5089,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstTxqB(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
@@ -5099,7 +5102,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstVabsdiff(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -5118,7 +5121,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstVabsdiff4(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -5139,7 +5142,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstVadd(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -5160,7 +5163,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstVmad(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -5180,7 +5183,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstVmnmx(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -5201,7 +5204,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstVote(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
public bool PredInv => (_opcode & 0x80000) != 0;
public int SrcPred => (int)((_opcode >> 39) & 0x7);
@@ -5224,7 +5227,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstVset(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -5254,7 +5257,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
public int SrcPred => (int)((_opcode >> 39) & 0x7);
public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
public int DestPred => (int)((_opcode >> 3) & 0x7);
- public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+ public int DestPredInv => (int)(_opcode & 0x7);
public bool BVideo => (_opcode & 0x4000000000000) != 0;
}
@@ -5262,7 +5265,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstVshl(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -5282,7 +5285,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstVshr(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -5302,7 +5305,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstXmadR(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcB => (int)((_opcode >> 20) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
@@ -5323,7 +5326,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstXmadI(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int Pred => (int)((_opcode >> 16) & 0x7);
@@ -5343,7 +5346,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstXmadC(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
@@ -5365,7 +5368,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
private ulong _opcode;
public InstXmadRc(ulong opcode) => _opcode = opcode;
- public int Dest => (int)((_opcode >> 0) & 0xFF);
+ public int Dest => (int)(_opcode & 0xFF);
public int SrcA => (int)((_opcode >> 8) & 0xFF);
public int SrcC => (int)((_opcode >> 39) & 0xFF);
public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
diff --git a/src/Ryujinx.Graphics.Shader/Decoders/InstProps.cs b/src/Ryujinx.Graphics.Shader/Decoders/InstProps.cs
index 1af94ab59..3f39e631d 100644
--- a/src/Ryujinx.Graphics.Shader/Decoders/InstProps.cs
+++ b/src/Ryujinx.Graphics.Shader/Decoders/InstProps.cs
@@ -1,5 +1,8 @@
+using System;
+
namespace Ryujinx.Graphics.Shader.Decoders
{
+ [Flags]
enum InstProps : ushort
{
None = 0,
diff --git a/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs b/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs
index 473964def..1c2b28097 100644
--- a/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs
+++ b/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs
@@ -331,6 +331,24 @@ namespace Ryujinx.Graphics.Shader
return true;
}
+ ///
+ /// Queries host GPU shader support for barrier instructions on divergent control flow paths.
+ ///
+ /// True if the GPU supports barriers on divergent control flow paths, false otherwise
+ bool QueryHostSupportsShaderBarrierDivergence()
+ {
+ return true;
+ }
+
+ ///
+ /// Queries host GPU support for 64-bit floating point (double precision) operations on the shader.
+ ///
+ /// True if the GPU and driver supports double operations, false otherwise
+ bool QueryHostSupportsShaderFloat64()
+ {
+ return true;
+ }
+
///
/// Queries host GPU support for signed normalized buffer texture formats.
///
@@ -349,6 +367,15 @@ namespace Ryujinx.Graphics.Shader
return true;
}
+ ///
+ /// Queries host GPU transform feedback support.
+ ///
+ /// True if the GPU and driver supports transform feedback, false otherwise
+ bool QueryHostSupportsTransformFeedback()
+ {
+ return true;
+ }
+
///
/// Queries host support for writes to the viewport index from vertex or tessellation shader stages.
///
diff --git a/src/Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs b/src/Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs
index d502a9b65..425cfd909 100644
--- a/src/Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs
+++ b/src/Ryujinx.Graphics.Shader/IntermediateRepresentation/Operation.cs
@@ -255,5 +255,35 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
_sources = new Operand[] { source };
}
+
+ public void TurnDoubleIntoFloat()
+ {
+ if ((Inst & ~Instruction.Mask) == Instruction.FP64)
+ {
+ Inst = (Inst & Instruction.Mask) | Instruction.FP32;
+ }
+ else
+ {
+ switch (Inst)
+ {
+ case Instruction.ConvertFP32ToFP64:
+ case Instruction.ConvertFP64ToFP32:
+ Inst = Instruction.Copy;
+ break;
+ case Instruction.ConvertFP64ToS32:
+ Inst = Instruction.ConvertFP32ToS32;
+ break;
+ case Instruction.ConvertFP64ToU32:
+ Inst = Instruction.ConvertFP32ToU32;
+ break;
+ case Instruction.ConvertS32ToFP64:
+ Inst = Instruction.ConvertS32ToFP32;
+ break;
+ case Instruction.ConvertU32ToFP64:
+ Inst = Instruction.ConvertU32ToFP32;
+ break;
+ }
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/TextureHandle.cs b/src/Ryujinx.Graphics.Shader/TextureHandle.cs
index 39d5c1c32..a59c8cd4a 100644
--- a/src/Ryujinx.Graphics.Shader/TextureHandle.cs
+++ b/src/Ryujinx.Graphics.Shader/TextureHandle.cs
@@ -61,7 +61,7 @@ namespace Ryujinx.Graphics.Shader
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int UnpackTextureId(int packedId)
{
- return (packedId >> 0) & 0xfffff;
+ return packedId & 0xfffff;
}
///
diff --git a/src/Ryujinx.Graphics.Shader/Translation/AggregateType.cs b/src/Ryujinx.Graphics.Shader/Translation/AggregateType.cs
index b1b40f652..a54eddc59 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/AggregateType.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/AggregateType.cs
@@ -1,5 +1,8 @@
-namespace Ryujinx.Graphics.Shader.Translation
+using System;
+
+namespace Ryujinx.Graphics.Shader.Translation
{
+ [Flags]
enum AggregateType
{
Invalid,
diff --git a/src/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs b/src/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
index 6ca74a379..87e5457f9 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
@@ -234,6 +234,45 @@ namespace Ryujinx.Graphics.Shader.Translation
public void PrepareForVertexReturn()
{
+ if (!Config.GpuAccessor.QueryHostSupportsTransformFeedback() && Config.GpuAccessor.QueryTransformFeedbackEnabled())
+ {
+ Operand vertexCount = this.Load(StorageKind.StorageBuffer, Constants.TfeInfoBinding, Const(1));
+
+ for (int tfbIndex = 0; tfbIndex < Constants.TfeBuffersCount; tfbIndex++)
+ {
+ var locations = Config.GpuAccessor.QueryTransformFeedbackVaryingLocations(tfbIndex);
+ var stride = Config.GpuAccessor.QueryTransformFeedbackStride(tfbIndex);
+
+ Operand baseOffset = this.Load(StorageKind.StorageBuffer, Constants.TfeInfoBinding, Const(0), Const(tfbIndex));
+ Operand baseVertex = this.Load(StorageKind.Input, IoVariable.BaseVertex);
+ Operand baseInstance = this.Load(StorageKind.Input, IoVariable.BaseInstance);
+ Operand vertexIndex = this.Load(StorageKind.Input, IoVariable.VertexIndex);
+ Operand instanceIndex = this.Load(StorageKind.Input, IoVariable.InstanceIndex);
+
+ Operand outputVertexOffset = this.ISubtract(vertexIndex, baseVertex);
+ Operand outputInstanceOffset = this.ISubtract(instanceIndex, baseInstance);
+
+ Operand outputBaseVertex = this.IMultiply(outputInstanceOffset, vertexCount);
+
+ Operand vertexOffset = this.IMultiply(this.IAdd(outputBaseVertex, outputVertexOffset), Const(stride / 4));
+ baseOffset = this.IAdd(baseOffset, vertexOffset);
+
+ for (int j = 0; j < locations.Length; j++)
+ {
+ byte location = locations[j];
+ if (location == 0xff)
+ {
+ continue;
+ }
+
+ Operand offset = this.IAdd(baseOffset, Const(j));
+ Operand value = Instructions.AttributeMap.GenerateAttributeLoad(this, null, location * 4, isOutput: true, isPerPatch: false);
+
+ this.Store(StorageKind.StorageBuffer, Constants.TfeBufferBaseBinding + tfbIndex, Const(0), offset, value);
+ }
+ }
+ }
+
if (Config.GpuAccessor.QueryViewportTransformDisable())
{
Operand x = this.Load(StorageKind.Output, IoVariable.Position, null, Const(0));
diff --git a/src/Ryujinx.Graphics.Shader/Translation/HelperFunctionManager.cs b/src/Ryujinx.Graphics.Shader/Translation/HelperFunctionManager.cs
index 7dd267f3c..6958b86f2 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/HelperFunctionManager.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/HelperFunctionManager.cs
@@ -45,12 +45,101 @@ namespace Ryujinx.Graphics.Shader.Translation
{
return functionName switch
{
+ HelperFunctionName.ConvertDoubleToFloat => GenerateConvertDoubleToFloatFunction(),
+ HelperFunctionName.ConvertFloatToDouble => GenerateConvertFloatToDoubleFunction(),
HelperFunctionName.TexelFetchScale => GenerateTexelFetchScaleFunction(),
HelperFunctionName.TextureSizeUnscale => GenerateTextureSizeUnscaleFunction(),
_ => throw new ArgumentException($"Invalid function name {functionName}")
};
}
+ private Function GenerateConvertDoubleToFloatFunction()
+ {
+ EmitterContext context = new EmitterContext();
+
+ Operand valueLow = Argument(0);
+ Operand valueHigh = Argument(1);
+
+ Operand mantissaLow = context.BitwiseAnd(valueLow, Const(((1 << 22) - 1)));
+ Operand mantissa = context.ShiftRightU32(valueLow, Const(22));
+
+ mantissa = context.BitwiseOr(mantissa, context.ShiftLeft(context.BitwiseAnd(valueHigh, Const(0xfffff)), Const(10)));
+ mantissa = context.BitwiseOr(mantissa, context.ConditionalSelect(mantissaLow, Const(1), Const(0)));
+
+ Operand exp = context.BitwiseAnd(context.ShiftRightU32(valueHigh, Const(20)), Const(0x7ff));
+ Operand sign = context.ShiftRightS32(valueHigh, Const(31));
+
+ Operand resultSign = context.ShiftLeft(sign, Const(31));
+
+ Operand notZero = context.BitwiseOr(mantissa, exp);
+
+ Operand lblNotZero = Label();
+
+ context.BranchIfTrue(lblNotZero, notZero);
+
+ context.Return(resultSign);
+
+ context.MarkLabel(lblNotZero);
+
+ Operand notNaNOrInf = context.ICompareNotEqual(exp, Const(0x7ff));
+
+ mantissa = context.BitwiseOr(mantissa, Const(0x40000000));
+ exp = context.ISubtract(exp, Const(0x381));
+
+ // Note: Overflow cases are not handled here and might produce incorrect results.
+
+ Operand roundBits = context.BitwiseAnd(mantissa, Const(0x7f));
+ Operand roundBitsXor64 = context.BitwiseExclusiveOr(roundBits, Const(0x40));
+ mantissa = context.ShiftRightU32(context.IAdd(mantissa, Const(0x40)), Const(7));
+ mantissa = context.BitwiseAnd(mantissa, context.ConditionalSelect(roundBitsXor64, Const(~0), Const(~1)));
+
+ exp = context.ConditionalSelect(mantissa, exp, Const(0));
+ exp = context.ConditionalSelect(notNaNOrInf, exp, Const(0xff));
+
+ Operand result = context.IAdd(context.IAdd(mantissa, context.ShiftLeft(exp, Const(23))), resultSign);
+
+ context.Return(result);
+
+ return new Function(ControlFlowGraph.Create(context.GetOperations()).Blocks, "ConvertDoubleToFloat", true, 2, 0);
+ }
+
+ private Function GenerateConvertFloatToDoubleFunction()
+ {
+ EmitterContext context = new EmitterContext();
+
+ Operand value = Argument(0);
+
+ Operand mantissa = context.BitwiseAnd(value, Const(0x7fffff));
+ Operand exp = context.BitwiseAnd(context.ShiftRightU32(value, Const(23)), Const(0xff));
+ Operand sign = context.ShiftRightS32(value, Const(31));
+
+ Operand notNaNOrInf = context.ICompareNotEqual(exp, Const(0xff));
+ Operand expNotZero = context.ICompareNotEqual(exp, Const(0));
+ Operand notDenorm = context.BitwiseOr(expNotZero, context.ICompareEqual(mantissa, Const(0)));
+
+ exp = context.IAdd(exp, Const(0x380));
+
+ Operand shiftDist = context.ISubtract(Const(32), context.FindMSBU32(mantissa));
+ Operand normExp = context.ISubtract(context.ISubtract(Const(1), shiftDist), Const(1));
+ Operand normMant = context.ShiftLeft(mantissa, shiftDist);
+
+ exp = context.ConditionalSelect(notNaNOrInf, exp, Const(0x7ff));
+ exp = context.ConditionalSelect(notDenorm, exp, normExp);
+ mantissa = context.ConditionalSelect(expNotZero, mantissa, normMant);
+
+ Operand resultLow = context.ShiftLeft(mantissa, Const(29));
+ Operand resultHigh = context.ShiftRightU32(mantissa, Const(3));
+
+ resultHigh = context.IAdd(resultHigh, context.ShiftLeft(exp, Const(20)));
+ resultHigh = context.IAdd(resultHigh, context.ShiftLeft(sign, Const(31)));
+
+ context.Copy(Argument(1), resultLow);
+ context.Copy(Argument(2), resultHigh);
+ context.Return();
+
+ return new Function(ControlFlowGraph.Create(context.GetOperations()).Blocks, "ConvertFloatToDouble", false, 1, 2);
+ }
+
private Function GenerateTexelFetchScaleFunction()
{
EmitterContext context = new EmitterContext();
diff --git a/src/Ryujinx.Graphics.Shader/Translation/HelperFunctionName.cs b/src/Ryujinx.Graphics.Shader/Translation/HelperFunctionName.cs
index 5accdf65f..8c37c34c7 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/HelperFunctionName.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/HelperFunctionName.cs
@@ -1,10 +1,9 @@
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using System.Collections.Generic;
-
namespace Ryujinx.Graphics.Shader.Translation
{
enum HelperFunctionName
{
+ ConvertDoubleToFloat,
+ ConvertFloatToDouble,
TexelFetchScale,
TextureSizeUnscale
}
diff --git a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/DoubleToFloat.cs b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/DoubleToFloat.cs
new file mode 100644
index 000000000..42bce5cc2
--- /dev/null
+++ b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/DoubleToFloat.cs
@@ -0,0 +1,70 @@
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using System.Collections.Generic;
+
+using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
+
+namespace Ryujinx.Graphics.Shader.Translation.Optimizations
+{
+ static class DoubleToFloat
+ {
+ public static void RunPass(HelperFunctionManager hfm, BasicBlock block)
+ {
+ for (LinkedListNode node = block.Operations.First; node != null; node = node.Next)
+ {
+ if (node.Value is not Operation operation)
+ {
+ continue;
+ }
+
+ node = InsertSoftFloat64(hfm, node);
+ }
+ }
+
+ private static LinkedListNode InsertSoftFloat64(HelperFunctionManager hfm, LinkedListNode node)
+ {
+ Operation operation = (Operation)node.Value;
+
+ if (operation.Inst == Instruction.PackDouble2x32)
+ {
+ int functionId = hfm.GetOrCreateFunctionId(HelperFunctionName.ConvertDoubleToFloat);
+
+ Operand[] callArgs = new Operand[] { Const(functionId), operation.GetSource(0), operation.GetSource(1) };
+
+ Operand floatValue = operation.Dest;
+
+ operation.Dest = null;
+
+ LinkedListNode newNode = node.List.AddBefore(node, new Operation(Instruction.Call, 0, floatValue, callArgs));
+
+ Utils.DeleteNode(node, operation);
+
+ return newNode;
+ }
+ else if (operation.Inst == Instruction.UnpackDouble2x32)
+ {
+ int functionId = hfm.GetOrCreateFunctionId(HelperFunctionName.ConvertFloatToDouble);
+
+ // TODO: Allow UnpackDouble2x32 to produce two outputs and get rid of "operation.Index".
+
+ Operand resultLow = operation.Index == 0 ? operation.Dest : Local();
+ Operand resultHigh = operation.Index == 1 ? operation.Dest : Local();
+
+ operation.Dest = null;
+
+ Operand[] callArgs = new Operand[] { Const(functionId), operation.GetSource(0), resultLow, resultHigh };
+
+ LinkedListNode newNode = node.List.AddBefore(node, new Operation(Instruction.Call, 0, (Operand)null, callArgs));
+
+ Utils.DeleteNode(node, operation);
+
+ return newNode;
+ }
+ else
+ {
+ operation.TurnDoubleIntoFloat();
+
+ return node;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs
index bdb3a62ec..8d2669c0d 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs
@@ -11,8 +11,12 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
{
RunOptimizationPasses(blocks, config);
+ // TODO: Some of those are not optimizations and shouldn't be here.
+
GlobalToStorage.RunPass(hfm, blocks, config);
+ bool hostSupportsShaderFloat64 = config.GpuAccessor.QueryHostSupportsShaderFloat64();
+
// Those passes are looking for specific patterns and only needs to run once.
for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++)
{
@@ -24,6 +28,12 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
{
EliminateMultiplyByFragmentCoordW(blocks[blkIndex]);
}
+
+ // If the host does not support double operations, we need to turn them into float operations.
+ if (!hostSupportsShaderFloat64)
+ {
+ DoubleToFloat.RunPass(hfm, blocks[blkIndex]);
+ }
}
// Run optimizations one last time to remove any code that is now optimizable after above passes.
diff --git a/src/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs b/src/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
index 5c0a1fb60..534bda70e 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
@@ -132,6 +132,11 @@ namespace Ryujinx.Graphics.Shader.Translation
_transformFeedbackDefinitions = new Dictionary();
+ TransformFeedbackEnabled =
+ stage != ShaderStage.Compute &&
+ gpuAccessor.QueryTransformFeedbackEnabled() &&
+ gpuAccessor.QueryHostSupportsTransformFeedback();
+
UsedInputAttributesPerPatch = new HashSet();
UsedOutputAttributesPerPatch = new HashSet();
@@ -139,6 +144,31 @@ namespace Ryujinx.Graphics.Shader.Translation
_usedImages = new Dictionary();
ResourceManager = new ResourceManager(stage, gpuAccessor, new ShaderProperties());
+
+ if (!gpuAccessor.QueryHostSupportsTransformFeedback() && gpuAccessor.QueryTransformFeedbackEnabled())
+ {
+ StructureType tfeInfoStruct = new StructureType(new StructureField[]
+ {
+ new StructureField(AggregateType.Array | AggregateType.U32, "base_offset", 4),
+ new StructureField(AggregateType.U32, "vertex_count")
+ });
+
+ BufferDefinition tfeInfoBuffer = new BufferDefinition(BufferLayout.Std430, 1, Constants.TfeInfoBinding, "tfe_info", tfeInfoStruct);
+
+ Properties.AddStorageBuffer(Constants.TfeInfoBinding, tfeInfoBuffer);
+
+ StructureType tfeDataStruct = new StructureType(new StructureField[]
+ {
+ new StructureField(AggregateType.Array | AggregateType.U32, "data", 0)
+ });
+
+ for (int i = 0; i < Constants.TfeBuffersCount; i++)
+ {
+ int binding = Constants.TfeBufferBaseBinding + i;
+ BufferDefinition tfeDataBuffer = new BufferDefinition(BufferLayout.Std430, 1, binding, $"tfe_data{i}", tfeDataStruct);
+ Properties.AddStorageBuffer(binding, tfeDataBuffer);
+ }
+ }
}
public ShaderConfig(
@@ -151,7 +181,6 @@ namespace Ryujinx.Graphics.Shader.Translation
ThreadsPerInputPrimitive = 1;
OutputTopology = outputTopology;
MaxOutputVertices = maxOutputVertices;
- TransformFeedbackEnabled = gpuAccessor.QueryTransformFeedbackEnabled();
}
public ShaderConfig(ShaderHeader header, IGpuAccessor gpuAccessor, TranslationOptions options) : this(header.Stage, gpuAccessor, options)
@@ -165,7 +194,6 @@ namespace Ryujinx.Graphics.Shader.Translation
OmapTargets = header.OmapTargets;
OmapSampleMask = header.OmapSampleMask;
OmapDepth = header.OmapDepth;
- TransformFeedbackEnabled = gpuAccessor.QueryTransformFeedbackEnabled();
LastInVertexPipeline = header.Stage < ShaderStage.Fragment;
}
@@ -726,7 +754,7 @@ namespace Ryujinx.Graphics.Shader.Translation
var descriptors = new TextureDescriptor[dict.Count];
int i = 0;
- foreach (var kv in dict.OrderBy(x => x.Key.Indexed).OrderBy(x => x.Key.Handle))
+ foreach (var kv in dict.OrderBy(x => x.Key.Indexed).ThenBy(x => x.Key.Handle))
{
var info = kv.Key;
var meta = kv.Value;
@@ -824,4 +852,4 @@ namespace Ryujinx.Graphics.Shader.Translation
OmapTargets);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Ryujinx.Graphics.Vulkan/DescriptorSetCollection.cs b/src/Ryujinx.Graphics.Vulkan/DescriptorSetCollection.cs
index 70b3ebfe4..a185d7871 100644
--- a/src/Ryujinx.Graphics.Vulkan/DescriptorSetCollection.cs
+++ b/src/Ryujinx.Graphics.Vulkan/DescriptorSetCollection.cs
@@ -16,9 +16,9 @@ namespace Ryujinx.Graphics.Vulkan
_descriptorSets = descriptorSets;
}
- public void InitializeBuffers(int setIndex, int baseBinding, int countPerUnit, DescriptorType type, VkBuffer dummyBuffer)
+ public void InitializeBuffers(int setIndex, int baseBinding, int count, DescriptorType type, VkBuffer dummyBuffer)
{
- Span infos = stackalloc DescriptorBufferInfo[countPerUnit];
+ Span infos = stackalloc DescriptorBufferInfo[count];
infos.Fill(new DescriptorBufferInfo()
{
diff --git a/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs b/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs
index cbac1cd47..b09a0667e 100644
--- a/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs
+++ b/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs
@@ -596,36 +596,19 @@ namespace Ryujinx.Graphics.Vulkan
}
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Initialize(CommandBufferScoped cbs, int setIndex, DescriptorSetCollection dsc)
{
+ // We don't support clearing texture descriptors currently.
+ if (setIndex != PipelineBase.UniformSetIndex && setIndex != PipelineBase.StorageSetIndex)
+ {
+ return;
+ }
+
var dummyBuffer = _dummyBuffer?.GetBuffer().Get(cbs).Value ?? default;
- uint stages = _program.Stages;
-
- while (stages != 0)
+ foreach (ResourceBindingSegment segment in _program.ClearSegments[setIndex])
{
- int stage = BitOperations.TrailingZeroCount(stages);
- stages &= ~(1u << stage);
-
- if (setIndex == PipelineBase.UniformSetIndex)
- {
- dsc.InitializeBuffers(
- 0,
- 1 + stage * Constants.MaxUniformBuffersPerStage,
- Constants.MaxUniformBuffersPerStage,
- DescriptorType.UniformBuffer,
- dummyBuffer);
- }
- else if (setIndex == PipelineBase.StorageSetIndex)
- {
- dsc.InitializeBuffers(
- 0,
- stage * Constants.MaxStorageBuffersPerStage,
- Constants.MaxStorageBuffersPerStage,
- DescriptorType.StorageBuffer,
- dummyBuffer);
- }
+ dsc.InitializeBuffers(0, segment.Binding, segment.Count, segment.Type.Convert(), dummyBuffer);
}
}
diff --git a/src/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs b/src/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs
index f600d93f0..393bcf1a2 100644
--- a/src/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs
+++ b/src/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs
@@ -26,6 +26,7 @@ namespace Ryujinx.Graphics.Vulkan
public readonly bool SupportsFragmentShaderInterlock;
public readonly bool SupportsGeometryShaderPassthrough;
public readonly bool SupportsSubgroupSizeControl;
+ public readonly bool SupportsShaderFloat64;
public readonly bool SupportsShaderInt8;
public readonly bool SupportsShaderStencilExport;
public readonly bool SupportsShaderStorageImageMultisample;
@@ -63,6 +64,7 @@ namespace Ryujinx.Graphics.Vulkan
bool supportsFragmentShaderInterlock,
bool supportsGeometryShaderPassthrough,
bool supportsSubgroupSizeControl,
+ bool supportsShaderFloat64,
bool supportsShaderInt8,
bool supportsShaderStencilExport,
bool supportsShaderStorageImageMultisample,
@@ -99,6 +101,7 @@ namespace Ryujinx.Graphics.Vulkan
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
SupportsSubgroupSizeControl = supportsSubgroupSizeControl;
+ SupportsShaderFloat64 = supportsShaderFloat64;
SupportsShaderInt8 = supportsShaderInt8;
SupportsShaderStencilExport = supportsShaderStencilExport;
SupportsShaderStorageImageMultisample = supportsShaderStorageImageMultisample;
diff --git a/src/Ryujinx.Graphics.Vulkan/MoltenVK/MVKConfiguration.cs b/src/Ryujinx.Graphics.Vulkan/MoltenVK/MVKConfiguration.cs
index 4fbae86e7..414dbc628 100644
--- a/src/Ryujinx.Graphics.Vulkan/MoltenVK/MVKConfiguration.cs
+++ b/src/Ryujinx.Graphics.Vulkan/MoltenVK/MVKConfiguration.cs
@@ -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,
diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineUid.cs b/src/Ryujinx.Graphics.Vulkan/PipelineUid.cs
index bf23f4714..f404be744 100644
--- a/src/Ryujinx.Graphics.Vulkan/PipelineUid.cs
+++ b/src/Ryujinx.Graphics.Vulkan/PipelineUid.cs
@@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.Vulkan
private uint VertexAttributeDescriptionsCount => (byte)((Id6 >> 38) & 0xFF);
private uint VertexBindingDescriptionsCount => (byte)((Id6 >> 46) & 0xFF);
private uint ViewportsCount => (byte)((Id6 >> 54) & 0xFF);
- private uint ScissorsCount => (byte)((Id7 >> 0) & 0xFF);
+ private uint ScissorsCount => (byte)(Id7 & 0xFF);
private uint ColorBlendAttachmentStateCount => (byte)((Id7 >> 8) & 0xFF);
private bool HasDepthStencil => ((Id7 >> 63) & 0x1) != 0UL;
diff --git a/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs b/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs
index c30d91c42..2fdddaeab 100644
--- a/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs
+++ b/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs
@@ -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 _queryPool;
private AutoResetEvent _queuedEvent = new AutoResetEvent(false);
diff --git a/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs b/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs
index d3aedb2f3..9d0a674b4 100644
--- a/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs
+++ b/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs
@@ -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;
diff --git a/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs b/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
index 334dfc200..222cdf2a7 100644
--- a/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
+++ b/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
@@ -24,6 +24,7 @@ namespace Ryujinx.Graphics.Vulkan
public uint Stages { get; }
+ public ResourceBindingSegment[][] ClearSegments { get; }
public ResourceBindingSegment[][] BindingSegments { get; }
public ProgramLinkStatus LinkStatus { get; private set; }
@@ -115,6 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
Stages = stages;
+ ClearSegments = BuildClearSegments(resourceLayout.Sets);
BindingSegments = BuildBindingSegments(resourceLayout.SetUsages);
_compileTask = Task.CompletedTask;
@@ -135,6 +137,60 @@ namespace Ryujinx.Graphics.Vulkan
_firstBackgroundUse = !fromCache;
}
+ private static ResourceBindingSegment[][] BuildClearSegments(ReadOnlyCollection sets)
+ {
+ ResourceBindingSegment[][] segments = new ResourceBindingSegment[sets.Count][];
+
+ for (int setIndex = 0; setIndex < sets.Count; setIndex++)
+ {
+ List currentSegments = new List();
+
+ ResourceDescriptor currentDescriptor = default;
+ int currentCount = 0;
+
+ for (int index = 0; index < sets[setIndex].Descriptors.Count; index++)
+ {
+ ResourceDescriptor descriptor = sets[setIndex].Descriptors[index];
+
+ if (currentDescriptor.Binding + currentCount != descriptor.Binding ||
+ currentDescriptor.Type != descriptor.Type ||
+ currentDescriptor.Stages != descriptor.Stages)
+ {
+ if (currentCount != 0)
+ {
+ currentSegments.Add(new ResourceBindingSegment(
+ currentDescriptor.Binding,
+ currentCount,
+ currentDescriptor.Type,
+ currentDescriptor.Stages,
+ ResourceAccess.ReadWrite));
+ }
+
+ currentDescriptor = descriptor;
+ currentCount = descriptor.Count;
+ }
+ else
+ {
+ currentCount += descriptor.Count;
+ }
+ }
+
+ if (currentCount != 0)
+ {
+ currentSegments.Add(new ResourceBindingSegment(
+ currentDescriptor.Binding,
+ currentCount,
+ currentDescriptor.Type,
+ currentDescriptor.Stages,
+ ResourceAccess.ReadWrite));
+ }
+
+ segments[setIndex] = currentSegments.ToArray();
+ }
+
+ return segments;
+ }
+
private static ResourceBindingSegment[][] BuildBindingSegments(ReadOnlyCollection setUsages)
{
ResourceBindingSegment[][] segments = new ResourceBindingSegment[setUsages.Count][];
diff --git a/src/Ryujinx.Graphics.Vulkan/TextureView.cs b/src/Ryujinx.Graphics.Vulkan/TextureView.cs
index c2be74974..eb094b3e6 100644
--- a/src/Ryujinx.Graphics.Vulkan/TextureView.cs
+++ b/src/Ryujinx.Graphics.Vulkan/TextureView.cs
@@ -15,6 +15,7 @@ namespace Ryujinx.Graphics.Vulkan
private readonly Device _device;
private readonly Auto _imageView;
+ private readonly Auto _imageViewDraw;
private readonly Auto _imageViewIdentity;
private readonly Auto _imageView2dArray;
private Dictionary _selfManagedViews;
@@ -127,7 +128,8 @@ namespace Ryujinx.Graphics.Vulkan
ComponentSwizzle.B,
ComponentSwizzle.A);
- _imageViewIdentity = CreateImageView(identityComponentMapping, subresourceRangeDepth, type, usage);
+ _imageViewDraw = CreateImageView(identityComponentMapping, subresourceRangeDepth, type, usage);
+ _imageViewIdentity = aspectFlagsDepth == aspectFlags ? _imageViewDraw : CreateImageView(identityComponentMapping, subresourceRange, type, usage);
// Framebuffer attachments also require 3D textures to be bound as 2D array.
if (info.Target == Target.Texture3D)
@@ -169,7 +171,7 @@ namespace Ryujinx.Graphics.Vulkan
public Auto GetImageViewForAttachment()
{
- return _imageView2dArray ?? _imageViewIdentity;
+ return _imageView2dArray ?? _imageViewDraw;
}
public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
@@ -909,6 +911,11 @@ namespace Ryujinx.Graphics.Vulkan
_imageViewIdentity.Dispose();
_imageView2dArray?.Dispose();
+ if (_imageViewDraw != _imageViewIdentity)
+ {
+ _imageViewDraw.Dispose();
+ }
+
Storage.DecrementViewsCount();
}
}
diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
index 3987be9b4..8c1787d69 100644
--- a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
+++ b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
@@ -306,6 +306,7 @@ namespace Ryujinx.Graphics.Vulkan
_physicalDevice.IsDeviceExtensionPresent("VK_EXT_fragment_shader_interlock"),
_physicalDevice.IsDeviceExtensionPresent("VK_NV_geometry_shader_passthrough"),
supportsSubgroupSizeControl,
+ features2.Features.ShaderFloat64,
featuresShaderInt8.ShaderInt8,
_physicalDevice.IsDeviceExtensionPresent("VK_EXT_shader_stencil_export"),
features2.Features.ShaderStorageImageMultisample,
@@ -588,12 +589,15 @@ namespace Ryujinx.Graphics.Vulkan
supportsFragmentShaderOrderingIntel: false,
supportsGeometryShader: Capabilities.SupportsGeometryShader,
supportsGeometryShaderPassthrough: Capabilities.SupportsGeometryShaderPassthrough,
+ supportsTransformFeedback: Capabilities.SupportsTransformFeedback,
supportsImageLoadFormatted: features2.Features.ShaderStorageImageReadWithoutFormat,
supportsLayerVertexTessellation: featuresVk12.ShaderOutputLayer,
supportsMismatchingViewFormat: true,
supportsCubemapView: !IsAmdGcn,
supportsNonConstantTextureOffset: false,
supportsShaderBallot: false,
+ supportsShaderBarrierDivergence: Vendor != Vendor.Intel,
+ supportsShaderFloat64: Capabilities.SupportsShaderFloat64,
supportsTextureShadowLod: false,
supportsViewportIndexVertexTessellation: featuresVk12.ShaderOutputViewportIndex,
supportsViewportMask: Capabilities.SupportsViewportArray2,
diff --git a/src/Ryujinx.HLE/FileSystem/ContentManager.cs b/src/Ryujinx.HLE/FileSystem/ContentManager.cs
index 9facdd0b7..e00310a07 100644
--- a/src/Ryujinx.HLE/FileSystem/ContentManager.cs
+++ b/src/Ryujinx.HLE/FileSystem/ContentManager.cs
@@ -181,7 +181,7 @@ namespace Ryujinx.HLE.FileSystem
}
}
- if (_locationEntries.ContainsKey(storageId) && _locationEntries[storageId]?.Count == 0)
+ if (_locationEntries.TryGetValue(storageId, out var locationEntriesItem) && locationEntriesItem?.Count == 0)
{
_locationEntries.Remove(storageId);
}
@@ -347,9 +347,9 @@ namespace Ryujinx.HLE.FileSystem
{
lock (_lock)
{
- if (_contentDictionary.ContainsKey((titleId, contentType)))
+ if (_contentDictionary.TryGetValue((titleId, contentType), out var contentDictionaryItem))
{
- return UInt128Utils.FromHex(_contentDictionary[(titleId, contentType)]);
+ return UInt128Utils.FromHex(contentDictionaryItem);
}
}
@@ -719,9 +719,9 @@ namespace Ryujinx.HLE.FileSystem
Nca nca = new Nca(_virtualFileSystem.KeySet, storage);
- if (updateNcas.ContainsKey(nca.Header.TitleId))
+ if (updateNcas.TryGetValue(nca.Header.TitleId, out var updateNcasItem))
{
- updateNcas[nca.Header.TitleId].Add((nca.Header.ContentType, entry.FullName));
+ updateNcasItem.Add((nca.Header.ContentType, entry.FullName));
}
else
{
@@ -732,10 +732,8 @@ namespace Ryujinx.HLE.FileSystem
}
}
- if (updateNcas.ContainsKey(SystemUpdateTitleId))
+ if (updateNcas.TryGetValue(SystemUpdateTitleId, out var ncaEntry))
{
- var ncaEntry = updateNcas[SystemUpdateTitleId];
-
string metaPath = ncaEntry.Find(x => x.type == NcaContentType.Meta).path;
CnmtContentMetaEntry[] metaEntries = null;
@@ -770,9 +768,9 @@ namespace Ryujinx.HLE.FileSystem
throw new FileNotFoundException("System update title was not found in the firmware package.");
}
- if (updateNcas.ContainsKey(SystemVersionTitleId))
+ if (updateNcas.TryGetValue(SystemVersionTitleId, out var updateNcasItem))
{
- string versionEntry = updateNcas[SystemVersionTitleId].Find(x => x.type != NcaContentType.Meta).path;
+ string versionEntry = updateNcasItem.Find(x => x.type != NcaContentType.Meta).path;
using (Stream ncaStream = GetZipStream(archive.GetEntry(versionEntry)))
{
@@ -916,9 +914,9 @@ namespace Ryujinx.HLE.FileSystem
}
}
- if (updateNcas.ContainsKey(nca.Header.TitleId))
+ if (updateNcas.TryGetValue(nca.Header.TitleId, out var updateNcasItem))
{
- updateNcas[nca.Header.TitleId].Add((nca.Header.ContentType, entry.FullPath));
+ updateNcasItem.Add((nca.Header.ContentType, entry.FullPath));
}
else
{
diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs
new file mode 100644
index 000000000..36e6ff512
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs
@@ -0,0 +1,17 @@
+using System.Text.RegularExpressions;
+
+namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
+{
+ public static partial class CJKCharacterValidation
+ {
+ public static bool IsCJK(char value)
+ {
+ Regex regex = CJKRegex();
+
+ return regex.IsMatch(value.ToString());
+ }
+
+ [GeneratedRegex("\\p{IsHangulJamo}|\\p{IsCJKRadicalsSupplement}|\\p{IsCJKSymbolsandPunctuation}|\\p{IsEnclosedCJKLettersandMonths}|\\p{IsCJKCompatibility}|\\p{IsCJKUnifiedIdeographsExtensionA}|\\p{IsCJKUnifiedIdeographs}|\\p{IsHangulSyllables}|\\p{IsCJKCompatibilityForms}")]
+ private static partial Regex CJKRegex();
+ }
+}
\ No newline at end of file
diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMode.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMode.cs
index 01b3c9634..e28622111 100644
--- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMode.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMode.cs
@@ -6,22 +6,30 @@
public enum KeyboardMode : uint
{
///
- /// A full alpha-numeric keyboard.
+ /// All UTF-16 characters allowed.
///
Default = 0,
///
- /// Number pad.
+ /// Only numbers allowed.
///
NumbersOnly = 1,
///
- /// ASCII characters keyboard.
+ /// Only ASCII characters allowed.
///
ASCII = 2,
- FullLatin = 3,
- Alphabet = 4,
+ ///
+ /// Synonymous with default.
+ ///
+ FullLatin = 3,
+
+ ///
+ /// All UTF-16 characters except CJK characters allowed.
+ ///
+ Alphabet = 4,
+
SimplifiedChinese = 5,
TraditionalChinese = 6,
Korean = 7,
diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs
index 4b484e802..4337ec44b 100644
--- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs
@@ -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;
diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRenderer.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRenderer.cs
index c30ad11b0..fb4cec82a 100644
--- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRenderer.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRenderer.cs
@@ -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;
diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs
index 9a91fa321..595223ed3 100644
--- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs
@@ -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 _surface = null;
@@ -311,7 +311,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
private static RectangleF MeasureString(ReadOnlySpan text, Font font)
{
RendererOptions options = new RendererOptions(font);
-
+
if (text == "")
{
FontRectangle emptyRectangle = TextMeasurer.Measure(" ", options);
diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TimedAction.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TimedAction.cs
index 0de78a0e5..ed876ffd2 100644
--- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TimedAction.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TimedAction.cs
@@ -26,8 +26,8 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
}
private TRef _cancelled = null;
- private Thread _thread = null;
- private object _lock = new object();
+ private Thread _thread = null;
+ private readonly object _lock = new();
public bool IsRunning
{
diff --git a/src/Ryujinx.HLE/HOS/Kernel/Process/KHandleTable.cs b/src/Ryujinx.HLE/HOS/Kernel/Process/KHandleTable.cs
index 50f04e90c..6dd7e5b78 100644
--- a/src/Ryujinx.HLE/HOS/Kernel/Process/KHandleTable.cs
+++ b/src/Ryujinx.HLE/HOS/Kernel/Process/KHandleTable.cs
@@ -137,7 +137,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
public void CancelHandleReservation(int handle)
{
- int index = (handle >> 0) & 0x7fff;
+ int index = handle & 0x7fff;
lock (_table)
{
diff --git a/src/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs b/src/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
index 21e89944e..510c99ea3 100644
--- a/src/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
+++ b/src/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
@@ -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();
diff --git a/src/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs b/src/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
index 633964686..78bd577e1 100644
--- a/src/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
+++ b/src/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
@@ -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();
_pinnedWaiters = new LinkedList();
-
- _activityOperationLock = new object();
}
public Result Initialize(
diff --git a/src/Ryujinx.HLE/HOS/Kernel/Threading/ThreadSchedState.cs b/src/Ryujinx.HLE/HOS/Kernel/Threading/ThreadSchedState.cs
index 9577075c0..1d09e021e 100644
--- a/src/Ryujinx.HLE/HOS/Kernel/Threading/ThreadSchedState.cs
+++ b/src/Ryujinx.HLE/HOS/Kernel/Threading/ThreadSchedState.cs
@@ -1,5 +1,8 @@
+using System;
+
namespace Ryujinx.HLE.HOS.Kernel.Threading
{
+ [Flags]
enum ThreadSchedState : ushort
{
LowMask = 0xf,
diff --git a/src/Ryujinx.HLE/HOS/ModLoader.cs b/src/Ryujinx.HLE/HOS/ModLoader.cs
index ac983cfe5..243510967 100644
--- a/src/Ryujinx.HLE/HOS/ModLoader.cs
+++ b/src/Ryujinx.HLE/HOS/ModLoader.cs
@@ -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)
{
diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ISelfController.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ISelfController.cs
index 399e778a4..8f93117e1 100644
--- a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ISelfController.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/SystemAppletProxy/ISelfController.cs
@@ -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;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/INotificationService.cs b/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/INotificationService.cs
index 063750c6b..505580221 100644
--- a/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/INotificationService.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Friend/ServiceCreator/INotificationService.cs
@@ -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;
diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/IHidbusServer.cs b/src/Ryujinx.HLE/HOS/Services/Hid/IHidbusServer.cs
index bfd1d4dcd..eec5292f5 100644
--- a/src/Ryujinx.HLE/HOS/Services/Hid/IHidbusServer.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Hid/IHidbusServer.cs
@@ -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;
+ }
}
}
\ No newline at end of file
diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs
new file mode 100644
index 000000000..936ee68c4
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusHandle.cs
@@ -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;
+ }
+}
diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs
new file mode 100644
index 000000000..41852365b
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/BusType.cs
@@ -0,0 +1,9 @@
+namespace Ryujinx.HLE.HOS.Services.Hid
+{
+ public enum BusType : long
+ {
+ LeftJoyRail = 0,
+ RightJoyRail = 1,
+ InternalBus = 2
+ }
+}
diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerType.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerType.cs
index b2d34e8e2..d830f46ad 100644
--- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerType.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerType.cs
@@ -3,7 +3,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Hid
{
[Flags]
- public enum ControllerType : int
+ public enum ControllerType
{
None,
ProController = 1 << 0,
diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadIdType.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadIdType.cs
index 1abd84680..4b488cd2c 100644
--- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadIdType.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/NpadIdType.cs
@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Hid
{
- public enum NpadIdType : int
+ public enum NpadIdType
{
Player1 = 0,
Player2 = 1,
diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/PlayerIndex.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/PlayerIndex.cs
index f4ced5df5..972d69b45 100644
--- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/PlayerIndex.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/PlayerIndex.cs
@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Hid
{
- public enum PlayerIndex : int
+ public enum PlayerIndex
{
Player1 = 0,
Player2 = 1,
diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/DeviceType.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/DeviceType.cs
index b02018353..95b1cb518 100644
--- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/DeviceType.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/DeviceType.cs
@@ -3,7 +3,7 @@
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad
{
[Flags]
- enum DeviceType : int
+ enum DeviceType
{
None = 0,
diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadBatteryLevel.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadBatteryLevel.cs
index 477dfd10f..e10e55cd8 100644
--- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadBatteryLevel.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Npad/NpadBatteryLevel.cs
@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad
{
- enum NpadBatteryLevel : int
+ enum NpadBatteryLevel
{
Percent0,
Percent25,
diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/CoreData.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/CoreData.cs
index f3a101d8b..abf18e36e 100644
--- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/CoreData.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/CoreData.cs
@@ -775,7 +775,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii.Types
private static ReadOnlySpan ElementInfos => MemoryMarshal.Cast(ElementInfoArray);
- private enum ElementInfoIndex : int
+ private enum ElementInfoIndex
{
HairType,
Height,
diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/RandomMiiConstants.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/RandomMiiConstants.cs
index 82529450b..6def469db 100644
--- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/RandomMiiConstants.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/RandomMiiConstants.cs
@@ -21,7 +21,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii.Types
};
[Flags]
- public enum BeardAndMustacheFlag : int
+ public enum BeardAndMustacheFlag
{
Beard = 1,
Mustache
diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/Source.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/Source.cs
index 1ded636a9..2ae02ea03 100644
--- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/Source.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/Source.cs
@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Mii.Types
{
- enum Source : int
+ enum Source
{
Database,
Default
diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/SourceFlag.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/SourceFlag.cs
index d51dce879..c9682bdbb 100644
--- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/SourceFlag.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/SourceFlag.cs
@@ -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,
diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostEvent.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostEvent.cs
index ac5512eda..383fb3fbe 100644
--- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostEvent.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostEvent.cs
@@ -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();
///
/// Max failing count until waiting on CPU.
diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostSyncPt.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostSyncPt.cs
index 27dd1bd16..1b842aa17 100644
--- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostSyncPt.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostSyncPt.cs
@@ -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)
{
diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvInternalResult.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvInternalResult.cs
index 9345baeb5..9a3aa7aa1 100644
--- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvInternalResult.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvInternalResult.cs
@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices
{
- enum NvInternalResult : int
+ enum NvInternalResult
{
Success = 0,
OperationNotPermitted = -1,
diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapHandleParam.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapHandleParam.cs
index 61b73cba2..9eb7efff9 100644
--- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapHandleParam.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapHandleParam.cs
@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
{
- enum NvMapHandleParam : int
+ enum NvMapHandleParam
{
Size = 1,
Align = 2,
diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/BsdContext.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/BsdContext.cs
index a93f176a5..b0ac6e680 100644
--- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/BsdContext.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/BsdContext.cs
@@ -10,7 +10,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
{
private static ConcurrentDictionary _registry = new ConcurrentDictionary();
- private readonly object _lock = new object();
+ private readonly object _lock = new();
private List _fds;
diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/ISocket.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/ISocket.cs
index 058748685..e04a35954 100644
--- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/ISocket.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/ISocket.cs
@@ -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; }
diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs
index 6514d4855..d7b53158a 100644
--- a/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs
@@ -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(); }
diff --git a/src/Ryujinx.HLE/HOS/Services/Spl/IRandomInterface.cs b/src/Ryujinx.HLE/HOS/Services/Spl/IRandomInterface.cs
index c911f434c..db2241631 100644
--- a/src/Ryujinx.HLE/HOS/Services/Spl/IRandomInterface.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Spl/IRandomInterface.cs
@@ -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)
{
diff --git a/src/Ryujinx.HLE/HOS/Services/Ssl/BuiltInCertificateManager.cs b/src/Ryujinx.HLE/HOS/Services/Ssl/BuiltInCertificateManager.cs
index abbc13541..dae0698c3 100644
--- a/src/Ryujinx.HLE/HOS/Services/Ssl/BuiltInCertificateManager.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Ssl/BuiltInCertificateManager.cs
@@ -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 _certificates;
- private object _lock = new object();
+ private readonly object _lock = new();
private struct CertStoreFileHeader
{
diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueCore.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueCore.cs
index 1efd37f49..8cf55912e 100644
--- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueCore.cs
+++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueCore.cs
@@ -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;
diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueProducer.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueProducer.cs
index 833bc26ec..fa840f2ad 100644
--- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueProducer.cs
+++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/BufferQueueProducer.cs
@@ -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)
{
diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/ConsumerBase.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/ConsumerBase.cs
index 49fceed9f..754fa7d73 100644
--- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/ConsumerBase.cs
+++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/ConsumerBase.cs
@@ -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;
}
}
diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowApi.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowApi.cs
index 1ae2732f5..794c48b82 100644
--- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowApi.cs
+++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/NativeWindowApi.cs
@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
{
- enum NativeWindowApi : int
+ enum NativeWindowApi
{
NoApi = 0,
NVN = 1,
diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Status.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Status.cs
index 5a1519021..925811fa2 100644
--- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Status.cs
+++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Status.cs
@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
{
- enum Status : int
+ enum Status
{
Success = 0,
WouldBlock = -11,
diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
index c7cddf100..0c1cea517 100644
--- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
+++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
@@ -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; }
diff --git a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneManager.cs b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneManager.cs
index ef4b7b399..8b85d697b 100644
--- a/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneManager.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneManager.cs
@@ -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();
_timeZoneUpdateTimePoint = SteadyClockTimePoint.GetRandom();
diff --git a/src/Ryujinx.Horizon/LogManager/Ipc/LmLogger.cs b/src/Ryujinx.Horizon/LogManager/Ipc/LmLogger.cs
index e930bdd75..88dddef5e 100644
--- a/src/Ryujinx.Horizon/LogManager/Ipc/LmLogger.cs
+++ b/src/Ryujinx.Horizon/LogManager/Ipc/LmLogger.cs
@@ -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 message)
{
- SpanReader reader = new(message);
- LogPacketHeader header = reader.Read();
+ 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();
+ if (!reader.TryRead(out _logPacket.Line))
+ {
+ return true;
+ }
}
else if (key == LogDataChunkKey.DropCount)
{
- _logPacket.DropCount = reader.Read();
+ if (!reader.TryRead(out _logPacket.DropCount))
+ {
+ return true;
+ }
}
else if (key == LogDataChunkKey.Time)
{
- _logPacket.Time = reader.Read();
+ if (!reader.TryRead(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();
+ if (!reader.TryRead(out encoded))
+ {
+ return false;
+ }
result += (encoded & 0x7F) << (7 * count);
count++;
} while ((encoded & 0x80) != 0);
- return result;
+ return true;
}
}
}
\ No newline at end of file
diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/Impl/MultiWaitImpl.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/Impl/MultiWaitImpl.cs
index a4a671eaf..04bc8d1db 100644
--- a/src/Ryujinx.Horizon/Sdk/OsTypes/Impl/MultiWaitImpl.cs
+++ b/src/Ryujinx.Horizon/Sdk/OsTypes/Impl/MultiWaitImpl.cs
@@ -13,7 +13,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
private readonly List _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();
-
- _lock = new object();
}
public void LinkMultiWaitHolder(MultiWaitHolderBase multiWaitHolder)
diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs
index 925526737..6a8c1204f 100644
--- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs
+++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs
@@ -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 _buttonsUserMapping;
diff --git a/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs b/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs
index edadae15e..2fe0614d8 100644
--- a/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs
+++ b/src/Ryujinx.Input.SDL2/SDL2Keyboard.cs
@@ -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;
diff --git a/src/Ryujinx.Input/HLE/NpadManager.cs b/src/Ryujinx.Input/HLE/NpadManager.cs
index 5290ecbb7..89a2f585b 100644
--- a/src/Ryujinx.Input/HLE/NpadManager.cs
+++ b/src/Ryujinx.Input/HLE/NpadManager.cs
@@ -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);
}
diff --git a/src/Ryujinx.Input/Motion/CemuHook/Client.cs b/src/Ryujinx.Input/Motion/CemuHook/Client.cs
index 4498b8ca6..a79412a17 100644
--- a/src/Ryujinx.Input/Motion/CemuHook/Client.cs
+++ b/src/Ryujinx.Input/Motion/CemuHook/Client.cs
@@ -338,12 +338,10 @@ namespace Ryujinx.Input.Motion.CemuHook
{
int slot = inputData.Shared.Slot;
- if (_motionData.ContainsKey(clientId))
+ if (_motionData.TryGetValue(clientId, out var motionDataItem))
{
- if (_motionData[clientId].ContainsKey(slot))
+ if (motionDataItem.TryGetValue(slot, out var previousData))
{
- MotionInput previousData = _motionData[clientId][slot];
-
previousData.Update(accelerometer, gyroscrope, timestamp, cemuHookConfig.Sensitivity, (float)cemuHookConfig.GyroDeadzone);
}
else
@@ -352,7 +350,7 @@ namespace Ryujinx.Input.Motion.CemuHook
input.Update(accelerometer, gyroscrope, timestamp, cemuHookConfig.Sensitivity, (float)cemuHookConfig.GyroDeadzone);
- _motionData[clientId].Add(slot, input);
+ motionDataItem.Add(slot, input);
}
}
else
diff --git a/src/Ryujinx.Memory/Tracking/RegionHandle.cs b/src/Ryujinx.Memory/Tracking/RegionHandle.cs
index 63a168847..777944888 100644
--- a/src/Ryujinx.Memory/Tracking/RegionHandle.cs
+++ b/src/Ryujinx.Memory/Tracking/RegionHandle.cs
@@ -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 _regions;
diff --git a/src/Ryujinx.SDL2.Common/SDL2Driver.cs b/src/Ryujinx.SDL2.Common/SDL2Driver.cs
index c41c6269d..5e2deb26d 100644
--- a/src/Ryujinx.SDL2.Common/SDL2Driver.cs
+++ b/src/Ryujinx.SDL2.Common/SDL2Driver.cs
@@ -41,7 +41,7 @@ namespace Ryujinx.SDL2.Common
private ConcurrentDictionary> _registeredWindowHandlers;
- private object _lock = new object();
+ private readonly object _lock = new();
private SDL2Driver() {}
diff --git a/src/Ryujinx.Tests.Memory/Tests.cs b/src/Ryujinx.Tests.Memory/Tests.cs
index d8a243e3e..5ab01d5a5 100644
--- a/src/Ryujinx.Tests.Memory/Tests.cs
+++ b/src/Ryujinx.Tests.Memory/Tests.cs
@@ -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);
diff --git a/src/Ryujinx.Tests/Cpu/CpuTest.cs b/src/Ryujinx.Tests/Cpu/CpuTest.cs
index 979b313b0..ad4ba539b 100644
--- a/src/Ryujinx.Tests/Cpu/CpuTest.cs
+++ b/src/Ryujinx.Tests/Cpu/CpuTest.cs
@@ -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();
diff --git a/src/Ryujinx.Tests/Cpu/CpuTest32.cs b/src/Ryujinx.Tests/Cpu/CpuTest32.cs
index 47dc9f8a8..a1f6431cf 100644
--- a/src/Ryujinx.Tests/Cpu/CpuTest32.cs
+++ b/src/Ryujinx.Tests/Cpu/CpuTest32.cs
@@ -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;
diff --git a/src/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs b/src/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs
index 2f9504cbf..c88c02c1b 100644
--- a/src/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs
+++ b/src/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs
@@ -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();
}
diff --git a/src/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs b/src/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs
index b19137a4b..603e2a559 100644
--- a/src/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs
+++ b/src/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs
@@ -3,6 +3,7 @@
using ARMeilleure.State;
using NUnit.Framework;
using System.Collections.Generic;
+using System.Runtime.InteropServices;
namespace Ryujinx.Tests.Cpu
{
@@ -703,6 +704,11 @@ namespace Ryujinx.Tests.Cpu
[Values] bool q,
[Values] bool u)
{
+ if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
+ {
+ Assert.Ignore("Unicorn on ARM64 crash while executing this test");
+ }
+
uint opcode = 0xf2000400u; // VSHL.S8 D0, D0, D0
if (q)
{
diff --git a/src/Ryujinx.Tests/Cpu/CpuTestT32Flow.cs b/src/Ryujinx.Tests/Cpu/CpuTestT32Flow.cs
index 2c83b01d8..03d90a1f1 100644
--- a/src/Ryujinx.Tests/Cpu/CpuTestT32Flow.cs
+++ b/src/Ryujinx.Tests/Cpu/CpuTestT32Flow.cs
@@ -109,7 +109,7 @@ namespace Ryujinx.Tests.Cpu
ExecuteOpcodes(runUnicorn: false);
- Assert.That(GetContext().GetX(0), Is.EqualTo(0x1005));
+ Assert.That(GetContext().GetX(0), Is.EqualTo(CodeBaseAddress + 0x5));
}
[Test]
@@ -133,7 +133,7 @@ namespace Ryujinx.Tests.Cpu
ExecuteOpcodes(runUnicorn: false);
- Assert.That(GetContext().GetX(0), Is.EqualTo(0x1005));
+ Assert.That(GetContext().GetX(0), Is.EqualTo(CodeBaseAddress + 0x5));
Assert.That(GetContext().GetPstateFlag(PState.TFlag), Is.EqualTo(false));
}
@@ -160,7 +160,7 @@ namespace Ryujinx.Tests.Cpu
ExecuteOpcodes(runUnicorn: false);
- Assert.That(GetContext().GetX(0), Is.EqualTo(0x1007));
+ Assert.That(GetContext().GetX(0), Is.EqualTo(CodeBaseAddress + 0x7));
Assert.That(GetContext().GetPstateFlag(PState.TFlag), Is.EqualTo(false));
}
}
diff --git a/src/Ryujinx.Tests/Cpu/CpuTestThumb.cs b/src/Ryujinx.Tests/Cpu/CpuTestThumb.cs
index b740f524a..3d13ff733 100644
--- a/src/Ryujinx.Tests/Cpu/CpuTestThumb.cs
+++ b/src/Ryujinx.Tests/Cpu/CpuTestThumb.cs
@@ -268,6 +268,12 @@ namespace Ryujinx.Tests.Cpu
[Test]
public void TestRandomTestCases([ValueSource(nameof(RandomTestCases))] PrecomputedThumbTestCase test)
{
+ if (Size != 0x1000)
+ {
+ // TODO: Change it to depend on DataBaseAddress instead.
+ Assert.Ignore("This test currently only support 4KiB page size");
+ }
+
RunPrecomputedTestCase(test);
}
diff --git a/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs b/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs
index 4f4b25245..542db9a7e 100644
--- a/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs
+++ b/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs
@@ -11,10 +11,10 @@ namespace Ryujinx.Ui.Common.Helper
{
public static partial class FileAssociationHelper
{
- private static string[] _fileExtensions = new string[] { ".nca", ".nro", ".nso", ".nsp", ".xci" };
+ private static readonly string[] _fileExtensions = { ".nca", ".nro", ".nso", ".nsp", ".xci" };
[SupportedOSPlatform("linux")]
- private static string _mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime");
+ private static readonly string _mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime");
private const int SHCNE_ASSOCCHANGED = 0x8000000;
private const int SHCNF_FLUSH = 0x1000;
@@ -32,7 +32,7 @@ namespace Ryujinx.Ui.Common.Helper
{
string installKeyword = uninstall ? "uninstall" : "install";
- if (!AreMimeTypesRegisteredLinux())
+ if ((uninstall && AreMimeTypesRegisteredLinux()) || (!uninstall && !AreMimeTypesRegisteredLinux()))
{
string mimeTypesFile = Path.Combine(ReleaseInformation.GetBaseApplicationDirectory(), "mime", "Ryujinx.xml");
string additionalArgs = !uninstall ? "--novendor" : "";
@@ -81,9 +81,9 @@ namespace Ryujinx.Ui.Common.Helper
return false;
}
- key.OpenSubKey(@"shell\open\command");
+ var openCmd = key.OpenSubKey(@"shell\open\command");
- string keyValue = (string)key.GetValue("");
+ string keyValue = (string)openCmd.GetValue("");
return keyValue is not null && (keyValue.Contains("Ryujinx") || keyValue.Contains(AppDomain.CurrentDomain.FriendlyName));
}
@@ -107,30 +107,31 @@ namespace Ryujinx.Ui.Common.Helper
if (uninstall)
{
+ // If the types don't already exist, there's nothing to do and we can call this operation successful.
if (!AreMimeTypesRegisteredWindows())
{
- return false;
+ return true;
}
-
+ Logger.Debug?.Print(LogClass.Application, $"Removing type association {ext}");
Registry.CurrentUser.DeleteSubKeyTree(keyString);
+ Logger.Debug?.Print(LogClass.Application, $"Removed type association {ext}");
}
else
{
- RegistryKey key = Registry.CurrentUser.CreateSubKey(keyString);
+ using var key = Registry.CurrentUser.CreateSubKey(keyString);
+
if (key is null)
{
return false;
}
- key.CreateSubKey(@"shell\open\command");
+ Logger.Debug?.Print(LogClass.Application, $"Adding type association {ext}");
+ using var openCmd = key.CreateSubKey(@"shell\open\command");
+ openCmd.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\"");
+ Logger.Debug?.Print(LogClass.Application, $"Added type association {ext}");
- key.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\"");
- key.Close();
}
- // Notify Explorer the file association has been changed.
- SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
-
return true;
}
@@ -141,6 +142,9 @@ namespace Ryujinx.Ui.Common.Helper
registered |= RegisterExtension(ext, uninstall);
}
+ // Notify Explorer the file association has been changed.
+ SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
+
return registered;
}
diff --git a/src/Ryujinx/Input/GTK3/GTK3Keyboard.cs b/src/Ryujinx/Input/GTK3/GTK3Keyboard.cs
index bc0ad87e5..ca3ff32f4 100644
--- a/src/Ryujinx/Input/GTK3/GTK3Keyboard.cs
+++ b/src/Ryujinx/Input/GTK3/GTK3Keyboard.cs
@@ -21,7 +21,7 @@ namespace Ryujinx.Input.GTK3
}
}
- private object _userMappingLock = new object();
+ private readonly object _userMappingLock = new();
private readonly GTK3KeyboardDriver _driver;
private StandardKeyboardInputConfig _configuration;
diff --git a/src/Ryujinx/Ui/Applet/SwkbdAppletDialog.cs b/src/Ryujinx/Ui/Applet/SwkbdAppletDialog.cs
index 28067b751..13d30f6c0 100644
--- a/src/Ryujinx/Ui/Applet/SwkbdAppletDialog.cs
+++ b/src/Ryujinx/Ui/Applet/SwkbdAppletDialog.cs
@@ -93,8 +93,8 @@ namespace Ryujinx.Ui.Applet
_checkInput = text => text.All(char.IsDigit);
break;
case KeyboardMode.Alphabet:
- _validationInfoText += "Must be alphabets only.";
- _checkInput = text => text.All(char.IsAsciiLetter);
+ _validationInfoText += "Must be non CJK-characters only.";
+ _checkInput = text => text.All(value => !CJKCharacterValidation.IsCJK(value));
break;
case KeyboardMode.ASCII:
_validationInfoText += "Must be ASCII text only.";
diff --git a/src/Ryujinx/Ui/GLRenderer.cs b/src/Ryujinx/Ui/GLRenderer.cs
index e3a9804ea..c56996910 100644
--- a/src/Ryujinx/Ui/GLRenderer.cs
+++ b/src/Ryujinx/Ui/GLRenderer.cs
@@ -1,8 +1,10 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Common.Configuration;
+using Ryujinx.Common.Logging;
using Ryujinx.Graphics.OpenGL;
using Ryujinx.Input.HLE;
using SPB.Graphics;
+using SPB.Graphics.Exceptions;
using SPB.Graphics.OpenGL;
using SPB.Platform;
using SPB.Platform.GLX;
@@ -112,24 +114,30 @@ namespace Ryujinx.Ui
protected override void Dispose(bool disposing)
{
- // Try to bind the OpenGL context before calling the shutdown event
+ // Try to bind the OpenGL context before calling the shutdown event.
try
{
_openGLContext?.MakeCurrent(_nativeWindow);
}
- catch (Exception) { }
+ catch (ContextException e)
+ {
+ Logger.Warning?.Print(LogClass.Ui, $"Failed to bind OpenGL context: {e}");
+ }
Device?.DisposeGpu();
NpadManager.Dispose();
- // Unbind context and destroy everything
+ // Unbind context and destroy everything.
try
{
_openGLContext?.MakeCurrent(null);
}
- catch (Exception) { }
+ catch (ContextException e)
+ {
+ Logger.Warning?.Print(LogClass.Ui, $"Failed to unbind OpenGL context: {e}");
+ }
_openGLContext?.Dispose();
}
}
-}
+}
\ No newline at end of file