aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2023-05-18 07:56:34 +0100
committerGitHub <noreply@github.com>2023-05-18 08:56:34 +0200
commitecbf303266d78d7b4287ce4ea97d59107a05fb2f (patch)
treebd9cf887d3f5d323ac53b8604ce08df05d4ab0f6 /src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
parentb3bf05356be755bcbf82611530ebd44c9b61b384 (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.cs27
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>