Compare commits

..

16 Commits

Author SHA1 Message Date
90432946ac Avalonia - Display language names in their corresponding language under "Change Language" (#3490)
* change languages to their native names

* fix Chinese language names

* Update MainWindow.axaml
2022-08-26 19:12:11 +02:00
9bad71afbf bsd: Fix Poll writting in input buffer (#3630)
This is a very old oversight on our Poll implementation.
This worked so far reliably because games and homebrews pass the same
buffer as input and output.
2022-08-26 18:10:45 +02:00
923089a298 Fast path for Inline-to-Memory texture data transfers (#3610)
* Fast path for Inline-to-Memory texture data transfers

* Only do it for block linear textures to be on the safe side
2022-08-26 02:16:41 +00:00
d9aa15eb24 pctl: Implement EndFreeCommunication
This PR Implement `EndFreeCommunication` (checked by RE). Nothing more.

Closes #2420
2022-08-25 23:18:37 +02:00
12c89a61f9 misc: Fix missing null terminator for strings with pchtxt (#3629)
As title say.
2022-08-25 19:59:15 +00:00
f5235fff29 ARMeilleure: Hardware accelerate SHA256 (#3585)
* ARMeilleure/HardwareCapabilities: Add Sha

* ARMeilleure/Intrinsic: Add X86Sha256Rnds2

* ARmeilleure: Hardware accelerate SHA256H/SHA256H2

* ARMeilleure/Intrinsic: Add X86Sha256Msg1, X86Sha256Msg2

* ARMeilleure/Intrinsic: Add X86Palignr

* ARMeilleure: Hardware accelerate SHA256SU0, SHA256SU1

* PTC: Bump InternalVersion
2022-08-25 10:12:13 +00:00
eba682b767 Implement some 32-bit Thumb instructions (#3614)
* Implement some 32-bit Thumb instructions

* Optimize OpCode32MemMult using PopCount
2022-08-25 09:59:34 +00:00
b994dafe7a Update PPTC dialog text to match label and tooltip (#3618)
* Update PPTC dialog text to match label and tooltip

* Update to requested text

* Reverting spaces

* Adding newline back in
2022-08-24 08:25:49 +00:00
54421760c3 Check if game directories have been updated before refreshing GUI (#3607)
* Check if game directories have been updated before refreshing list on save.

* Cleanup spacing

* Add Avalonia and reset value after saving

* Fix Avalonia

* Fix multiple directories not being added in GTK
2022-08-21 13:07:28 +00:00
88a0e720cb Use RGBA16 vertex format if RGB16 is not supported on Vulkan (#3552)
* Use RGBA16 vertex format if RGB16 is not supported on Vulkan

* Catch all shader compilation exceptions
2022-08-20 16:20:27 -03:00
53cc9e0561 Change 'Purge PPTC Cache' label & tooltip to reflect function behavior (#3601)
* Change PPTC purge label & tooltip

* Change Avalonia labels
2022-08-19 23:39:59 +00:00
7defc59b9d A few minor documentation fixes. (#3599)
* A few minor documentation fixes.

* Removed more invalid inheritdoc instances.
2022-08-19 18:21:06 -03:00
951700fdd8 Removed unused usings. (#3593)
* Removed unused usings.

* Added back using, now that it's used.

* Removed extra whitespace.
2022-08-18 18:04:54 +02:00
eb6430f103 Skipped over the last "Count" key explicitly, instead of relying on an exception. (#3595) 2022-08-18 02:00:27 +02:00
80a879cb44 Fix SpirV parse failure (#3597)
* Added .ToString overrides, to help diagnose and debug SpirV generated code.

* Added Spirv to team shared dictionary, so the word will not show up as a warning.

* Fixed bug where we were creating invalid constants (bool 0i and float 0i)

* Update Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

* Update Spv.Generator/Instruction.cs

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

* Adjusted spacing to match style of the rest of the code.

* Added handler for FP64(double) as well, for undefined aggregate types.

* Made the operand labels a static dictionary, to avoid re-allocation on each call.
Replaced Contains/Get with a TryGetValue, to reduce the number of dictionary lookups.

* Added newline between AllOperands and ToString().

Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2022-08-18 01:49:43 +02:00
2197f41506 Removed extra semicolons. (#3594) 2022-08-17 09:05:15 +02:00
199 changed files with 885 additions and 450 deletions

View File

@ -58,7 +58,6 @@ namespace ARMeilleure.CodeGen.Linking
/// <param name="a">First instance</param>
/// <param name="b">Second instance</param>
/// <returns><see langword="true"/> if not equal; otherwise <see langword="false"/></returns>
/// <inheritdoc/>
public static bool operator !=(Symbol a, Symbol b)
{
return !(a == b);

View File

@ -1,6 +1,4 @@
using ARMeilleure.Common;
using ARMeilleure.IntermediateRepresentation;
using System;
namespace ARMeilleure.CodeGen.RegisterAllocators
{

View File

@ -157,6 +157,7 @@ namespace ARMeilleure.CodeGen.X86
Add(X86Instruction.Paddd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000ffe, InstructionFlags.Vex | InstructionFlags.Prefix66));
Add(X86Instruction.Paddq, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fd4, InstructionFlags.Vex | InstructionFlags.Prefix66));
Add(X86Instruction.Paddw, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000ffd, InstructionFlags.Vex | InstructionFlags.Prefix66));
Add(X86Instruction.Palignr, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x000f3a0f, InstructionFlags.Vex | InstructionFlags.Prefix66));
Add(X86Instruction.Pand, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fdb, InstructionFlags.Vex | InstructionFlags.Prefix66));
Add(X86Instruction.Pandn, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fdf, InstructionFlags.Vex | InstructionFlags.Prefix66));
Add(X86Instruction.Pavgb, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fe0, InstructionFlags.Vex | InstructionFlags.Prefix66));
@ -239,6 +240,9 @@ namespace ARMeilleure.CodeGen.X86
Add(X86Instruction.Rsqrtss, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f52, InstructionFlags.Vex | InstructionFlags.PrefixF3));
Add(X86Instruction.Sar, new InstructionInfo(0x070000d3, 0x070000c1, BadOp, BadOp, BadOp, InstructionFlags.None));
Add(X86Instruction.Setcc, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f90, InstructionFlags.Reg8Dest));
Add(X86Instruction.Sha256Msg1, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x000f38cc, InstructionFlags.None));
Add(X86Instruction.Sha256Msg2, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x000f38cd, InstructionFlags.None));
Add(X86Instruction.Sha256Rnds2, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x000f38cb, InstructionFlags.None));
Add(X86Instruction.Shl, new InstructionInfo(0x040000d3, 0x040000c1, BadOp, BadOp, BadOp, InstructionFlags.None));
Add(X86Instruction.Shr, new InstructionInfo(0x050000d3, 0x050000c1, BadOp, BadOp, BadOp, InstructionFlags.None));
Add(X86Instruction.Shufpd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fc6, InstructionFlags.Vex | InstructionFlags.Prefix66));

View File

@ -1,5 +1,4 @@
using System;
using System.Runtime.InteropServices;
namespace ARMeilleure.CodeGen.X86
{

View File

@ -12,21 +12,28 @@ namespace ARMeilleure.CodeGen.X86
return;
}
(_, _, int ecx, int edx) = X86Base.CpuId(0x00000001, 0x00000000);
(int maxNum, _, _, _) = X86Base.CpuId(0x00000000, 0x00000000);
FeatureInfoEdx = (FeatureFlagsEdx)edx;
FeatureInfoEcx = (FeatureFlagsEcx)ecx;
(_, _, int ecx1, int edx1) = X86Base.CpuId(0x00000001, 0x00000000);
FeatureInfo1Edx = (FeatureFlags1Edx)edx1;
FeatureInfo1Ecx = (FeatureFlags1Ecx)ecx1;
if (maxNum >= 7)
{
(_, int ebx7, _, _) = X86Base.CpuId(0x00000007, 0x00000000);
FeatureInfo7Ebx = (FeatureFlags7Ebx)ebx7;
}
}
[Flags]
public enum FeatureFlagsEdx
public enum FeatureFlags1Edx
{
Sse = 1 << 25,
Sse2 = 1 << 26
}
[Flags]
public enum FeatureFlagsEcx
public enum FeatureFlags1Ecx
{
Sse3 = 1 << 0,
Pclmulqdq = 1 << 1,
@ -40,21 +47,31 @@ namespace ARMeilleure.CodeGen.X86
F16c = 1 << 29
}
public static FeatureFlagsEdx FeatureInfoEdx { get; }
public static FeatureFlagsEcx FeatureInfoEcx { get; }
[Flags]
public enum FeatureFlags7Ebx
{
Avx2 = 1 << 5,
Sha = 1 << 29
}
public static bool SupportsSse => FeatureInfoEdx.HasFlag(FeatureFlagsEdx.Sse);
public static bool SupportsSse2 => FeatureInfoEdx.HasFlag(FeatureFlagsEdx.Sse2);
public static bool SupportsSse3 => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Sse3);
public static bool SupportsPclmulqdq => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Pclmulqdq);
public static bool SupportsSsse3 => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Ssse3);
public static bool SupportsFma => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Fma);
public static bool SupportsSse41 => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Sse41);
public static bool SupportsSse42 => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Sse42);
public static bool SupportsPopcnt => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Popcnt);
public static bool SupportsAesni => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Aes);
public static bool SupportsAvx => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.Avx);
public static bool SupportsF16c => FeatureInfoEcx.HasFlag(FeatureFlagsEcx.F16c);
public static FeatureFlags1Edx FeatureInfo1Edx { get; }
public static FeatureFlags1Ecx FeatureInfo1Ecx { get; }
public static FeatureFlags7Ebx FeatureInfo7Ebx { get; } = 0;
public static bool SupportsSse => FeatureInfo1Edx.HasFlag(FeatureFlags1Edx.Sse);
public static bool SupportsSse2 => FeatureInfo1Edx.HasFlag(FeatureFlags1Edx.Sse2);
public static bool SupportsSse3 => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Sse3);
public static bool SupportsPclmulqdq => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Pclmulqdq);
public static bool SupportsSsse3 => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Ssse3);
public static bool SupportsFma => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Fma);
public static bool SupportsSse41 => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Sse41);
public static bool SupportsSse42 => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Sse42);
public static bool SupportsPopcnt => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Popcnt);
public static bool SupportsAesni => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Aes);
public static bool SupportsAvx => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Avx);
public static bool SupportsAvx2 => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx2) && SupportsAvx;
public static bool SupportsF16c => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.F16c);
public static bool SupportsSha => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Sha);
public static bool ForceLegacySse { get; set; }

