diff options
author | riperiperi <rhy3756547@hotmail.com> | 2023-05-18 07:56:34 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-18 08:56:34 +0200 |
commit | ecbf303266d78d7b4287ce4ea97d59107a05fb2f (patch) | |
tree | bd9cf887d3f5d323ac53b8604ce08df05d4ab0f6 /src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs | |
parent | b3bf05356be755bcbf82611530ebd44c9b61b384 (diff) |
GPU: Avoid using garbage size for non-cb0 storage buffers (#4999)1.1.804
* GPU: Avoid using garbage size for non-cb0 storage buffers
In the depths area, Tears of the Kingdom uses a global memory access with address on constant buffer slot 6. This isn't standard and thus doesn't actually have a size 8 bytes after it, so we were reading back a garbage size that ended up very large (at least in version 1.1.0), and would synchronize a lot of data per frame.
This PR makes storage buffers created from addresses outside constant buffer slot 0 get their size as the number of bytes remaining in the GPU mapping starting at the given virtual address. This should bound the buffer to a reasonable size, and ideally stop it crossing into other memory.
* Limit max size
* Add TODO
* Feedback
Diffstat (limited to 'src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs')
-rw-r--r-- | src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs b/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs index 0d4a41f0..c7a138c9 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs @@ -638,6 +638,33 @@ namespace Ryujinx.Graphics.Gpu.Memory } /// <summary> + /// Translates a GPU virtual address and returns the number of bytes that are mapped after it. + /// </summary> + /// <param name="va">GPU virtual address to be translated</param> + /// <param name="maxSize">Maximum size in bytes to scan</param> + /// <returns>Number of bytes, 0 if unmapped</returns> + public ulong GetMappedSize(ulong va, ulong maxSize) + { + if (!ValidateAddress(va)) + { + return 0; + } + + ulong startVa = va; + ulong endVa = va + maxSize; + + ulong pte = GetPte(va); + + while (pte != PteUnmapped && va < endVa) + { + va += PageSize - (va & PageMask); + pte = GetPte(va); + } + + return Math.Min(maxSize, va - startVa); + } + + /// <summary> /// 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. /// </summary> |