diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2022-03-20 13:55:07 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-03-20 13:55:07 -0300 |
| commit | 79408b68c3e72c26d42f858089d97d77d58b44d9 (patch) | |
| tree | 9aaa12a877030dc17b4333eefe886be7fb8eb820 /Ryujinx.Graphics.Gpu/Engine | |
| parent | d461d4f68bf64f008336845ae8a25af4f69ec9ed (diff) | |
De-tile GOB when DMA copying from block linear to pitch kind memory regions (#3207)
* De-tile GOB when DMA copying from block linear to pitch kind memory regions
* XML docs + nits
* Remove using
* No flush for regular buffer copies
* Add back ulong casts, fix regression due to oversight
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Engine')
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs | 88 |
1 files changed, 86 insertions, 2 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs b/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs index cbd0902d..df7e55a1 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs @@ -1,7 +1,7 @@ using Ryujinx.Common; -using Ryujinx.Common.Logging; using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Gpu.Engine.Threed; +using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.Graphics.Texture; using System; using System.Collections.Generic; @@ -330,12 +330,96 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma { // TODO: Implement remap functionality. // Buffer to buffer copy. - memoryManager.Physical.BufferCache.CopyBuffer(memoryManager, srcGpuVa, dstGpuVa, size); + + bool srcIsPitchKind = memoryManager.GetKind(srcGpuVa).IsPitch(); + bool dstIsPitchKind = memoryManager.GetKind(dstGpuVa).IsPitch(); + + if (!srcIsPitchKind && dstIsPitchKind) + { + CopyGobBlockLinearToLinear(memoryManager, srcGpuVa, dstGpuVa, size); + } + else if (srcIsPitchKind && !dstIsPitchKind) + { + CopyGobLinearToBlockLinear(memoryManager, srcGpuVa, dstGpuVa, size); + } + else + { + memoryManager.Physical.BufferCache.CopyBuffer(memoryManager, srcGpuVa, dstGpuVa, size); + } } } } /// <summary> + /// Copies block linear data with block linear GOBs to a block linear destination with linear GOBs. + /// </summary> + /// <param name="memoryManager">GPU memory manager</param> + /// <param name="srcGpuVa">Source GPU virtual address</param> + /// <param name="dstGpuVa">Destination GPU virtual address</param> + /// <param name="size">Size in bytes of the copy</param> + private static void CopyGobBlockLinearToLinear(MemoryManager memoryManager, ulong srcGpuVa, ulong dstGpuVa, ulong size) + { + if (((srcGpuVa | dstGpuVa | size) & 0xf) == 0) + { + for (ulong offset = 0; offset < size; offset += 16) + { + Vector128<byte> data = memoryManager.Read<Vector128<byte>>(ConvertGobLinearToBlockLinearAddress(srcGpuVa + offset), true); + memoryManager.Write(dstGpuVa + offset, data); + } + } + else + { + for (ulong offset = 0; offset < size; offset++) + { + byte data = memoryManager.Read<byte>(ConvertGobLinearToBlockLinearAddress(srcGpuVa + offset), true); + memoryManager.Write(dstGpuVa + offset, data); + } + } + } + + /// <summary> + /// Copies block linear data with linear GOBs to a block linear destination with block linear GOBs. + /// </summary> + /// <param name="memoryManager">GPU memory manager</param> + /// <param name="srcGpuVa">Source GPU virtual address</param> + /// <param name="dstGpuVa">Destination GPU virtual address</param> + /// <param name="size">Size in bytes of the copy</param> + private static void CopyGobLinearToBlockLinear(MemoryManager memoryManager, ulong srcGpuVa, ulong dstGpuVa, ulong size) + { + if (((srcGpuVa | dstGpuVa | size) & 0xf) == 0) + { + for (ulong offset = 0; offset < size; offset += 16) + { + Vector128<byte> data = memoryManager.Read<Vector128<byte>>(srcGpuVa + offset, true); + memoryManager.Write(ConvertGobLinearToBlockLinearAddress(dstGpuVa + offset), data); + } + } + else + { + for (ulong offset = 0; offset < size; offset++) + { + byte data = memoryManager.Read<byte>(srcGpuVa + offset, true); + memoryManager.Write(ConvertGobLinearToBlockLinearAddress(dstGpuVa + offset), data); + } + } + } + + /// <summary> + /// Calculates the GOB block linear address from a linear address. + /// </summary> + /// <param name="address">Linear address</param> + /// <returns>Block linear address</returns> + private static ulong ConvertGobLinearToBlockLinearAddress(ulong address) + { + // y2 y1 y0 x5 x4 x3 x2 x1 x0 -> x5 y2 y1 x4 y0 x3 x2 x1 x0 + return (address & ~0x1f0UL) | + ((address & 0x40) >> 2) | + ((address & 0x10) << 1) | + ((address & 0x180) >> 1) | + ((address & 0x20) << 3); + } + + /// <summary> /// Performs a buffer to buffer, or buffer to texture copy, then optionally releases a semaphore. /// </summary> /// <param name="argument">Method call argument</param> |