View File

@ -82,6 +82,7 @@ namespace ARMeilleure.CodeGen.X86
Add(Intrinsic.X86Paddd, new IntrinsicInfo(X86Instruction.Paddd, IntrinsicType.Binary));
Add(Intrinsic.X86Paddq, new IntrinsicInfo(X86Instruction.Paddq, IntrinsicType.Binary));
Add(Intrinsic.X86Paddw, new IntrinsicInfo(X86Instruction.Paddw, IntrinsicType.Binary));
Add(Intrinsic.X86Palignr, new IntrinsicInfo(X86Instruction.Palignr, IntrinsicType.TernaryImm));
Add(Intrinsic.X86Pand, new IntrinsicInfo(X86Instruction.Pand, IntrinsicType.Binary));
Add(Intrinsic.X86Pandn, new IntrinsicInfo(X86Instruction.Pandn, IntrinsicType.Binary));
Add(Intrinsic.X86Pavgb, new IntrinsicInfo(X86Instruction.Pavgb, IntrinsicType.Binary));
@ -151,6 +152,9 @@ namespace ARMeilleure.CodeGen.X86
Add(Intrinsic.X86Roundss, new IntrinsicInfo(X86Instruction.Roundss, IntrinsicType.BinaryImm));
Add(Intrinsic.X86Rsqrtps, new IntrinsicInfo(X86Instruction.Rsqrtps, IntrinsicType.Unary));
Add(Intrinsic.X86Rsqrtss, new IntrinsicInfo(X86Instruction.Rsqrtss, IntrinsicType.Unary));
Add(Intrinsic.X86Sha256Msg1, new IntrinsicInfo(X86Instruction.Sha256Msg1, IntrinsicType.Binary));
Add(Intrinsic.X86Sha256Msg2, new IntrinsicInfo(X86Instruction.Sha256Msg2, IntrinsicType.Binary));
Add(Intrinsic.X86Sha256Rnds2, new IntrinsicInfo(X86Instruction.Sha256Rnds2, IntrinsicType.Ternary));
Add(Intrinsic.X86Shufpd, new IntrinsicInfo(X86Instruction.Shufpd, IntrinsicType.TernaryImm));
Add(Intrinsic.X86Shufps, new IntrinsicInfo(X86Instruction.Shufps, IntrinsicType.TernaryImm));
Add(Intrinsic.X86Sqrtpd, new IntrinsicInfo(X86Instruction.Sqrtpd, IntrinsicType.Unary));

View File

