From 79408b68c3e72c26d42f858089d97d77d58b44d9 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 20 Mar 2022 13:55:07 -0300 Subject: 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 --- Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs | 65 +++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 5 deletions(-) (limited to 'Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs') diff --git a/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs b/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs index 977fbdf9..c57f1a6f 100644 --- a/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs +++ b/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs @@ -264,7 +264,8 @@ namespace Ryujinx.Graphics.Gpu.Memory /// CPU virtual address to map into /// GPU virtual address to be mapped /// Size in bytes of the mapping - public void Map(ulong pa, ulong va, ulong size) + /// Kind of the resource located at the mapping + public void Map(ulong pa, ulong va, ulong size, PteKind kind) { lock (_pageTable) { @@ -272,7 +273,7 @@ namespace Ryujinx.Graphics.Gpu.Memory for (ulong offset = 0; offset < size; offset += PageSize) { - SetPte(va + offset, pa + offset); + SetPte(va + offset, PackPte(pa + offset, kind)); } } } @@ -462,14 +463,37 @@ namespace Ryujinx.Graphics.Gpu.Memory return PteUnmapped; } - ulong baseAddress = GetPte(va); + ulong pte = GetPte(va); - if (baseAddress == PteUnmapped) + if (pte == PteUnmapped) { return PteUnmapped; } - return baseAddress + (va & PageMask); + return UnpackPaFromPte(pte) + (va & PageMask); + } + + /// + /// Gets the kind of a given memory page. + /// This might indicate the type of resource that can be allocated on the page, and also texture tiling. + /// + /// GPU virtual address + /// Kind of the memory page + public PteKind GetKind(ulong va) + { + if (!ValidateAddress(va)) + { + return PteKind.Invalid; + } + + ulong pte = GetPte(va); + + if (pte == PteUnmapped) + { + return PteKind.Invalid; + } + + return UnpackKindFromPte(pte); } /// @@ -512,5 +536,36 @@ namespace Ryujinx.Graphics.Gpu.Memory _pageTable[l0][l1] = pte; } + + /// + /// Creates a page table entry from a physical address and kind. + /// + /// Physical address + /// Kind + /// Page table entry + private static ulong PackPte(ulong pa, PteKind kind) + { + return pa | ((ulong)kind << 56); + } + + /// + /// Unpacks kind from a page table entry. + /// + /// Page table entry + /// Kind + private static PteKind UnpackKindFromPte(ulong pte) + { + return (PteKind)(pte >> 56); + } + + /// + /// Unpacks physical address from a page table entry. + /// + /// Page table entry + /// Physical address + private static ulong UnpackPaFromPte(ulong pte) + { + return pte & 0xffffffffffffffUL; + } } } \ No newline at end of file -- cgit v1.2.3