diff --git a/ChocolArm64/Memory/AMemory.cs b/ChocolArm64/Memory/AMemory.cs index e969cca5fe..5a08aef357 100644 --- a/ChocolArm64/Memory/AMemory.cs +++ b/ChocolArm64/Memory/AMemory.cs @@ -691,6 +691,19 @@ namespace ChocolArm64.Memory Marshal.Copy(Data, 0, (IntPtr)(RamPtr + (uint)Position), Data.Length); } + public void CopyBytes(long Src, long Dst, long Size) + { + EnsureRangeIsValid(Src, Size, AMemoryPerm.Read); + EnsureRangeIsValid(Dst, Size, AMemoryPerm.Write); + + Buffer.MemoryCopy( + RamPtr + (uint)Src, + RamPtr + (uint)Dst, + Size, + Size); + } + + private void EnsureRangeIsValid(long Position, long Size, AMemoryPerm Perm) { long EndPos = Position + Size; diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDma.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDma.cs index 7e355e8de9..b2fc86581e 100644 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDma.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDma.cs @@ -58,6 +58,9 @@ namespace Ryujinx.HLE.Gpu.Engines int SrcPitch = ReadRegister(NvGpuEngineDmaReg.SrcPitch); int DstPitch = ReadRegister(NvGpuEngineDmaReg.DstPitch); + int XCount = ReadRegister(NvGpuEngineDmaReg.XCount); + int YCount = ReadRegister(NvGpuEngineDmaReg.YCount); + int DstBlkDim = ReadRegister(NvGpuEngineDmaReg.DstBlkDim); int DstSizeX = ReadRegister(NvGpuEngineDmaReg.DstSizeX); int DstSizeY = ReadRegister(NvGpuEngineDmaReg.DstSizeY); @@ -103,13 +106,23 @@ namespace Ryujinx.HLE.Gpu.Engines DstSwizzle = new BlockLinearSwizzle(DstSizeX, 1, DstBlockHeight); } - for (int Y = 0; Y < DstSizeY; Y++) - for (int X = 0; X < DstSizeX; X++) + if (SrcLinear == DstLinear) { - long SrcOffset = SrcAddress + (uint)SrcSwizzle.GetSwizzleOffset(X, Y); - long DstOffset = DstAddress + (uint)DstSwizzle.GetSwizzleOffset(X, Y); + long Src = Vmm.GetPhysicalAddress(SrcAddress); + long Dst = Vmm.GetPhysicalAddress(DstAddress); - Vmm.WriteByte(DstOffset, Vmm.ReadByte(SrcOffset)); + Vmm.Memory.CopyBytes(Src, Dst, XCount * YCount); + } + else + { + for (int Y = 0; Y < YCount; Y++) + for (int X = 0; X < XCount; X++) + { + long SrcOffset = SrcAddress + (uint)SrcSwizzle.GetSwizzleOffset(X, Y); + long DstOffset = DstAddress + (uint)DstSwizzle.GetSwizzleOffset(X, Y); + + Vmm.WriteByte(DstOffset, Vmm.ReadByte(SrcOffset)); + } } } diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDmaReg.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDmaReg.cs index 835a822d16..bf915d4e4d 100644 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDmaReg.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngineDmaReg.cs @@ -6,6 +6,8 @@ namespace Ryujinx.HLE.Gpu.Engines DstAddress = 0x102, SrcPitch = 0x104, DstPitch = 0x105, + XCount = 0x106, + YCount = 0x107, DstBlkDim = 0x1c3, DstSizeX = 0x1c4, DstSizeY = 0x1c5,