@ -308,11 +308,13 @@ namespace ARMeilleure.CodeGen.X86
case Instruction.Extended:
{
bool isBlend = node.Intrinsic == Intrinsic.X86Blendvpd ||
node.Intrinsic == Intrinsic.X86Blendvps ||
node.Intrinsic == Intrinsic.X86Pblendvb;
// BLENDVPD, BLENDVPS, PBLENDVB last operand is always implied to be XMM0 when VEX is not supported.
if ((node.Intrinsic == Intrinsic.X86Blendvpd ||
node.Intrinsic == Intrinsic.X86Blendvps ||
node.Intrinsic == Intrinsic.X86Pblendvb) &&
!HardwareCapabilities.SupportsVexEncoding)
// SHA256RNDS2 always has an implied XMM0 as a last operand.
if ((isBlend && !HardwareCapabilities.SupportsVexEncoding) || node.Intrinsic == Intrinsic.X86Sha256Rnds2)
{
Operand xmm0 = Xmm(X86Register.Xmm0, OperandType.V128);

View File

@ -98,6 +98,7 @@ namespace ARMeilleure.CodeGen.X86
Paddd,
Paddq,
Paddw,
Palignr,
Pand,
Pandn,
Pavgb,
@ -180,6 +181,9 @@ namespace ARMeilleure.CodeGen.X86
Rsqrtss,
Sar,
Setcc,
Sha256Msg1,
Sha256Msg2,
Sha256Rnds2,
Shl,
Shr,
Shufpd,

View File

@ -206,7 +206,7 @@ namespace ARMeilleure.Common
/// <typeparam name="T">Type of elements</typeparam>
/// <param name="length">Number of elements</param>
/// <param name="fill">Fill value</param>
/// <param name="leaf"><see langword="true"/> if leaf; otherwise <see langword=""="false"/></param>
/// <param name="leaf"><see langword="true"/> if leaf; otherwise <see langword="false"/></param>
/// <returns>Allocated block</returns>
private IntPtr Allocate<T>(int length, T fill, bool leaf) where T : unmanaged
{

View File

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
namespace ARMeilleure.Common
{

View File

@ -9,6 +9,9 @@ namespace ARMeilleure.Common
class Counter<T> : IDisposable where T : unmanaged
{
private bool _disposed;
/// <summary>
/// Index in the <see cref="EntryTable{T}"/>
/// </summary>
private readonly int _index;
private readonly EntryTable<T> _countTable;
@ -17,7 +20,6 @@ namespace ARMeilleure.Common
/// <see cref="EntryTable{T}"/> instance and index.
/// </summary>
/// <param name="countTable"><see cref="EntryTable{T}"/> instance</param>
/// <param name="index">Index in the <see cref="EntryTable{T}"/></param>
/// <exception cref="ArgumentNullException"><paramref name="countTable"/> is <see langword="null"/></exception>
/// <exception cref="ArgumentException"><typeparamref name="T"/> is unsupported</exception>
public Counter(EntryTable<T> countTable)
@ -68,7 +70,7 @@ namespace ARMeilleure.Common
/// <summary>
/// Releases all unmanaged and optionally managed resources used by the <see cref="Counter{T}"/> instance.
/// </summary>
/// <param name="disposing"><see langword="true"/> to dispose managed resources also; otherwise just unmanaged resouces</param>
/// <param name="disposing"><see langword="true"/> to dispose managed resources also; otherwise just unmanaged resources</param>
protected virtual void Dispose(bool disposing)
{
if (!_disposed)

View File

@ -0,0 +1,8 @@
namespace ARMeilleure.Decoders
{
interface IOpCode32MemRsImm : IOpCode32Mem
{
int Rm { get; }
ShiftType ShiftType { get; }
}
}

View File

@ -1,3 +1,5 @@
using System.Numerics;
namespace ARMeilleure.Decoders
{
class OpCode32MemMult : OpCode32, IOpCode32MemMult
@ -23,14 +25,7 @@ namespace ARMeilleure.Decoders
RegisterMask = opCode & 0xffff;
int regsSize = 0;
for (int index = 0; index < 16; index++)
{
regsSize += (RegisterMask >> index) & 1;
}
regsSize *= 4;
int regsSize = BitOperations.PopCount((uint)RegisterMask) * 4;
if (!u)
{

View File

@ -1,6 +1,6 @@
namespace ARMeilleure.Decoders
{
class OpCode32MemRsImm : OpCode32Mem
class OpCode32MemRsImm : OpCode32Mem, IOpCode32MemRsImm
{
public int Rm { get; }
public ShiftType ShiftType { get; }

View File

@ -1,10 +1,10 @@
namespace ARMeilleure.Decoders
{
class OpCodeT16BImmCmp : OpCodeT16
class OpCodeT16BImmCmp : OpCodeT16, IOpCode32BImm
{
public int Rn { get; }
public int Immediate { get; }
public long Immediate { get; }
public static new OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16BImmCmp(inst, address, opCode);

View File

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Reflection.Emit;
namespace ARMeilleure.Decoders
{

View File

@ -1,6 +1,4 @@
using ARMeilleure.Instructions;
namespace ARMeilleure.Decoders
namespace ARMeilleure.Decoders
{
class OpCodeT32BImm20 : OpCodeT32, IOpCode32BImm
{

View File

@ -0,0 +1,31 @@
namespace ARMeilleure.Decoders
{
class OpCodeT32MemImm8D : OpCodeT32, IOpCode32Mem
{
public int Rt { get; }
public int Rt2 { get; }
public int Rn { get; }
public bool WBack { get; }
public bool IsLoad { get; }
public bool Index { get; }
public bool Add { get; }
public int Immediate { get; }
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MemImm8D(inst, address, opCode);
public OpCodeT32MemImm8D(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{
Rt2 = (opCode >> 8) & 0xf;
Rt = (opCode >> 12) & 0xf;
Rn = (opCode >> 16) & 0xf;
Index = ((opCode >> 24) & 1) != 0;
Add = ((opCode >> 23) & 1) != 0;
WBack = ((opCode >> 21) & 1) != 0;
Immediate = opCode & 0xff;
IsLoad = ((opCode >> 20) & 1) != 0;
}
}
}

View File

@ -0,0 +1,24 @@
namespace ARMeilleure.Decoders
{
class OpCodeT32MemLdEx : OpCodeT32, IOpCode32MemEx
{
public int Rd => 0;
public int Rt { get; }
public int Rn { get; }
public bool WBack => false;
public bool IsLoad => true;
public bool Index => false;
public bool Add => false;
public int Immediate => 0;
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MemLdEx(inst, address, opCode);
public OpCodeT32MemLdEx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{
Rt = (opCode >> 12) & 0xf;
Rn = (opCode >> 16) & 0xf;
}
}
}

View File

@ -0,0 +1,52 @@
using System.Numerics;
namespace ARMeilleure.Decoders
{
class OpCodeT32MemMult : OpCodeT32, IOpCode32MemMult
{
public int Rn { get; }
public int RegisterMask { get; }
public int Offset { get; }
public int PostOffset { get; }
public bool IsLoad { get; }
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MemMult(inst, address, opCode);
public OpCodeT32MemMult(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{
Rn = (opCode >> 16) & 0xf;
bool isLoad = (opCode & (1 << 20)) != 0;
bool w = (opCode & (1 << 21)) != 0;
bool u = (opCode & (1 << 23)) != 0;
bool p = (opCode & (1 << 24)) != 0;
RegisterMask = opCode & 0xffff;
int regsSize = BitOperations.PopCount((uint)RegisterMask) * 4;
if (!u)
{
Offset -= regsSize;
}
if (u == p)
{
Offset += 4;
}
if (w)
{
PostOffset = u ? regsSize : -regsSize;
}
else
{
PostOffset = 0;
}
IsLoad = isLoad;
}
}
}

View File

@ -0,0 +1,30 @@
namespace ARMeilleure.Decoders
{
class OpCodeT32MemRsImm : OpCodeT32, IOpCode32MemRsImm
{
public int Rt { get; }
public int Rn { get; }
public int Rm { get; }
public ShiftType ShiftType => ShiftType.Lsl;
public bool WBack => false;
public bool IsLoad { get; }
public bool Index => true;
public bool Add => true;
public int Immediate { get; }
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MemRsImm(inst, address, opCode);
public OpCodeT32MemRsImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{
Rm = (opCode >> 0) & 0xf;
Rt = (opCode >> 12) & 0xf;
Rn = (opCode >> 16) & 0xf;
IsLoad = (opCode & (1 << 20)) != 0;
Immediate = (opCode >> 4) & 3;
}
}
}

View File

@ -0,0 +1,25 @@
namespace ARMeilleure.Decoders
{
class OpCodeT32MemStEx : OpCodeT32, IOpCode32MemEx
{
public int Rd { get; }
public int Rt { get; }
public int Rn { get; }
public bool WBack => false;
public bool IsLoad => false;
public bool Index => false;
public bool Add => false;
public int Immediate => 0;
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MemStEx(inst, address, opCode);
public OpCodeT32MemStEx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{
Rd = (opCode >> 0) & 0xf;
Rt = (opCode >> 12) & 0xf;
Rn = (opCode >> 16) & 0xf;
}
}
}

View File

@ -1070,14 +1070,19 @@ namespace ARMeilleure.Decoders
SetT32("11110x011011xxxx0xxx1111xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT32AluImm.Create);
SetT32("11101010100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluRsImm.Create);
SetT32("11110x00100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluImm.Create);
SetT32("111010001101xxxxxxxx111111101111", InstName.Ldaex, InstEmit32.Ldaex, OpCodeT32MemLdEx.Create);
SetT32("1110100010x1xxxxxxxxxxxxxxxxxxxx", InstName.Ldm, InstEmit32.Ldm, OpCodeT32MemMult.Create);
SetT32("1110100100x1xxxxxxxxxxxxxxxxxxxx", InstName.Ldm, InstEmit32.Ldm, OpCodeT32MemMult.Create);
SetT32("111110000101xxxx<<<<10x1xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create);
SetT32("111110000101xxxx<<<<1100xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create);
SetT32("111110000101xxxx<<<<11x1xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create);
SetT32("111110001101xxxxxxxxxxxxxxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm12.Create);
SetT32("111110000101<<<<xxxx000000xxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemRsImm.Create);
SetT32("111110000001xxxx<<<<10x1xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create);
SetT32("111110000001xxxx<<<<1100xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create);
SetT32("111110000001xxxx<<<<11x1xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create);
SetT32("111110001001xxxxxxxxxxxxxxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm12.Create);
SetT32("1110100>x1>1<<<<xxxxxxxxxxxxxxxx", InstName.Ldrd, InstEmit32.Ldrd, OpCodeT32MemImm8D.Create);
SetT32("111110000011xxxx<<<<10x1xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create);
SetT32("111110000011xxxx<<<<1100xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create);
SetT32("111110000011xxxx<<<<11x1xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create);
@ -1102,10 +1107,15 @@ namespace ARMeilleure.Decoders
SetT32("11110x01110xxxxx0xxxxxxxxxxxxxxx", InstName.Rsb, InstEmit32.Rsb, OpCodeT32AluImm.Create);
SetT32("11101011011xxxxx0xxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, OpCodeT32AluRsImm.Create);
SetT32("11110x01011xxxxx0xxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, OpCodeT32AluImm.Create);
SetT32("111010001100xxxxxxxx11111110xxxx", InstName.Stlex, InstEmit32.Stlex, OpCodeT32MemStEx.Create);
SetT32("1110100010x0xxxx0xxxxxxxxxxxxxxx", InstName.Stm, InstEmit32.Stm, OpCodeT32MemMult.Create);
SetT32("1110100100x0xxxx0xxxxxxxxxxxxxxx", InstName.Stm, InstEmit32.Stm, OpCodeT32MemMult.Create);
SetT32("111110000100xxxxxxxx1<<>xxxxxxxx", InstName.Str, InstEmit32.Str, OpCodeT32MemImm8.Create);
SetT32("111110001100xxxxxxxxxxxxxxxxxxxx", InstName.Str, InstEmit32.Str, OpCodeT32MemImm12.Create);
SetT32("111110000100<<<<xxxx000000xxxxxx", InstName.Str, InstEmit32.Str, OpCodeT32MemRsImm.Create);
SetT32("111110000000xxxxxxxx1<<>xxxxxxxx", InstName.Strb, InstEmit32.Strb, OpCodeT32MemImm8.Create);
SetT32("111110001000xxxxxxxxxxxxxxxxxxxx", InstName.Strb, InstEmit32.Strb, OpCodeT32MemImm12.Create);
SetT32("1110100>x1>0<<<<xxxxxxxxxxxxxxxx", InstName.Strd, InstEmit32.Strd, OpCodeT32MemImm8D.Create);
SetT32("111110000010xxxxxxxx1<<>xxxxxxxx", InstName.Strh, InstEmit32.Strh, OpCodeT32MemImm8.Create);
SetT32("111110001010xxxxxxxxxxxxxxxxxxxx", InstName.Strh, InstEmit32.Strh, OpCodeT32MemImm12.Create);
SetT32("11101011101<xxxx0xxx<<<<xxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT32AluRsImm.Create);

View File

@ -1,7 +1,5 @@
using ARMeilleure.Decoders;
using ARMeilleure.Translation;
using static ARMeilleure.Instructions.InstEmitFlowHelper;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
namespace ARMeilleure.Instructions

View File

@ -88,7 +88,7 @@ namespace ARMeilleure.Instructions
{
OpCodeT16BImmCmp op = (OpCodeT16BImmCmp)context.CurrOp;
Operand value = GetIntOrZR(context, op.Rn);
Operand value = GetIntA32(context, op.Rn);
Operand lblTarget = context.GetLabel((ulong)op.Immediate);
if (onNotZero)

View File

@ -547,7 +547,7 @@ namespace ARMeilleure.Instructions
{
switch (context.CurrOp)
{
case OpCode32MemRsImm op: return GetMShiftedByImmediate(context, op, setCarry);
case IOpCode32MemRsImm op: return GetMShiftedByImmediate(context, op, setCarry);
case IOpCode32MemReg op: return GetIntA32(context, op.Rm);
@ -564,7 +564,7 @@ namespace ARMeilleure.Instructions
return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\".");
}
public static Operand GetMShiftedByImmediate(ArmEmitterContext context, OpCode32MemRsImm op, bool setCarry)
public static Operand GetMShiftedByImmediate(ArmEmitterContext context, IOpCode32MemRsImm op, bool setCarry)
{
Operand m = GetIntA32(context, op.Rm);

View File

@ -2,8 +2,6 @@
using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation;
using System;
using System.Diagnostics;
using static ARMeilleure.Instructions.InstEmitFlowHelper;
using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.Instructions.InstEmitSimdHelper;

View File

@ -100,7 +100,7 @@ namespace ARMeilleure.Instructions
Operand n = GetVec(op.Rn);
Operand m = GetVec(op.Rm);
Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashLower)), d, n, m);
Operand res = InstEmitSimdHashHelper.EmitSha256h(context, d, n, m, part2: false);
context.Copy(GetVec(op.Rd), res);
}
@ -113,7 +113,7 @@ namespace ARMeilleure.Instructions
Operand n = GetVec(op.Rn);
Operand m = GetVec(op.Rm);
Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashUpper)), d, n, m);
Operand res = InstEmitSimdHashHelper.EmitSha256h(context, n, d, m, part2: true);
context.Copy(GetVec(op.Rd), res);
}
@ -125,7 +125,7 @@ namespace ARMeilleure.Instructions
Operand d = GetVec(op.Rd);
Operand n = GetVec(op.Rn);
Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1)), d, n);
Operand res = InstEmitSimdHashHelper.EmitSha256su0(context, d, n);
context.Copy(GetVec(op.Rd), res);
}
@ -138,7 +138,7 @@ namespace ARMeilleure.Instructions
Operand n = GetVec(op.Rn);
Operand m = GetVec(op.Rm);
Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2)), d, n, m);
Operand res = InstEmitSimdHashHelper.EmitSha256su1(context, d, n, m);
context.Copy(GetVec(op.Rd), res);
}

View File

@ -17,7 +17,7 @@ namespace ARMeilleure.Instructions
Operand n = GetVecA32(op.Qn);
Operand m = GetVecA32(op.Qm);
Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashLower)), d, n, m);
Operand res = InstEmitSimdHashHelper.EmitSha256h(context, d, n, m, part2: false);
context.Copy(GetVecA32(op.Qd), res);
}
@ -30,7 +30,7 @@ namespace ARMeilleure.Instructions
Operand n = GetVecA32(op.Qn);
Operand m = GetVecA32(op.Qm);
Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashUpper)), d, n, m);
Operand res = InstEmitSimdHashHelper.EmitSha256h(context, n, d, m, part2: true);
context.Copy(GetVecA32(op.Qd), res);
}
@ -42,7 +42,7 @@ namespace ARMeilleure.Instructions
Operand d = GetVecA32(op.Qd);
Operand m = GetVecA32(op.Qm);
Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1)), d, m);
Operand res = InstEmitSimdHashHelper.EmitSha256su0(context, d, m);
context.Copy(GetVecA32(op.Qd), res);
}
@ -55,7 +55,7 @@ namespace ARMeilleure.Instructions
Operand n = GetVecA32(op.Qn);
Operand m = GetVecA32(op.Qm);
Operand res = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2)), d, n, m);
Operand res = InstEmitSimdHashHelper.EmitSha256su1(context, d, n, m);
context.Copy(GetVecA32(op.Qd), res);
}

View File

@ -0,0 +1,56 @@
using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation;
using System;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
namespace ARMeilleure.Instructions
{
static class InstEmitSimdHashHelper
{
public static Operand EmitSha256h(ArmEmitterContext context, Operand x, Operand y, Operand w, bool part2)
{
if (Optimizations.UseSha)
{
Operand src1 = context.AddIntrinsic(Intrinsic.X86Shufps, y, x, Const(0xbb));
Operand src2 = context.AddIntrinsic(Intrinsic.X86Shufps, y, x, Const(0x11));
Operand w2 = context.AddIntrinsic(Intrinsic.X86Punpckhqdq, w, w);
Operand round2 = context.AddIntrinsic(Intrinsic.X86Sha256Rnds2, src1, src2, w);
Operand round4 = context.AddIntrinsic(Intrinsic.X86Sha256Rnds2, src2, round2, w2);
Operand res = context.AddIntrinsic(Intrinsic.X86Shufps, round4, round2, Const(part2 ? 0x11 : 0xbb));
return res;
}
String method = part2 ? nameof(SoftFallback.HashUpper) : nameof(SoftFallback.HashLower);
return context.Call(typeof(SoftFallback).GetMethod(method), x, y, w);
}
public static Operand EmitSha256su0(ArmEmitterContext context, Operand x, Operand y)
{
if (Optimizations.UseSha)
{
return context.AddIntrinsic(Intrinsic.X86Sha256Msg1, x, y);
}
return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1)), x, y);
}
public static Operand EmitSha256su1(ArmEmitterContext context, Operand x, Operand y, Operand z)
{
if (Optimizations.UseSha && Optimizations.UseSsse3)
{
Operand extr = context.AddIntrinsic(Intrinsic.X86Palignr, z, y, Const(4));
Operand tmp = context.AddIntrinsic(Intrinsic.X86Paddd, extr, x);
Operand res = context.AddIntrinsic(Intrinsic.X86Sha256Msg2, tmp, z);
return res;
}
return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2)), x, y, z);
}
}
}

