aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/Gpu
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-08-15 15:59:51 -0300
committerGitHub <noreply@github.com>2018-08-15 15:59:51 -0300
commitc393cdf8e3775bc95850e4d8c8e4c446b286d3b4 (patch)
tree25035a244741d2daf3f7d6be8b23153ff061ea15 /Ryujinx.HLE/Gpu
parent76d95dee05e3c51c18e1799f54cc407e0f633b4e (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.cs35
-rw-r--r--Ryujinx.HLE/Gpu/Memory/NvGpuVmm.cs47
-rw-r--r--Ryujinx.HLE/Gpu/Memory/NvGpuVmmCache.cs14
-rw-r--r--Ryujinx.HLE/Gpu/Texture/TextureReader.cs22
-rw-r--r--Ryujinx.HLE/Gpu/Texture/TextureWriter.cs2
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;
}