diff options
| author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2018-09-08 14:51:50 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-09-08 14:51:50 -0300 |
| commit | ce1d5be212e6f71a7ca32c3bd7b48e32d9f51b9a (patch) | |
| tree | 759fe422127ce08c545d4616ccc9691f668032ec /Ryujinx.HLE/Gpu/Memory | |
| parent | a0c78f792012cdea060444d7cb6a36dbabb04d52 (diff) | |
Move GPU emulation from Ryujinx.HLE to Ryujinx.Graphics and misc changes (#402)
* Move GPU LLE emulation from HLE to Graphics
* Graphics: Move Gal/Texture to Texture
* Remove Engines/ directory and namespace
* Use tables for image formats
* Abstract OpCode decoding
* Simplify image table
* Do not leak Read* symbols in TextureReader
* Fixups
* Rename IGalFrameBuffer -> IGalRenderTarget
* Remove MaxBpp hardcoded value
* Change yet again texture data and add G8R8 flipping
* Rename GalFrameBufferFormat to GalSurfaceFormat
* Unident EnsureSetup in ImageHandler
* Add IsCompressed
* Address some feedback
Diffstat (limited to 'Ryujinx.HLE/Gpu/Memory')
| -rw-r--r-- | Ryujinx.HLE/Gpu/Memory/NvGpuBufferType.cs | 11 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Memory/NvGpuPBEntry.cs | 23 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Memory/NvGpuPushBuffer.cs | 101 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs | 377 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs | 308 |
5 files changed, 0 insertions, 820 deletions
diff --git a/Ryujinx.HLE/Gpu/Memory/NvGpuBufferType.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuBufferType.cs deleted file mode 100644 index a6c03f42..00000000 --- a/Ryujinx.HLE/Gpu/Memory/NvGpuBufferType.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.HLE.Gpu.Memory -{ - enum NvGpuBufferType - { - Index, - Vertex, - Texture, - ConstBuffer, - Count - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Memory/NvGpuPBEntry.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuPBEntry.cs deleted file mode 100644 index aba89e3c..00000000 --- a/Ryujinx.HLE/Gpu/Memory/NvGpuPBEntry.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.ObjectModel; - -namespace Ryujinx.HLE.Gpu.Memory -{ - struct NvGpuPBEntry - { - public int Method { get; private set; } - - public int SubChannel { get; private set; } - - private int[] m_Arguments; - - public ReadOnlyCollection<int> Arguments => Array.AsReadOnly(m_Arguments); - - public NvGpuPBEntry(int Method, int SubChannel, params int[] Arguments) - { - this.Method = Method; - this.SubChannel = SubChannel; - this.m_Arguments = Arguments; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Memory/NvGpuPushBuffer.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuPushBuffer.cs deleted file mode 100644 index 6121b3e6..00000000 --- a/Ryujinx.HLE/Gpu/Memory/NvGpuPushBuffer.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System.Collections.Generic; -using System.IO; - -namespace Ryujinx.HLE.Gpu.Memory -{ - static class NvGpuPushBuffer - { - private enum SubmissionMode - { - Incrementing = 1, - NonIncrementing = 3, - Immediate = 4, - IncrementOnce = 5 - } - - public static NvGpuPBEntry[] Decode(byte[] Data) - { - using (MemoryStream MS = new MemoryStream(Data)) - { - BinaryReader Reader = new BinaryReader(MS); - - List<NvGpuPBEntry> PushBuffer = new List<NvGpuPBEntry>(); - - bool CanRead() => MS.Position + 4 <= MS.Length; - - while (CanRead()) - { - int Packed = Reader.ReadInt32(); - - int Meth = (Packed >> 0) & 0x1fff; - int SubC = (Packed >> 13) & 7; - int Args = (Packed >> 16) & 0x1fff; - int Mode = (Packed >> 29) & 7; - - switch ((SubmissionMode)Mode) - { - case SubmissionMode.Incrementing: - { - for (int Index = 0; Index < Args && CanRead(); Index++, Meth++) - { - PushBuffer.Add(new NvGpuPBEntry(Meth, SubC, Reader.ReadInt32())); - } - - break; - } - - case SubmissionMode.NonIncrementing: - { - int[] Arguments = new int[Args]; - - for (int Index = 0; Index < Arguments.Length; Index++) - { - if (!CanRead()) - { - break; - } - - Arguments[Index] = Reader.ReadInt32(); - } - - PushBuffer.Add(new NvGpuPBEntry(Meth, SubC, Arguments)); - - break; - } - - case SubmissionMode.Immediate: - { - PushBuffer.Add(new NvGpuPBEntry(Meth, SubC, Args)); - - break; - } - - case SubmissionMode.IncrementOnce: - { - if (CanRead()) - { - PushBuffer.Add(new NvGpuPBEntry(Meth, SubC, Reader.ReadInt32())); - } - - if (CanRead() && Args > 1) - { - int[] Arguments = new int[Args - 1]; - - for (int Index = 0; Index < Arguments.Length && CanRead(); Index++) - { - Arguments[Index] = Reader.ReadInt32(); - } - - PushBuffer.Add(new NvGpuPBEntry(Meth + 1, SubC, Arguments)); - } - - break; - } - } - } - - return PushBuffer.ToArray(); - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs deleted file mode 100644 index e7e18064..00000000 --- a/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs +++ /dev/null @@ -1,377 +0,0 @@ -using ChocolArm64.Memory; -using Ryujinx.Graphics.Gal; -using System; - -namespace Ryujinx.HLE.Gpu.Memory -{ - class NvGpuVmm : IAMemory, IGalMemory - { - public const long AddrSize = 1L << 40; - - private const int PTLvl0Bits = 14; - private const int PTLvl1Bits = 14; - private const int PTPageBits = 12; - - private const int PTLvl0Size = 1 << PTLvl0Bits; - private const int PTLvl1Size = 1 << PTLvl1Bits; - public const int PageSize = 1 << PTPageBits; - - private const int PTLvl0Mask = PTLvl0Size - 1; - private const int PTLvl1Mask = PTLvl1Size - 1; - public const int PageMask = PageSize - 1; - - private const int PTLvl0Bit = PTPageBits + PTLvl1Bits; - private const int PTLvl1Bit = PTPageBits; - - public AMemory Memory { get; private set; } - - private NvGpuVmmCache Cache; - - private const long PteUnmapped = -1; - private const long PteReserved = -2; - - private long[][] PageTable; - - public NvGpuVmm(AMemory Memory) - { - this.Memory = Memory; - - Cache = new NvGpuVmmCache(); - - PageTable = new long[PTLvl0Size][]; - } - - public long Map(long PA, long VA, long Size) - { - lock (PageTable) - { - for (long Offset = 0; Offset < Size; Offset += PageSize) - { - SetPte(VA + Offset, PA + Offset); - } - } - - return VA; - } - - public long Map(long PA, long Size) - { - lock (PageTable) - { - long VA = GetFreePosition(Size); - - if (VA != -1) - { - for (long Offset = 0; Offset < Size; Offset += PageSize) - { - SetPte(VA + Offset, PA + Offset); - } - } - - return VA; - } - } - - public long ReserveFixed(long VA, long Size) - { - lock (PageTable) - { - for (long Offset = 0; Offset < Size; Offset += PageSize) - { - if (IsPageInUse(VA + Offset)) - { - return -1; - } - } - - for (long Offset = 0; Offset < Size; Offset += PageSize) - { - SetPte(VA + Offset, PteReserved); - } - } - - return VA; - } - - public long Reserve(long Size, long Align) - { - lock (PageTable) - { - long Position = GetFreePosition(Size, Align); - - if (Position != -1) - { - for (long Offset = 0; Offset < Size; Offset += PageSize) - { - SetPte(Position + Offset, PteReserved); - } - } - - return Position; - } - } - - public void Free(long VA, long Size) - { - lock (PageTable) - { - for (long Offset = 0; Offset < Size; Offset += PageSize) - { - SetPte(VA + Offset, PteUnmapped); - } - } - } - - private long GetFreePosition(long Size, long Align = 1) - { - //Note: Address 0 is not considered valid by the driver, - //when 0 is returned it's considered a mapping error. - long Position = PageSize; - long FreeSize = 0; - - if (Align < 1) - { - Align = 1; - } - - Align = (Align + PageMask) & ~PageMask; - - while (Position + FreeSize < AddrSize) - { - if (!IsPageInUse(Position + FreeSize)) - { - FreeSize += PageSize; - - if (FreeSize >= Size) - { - return Position; - } - } - else - { - Position += FreeSize + PageSize; - FreeSize = 0; - - long Remainder = Position % Align; - - if (Remainder != 0) - { - Position = (Position - Remainder) + Align; - } - } - } - - return -1; - } - - public long GetPhysicalAddress(long VA) - { - long BasePos = GetPte(VA); - - if (BasePos < 0) - { - return -1; - } - - return BasePos + (VA & PageMask); - } - - public bool IsRegionFree(long VA, long Size) - { - for (long Offset = 0; Offset < Size; Offset += PageSize) - { - if (IsPageInUse(VA + Offset)) - { - return false; - } - } - - return true; - } - - private bool IsPageInUse(long VA) - { - if (VA >> PTLvl0Bits + PTLvl1Bits + PTPageBits != 0) - { - return false; - } - - long L0 = (VA >> PTLvl0Bit) & PTLvl0Mask; - long L1 = (VA >> PTLvl1Bit) & PTLvl1Mask; - - if (PageTable[L0] == null) - { - return false; - } - - return PageTable[L0][L1] != PteUnmapped; - } - - private long GetPte(long Position) - { - long L0 = (Position >> PTLvl0Bit) & PTLvl0Mask; - long L1 = (Position >> PTLvl1Bit) & PTLvl1Mask; - - if (PageTable[L0] == null) - { - return -1; - } - - return PageTable[L0][L1]; - } - - private void SetPte(long Position, long TgtAddr) - { - long L0 = (Position >> PTLvl0Bit) & PTLvl0Mask; - long L1 = (Position >> PTLvl1Bit) & PTLvl1Mask; - - if (PageTable[L0] == null) - { - PageTable[L0] = new long[PTLvl1Size]; - - for (int Index = 0; Index < PTLvl1Size; Index++) - { - PageTable[L0][Index] = PteUnmapped; - } - } - - PageTable[L0][L1] = TgtAddr; - } - - public bool IsRegionModified(long PA, long Size, NvGpuBufferType BufferType) - { - return Cache.IsRegionModified(Memory, BufferType, PA, Size); - } - - public IntPtr GetHostAddress(long Position, long Size) - { - return Memory.GetHostAddress(GetPhysicalAddress(Position), Size); - } - - public byte ReadByte(long Position) - { - Position = GetPhysicalAddress(Position); - - return Memory.ReadByte(Position); - } - - public ushort ReadUInt16(long Position) - { - Position = GetPhysicalAddress(Position); - - return Memory.ReadUInt16(Position); - } - - public uint ReadUInt32(long Position) - { - Position = GetPhysicalAddress(Position); - - return Memory.ReadUInt32(Position); - } - - public ulong ReadUInt64(long Position) - { - Position = GetPhysicalAddress(Position); - - return Memory.ReadUInt64(Position); - } - - public sbyte ReadSByte(long Position) - { - Position = GetPhysicalAddress(Position); - - return Memory.ReadSByte(Position); - } - - public short ReadInt16(long Position) - { - Position = GetPhysicalAddress(Position); - - return Memory.ReadInt16(Position); - } - - public int ReadInt32(long Position) - { - Position = GetPhysicalAddress(Position); - - return Memory.ReadInt32(Position); - } - - public long ReadInt64(long Position) - { - Position = GetPhysicalAddress(Position); - - return Memory.ReadInt64(Position); - } - - public byte[] ReadBytes(long Position, long Size) - { - Position = GetPhysicalAddress(Position); - - return Memory.ReadBytes(Position, Size); - } - - public void WriteByte(long Position, byte Value) - { - Position = GetPhysicalAddress(Position); - - Memory.WriteByte(Position, Value); - } - - public void WriteUInt16(long Position, ushort Value) - { - Position = GetPhysicalAddress(Position); - - Memory.WriteUInt16(Position, Value); - } - - public void WriteUInt32(long Position, uint Value) - { - Position = GetPhysicalAddress(Position); - - Memory.WriteUInt32(Position, Value); - } - - public void WriteUInt64(long Position, ulong Value) - { - Position = GetPhysicalAddress(Position); - - Memory.WriteUInt64(Position, Value); - } - - public void WriteSByte(long Position, sbyte Value) - { - Position = GetPhysicalAddress(Position); - - Memory.WriteSByte(Position, Value); - } - - public void WriteInt16(long Position, short Value) - { - Position = GetPhysicalAddress(Position); - - Memory.WriteInt16(Position, Value); - } - - public void WriteInt32(long Position, int Value) - { - Position = GetPhysicalAddress(Position); - - Memory.WriteInt32(Position, Value); - } - - public void WriteInt64(long Position, long Value) - { - Position = GetPhysicalAddress(Position); - - Memory.WriteInt64(Position, Value); - } - - public void WriteBytes(long Position, byte[] Data) - { - Position = GetPhysicalAddress(Position); - - Memory.WriteBytes(Position, Data); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs deleted file mode 100644 index b3f253b3..00000000 --- a/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs +++ /dev/null @@ -1,308 +0,0 @@ -using ChocolArm64.Memory; -using Ryujinx.HLE.Memory; -using System; -using System.Collections.Generic; - -namespace Ryujinx.HLE.Gpu.Memory -{ - class NvGpuVmmCache - { - private const int MaxCpCount = 10000; - private const int MaxCpTimeDelta = 60000; - - private class CachedPage - { - private struct Range - { - public long Start; - public long End; - - public Range(long Start, long End) - { - this.Start = Start; - this.End = End; - } - } - - private List<Range>[] Regions; - - private HashSet<long> ResidencyKeys; - - public LinkedListNode<long> Node { get; set; } - - public int Timestamp { get; private set; } - - public CachedPage() - { - Regions = new List<Range>[(int)NvGpuBufferType.Count]; - - for (int Index = 0; Index < Regions.Length; Index++) - { - Regions[Index] = new List<Range>(); - } - - ResidencyKeys = new HashSet<long>(); - } - - public void AddResidency(long Key) - { - ResidencyKeys.Add(Key); - } - - public void RemoveResidency(HashSet<long>[] Residency, long PageSize) - { - for (int i = 0; i < (int)NvGpuBufferType.Count; i++) - { - foreach (Range Region in Regions[i]) - { - foreach (long Key in ResidencyKeys) - { - Residency[Region.Start / PageSize].Remove(Key); - } - } - } - } - - public bool AddRange(long Start, long End, NvGpuBufferType BufferType) - { - List<Range> BtRegions = Regions[(int)BufferType]; - - for (int Index = 0; Index < BtRegions.Count; Index++) - { - Range Rg = BtRegions[Index]; - - if (Start >= Rg.Start && End <= Rg.End) - { - return false; - } - - if (Start <= Rg.End && Rg.Start <= End) - { - long MinStart = Math.Min(Rg.Start, Start); - long MaxEnd = Math.Max(Rg.End, End); - - BtRegions[Index] = new Range(MinStart, MaxEnd); - - Timestamp = Environment.TickCount; - - return true; - } - } - - 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; - - private LinkedList<long> SortedCache; - - private HashSet<long>[] Residency; - - private long ResidencyPageSize; - - private int CpCount; - - public NvGpuVmmCache() - { - Cache = new Dictionary<long, CachedPage>(); - - SortedCache = new LinkedList<long>(); - } - - public bool IsRegionModified(AMemory Memory, NvGpuBufferType BufferType, long PA, long Size) - { - (bool[] Modified, long ModifiedCount) = Memory.IsRegionModified(PA, Size); - - PA = Memory.GetPhysicalAddress(PA); - - ClearCachedPagesIfNeeded(); - - long PageSize = AMemory.PageSize; - - EnsureResidencyInitialized(PageSize); - - bool HasResidents = AddResidency(PA, Size); - - if (!HasResidents && ModifiedCount == 0) - { - return false; - } - - long Mask = PageSize - 1; - - long ResidencyKey = PA; - - long PAEnd = PA + Size; - - bool RegMod = false; - - int Index = 0; - - while (PA < PAEnd) - { - long Key = PA & ~AMemory.PageMask; - - long PAPgEnd = Math.Min((PA + AMemory.PageSize) & ~AMemory.PageMask, PAEnd); - - bool IsCached = Cache.TryGetValue(Key, out CachedPage Cp); - - if (IsCached) - { - CpCount -= Cp.GetTotalCount(); - - SortedCache.Remove(Cp.Node); - } - else - { - Cp = new CachedPage(); - - Cache.Add(Key, Cp); - } - - if (Modified[Index++] && IsCached) - { - Cp = new CachedPage(); - - Cache[Key] = Cp; - } - - Cp.AddResidency(ResidencyKey); - - Cp.Node = SortedCache.AddLast(Key); - - RegMod |= Cp.AddRange(PA, PAPgEnd, BufferType); - - CpCount += Cp.GetTotalCount(); - - PA = PAPgEnd; - } - - return RegMod; - } - - private bool AddResidency(long PA, long Size) - { - long PageSize = ResidencyPageSize; - - long Mask = PageSize - 1; - - long Key = PA; - - bool ResidentFound = false; - - for (long Cursor = PA & ~Mask; Cursor < ((PA + Size + PageSize - 1) & ~Mask); Cursor += PageSize) - { - long PageIndex = Cursor / PageSize; - - Residency[PageIndex].Add(Key); - - if (Residency[PageIndex].Count > 1) - { - ResidentFound = true; - } - } - - return ResidentFound; - } - - private void EnsureResidencyInitialized(long PageSize) - { - if (Residency == null) - { - Residency = new HashSet<long>[DeviceMemory.RamSize / PageSize]; - - for (int i = 0; i < Residency.Length; i++) - { - Residency[i] = new HashSet<long>(); - } - - ResidencyPageSize = PageSize; - } - else - { - if (ResidencyPageSize != PageSize) - { - throw new InvalidOperationException("Tried to change residency page size"); - } - } - } - - private void ClearCachedPagesIfNeeded() - { - if (CpCount <= MaxCpCount) - { - return; - } - - int Timestamp = Environment.TickCount; - - int TimeDelta; - - do - { - if (!TryPopOldestCachedPageKey(Timestamp, out long Key)) - { - break; - } - - CachedPage Cp = Cache[Key]; - - Cp.RemoveResidency(Residency, ResidencyPageSize); - - Cache.Remove(Key); - - CpCount -= Cp.GetTotalCount(); - - TimeDelta = RingDelta(Cp.Timestamp, Timestamp); - } - while (CpCount > (MaxCpCount >> 1) || (uint)TimeDelta > (uint)MaxCpTimeDelta); - } - - private bool TryPopOldestCachedPageKey(int Timestamp, out long Key) - { - LinkedListNode<long> Node = SortedCache.First; - - if (Node == null) - { - Key = 0; - - return false; - } - - SortedCache.Remove(Node); - - Key = Node.Value; - - return true; - } - - private int RingDelta(int Old, int New) - { - if ((uint)New < (uint)Old) - { - return New + (~Old + 1); - } - else - { - return New - Old; - } - } - } -}
\ No newline at end of file |
