diff options
author | gdkchan <gab.dark.100@gmail.com> | 2021-01-23 09:38:00 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-23 13:38:00 +0100 |
commit | f565b0e5a6bebc09381aabb046e9b0b6285b7d10 (patch) | |
tree | 76a2a43837c61fe234677b9d91e7f4562680f7a1 | |
parent | 6982282cc8ad362924bcb0c176ccb6e6d0339fa4 (diff) |
Match texture if the physical range is the same (#1934)
* Match texture if the physical range is the same
* XML docs and comments
-rw-r--r-- | Ryujinx.Graphics.Gpu/Image/TextureManager.cs | 24 | ||||
-rw-r--r-- | Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs | 33 |
2 files changed, 52 insertions, 5 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs index 30137d06..2646a75b 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs @@ -685,13 +685,27 @@ namespace Ryujinx.Graphics.Gpu.Image { Texture overlap = _textureOverlaps[index]; - bool rangeMatches = range != null ? overlap.Range.Equals(range.Value) : overlap.Info.GpuAddress == info.GpuAddress; - if (!rangeMatches) + TextureMatchQuality matchQuality = overlap.IsExactMatch(info, flags); + + if (matchQuality != TextureMatchQuality.NoMatch) { - continue; - } + // If the parameters match, we need to make sure the texture is mapped to the same memory regions. - TextureMatchQuality matchQuality = overlap.IsExactMatch(info, flags); + // If a range of memory was supplied, just check if the ranges match. + if (range != null && !overlap.Range.Equals(range.Value)) + { + continue; + } + + // If no range was supplied, we can check if the GPU virtual address match. If they do, + // we know the textures are located at the same memory region. + // If they don't, it may still be mapped to the same physical region, so we + // do a more expensive check to tell if they are mapped into the same physical regions. + if (overlap.Info.GpuAddress != info.GpuAddress && !_context.MemoryManager.CompareRange(overlap.Range, info.GpuAddress)) + { + continue; + } + } if (matchQuality == TextureMatchQuality.Perfect) { diff --git a/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs b/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs index 7021cd20..5776836c 100644 --- a/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs +++ b/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs @@ -344,6 +344,39 @@ namespace Ryujinx.Graphics.Gpu.Memory } /// <summary> + /// Checks if a given GPU virtual memory range is mapped to the same physical regions + /// as the specified physical memory multi-range. + /// </summary> + /// <param name="range">Physical memory multi-range</param> + /// <param name="va">GPU virtual memory address</param> + /// <returns>True if the virtual memory region is mapped into the specified physical one, false otherwise</returns> + public bool CompareRange(MultiRange range, ulong va) + { + va &= ~PageMask; + + for (int i = 0; i < range.Count; i++) + { + MemoryRange currentRange = range.GetSubRange(i); + + ulong address = currentRange.Address & ~PageMask; + ulong endAddress = (currentRange.EndAddress + PageMask) & ~PageMask; + + while (address < endAddress) + { + if (Translate(va) != address) + { + return false; + } + + va += PageSize; + address += PageSize; + } + } + + return true; + } + + /// <summary> /// Validates a GPU virtual address. /// </summary> /// <param name="va">Address to validate</param> |