aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/Gpu/Memory
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-07-08 16:55:15 -0300
committerGitHub <noreply@github.com>2018-07-08 16:55:15 -0300
commit095db47e132a475e25d128e691ebdae101611cc9 (patch)
treef10299c8168709bf8db7f2da966eb0cbe6b598a9 /Ryujinx.HLE/Gpu/Memory
parent0f8f40486d1b3215c845325744bd545149223805 (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.cs3
-rw-r--r--Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs6
-rw-r--r--Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs116
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);
}