| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- using ChocolArm64.Memory;
- using System;
- namespace Ryujinx.Graphics.Memory
- {
- class NvGpuVmmCache
- {
- private ValueRangeSet<int> CachedRanges;
- public NvGpuVmmCache()
- {
- CachedRanges = new ValueRangeSet<int>();
- }
- public bool IsRegionModified(AMemory Memory, NvGpuBufferType BufferType, long PA, long Size)
- {
- (bool[] Modified, long ModifiedCount) = Memory.IsRegionModified(PA, Size);
- //Remove all modified ranges.
- int Index = 0;
- long Position = PA & ~NvGpuVmm.PageMask;
- while (ModifiedCount > 0)
- {
- if (Modified[Index++])
- {
- CachedRanges.Remove(new ValueRange<int>(Position, Position + NvGpuVmm.PageSize));
- ModifiedCount--;
- }
- Position += NvGpuVmm.PageSize;
- }
- //Mask has the bit set for the current resource type.
- //If the region is not yet present on the list, then a new ValueRange
- //is directly added with the current resource type as the only bit set.
- //Otherwise, it just sets the bit for this new resource type on the current mask.
- int Mask = 1 << (int)BufferType;
- ValueRange<int> NewCached = new ValueRange<int>(PA, PA + Size);
- ValueRange<int>[] Ranges = CachedRanges.GetAllIntersections(NewCached);
- long LastEnd = NewCached.Start;
- long Coverage = 0;
- for (Index = 0; Index < Ranges.Length; Index++)
- {
- ValueRange<int> Current = Ranges[Index];
- long RgStart = Math.Max(Current.Start, NewCached.Start);
- long RgEnd = Math.Min(Current.End, NewCached.End);
- if ((Current.Value & Mask) == 0)
- {
- CachedRanges.Add(new ValueRange<int>(RgStart, RgEnd, Current.Value | Mask));
- }
- else
- {
- Coverage += RgEnd - RgStart;
- }
- if (RgStart > LastEnd)
- {
- CachedRanges.Add(new ValueRange<int>(LastEnd, RgStart, Mask));
- }
- LastEnd = RgEnd;
- }
- if (LastEnd < NewCached.End)
- {
- CachedRanges.Add(new ValueRange<int>(LastEnd, NewCached.End, Mask));
- }
- return Coverage != Size;
- }
- }
- }
|