diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-07-08 16:55:15 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-07-08 16:55:15 -0300 |
| commit | 095db47e132a475e25d128e691ebdae101611cc9 (patch) | |
| tree | f10299c8168709bf8db7f2da966eb0cbe6b598a9 /Ryujinx.HLE/Gpu/Memory | |
| parent | 0f8f40486d1b3215c845325744bd545149223805 (diff) | |
Query multiple pages at once with GetWriteWatch (#222)
* Query multiple pages at once with GetWriteWatch
* Allow multiple buffer types to share the same page, aways use the physical address as cache key
* Remove a variable that is no longer needed
Diffstat (limited to 'Ryujinx.HLE/Gpu/Memory')
| -rw-r--r-- | Ryujinx.HLE/Gpu/Memory/NvGpuBufferType.cs | 3 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs | 6 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs | 116 |
3 files changed, 68 insertions, 57 deletions
diff --git a/Ryujinx.HLE/Gpu/Memory/NvGpuBufferType.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuBufferType.cs index 7474aa33..469cd6cd 100644 --- a/Ryujinx.HLE/Gpu/Memory/NvGpuBufferType.cs +++ b/Ryujinx.HLE/Gpu/Memory/NvGpuBufferType.cs @@ -4,6 +4,7 @@ namespace Ryujinx.HLE.Gpu.Memory { Index, Vertex, - Texture + Texture, + Count } }
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs index 36f6406a..0c81dd15 100644 --- a/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs +++ b/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs @@ -274,11 +274,9 @@ namespace Ryujinx.HLE.Gpu.Memory PageTable[L0][L1] = TgtAddr; } - public bool IsRegionModified(long Position, long Size, NvGpuBufferType BufferType) + public bool IsRegionModified(long PA, long Size, NvGpuBufferType BufferType) { - long PA = GetPhysicalAddress(Position); - - return Cache.IsRegionModified(Memory, BufferType, Position, PA, Size); + return Cache.IsRegionModified(Memory, BufferType, PA, Size); } public byte ReadByte(long Position) diff --git a/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs index c7108f00..ac9bd850 100644 --- a/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs +++ b/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs @@ -11,43 +11,53 @@ namespace Ryujinx.HLE.Gpu.Memory private class CachedPage { - private List<(long Start, long End)> Regions; - - public LinkedListNode<long> Node { get; set; } + private struct Range + { + public long Start; + public long End; - public int Count => Regions.Count; + public Range(long Start, long End) + { + this.Start = Start; + this.End = End; + } + } - public int Timestamp { get; private set; } + private List<Range>[] Regions; - public long PABase { get; private set; } + public LinkedListNode<long> Node { get; set; } - public NvGpuBufferType BufferType { get; private set; } + public int Timestamp { get; private set; } - public CachedPage(long PABase, NvGpuBufferType BufferType) + public CachedPage() { - this.PABase = PABase; - this.BufferType = BufferType; + Regions = new List<Range>[(int)NvGpuBufferType.Count]; - Regions = new List<(long, long)>(); + for (int Index = 0; Index < Regions.Length; Index++) + { + Regions[Index] = new List<Range>(); + } } - public bool AddRange(long Start, long End) + public bool AddRange(long Start, long End, NvGpuBufferType BufferType) { - for (int Index = 0; Index < Regions.Count; Index++) + List<Range> BtRegions = Regions[(int)BufferType]; + + for (int Index = 0; Index < BtRegions.Count; Index++) { - (long RgStart, long RgEnd) = Regions[Index]; + Range Rg = BtRegions[Index]; - if (Start >= RgStart && End <= RgEnd) + if (Start >= Rg.Start && End <= Rg.End) { return false; } - if (Start <= RgEnd && RgStart <= End) + if (Start <= Rg.End && Rg.Start <= End) { - long MinStart = Math.Min(RgStart, Start); - long MaxEnd = Math.Max(RgEnd, End); + long MinStart = Math.Min(Rg.Start, Start); + long MaxEnd = Math.Max(Rg.End, End); - Regions[Index] = (MinStart, MaxEnd); + BtRegions[Index] = new Range(MinStart, MaxEnd); Timestamp = Environment.TickCount; @@ -55,12 +65,24 @@ namespace Ryujinx.HLE.Gpu.Memory } } - Regions.Add((Start, End)); + BtRegions.Add(new Range(Start, End)); Timestamp = Environment.TickCount; return true; } + + public int GetTotalCount() + { + int Count = 0; + + for (int Index = 0; Index < Regions.Length; Index++) + { + Count += Regions[Index].Count; + } + + return Count; + } } private Dictionary<long, CachedPage> Cache; @@ -76,71 +98,61 @@ namespace Ryujinx.HLE.Gpu.Memory SortedCache = new LinkedList<long>(); } - public bool IsRegionModified( - AMemory Memory, - NvGpuBufferType BufferType, - long VA, - long PA, - long Size) + public bool IsRegionModified(AMemory Memory, NvGpuBufferType BufferType, long PA, long Size) { + bool[] Modified = Memory.IsRegionModified(PA, Size); + + if (Modified == null) + { + return true; + } + ClearCachedPagesIfNeeded(); long PageSize = Memory.GetHostPageSize(); long Mask = PageSize - 1; - long VAEnd = VA + Size; long PAEnd = PA + Size; bool RegMod = false; - while (VA < VAEnd) + int Index = 0; + + while (PA < PAEnd) { - long Key = VA & ~Mask; - long PABase = PA & ~Mask; + long Key = PA & ~Mask; - long VAPgEnd = Math.Min((VA + PageSize) & ~Mask, VAEnd); long PAPgEnd = Math.Min((PA + PageSize) & ~Mask, PAEnd); bool IsCached = Cache.TryGetValue(Key, out CachedPage Cp); - bool PgReset = false; - - if (!IsCached) + if (IsCached) { - Cp = new CachedPage(PABase, BufferType); + CpCount -= Cp.GetTotalCount(); - Cache.Add(Key, Cp); + SortedCache.Remove(Cp.Node); } else { - CpCount -= Cp.Count; - - SortedCache.Remove(Cp.Node); + Cp = new CachedPage(); - if (Cp.PABase != PABase || - Cp.BufferType != BufferType) - { - PgReset = true; - } + Cache.Add(Key, Cp); } - PgReset |= Memory.IsRegionModified(PA, PAPgEnd - PA) && IsCached; - - if (PgReset) + if (Modified[Index++] && IsCached) { - Cp = new CachedPage(PABase, BufferType); + Cp = new CachedPage(); Cache[Key] = Cp; } Cp.Node = SortedCache.AddLast(Key); - RegMod |= Cp.AddRange(VA, VAPgEnd); + RegMod |= Cp.AddRange(PA, PAPgEnd, BufferType); - CpCount += Cp.Count; + CpCount += Cp.GetTotalCount(); - VA = VAPgEnd; PA = PAPgEnd; } @@ -169,7 +181,7 @@ namespace Ryujinx.HLE.Gpu.Memory Cache.Remove(Key); - CpCount -= Cp.Count; + CpCount -= Cp.GetTotalCount(); TimeDelta = RingDelta(Cp.Timestamp, Timestamp); } |