View File

@ -2,8 +2,6 @@ using ARMeilleure.Memory;
using ARMeilleure.State;
using ARMeilleure.Translation;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ARMeilleure.Instructions
{

View File

@ -1129,7 +1129,7 @@ namespace ARMeilleure.Instructions
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: true);
}
public static V128 HashUpper(V128 hash_efgh, V128 hash_abcd, V128 wk)
public static V128 HashUpper(V128 hash_abcd, V128 hash_efgh, V128 wk)
{
return Sha256Hash(hash_abcd, hash_efgh, wk, part1: false);
}

View File

@ -71,6 +71,7 @@ namespace ARMeilleure.IntermediateRepresentation
X86Paddd,
X86Paddq,
X86Paddw,
X86Palignr,
X86Pand,
X86Pandn,
X86Pavgb,
@ -140,6 +141,9 @@ namespace ARMeilleure.IntermediateRepresentation
X86Roundss,
X86Rsqrtps,
X86Rsqrtss,
X86Sha256Msg1,
X86Sha256Msg2,
X86Sha256Rnds2,
X86Shufpd,
X86Shufps,
X86Sqrtpd,

View File

@ -21,6 +21,7 @@ namespace ARMeilleure
public static bool UseFmaIfAvailable { get; set; } = true;
public static bool UseAesniIfAvailable { get; set; } = true;
public static bool UsePclmulqdqIfAvailable { get; set; } = true;
public static bool UseShaIfAvailable { get; set; } = true;
public static bool ForceLegacySse
{
@ -40,5 +41,6 @@ namespace ARMeilleure
internal static bool UseFma => UseFmaIfAvailable && HardwareCapabilities.SupportsFma;
internal static bool UseAesni => UseAesniIfAvailable && HardwareCapabilities.SupportsAesni;
internal static bool UsePclmulqdq => UsePclmulqdqIfAvailable && HardwareCapabilities.SupportsPclmulqdq;
internal static bool UseSha => UseShaIfAvailable && HardwareCapabilities.SupportsSha;
}
}

