Merge pull request #2 from gdkchan/direct_memory

Removed parts of the MMU functionality to use memory directly (faster…
This commit is contained in:
gdkchan 2018-02-08 20:20:01 -03:00 committed by GitHub
commit ae91da5b60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 89 additions and 188 deletions

View File

@ -6,6 +6,7 @@ using Gal;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using Ryujinx.OsHle;
using System; using System;
namespace Ryujinx namespace Ryujinx
@ -60,12 +61,14 @@ namespace Ryujinx
unsafe void UploadBitmap() unsafe void UploadBitmap()
{ {
if (Renderer.FrameBufferPtr == 0) int FbSize = Width * Height * 4;
if (Renderer.FrameBufferPtr == 0 || Renderer.FrameBufferPtr + FbSize > uint.MaxValue)
{ {
return; return;
} }
byte* SrcPtr = (byte*)IntPtr.Add(Ns.Ram, (int)Renderer.FrameBufferPtr); byte* SrcPtr = (byte*)Ns.Ram + (uint)Renderer.FrameBufferPtr;
for (int Y = 0; Y < Height; Y++) for (int Y = 0; Y < Height; Y++)
{ {
@ -275,7 +278,14 @@ void main(void) {
{ {
unsafe unsafe
{ {
byte* Ptr = (byte*)IntPtr.Add(Ns.Ram, (int)Ns.Os.HidOffset); long HidOffset = Ns.Os.GetVirtHidOffset();
if (HidOffset == 0 || HidOffset + Horizon.HidSize > uint.MaxValue)
{
return;
}
byte* Ptr = (byte*)Ns.Ram + (uint)HidOffset;
int State = 0; int State = 0;

View File

@ -361,15 +361,7 @@ namespace ChocolArm64.Instruction
{ {
AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
Context.EmitLdvec(Op.Rn); EmitVectorImmBinaryZx(Context, OpCodes.Shl, Op.Imm - (8 << Op.Size));
Context.EmitLdc_I4(Op.Imm - (8 << Op.Size));
Context.EmitLdc_I4(Op.Size);
ASoftFallback.EmitCall(Context,
nameof(ASoftFallback.Shl64),
nameof(ASoftFallback.Shl128));
Context.EmitStvec(Op.Rd);
} }
public static void Smax_V(AILEmitterCtx Context) => EmitVectorSmax(Context); public static void Smax_V(AILEmitterCtx Context) => EmitVectorSmax(Context);
@ -396,15 +388,7 @@ namespace ChocolArm64.Instruction
{ {
AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
Context.EmitLdvec(Op.Rn); EmitVectorImmBinarySx(Context, OpCodes.Shr, (8 << (Op.Size + 1)) - Op.Imm);
Context.EmitLdc_I4((8 << (Op.Size + 1)) - Op.Imm);
Context.EmitLdc_I4(Op.Size);
ASoftFallback.EmitCall(Context,
nameof(ASoftFallback.Sshr64),
nameof(ASoftFallback.Sshr128));
Context.EmitStvec(Op.Rd);
} }
public static void St__V(AILEmitterCtx Context) => EmitSimdMultLdSt(Context, IsLoad: false); public static void St__V(AILEmitterCtx Context) => EmitSimdMultLdSt(Context, IsLoad: false);
@ -881,6 +865,55 @@ namespace ChocolArm64.Instruction
} }
} }
private static void EmitVectorImmBinarySx(AILEmitterCtx Context, OpCode ILOp, long Imm)
{
EmitVectorImmBinarySx(Context, () => Context.Emit(ILOp), Imm);
}
private static void EmitVectorImmBinaryZx(AILEmitterCtx Context, OpCode ILOp, long Imm)
{
EmitVectorImmBinaryZx(Context, () => Context.Emit(ILOp), Imm);
}
private static void EmitVectorImmBinarySx(AILEmitterCtx Context, Action Emit, long Imm)
{
EmitVectorImmBinaryOp(Context, Emit, Imm, true);
}
private static void EmitVectorImmBinaryZx(AILEmitterCtx Context, Action Emit, long Imm)
{
EmitVectorImmBinaryOp(Context, Emit, Imm, false);
}
private static void EmitVectorImmBinaryOp(AILEmitterCtx Context, Action Emit, long Imm, bool Signed)
{
AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
for (int Index = 0; Index < (Bytes >> Op.Size); Index++)
{
Context.EmitLdvec(Op.Rd);
Context.EmitLdc_I4(Index);
Context.EmitLdc_I4(Op.Size);
EmitVectorExtract(Context, Op.Rn, Index, Signed);
Context.EmitLdc_I8(Imm);
Emit();
ASoftFallback.EmitCall(Context, nameof(ASoftFallback.InsertVec));
Context.EmitStvec(Op.Rd);
}
if (Op.RegisterSize == ARegisterSize.SIMD64)
{
EmitVectorZeroUpper(Context, Op.Rd);
}
}
private static void EmitVectorCmp(AILEmitterCtx Context, OpCode ILOp) private static void EmitVectorCmp(AILEmitterCtx Context, OpCode ILOp)
{ {
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
@ -936,7 +969,7 @@ namespace ChocolArm64.Instruction
private static void EmitVectorExtract(AILEmitterCtx Context, int Reg, int Index, bool Signed) private static void EmitVectorExtract(AILEmitterCtx Context, int Reg, int Index, bool Signed)
{ {
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp;
Context.EmitLdvec(Reg); Context.EmitLdvec(Reg);
Context.EmitLdc_I4(Index); Context.EmitLdc_I4(Index);

View File

@ -790,32 +790,6 @@ namespace ChocolArm64.Instruction
return Res; return Res;
} }
public static AVec Shl64(AVec Vector, int Shift, int Size)
{
return Shl(Vector, Shift, Size, 8);
}
public static AVec Shl128(AVec Vector, int Shift, int Size)
{
return Shl(Vector, Shift, Size, 16);
}
private static AVec Shl(AVec Vector, int Shift, int Size, int Bytes)
{
AVec Res = new AVec();
int Elems = Bytes >> Size;
for (int Index = 0; Index < Elems; Index++)
{
ulong Value = ExtractVec(Vector, Index, Size);
Res = InsertVec(Res, Index, Size, Value << Shift);
}
return Res;
}
public static AVec Sshll(AVec Vector, int Shift, int Size) public static AVec Sshll(AVec Vector, int Shift, int Size)
{ {
return Sshll_(Vector, Shift, Size, false); return Sshll_(Vector, Shift, Size, false);
@ -843,32 +817,6 @@ namespace ChocolArm64.Instruction
return Res; return Res;
} }
public static AVec Sshr64(AVec Vector, int Shift, int Size)
{
return Sshr(Vector, Shift, Size, 8);
}
public static AVec Sshr128(AVec Vector, int Shift, int Size)
{
return Sshr(Vector, Shift, Size, 16);
}
private static AVec Sshr(AVec Vector, int Shift, int Size, int Bytes)
{
AVec Res = new AVec();
int Elems = Bytes >> Size;
for (int Index = 0; Index < Elems; Index++)
{
long Value = ExtractSVec(Vector, Index, Size);
Res = InsertSVec(Res, Index, Size, Value >> Shift);
}
return Res;
}
public static AVec Tbl1_V64(AVec Vector, AVec Tb0) public static AVec Tbl1_V64(AVec Vector, AVec Tb0)
{ {
return Tbl(Vector, 8, Tb0); return Tbl(Vector, 8, Tb0);

View File

@ -119,55 +119,22 @@ namespace ChocolArm64.Memory
public byte ReadByte(long Position) public byte ReadByte(long Position)
{ {
return *((byte*)(RamPtr + Manager.GetPhys(Position, AMemoryPerm.Read))); return *((byte*)(RamPtr + (uint)Position));
} }
public ushort ReadUInt16(long Position) public ushort ReadUInt16(long Position)
{ {
long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Read); return *((ushort*)(RamPtr + (uint)Position));
if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 2))
{
return *((ushort*)(RamPtr + PhysPos));
}
else
{
return (ushort)(
ReadByte(Position + 0) << 0 |
ReadByte(Position + 1) << 8);
}
} }
public uint ReadUInt32(long Position) public uint ReadUInt32(long Position)
{ {
long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Read); return *((uint*)(RamPtr + (uint)Position));
if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 4))
{
return *((uint*)(RamPtr + PhysPos));
}
else
{
return (uint)(
ReadUInt16(Position + 0) << 0 |
ReadUInt16(Position + 2) << 16);
}
} }
public ulong ReadUInt64(long Position) public ulong ReadUInt64(long Position)
{ {
long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Read); return *((ulong*)(RamPtr + (uint)Position));
if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 8))
{
return *((ulong*)(RamPtr + PhysPos));
}
else
{
return
(ulong)ReadUInt32(Position + 0) << 0 |
(ulong)ReadUInt32(Position + 4) << 32;
}
} }
public AVec ReadVector128(long Position) public AVec ReadVector128(long Position)
@ -186,52 +153,22 @@ namespace ChocolArm64.Memory
public void WriteByte(long Position, byte Value) public void WriteByte(long Position, byte Value)
{ {
*((byte*)(RamPtr + Manager.GetPhys(Position, AMemoryPerm.Write))) = Value; *((byte*)(RamPtr + (uint)Position)) = Value;
} }
public void WriteUInt16(long Position, ushort Value) public void WriteUInt16(long Position, ushort Value)
{ {
long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Write); *((ushort*)(RamPtr + (uint)Position)) = Value;
if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 2))
{
*((ushort*)(RamPtr + PhysPos)) = Value;
}
else
{
WriteByte(Position + 0, (byte)(Value >> 0));
WriteByte(Position + 1, (byte)(Value >> 8));
}
} }
public void WriteUInt32(long Position, uint Value) public void WriteUInt32(long Position, uint Value)
{ {
long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Write); *((uint*)(RamPtr + (uint)Position)) = Value;
if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 4))
{
*((uint*)(RamPtr + PhysPos)) = Value;
}
else
{
WriteUInt16(Position + 0, (ushort)(Value >> 0));
WriteUInt16(Position + 2, (ushort)(Value >> 16));
}
} }
public void WriteUInt64(long Position, ulong Value) public void WriteUInt64(long Position, ulong Value)
{ {
long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Write); *((ulong*)(RamPtr + (uint)Position)) = Value;
if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 8))
{
*((ulong*)(RamPtr + PhysPos)) = Value;
}
else
{
WriteUInt32(Position + 0, (uint)(Value >> 0));
WriteUInt32(Position + 4, (uint)(Value >> 32));
}
} }
public void WriteVector128(long Position, AVec Value) public void WriteVector128(long Position, AVec Value)

