From e58b540c4e2a8df460e0e357e3f341842dd59a71 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 31 Dec 2019 00:22:58 -0300 Subject: Add XML documentation to Ryujinx.Graphics.Gpu.Memory --- Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs | 111 +++++++++++++++++++++++---- 1 file changed, 98 insertions(+), 13 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 59319a47..d4d9b48a 100644 --- a/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs +++ b/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs @@ -1,5 +1,8 @@ namespace Ryujinx.Graphics.Gpu.Memory { + /// + /// GPU memory manager. + /// public class MemoryManager { private const ulong AddressSpaceSize = 1UL << 40; @@ -26,11 +29,22 @@ namespace Ryujinx.Graphics.Gpu.Memory private ulong[][] _pageTable; + /// + /// Creates a new instance of the GPU memory manager. + /// public MemoryManager() { _pageTable = new ulong[PtLvl0Size][]; } + /// + /// Maps a given range of pages to the specified CPU virtual address. + /// All addresses and sizes must be page aligned. + /// + /// CPU virtual address to map into + /// GPU virtual address to be mapped + /// Size in bytes of the mapping + /// The GPU virtual address of the mapping public ulong Map(ulong pa, ulong va, ulong size) { lock (_pageTable) @@ -44,6 +58,13 @@ namespace Ryujinx.Graphics.Gpu.Memory return va; } + /// + /// Maps a given range of pages to a allocated GPU virtual address. + /// The memory is automatically allocated by the memory manager. + /// + /// CPU virtual address to map into + /// Mapping size in bytes + /// GPU virtual address where the range was mapped, or an all ones mask in case of failure public ulong Map(ulong pa, ulong size) { lock (_pageTable) @@ -62,6 +83,14 @@ namespace Ryujinx.Graphics.Gpu.Memory } } + /// + /// Maps a given range of pages to a allocated GPU virtual address. + /// The memory is automatically allocated by the memory manager. + /// This also ensures that the mapping is always done in the first 4GB of GPU address space. + /// + /// CPU virtual address to map into + /// Mapping size in bytes + /// GPU virtual address where the range was mapped, or an all ones mask in case of failure public ulong MapLow(ulong pa, ulong size) { lock (_pageTable) @@ -84,6 +113,13 @@ namespace Ryujinx.Graphics.Gpu.Memory } } + /// + /// Reserves memory at a fixed GPU memory location. + /// This prevents the reserved region from being used for memory allocation for map. + /// + /// CPU virtual address to reserve + /// Reservation size in bytes + /// GPU virtual address of the reservation, or an all ones mask in case of failure public ulong ReserveFixed(ulong va, ulong size) { lock (_pageTable) @@ -105,6 +141,12 @@ namespace Ryujinx.Graphics.Gpu.Memory return va; } + /// + /// Reserves memory at any GPU memory location. + /// + /// Reservation size in bytes + /// Reservation address alignment in bytes + /// GPU virtual address of the reservation, or an all ones mask in case of failure public ulong Reserve(ulong size, ulong alignment) { lock (_pageTable) @@ -123,6 +165,11 @@ namespace Ryujinx.Graphics.Gpu.Memory } } + /// + /// Frees memory that was previously allocated by a map or reserved. + /// + /// GPU virtual address to free + /// Size in bytes of the region being freed public void Free(ulong va, ulong size) { lock (_pageTable) @@ -134,6 +181,13 @@ namespace Ryujinx.Graphics.Gpu.Memory } } + /// + /// Gets the address of a unused (free) region of the specified size. + /// + /// Size of the region in bytes + /// Required alignment of the region address in bytes + /// Start address of the search on the address space + /// GPU virtual address of the allocation, or an all ones mask in case of failure private ulong GetFreePosition(ulong size, ulong alignment = 1, ulong start = 1UL << 32) { // Note: Address 0 is not considered valid by the driver, @@ -176,6 +230,11 @@ namespace Ryujinx.Graphics.Gpu.Memory return PteUnmapped; } + /// + /// Gets the number of mapped or reserved pages on a given region. + /// + /// Start GPU virtual address of the region + /// Mapped size in bytes of the specified region internal ulong GetSubSize(ulong gpuVa) { ulong size = 0; @@ -188,6 +247,11 @@ namespace Ryujinx.Graphics.Gpu.Memory return size; } + /// + /// Translated a GPU virtual address to a CPU virtual address. + /// + /// GPU virtual address to be translated + /// CPU virtual address internal ulong Translate(ulong gpuVa) { ulong baseAddress = GetPte(gpuVa); @@ -200,11 +264,17 @@ namespace Ryujinx.Graphics.Gpu.Memory return baseAddress + (gpuVa & PageMask); } - public bool IsRegionFree(ulong va, ulong size) + /// + /// Checks if a given memory region is currently unmapped. + /// + /// Start GPU virtual address of the region + /// Size in bytes of the region + /// True if the region is unmapped (free), false otherwise + public bool IsRegionFree(ulong gpuVa, ulong size) { for (ulong offset = 0; offset < size; offset += PageSize) { - if (IsPageInUse(va + offset)) + if (IsPageInUse(gpuVa + offset)) { return false; } @@ -213,15 +283,20 @@ namespace Ryujinx.Graphics.Gpu.Memory return true; } - private bool IsPageInUse(ulong va) + /// + /// Checks if a given memory page is mapped or reserved. + /// + /// GPU virtual address of the page + /// True if the page is mapped or reserved, false otherwise + private bool IsPageInUse(ulong gpuVa) { - if (va >> PtLvl0Bits + PtLvl1Bits + PtPageBits != 0) + if (gpuVa >> PtLvl0Bits + PtLvl1Bits + PtPageBits != 0) { return false; } - ulong l0 = (va >> PtLvl0Bit) & PtLvl0Mask; - ulong l1 = (va >> PtLvl1Bit) & PtLvl1Mask; + ulong l0 = (gpuVa >> PtLvl0Bit) & PtLvl0Mask; + ulong l1 = (gpuVa >> PtLvl1Bit) & PtLvl1Mask; if (_pageTable[l0] == null) { @@ -231,10 +306,15 @@ namespace Ryujinx.Graphics.Gpu.Memory return _pageTable[l0][l1] != PteUnmapped; } - private ulong GetPte(ulong address) + /// + /// Gets the Page Table entry for a given GPU virtual address. + /// + /// GPU virtual address + /// Page table entry (CPU virtual address) + private ulong GetPte(ulong gpuVa) { - ulong l0 = (address >> PtLvl0Bit) & PtLvl0Mask; - ulong l1 = (address >> PtLvl1Bit) & PtLvl1Mask; + ulong l0 = (gpuVa >> PtLvl0Bit) & PtLvl0Mask; + ulong l1 = (gpuVa >> PtLvl1Bit) & PtLvl1Mask; if (_pageTable[l0] == null) { @@ -244,10 +324,15 @@ namespace Ryujinx.Graphics.Gpu.Memory return _pageTable[l0][l1]; } - private void SetPte(ulong address, ulong tgtAddr) + /// + /// Sets a Page Table entry at a given GPU virtual address. + /// + /// GPU virtual address + /// Page table entry (CPU virtual address) + private void SetPte(ulong gpuVa, ulong pte) { - ulong l0 = (address >> PtLvl0Bit) & PtLvl0Mask; - ulong l1 = (address >> PtLvl1Bit) & PtLvl1Mask; + ulong l0 = (gpuVa >> PtLvl0Bit) & PtLvl0Mask; + ulong l1 = (gpuVa >> PtLvl1Bit) & PtLvl1Mask; if (_pageTable[l0] == null) { @@ -259,7 +344,7 @@ namespace Ryujinx.Graphics.Gpu.Memory } } - _pageTable[l0][l1] = tgtAddr; + _pageTable[l0][l1] = pte; } } } \ No newline at end of file -- cgit v1.2.3