View File

@ -1,5 +1,4 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace ARMeilleure.Signal

View File

@ -14,7 +14,7 @@ namespace ARMeilleure.Translation
public BasicBlock Entry { get; }
public IntrusiveList<BasicBlock> Blocks { get; }
public BasicBlock[] PostOrderBlocks => _postOrderBlocks;
public int[] PostOrderMap => _postOrderMap;
public int[] PostOrderMap => _postOrderMap;
public ControlFlowGraph(BasicBlock entry, IntrusiveList<BasicBlock> blocks, int localsCount)
{

View File

@ -344,7 +344,7 @@ namespace ARMeilleure.Translation
}
/// <summary>
/// Removes the value from the dictionary after searching for it with <paramref name="key">.
/// Removes the value from the dictionary after searching for it with <paramref name="key"/>.
/// </summary>
/// <param name="key">Key to search for</param>
/// <returns>Number of deleted values</returns>

View File

@ -27,7 +27,7 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\0\0";
private const string InnerHeaderMagicString = "PTCihd\0\0";
private const uint InternalVersion = 3439; //! To be incremented manually for each change to the ARMeilleure project.
private const uint InternalVersion = 3585; //! To be incremented manually for each change to the ARMeilleure project.
private const string ActualDir = "0";
private const string BackupDir = "1";
@ -946,9 +946,12 @@ namespace ARMeilleure.Translation.PTC
return BitConverter.IsLittleEndian;
}
private static ulong GetFeatureInfo()
private static FeatureInfo GetFeatureInfo()
{
return (ulong)HardwareCapabilities.FeatureInfoEdx << 32 | (uint)HardwareCapabilities.FeatureInfoEcx;
return new FeatureInfo(
(uint)HardwareCapabilities.FeatureInfo1Ecx,
(uint)HardwareCapabilities.FeatureInfo1Edx,
(uint)HardwareCapabilities.FeatureInfo7Ebx);
}
private static byte GetMemoryManagerMode()
@ -968,7 +971,7 @@ namespace ARMeilleure.Translation.PTC
return osPlatform;
}
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 50*/)]
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 54*/)]
private struct OuterHeader
{
public ulong Magic;
@ -976,7 +979,7 @@ namespace ARMeilleure.Translation.PTC
public uint CacheFileVersion;
public bool Endianness;
public ulong FeatureInfo;
public FeatureInfo FeatureInfo;
public byte MemoryManagerMode;
public uint OSPlatform;
@ -999,6 +1002,9 @@ namespace ARMeilleure.Translation.PTC
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 12*/)]
private record struct FeatureInfo(uint FeatureInfo0, uint FeatureInfo1, uint FeatureInfo2);
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 128*/)]
private struct InnerHeader
{

View File

@ -4,7 +4,6 @@ using Ryujinx.Memory;
using Ryujinx.SDL2.Common;
using System;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
using System.Threading;
using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;

View File

@ -4,7 +4,6 @@ using Ryujinx.Common.Logging;
using Ryujinx.Memory;
using System;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
using System.Threading;
using static SDL2.SDL;

View File

@ -1,5 +1,4 @@
using System;
namespace SoundIOSharp
namespace SoundIOSharp
{
public struct SoundIOSampleRateRange
{

View File

@ -1,7 +1,6 @@
using Ryujinx.Audio.Renderer.Dsp.State;
using Ryujinx.Audio.Renderer.Parameter;
using System;
using System.Runtime.CompilerServices;
namespace Ryujinx.Audio.Renderer.Dsp.Command
{

View File

@ -1,5 +1,4 @@
using Ryujinx.Audio.Renderer.Dsp.State;
using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Memory;
using System;
using System.Runtime.CompilerServices;

View File

@ -1,6 +1,5 @@
using Ryujinx.Audio.Renderer.Parameter.Sink;
using Ryujinx.Audio.Renderer.Server.MemoryPool;
using System;
using System.Diagnostics;
namespace Ryujinx.Audio.Renderer.Dsp.Command

View File

@ -6,7 +6,6 @@ using Ryujinx.Memory;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace Ryujinx.Audio.Renderer.Dsp.Command

View File

@ -1,5 +1,3 @@
using System;
namespace Ryujinx.Audio.Renderer.Dsp.Command
{
public class CopyMixBufferCommand : ICommand

View File

@ -1,5 +1,4 @@
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace Ryujinx.Audio.Renderer.Dsp.Command

View File

@ -2,7 +2,6 @@ using Ryujinx.Audio.Renderer.Dsp.State;
using Ryujinx.Audio.Renderer.Parameter.Effect;
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace Ryujinx.Audio.Renderer.Dsp.Command
{

View File

@ -3,7 +3,6 @@ using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Audio.Renderer.Parameter.Effect;
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Ryujinx.Audio.Renderer.Dsp.Command

View File

@ -1,6 +1,5 @@
using Ryujinx.Audio.Renderer.Server.Upsampler;
using System;
using System.Runtime.CompilerServices;
namespace Ryujinx.Audio.Renderer.Dsp.Command
{

View File

@ -7,7 +7,6 @@ using Ryujinx.Audio.Renderer.Server.Performance;
using Ryujinx.Audio.Renderer.Server.Sink;
using Ryujinx.Audio.Renderer.Server.Upsampler;
using Ryujinx.Audio.Renderer.Server.Voice;
using Ryujinx.Common.Memory;
using System;
using CpuAddress = System.UInt64;

View File

@ -1,9 +1,5 @@
using Ryujinx.Audio.Common;
using Ryujinx.Audio.Renderer.Dsp.Command;
using Ryujinx.Audio.Renderer.Parameter.Effect;
using System;
using System.Diagnostics;
using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
namespace Ryujinx.Audio.Renderer.Server
{

View File

@ -52,8 +52,8 @@
"GameListContextMenuOpenModsDirectory": "Open Mods Directory",
"GameListContextMenuOpenModsDirectoryToolTip": "Opens the directory which contains Application's Mods",
"GameListContextMenuCacheManagement": "Cache Management",
"GameListContextMenuCacheManagementPurgePptc": "Purge PPTC Cache",
"GameListContextMenuCacheManagementPurgePptcToolTip": "Deletes Application's PPTC cache",
"GameListContextMenuCacheManagementPurgePptc": "Queue PPTC Rebuild",
"GameListContextMenuCacheManagementPurgePptcToolTip": "Trigger PPTC to rebuild at boot time on the next game launch",
"GameListContextMenuCacheManagementPurgeShaderCache": "Purge Shader Cache",
"GameListContextMenuCacheManagementPurgeShaderCacheToolTip": "Deletes Application's shader cache",
"GameListContextMenuCacheManagementOpenPptcDirectory": "Open PPTC Directory",
@ -350,7 +350,7 @@
"DialogProfileDeleteProfileTitle": "Deleting Profile",
"DialogProfileDeleteProfileMessage": "This action is irreversible, are you sure you want to continue?",
"DialogWarning": "Warning",
"DialogPPTCDeletionMessage": "You are about to delete the PPTC cache for :\n\n{0}\n\nAre you sure you want to proceed?",
"DialogPPTCDeletionMessage": "You are about to queue a PPTC rebuild on the next boot of:\n\n{0}\n\nAre you sure you want to proceed?",
"DialogPPTCDeletionErrorMessage": "Error purging PPTC cache at {0}: {1}",
"DialogShaderDeletionMessage": "You are about to delete the Shader cache for :\n\n{0}\n\nAre you sure you want to proceed?",
"DialogShaderDeletionErrorMessage": "Error purging Shader cache at {0}: {1}",

View File

@ -24,7 +24,6 @@ using System.Buffers;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using static LibHac.Fs.ApplicationSaveDataManagement;
using Path = System.IO.Path;
namespace Ryujinx.Ava.Common

View File

@ -1,7 +1,6 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Threading;
using Ryujinx.Input;
using System;
using System.Numerics;

View File

@ -16,8 +16,6 @@ using Ryujinx.Graphics.Vulkan;
using Ryujinx.Modules;
using Ryujinx.Ui.Common;
using Ryujinx.Ui.Common.Configuration;
using Silk.NET.Vulkan.Extensions.EXT;
using Silk.NET.Vulkan.Extensions.KHR;
using System;
using System.Collections.Generic;
using System.IO;

View File

@ -10,7 +10,6 @@ using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationPr
using Ryujinx.HLE.Ui;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Ryujinx.Ava.Ui.Applet
{

View File

@ -1,7 +1,6 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.Threading;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.Windows;

View File

@ -1,7 +1,6 @@
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using FluentAvalonia.Core;
using FluentAvalonia.UI.Controls;

View File

@ -1,9 +1,7 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.Models;
using Ryujinx.Ava.Ui.Windows;
using System.Threading.Tasks;
namespace Ryujinx.Ava.Ui.Controls

View File

@ -1,6 +1,4 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Ryujinx.Ava.Ui.Windows;
namespace Ryujinx.Ava.Ui.Controls

View File

@ -3,7 +3,6 @@ using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Svg.Skia;
using Avalonia.Threading;
using Avalonia.VisualTree;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Input;
using Ryujinx.Ava.Ui.Controls;
@ -24,7 +23,6 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using ConfigGamepadInputId = Ryujinx.Common.Configuration.Hid.Controller.GamepadInputId;
using ConfigStickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;

View File

@ -49,6 +49,7 @@ namespace Ryujinx.Ava.Ui.ViewModels
private float _previousVolumeLevel;
private float _volume;
private bool _isVulkanAvailable = true;
private bool _directoryChanged = false;
private List<string> _gpuIds = new List<string>();
private KeyboardHotkeys _keyboardHotkeys;
private int _graphicsBackendIndex;
@ -112,6 +113,17 @@ namespace Ryujinx.Ava.Ui.ViewModels
}
}
public bool DirectoryChanged
{
get => _directoryChanged;
set
{
_directoryChanged = value;
OnPropertyChanged();
}
}
public bool EnableDiscordIntegration { get; set; }
public bool CheckUpdatesOnStart { get; set; }
public bool ShowConfirmExit { get; set; }
@ -397,10 +409,14 @@ namespace Ryujinx.Ava.Ui.ViewModels
public async Task SaveSettings()
{
List<string> gameDirs = new List<string>(GameDirectories);
ConfigurationState config = ConfigurationState.Instance;
if (_directoryChanged)
{
List<string> gameDirs = new List<string>(GameDirectories);
config.Ui.GameDirs.Value = gameDirs;
}
if (_validTzRegions.Contains(TimeZone))
{
config.System.TimeZone.Value = TimeZone;
@ -465,7 +481,6 @@ namespace Ryujinx.Ava.Ui.ViewModels
config.System.SystemTimeOffset.Value = systemTimeOffset.Seconds;
config.Graphics.ShadersDumpPath.Value = ShaderDumpPath;
config.Ui.GameDirs.Value = gameDirs;
config.System.FsGlobalAccessLogMode.Value = FsGlobalAccessLogMode;
config.System.MemoryManagerMode.Value = (MemoryManagerMode)MemoryMode;

View File

@ -1,5 +1,4 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Threading;

View File

@ -1,4 +1,3 @@
using Avalonia;
using Avalonia.Interactivity;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.Models;

View File

@ -1,11 +1,9 @@
using Avalonia;
using Avalonia.Collections;
using Avalonia.Collections;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.Models;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;

View File

@ -131,56 +131,56 @@
<MenuItem Header="{locale:Locale MenuBarOptionsChangeLanguage}">
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="en_US"
Header="American English" />
CommandParameter="de_DE"
Header="Deutsch" />
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="pt_BR"
Header="Brazilian Portuguese" />
CommandParameter="en_US"
Header="English (US)" />
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="es_ES"
Header="Castilian Spanish" />
Header="Español (ES)" />
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="fr_FR"
Header="French" />
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="de_DE"
Header="German" />
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="el_GR"
Header="Greek" />
Header="Français" />
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="it_IT"
Header="Italian" />
Header="Italiano" />
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="ja_JP"
Header="Japanese" />
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="ko_KR"
Header="Korean" />
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="ru_RU"
Header="Russian" />
CommandParameter="pt_BR"
Header="Português (BR)" />
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="tr_TR"
Header="Turkish" />
Header="Türkçe" />
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="el_GR"
Header="Ελληνικά" />
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="ru_RU"
Header="Русский" />
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="zh_CN"
Header="Simplified Chinese" />
Header="简体中文" />
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="zh_TW"
Header="Traditional Chinese (Taiwan)" />
Header="繁體中文" />
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="ja_JP"
Header="日本語" />
<MenuItem
Command="{ReflectionBinding ChangeLanguage}"
CommandParameter="ko_KR"
Header="한국어" />
</MenuItem>
<Separator />
<MenuItem

View File

@ -12,7 +12,6 @@ using Ryujinx.Ava.Ui.Applet;
using Ryujinx.Ava.Ui.Controls;
using Ryujinx.Ava.Ui.Models;
using Ryujinx.Ava.Ui.ViewModels;
using Ryujinx.Ava.Ui.Vulkan;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu;
@ -27,7 +26,6 @@ using Ryujinx.Ui.Common.Configuration;
using SixLabors.ImageSharp.PixelFormats;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

View File

@ -162,6 +162,7 @@ namespace Ryujinx.Ava.Ui.Windows
if (!string.IsNullOrWhiteSpace(path) && Directory.Exists(path) && !ViewModel.GameDirectories.Contains(path))
{
ViewModel.GameDirectories.Add(path);
ViewModel.DirectoryChanged = true;
}
else
{
@ -170,6 +171,7 @@ namespace Ryujinx.Ava.Ui.Windows
if (!string.IsNullOrWhiteSpace(path))
{
ViewModel.GameDirectories.Add(path);
ViewModel.DirectoryChanged = true;
}
}
}
@ -181,6 +183,7 @@ namespace Ryujinx.Ava.Ui.Windows
foreach (string path in selected)
{
ViewModel.GameDirectories.Remove(path);
ViewModel.DirectoryChanged = true;
}
}
@ -232,10 +235,12 @@ namespace Ryujinx.Ava.Ui.Windows
ControllerSettings?.SaveCurrentProfile();
if (Owner is MainWindow window)
if (Owner is MainWindow window && ViewModel.DirectoryChanged)
{
window.ViewModel.LoadApplications();
}
ViewModel.DirectoryChanged = false;
}
protected override void OnClosed(EventArgs e)

View File

@ -1,4 +1,3 @@
using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Threading;
@ -18,7 +17,6 @@ using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

View File

@ -1,5 +1,3 @@
using Avalonia;
using Avalonia.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Modules;
using System;

View File

@ -1,8 +1,6 @@
using Ryujinx.Common.Configuration.Hid.Controller.Motion;
using System;
using System.ComponentModel;
using System.Text.Json.Serialization;
using NotImplementedException = System.NotImplementedException;
namespace Ryujinx.Common.Configuration.Hid.Controller
{

View File

@ -1,5 +1,4 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices;
namespace Ryujinx.Common.GraphicsDriver.NVAPI
{

View File

@ -1,5 +1,4 @@
using System;
using System.Collections.Concurrent;
namespace Ryujinx.Common.Logging
{

View File

@ -1,7 +1,6 @@
using System;
using System.IO;
using System.Linq;
using System.Reflection;
namespace Ryujinx.Common.Logging
{

View File

@ -3,7 +3,6 @@ using System;
using System.Drawing;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
namespace Ryujinx.Common.System
{

View File

@ -24,7 +24,7 @@ namespace Ryujinx.Common.SystemInfo
if (sysctlbyname("hw.memsize", ref totalRAM) != 0) // Bytes
{
totalRAM = 0;
};
}
CpuName = $"{cpuName} ; {LogicalCoreCount} logical";
RamTotal = totalRAM;

View File

@ -1,5 +1,4 @@
using System;
using System.Globalization;
using System.Management;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;

View File

@ -1,4 +1,3 @@
using System;
using System.Numerics;
namespace Ryujinx.Common

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Ryujinx.Graphics.GAL
namespace Ryujinx.Graphics.GAL
{
public struct HardwareInfo
{

View File

@ -1,5 +1,4 @@
using Ryujinx.Common.Configuration;
using Ryujinx.Graphics.Shader;
using System;
namespace Ryujinx.Graphics.GAL

View File

@ -19,6 +19,7 @@ namespace Ryujinx.Graphics.GAL
void SetData(ReadOnlySpan<byte> data);
void SetData(ReadOnlySpan<byte> data, int layer, int level);
void SetData(ReadOnlySpan<byte> data, int layer, int level, Rectangle<int> region);
void SetStorage(BufferRange buffer);
void Release();
}

View File

@ -113,6 +113,8 @@ namespace Ryujinx.Graphics.GAL.Multithreading
TextureSetDataCommand.Run(ref GetCommand<TextureSetDataCommand>(memory), threaded, renderer);
_lookup[(int)CommandType.TextureSetDataSlice] = (Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer) =>
TextureSetDataSliceCommand.Run(ref GetCommand<TextureSetDataSliceCommand>(memory), threaded, renderer);
_lookup[(int)CommandType.TextureSetDataSliceRegion] = (Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer) =>
TextureSetDataSliceRegionCommand.Run(ref GetCommand<TextureSetDataSliceRegionCommand>(memory), threaded, renderer);
_lookup[(int)CommandType.TextureSetStorage] = (Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer) =>
TextureSetStorageCommand.Run(ref GetCommand<TextureSetStorageCommand>(memory), threaded, renderer);

View File

@ -37,6 +37,7 @@
TextureRelease,
TextureSetData,
TextureSetDataSlice,
TextureSetDataSliceRegion,
TextureSetStorage,
WindowPresent,

View File

@ -1,6 +1,5 @@
using Ryujinx.Graphics.GAL.Multithreading.Model;
using System;
using System.Buffers;
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
{

View File

@ -1,6 +1,5 @@
using Ryujinx.Graphics.GAL.Multithreading.Model;
using System;
using System.Buffers;
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
{

View File

@ -0,0 +1,31 @@
using Ryujinx.Graphics.GAL.Multithreading.Model;
using Ryujinx.Graphics.GAL.Multithreading.Resources;
using System;
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture
{
struct TextureSetDataSliceRegionCommand : IGALCommand
{
public CommandType CommandType => CommandType.TextureSetDataSliceRegion;
private TableRef<ThreadedTexture> _texture;
private TableRef<byte[]> _data;
private int _layer;
private int _level;
private Rectangle<int> _region;
public void Set(TableRef<ThreadedTexture> texture, TableRef<byte[]> data, int layer, int level, Rectangle<int> region)
{
_texture = texture;
_data = data;
_layer = layer;
_level = level;
_region = region;
}
public static void Run(ref TextureSetDataSliceRegionCommand command, ThreadedRenderer threaded, IRenderer renderer)
{
ThreadedTexture texture = command._texture.Get(threaded);
texture.Base.SetData(new ReadOnlySpan<byte>(command._data.Get(threaded)), command._layer, command._level, command._region);
}
}
}

View File

@ -1,5 +1,4 @@
using Ryujinx.Graphics.GAL.Multithreading.Model;
using Ryujinx.Graphics.Shader;
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
{

View File

@ -1,6 +1,4 @@
using System.Linq;
namespace Ryujinx.Graphics.GAL.Multithreading.Resources.Programs
namespace Ryujinx.Graphics.GAL.Multithreading.Resources.Programs
{
class SourceProgramRequest : IProgramRequest
{

View File

@ -119,6 +119,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
_renderer.QueueCommand();
}
public void SetData(ReadOnlySpan<byte> data, int layer, int level, Rectangle<int> region)
{
_renderer.New<TextureSetDataSliceRegionCommand>().Set(Ref(this), Ref(data.ToArray()), layer, level, region);
_renderer.QueueCommand();
}
public void SetStorage(BufferRange buffer)
{
_renderer.New<TextureSetStorageCommand>().Set(Ref(this), buffer);

View File

@ -224,7 +224,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
xCount,
yCount,
dstLinear,
dst.MemoryLayout);
dst.MemoryLayout.UnpackGobBlocksInY(),
dst.MemoryLayout.UnpackGobBlocksInZ());
if (target != null)
{

View File

@ -29,6 +29,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
private int _dstHeight;
private int _dstStride;
private int _dstGobBlocksInY;
private int _dstGobBlocksInZ;
private int _lineLengthIn;
private int _lineCount;
@ -117,6 +118,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
_dstHeight = (int)state.SetDstHeight;
_dstStride = (int)state.PitchOut;
_dstGobBlocksInY = 1 << (int)state.SetDstBlockSizeHeight;
_dstGobBlocksInZ = 1 << (int)state.SetDstBlockSizeDepth;
_lineLengthIn = (int)state.LineLengthIn;
_lineCount = (int)state.LineCount;
@ -176,6 +178,31 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
}
else
{
// TODO: Verify if the destination X/Y and width/height are taken into account
// for linear texture transfers. If not, we can use the fast path for that aswell.
// Right now the copy code at the bottom assumes that it is used on both which might be incorrect.
if (!_isLinear)
{
var target = memoryManager.Physical.TextureCache.FindTexture(
memoryManager,
_dstGpuVa,
1,
_dstStride,
_dstHeight,
_lineLengthIn,
_lineCount,
_isLinear,
_dstGobBlocksInY,
_dstGobBlocksInZ);
if (target != null)
{
target.SetData(data, 0, 0, new GAL.Rectangle<int>(_dstX, _dstY, _lineLengthIn / target.Info.FormatInfo.BytesPerPixel, _lineCount));
return;
}
}
var dstCalculator = new OffsetCalculator(
_dstWidth,
_dstHeight,

View File

@ -1,6 +1,5 @@
using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.Gpu.Engine.GPFifo;
using Ryujinx.Graphics.Gpu.Memory;
using System;
namespace Ryujinx.Graphics.Gpu.Engine.MME

View File

@ -1,7 +1,6 @@
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Engine.Types;
using System;
using System.Text;
namespace Ryujinx.Graphics.Gpu.Engine.Threed
{

View File

@ -1317,10 +1317,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
for (int location = 0; location < attributeTypes.Length; location++)
{
attributeTypes[location] = vertexAttribState[location].UnpackType() switch
VertexAttribType type = vertexAttribState[location].UnpackType();
attributeTypes[location] = type switch
{
3 => AttributeType.Sint,
4 => AttributeType.Uint,
VertexAttribType.Sint => AttributeType.Sint,
VertexAttribType.Uint => AttributeType.Uint,
_ => AttributeType.Float
};
}

View File

@ -267,6 +267,41 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
#pragma warning restore CS0649
}
/// <summary>
/// Vertex attribute vector and component size.
/// </summary>
enum VertexAttribSize
{
Size32x4 = 1,
Size32x3 = 2,
Size16x4 = 3,
Size32x2 = 4,
Size16x3 = 5,
Size8x4 = 0xa,
Size16x2 = 0xf,
Size32 = 0x12,
Size8x3 = 0x13,
Size8x2 = 0x18,
Size16 = 0x1b,
Size8 = 0x1d,
Rgb10A2 = 0x30,
Rg11B10 = 0x31
}
/// <summary>
/// Vertex attribute component type.
/// </summary>
enum VertexAttribType
{
Snorm = 1,
Unorm = 2,
Sint = 3,
Uint = 4,
Uscaled = 5,
Sscaled = 6,
Float = 7
}
/// <summary>
/// Vertex buffer attribute state.
/// </summary>
@ -312,13 +347,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
return Attribute & 0x3fe00000;
}
/// <summary>
/// <summary>
/// Unpacks the Maxwell attribute size.
/// </summary>
/// <returns>Attribute size</returns>
public VertexAttribSize UnpackSize()
{
return (VertexAttribSize)((Attribute >> 21) & 0x3f);
}
/// <summary>
/// Unpacks the Maxwell attribute component type.
/// </summary>
/// <returns>Attribute component type</returns>
public uint UnpackType()
public VertexAttribType UnpackType()
{
return (Attribute >> 27) & 7;
return (VertexAttribType)((Attribute >> 27) & 7);
}
}

View File

@ -82,7 +82,7 @@ namespace Ryujinx.Graphics.Gpu
/// <summary>
/// Host hardware capabilities.
/// </summary>
internal Capabilities Capabilities { get; private set; }
internal Capabilities Capabilities;
/// <summary>
/// Event for signalling shader cache loading progress.

View File

@ -1,4 +1,3 @@
using Ryujinx.Common.Logging;
using System.Collections;
using System.Collections.Generic;

View File

@ -761,6 +761,24 @@ namespace Ryujinx.Graphics.Gpu.Image
_hasData = true;
}
/// <summary>
/// Uploads new texture data to the host GPU for a specific layer/level and 2D sub-region.
/// </summary>
/// <param name="data">New data</param>
/// <param name="layer">Target layer</param>
/// <param name="level">Target level</param>
/// <param name="region">Target sub-region of the texture to update</param>
public void SetData(ReadOnlySpan<byte> data, int layer, int level, Rectangle<int> region)
{
BlacklistScale();
HostTexture.SetData(data, layer, level, region);
_currentData = null;
_hasData = true;
}
/// <summary>
/// Converts texture data to a format and layout that is supported by the host GPU.
/// </summary>

View File

@ -1,10 +1,8 @@
using Ryujinx.Common;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Engine.Dma;
using Ryujinx.Graphics.Gpu.Engine.Threed;
using Ryujinx.Graphics.Gpu.Engine.Twod;
using Ryujinx.Graphics.Gpu.Engine.Types;
using Ryujinx.Graphics.Gpu.Image;
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Texture;
using Ryujinx.Memory.Range;
@ -907,7 +905,8 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <param name="xCount">Number of pixels to be copied per line</param>
/// <param name="yCount">Number of lines to be copied</param>
/// <param name="linear">True if the texture has a linear layout, false otherwise</param>
/// <param name="memoryLayout">If <paramref name="linear"/> is false, should have the memory layout, otherwise ignored</param>
/// <param name="gobBlocksInY">If <paramref name="linear"/> is false, the amount of GOB blocks in the Y axis</param>
/// <param name="gobBlocksInZ">If <paramref name="linear"/> is false, the amount of GOB blocks in the Z axis</param>
/// <returns>A matching texture, or null if there is no match</returns>
public Texture FindTexture(
MemoryManager memoryManager,
@ -918,7 +917,8 @@ namespace Ryujinx.Graphics.Gpu.Image
int xCount,
int yCount,
bool linear,
MemoryLayout memoryLayout)
int gobBlocksInY,
int gobBlocksInZ)
{
ulong address = memoryManager.Translate(gpuVa);
@ -957,8 +957,8 @@ namespace Ryujinx.Graphics.Gpu.Image
bool sizeMatch = xCount * bpp == texture.Info.Width * format.BytesPerPixel && height == texture.Info.Height;
bool formatMatch = !texture.Info.IsLinear &&
texture.Info.GobBlocksInY == memoryLayout.UnpackGobBlocksInY() &&
texture.Info.GobBlocksInZ == memoryLayout.UnpackGobBlocksInZ();
texture.Info.GobBlocksInY == gobBlocksInY &&
texture.Info.GobBlocksInZ == gobBlocksInZ;
match = sizeMatch && formatMatch;
}

Some files were not shown because too many files have changed in this diff Show More