View File

@ -6,8 +6,8 @@ namespace ChocolArm64.Memory
{ {
public class AMemoryMgr public class AMemoryMgr
{ {
public const long AddrSize = 1L << 36; public const long AddrSize = RamSize;
public const long RamSize = 2L * 1024 * 1024 * 1024; public const long RamSize = 4L * 1024 * 1024 * 1024;
private const int PTLvl0Bits = 11; private const int PTLvl0Bits = 11;
private const int PTLvl1Bits = 13; private const int PTLvl1Bits = 13;
@ -117,7 +117,7 @@ namespace ChocolArm64.Memory
while ((ulong)Size < (ulong)HeapSize) while ((ulong)Size < (ulong)HeapSize)
{ {
Allocator.Free(GetPhys(Position, AMemoryPerm.None)); Allocator.Free(Position);
Position += PageSize; Position += PageSize;
} }
@ -254,38 +254,6 @@ namespace ChocolArm64.Memory
return new AMemoryMapInfo(Start, Size, BaseEntry.Type, BaseEntry.Perm); return new AMemoryMapInfo(Start, Size, BaseEntry.Type, BaseEntry.Perm);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public long GetPhys(long Position, AMemoryPerm Perm)
{
if (!HasPTEntry(Position))
{
if (Position < 0x08000000)
{
Console.WriteLine($"HACK: Ignoring bad access at {Position:x16}");
return 0;
}
throw new VmmPageFaultException(Position);
}
PTEntry Entry = GetPTEntry(Position);
long AbsPos = Entry.Position + (Position & PageMask);
if (Entry.Map == PTMap.Mirror)
{
return GetPhys(AbsPos, Perm);
}
if (Entry.Map == PTMap.Unmapped)
{
throw new VmmPageFaultException(Position);
}
return AbsPos;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool HasPTEntry(long Position) private bool HasPTEntry(long Position)
{ {

View File

@ -3,6 +3,7 @@ namespace Ryujinx.OsHle.Handles
class HSharedMem class HSharedMem
{ {
public long PhysPos { get; private set; } public long PhysPos { get; private set; }
public long VirtPos { get; set; }
public HSharedMem(long PhysPos) public HSharedMem(long PhysPos)
{ {

View File

@ -9,15 +9,13 @@ namespace Ryujinx.OsHle.Handles
public long Position { get; private set; } public long Position { get; private set; }
public long Size { get; private set; } public long Size { get; private set; }
public long PhysPos { get; private set; }
public HTransferMem(AMemory Memory, AMemoryPerm Perm, long Position, long Size, long PhysPos) public HTransferMem(AMemory Memory, AMemoryPerm Perm, long Position, long Size)
{ {
this.Memory = Memory; this.Memory = Memory;
this.Perm = Perm; this.Perm = Perm;
this.Position = Position; this.Position = Position;
this.Size = Size; this.Size = Size;
this.PhysPos = PhysPos;
} }
} }
} }

View File

@ -159,5 +159,12 @@ namespace Ryujinx.OsHle
Handles.Delete(Handle); Handles.Delete(Handle);
} }
public long GetVirtHidOffset()
{
HSharedMem HidSharedMem = Handles.GetData<HSharedMem>(HidHandle);
return HidSharedMem.VirtPos;
}
} }
} }

View File

@ -155,8 +155,7 @@ namespace Ryujinx.OsHle.Objects
HNvMap NvMap = Context.Ns.Os.Handles.GetData<HNvMap>(Handle); HNvMap NvMap = Context.Ns.Os.Handles.GetData<HNvMap>(Handle);
Context.Ns.Gpu.Renderer.FrameBufferPtr = Context.Ns.Gpu.Renderer.FrameBufferPtr = NvMap.Address;
Context.Memory.Manager.GetPhys(NvMap.Address, AMemoryPerm.Read);
} }
return MakeReplyParcel(Context, 0); return MakeReplyParcel(Context, 0);

View File

@ -77,6 +77,8 @@ namespace Ryujinx.OsHle.Svc
long Src = Position; long Src = Position;
long Dst = HndData.PhysPos; long Dst = HndData.PhysPos;
HndData.VirtPos = Src;
if (Memory.Manager.MapPhys(Src, Dst, Size, if (Memory.Manager.MapPhys(Src, Dst, Size,
(int)MemoryType.SharedMemory, (AMemoryPerm)Perm)) (int)MemoryType.SharedMemory, (AMemoryPerm)Perm))
{ {
@ -113,9 +115,7 @@ namespace Ryujinx.OsHle.Svc
Memory.Manager.Reprotect(Position, Size, (AMemoryPerm)Perm); Memory.Manager.Reprotect(Position, Size, (AMemoryPerm)Perm);
long PhysPos = Memory.Manager.GetPhys(Position, AMemoryPerm.None); HTransferMem HndData = new HTransferMem(Memory, MapInfo.Perm, Position, Size);
HTransferMem HndData = new HTransferMem(Memory, MapInfo.Perm, Position, Size, PhysPos);
int Handle = Ns.Os.Handles.GenerateId(HndData); int Handle = Ns.Os.Handles.GenerateId(HndData);