diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-08-15 15:59:51 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-08-15 15:59:51 -0300 |
| commit | c393cdf8e3775bc95850e4d8c8e4c446b286d3b4 (patch) | |
| tree | 25035a244741d2daf3f7d6be8b23153ff061ea15 /Ryujinx.HLE/Gpu | |
| parent | 76d95dee05e3c51c18e1799f54cc407e0f633b4e (diff) | |
More flexible memory manager (#307)
* Keep track mapped buffers with fixed offsets
* Started rewriting the memory manager
* Initial support for MapPhysicalMemory and UnmapPhysicalMemory, other tweaks
* MapPhysicalMemory/UnmapPhysicalMemory support, other tweaks
* Rebased
* Optimize the map/unmap physical memory svcs
* Integrate shared font support
* Fix address space reserve alignment
* Some fixes related to gpu memory mapping
* Some cleanup
* Only try uploading const buffers that are really used
* Check if memory region is contiguous
* Rebased
* Add missing count increment on IsRegionModified
* Check for reads/writes outside of the address space, optimize translation with a tail call
Diffstat (limited to 'Ryujinx.HLE/Gpu')
| -rw-r--r-- | Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs | 35 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs | 47 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs | 14 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Texture/TextureReader.cs | 22 | ||||
| -rw-r--r-- | Ryujinx.HLE/Gpu/Texture/TextureWriter.cs | 2 |
5 files changed, 47 insertions, 73 deletions
diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs index cb1514b5..6f601244 100644 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs @@ -109,7 +109,7 @@ namespace Ryujinx.HLE.Gpu.Engines Gpu.Renderer.Shader.BindProgram(); UploadTextures(Vmm, State, Keys); - UploadConstBuffers(Vmm, State); + UploadConstBuffers(Vmm, State, Keys); UploadVertexArrays(Vmm, State); DispatchRender(Vmm, State); @@ -426,6 +426,12 @@ namespace Ryujinx.HLE.Gpu.Engines Key = Vmm.GetPhysicalAddress(Key); + if (Key == -1) + { + //FIXME: Should'nt ignore invalid addresses. + return; + } + if (IsFrameBufferPosition(Key)) { //This texture is a frame buffer texture, @@ -465,24 +471,29 @@ namespace Ryujinx.HLE.Gpu.Engines Gpu.Renderer.Texture.SetSampler(Sampler); } - private void UploadConstBuffers(NvGpuVmm Vmm, GalPipelineState State) + private void UploadConstBuffers(NvGpuVmm Vmm, GalPipelineState State, long[] Keys) { - for (int Stage = 0; Stage < State.ConstBufferKeys.Length; Stage++) + for (int Stage = 0; Stage < Keys.Length; Stage++) { - for (int Index = 0; Index < State.ConstBufferKeys[Stage].Length; Index++) + foreach (ShaderDeclInfo DeclInfo in Gpu.Renderer.Shader.GetConstBufferUsage(Keys[Stage])) { - ConstBuffer Cb = ConstBuffers[Stage][Index]; + ConstBuffer Cb = ConstBuffers[Stage][DeclInfo.Cbuf]; - long Key = Cb.Position; + if (!Cb.Enabled) + { + continue; + } - if (Cb.Enabled && QueryKeyUpload(Vmm, Key, Cb.Size, NvGpuBufferType.ConstBuffer)) + long Key = Vmm.GetPhysicalAddress(Cb.Position); + + if (QueryKeyUpload(Vmm, Key, Cb.Size, NvGpuBufferType.ConstBuffer)) { - IntPtr Source = Vmm.GetHostAddress(Key, Cb.Size); + IntPtr Source = Vmm.GetHostAddress(Cb.Position, Cb.Size); Gpu.Renderer.Buffer.SetData(Key, Cb.Size, Source); } - State.ConstBufferKeys[Stage][Index] = Key; + State.ConstBufferKeys[Stage][DeclInfo.Cbuf] = Key; } } } @@ -668,11 +679,13 @@ namespace Ryujinx.HLE.Gpu.Engines long Position = MakeInt64From2xInt32(NvGpuEngine3dReg.ConstBufferAddress); + long CbKey = Vmm.GetPhysicalAddress(Position); + int Size = ReadRegister(NvGpuEngine3dReg.ConstBufferSize); - if (!Gpu.Renderer.Buffer.IsCached(Position, Size)) + if (!Gpu.Renderer.Buffer.IsCached(CbKey, Size)) { - Gpu.Renderer.Buffer.Create(Position, Size); + Gpu.Renderer.Buffer.Create(CbKey, Size); } ConstBuffer Cb = ConstBuffers[Stage][Index]; diff --git a/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs index 7b23e49f..e7e18064 100644 --- a/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs +++ b/Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs @@ -1,7 +1,6 @@ using ChocolArm64.Memory; using Ryujinx.Graphics.Gal; using System; -using System.Collections.Concurrent; namespace Ryujinx.HLE.Gpu.Memory { @@ -26,18 +25,6 @@ namespace Ryujinx.HLE.Gpu.Memory public AMemory Memory { get; private set; } - private struct MappedMemory - { - public long Size; - - public MappedMemory(long Size) - { - this.Size = Size; - } - } - - private ConcurrentDictionary<long, MappedMemory> Maps; - private NvGpuVmmCache Cache; private const long PteUnmapped = -1; @@ -49,8 +36,6 @@ namespace Ryujinx.HLE.Gpu.Memory { this.Memory = Memory; - Maps = new ConcurrentDictionary<long, MappedMemory>(); - Cache = new NvGpuVmmCache(); PageTable = new long[PTLvl0Size][]; @@ -62,14 +47,6 @@ namespace Ryujinx.HLE.Gpu.Memory { for (long Offset = 0; Offset < Size; Offset += PageSize) { - if (GetPte(VA + Offset) != PteReserved) - { - return Map(PA, Size); - } - } - - for (long Offset = 0; Offset < Size; Offset += PageSize) - { SetPte(VA + Offset, PA + Offset); } } @@ -85,10 +62,6 @@ namespace Ryujinx.HLE.Gpu.Memory if (VA != -1) { - MappedMemory Map = new MappedMemory(Size); - - Maps.AddOrUpdate(VA, Map, (Key, Old) => Map); - for (long Offset = 0; Offset < Size; Offset += PageSize) { SetPte(VA + Offset, PA + Offset); @@ -99,19 +72,7 @@ namespace Ryujinx.HLE.Gpu.Memory } } - public bool Unmap(long VA) - { - if (Maps.TryRemove(VA, out MappedMemory Map)) - { - Free(VA, Map.Size); - - return true; - } - - return false; - } - - public long Reserve(long VA, long Size, long Align) + public long ReserveFixed(long VA, long Size) { lock (PageTable) { @@ -119,7 +80,7 @@ namespace Ryujinx.HLE.Gpu.Memory { if (IsPageInUse(VA + Offset)) { - return Reserve(Size, Align); + return -1; } } @@ -163,7 +124,9 @@ namespace Ryujinx.HLE.Gpu.Memory private long GetFreePosition(long Size, long Align = 1) { - long Position = 0; + //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) diff --git a/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs b/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs index 3c256044..b3f253b3 100644 --- a/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs +++ b/Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs @@ -1,4 +1,5 @@ using ChocolArm64.Memory; +using Ryujinx.HLE.Memory; using System; using System.Collections.Generic; @@ -129,14 +130,11 @@ namespace Ryujinx.HLE.Gpu.Memory { (bool[] Modified, long ModifiedCount) = Memory.IsRegionModified(PA, Size); - if (Modified == null) - { - return true; - } + PA = Memory.GetPhysicalAddress(PA); ClearCachedPagesIfNeeded(); - long PageSize = Memory.GetHostPageSize(); + long PageSize = AMemory.PageSize; EnsureResidencyInitialized(PageSize); @@ -159,9 +157,9 @@ namespace Ryujinx.HLE.Gpu.Memory while (PA < PAEnd) { - long Key = PA & ~Mask; + long Key = PA & ~AMemory.PageMask; - long PAPgEnd = Math.Min((PA + PageSize) & ~Mask, PAEnd); + long PAPgEnd = Math.Min((PA + AMemory.PageSize) & ~AMemory.PageMask, PAEnd); bool IsCached = Cache.TryGetValue(Key, out CachedPage Cp); @@ -228,7 +226,7 @@ namespace Ryujinx.HLE.Gpu.Memory { if (Residency == null) { - Residency = new HashSet<long>[AMemoryMgr.RamSize / PageSize]; + Residency = new HashSet<long>[DeviceMemory.RamSize / PageSize]; for (int i = 0; i < Residency.Length; i++) { diff --git a/Ryujinx.HLE/Gpu/Texture/TextureReader.cs b/Ryujinx.HLE/Gpu/Texture/TextureReader.cs index f8cd6765..0c6103af 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureReader.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureReader.cs @@ -72,7 +72,7 @@ namespace Ryujinx.HLE.Gpu.Texture { long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - byte Pixel = CpuMem.ReadByteUnchecked(Position + Offset); + byte Pixel = CpuMem.ReadByte(Position + Offset); *(BuffPtr + OutOffs) = Pixel; @@ -105,7 +105,7 @@ namespace Ryujinx.HLE.Gpu.Texture { long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - uint Pixel = (uint)CpuMem.ReadInt16Unchecked(Position + Offset); + uint Pixel = (uint)CpuMem.ReadInt16(Position + Offset); Pixel = (Pixel & 0x001f) << 11 | (Pixel & 0x03e0) << 1 | @@ -143,7 +143,7 @@ namespace Ryujinx.HLE.Gpu.Texture { long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - uint Pixel = (uint)CpuMem.ReadInt16Unchecked(Position + Offset); + uint Pixel = (uint)CpuMem.ReadInt16(Position + Offset); Pixel = (Pixel & 0x001f) << 11 | (Pixel & 0x07e0) | @@ -180,7 +180,7 @@ namespace Ryujinx.HLE.Gpu.Texture { long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - short Pixel = CpuMem.ReadInt16Unchecked(Position + Offset); + short Pixel = CpuMem.ReadInt16(Position + Offset); *(short*)(BuffPtr + OutOffs) = Pixel; @@ -213,7 +213,7 @@ namespace Ryujinx.HLE.Gpu.Texture { long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - int Pixel = CpuMem.ReadInt32Unchecked(Position + Offset); + int Pixel = CpuMem.ReadInt32(Position + Offset); *(int*)(BuffPtr + OutOffs) = Pixel; @@ -246,7 +246,7 @@ namespace Ryujinx.HLE.Gpu.Texture { long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - long Pixel = CpuMem.ReadInt64Unchecked(Position + Offset); + long Pixel = CpuMem.ReadInt64(Position + Offset); *(long*)(BuffPtr + OutOffs) = Pixel; @@ -279,8 +279,8 @@ namespace Ryujinx.HLE.Gpu.Texture { long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - long PxLow = CpuMem.ReadInt64Unchecked(Position + Offset + 0); - long PxHigh = CpuMem.ReadInt64Unchecked(Position + Offset + 8); + long PxLow = CpuMem.ReadInt64(Position + Offset + 0); + long PxHigh = CpuMem.ReadInt64(Position + Offset + 8); *(long*)(BuffPtr + OutOffs + 0) = PxLow; *(long*)(BuffPtr + OutOffs + 8) = PxHigh; @@ -314,7 +314,7 @@ namespace Ryujinx.HLE.Gpu.Texture { long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - long Tile = CpuMem.ReadInt64Unchecked(Position + Offset); + long Tile = CpuMem.ReadInt64(Position + Offset); *(long*)(BuffPtr + OutOffs) = Tile; @@ -347,8 +347,8 @@ namespace Ryujinx.HLE.Gpu.Texture { long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - long Tile0 = CpuMem.ReadInt64Unchecked(Position + Offset + 0); - long Tile1 = CpuMem.ReadInt64Unchecked(Position + Offset + 8); + long Tile0 = CpuMem.ReadInt64(Position + Offset + 0); + long Tile1 = CpuMem.ReadInt64(Position + Offset + 8); *(long*)(BuffPtr + OutOffs + 0) = Tile0; *(long*)(BuffPtr + OutOffs + 8) = Tile1; diff --git a/Ryujinx.HLE/Gpu/Texture/TextureWriter.cs b/Ryujinx.HLE/Gpu/Texture/TextureWriter.cs index a87d4545..113dc6f6 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureWriter.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureWriter.cs @@ -25,7 +25,7 @@ namespace Ryujinx.HLE.Gpu.Texture int Pixel = *(int*)(BuffPtr + InOffs); - CpuMem.WriteInt32Unchecked(Position + Offset, Pixel); + CpuMem.WriteInt32(Position + Offset, Pixel); InOffs += 4; } |
