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.Graphics;
using OpenTK.Graphics.OpenGL;
using Ryujinx.OsHle;
using System;
namespace Ryujinx
@ -60,12 +61,14 @@ namespace Ryujinx
unsafe void UploadBitmap()
{
if (Renderer.FrameBufferPtr == 0)
int FbSize = Width * Height * 4;
if (Renderer.FrameBufferPtr == 0 || Renderer.FrameBufferPtr + FbSize > uint.MaxValue)
{
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++)
{
@ -275,7 +278,14 @@ void main(void) {
{
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;

View file

@ -361,15 +361,7 @@ namespace ChocolArm64.Instruction
{
AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
Context.EmitLdvec(Op.Rn);
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);
EmitVectorImmBinaryZx(Context, OpCodes.Shl, Op.Imm - (8 << Op.Size));
}
public static void Smax_V(AILEmitterCtx Context) => EmitVectorSmax(Context);
@ -396,15 +388,7 @@ namespace ChocolArm64.Instruction
{
AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
Context.EmitLdvec(Op.Rn);
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);
EmitVectorImmBinarySx(Context, OpCodes.Shr, (8 << (Op.Size + 1)) - Op.Imm);
}
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)
{
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
@ -936,7 +969,7 @@ namespace ChocolArm64.Instruction
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.EmitLdc_I4(Index);

View file

@ -790,32 +790,6 @@ namespace ChocolArm64.Instruction
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)
{
return Sshll_(Vector, Shift, Size, false);
@ -843,32 +817,6 @@ namespace ChocolArm64.Instruction
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)
{
return Tbl(Vector, 8, Tb0);

View file

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

View file

@ -6,8 +6,8 @@ namespace ChocolArm64.Memory
{
public class AMemoryMgr
{
public const long AddrSize = 1L << 36;
public const long RamSize = 2L * 1024 * 1024 * 1024;
public const long AddrSize = RamSize;
public const long RamSize = 4L * 1024 * 1024 * 1024;
private const int PTLvl0Bits = 11;
private const int PTLvl1Bits = 13;
@ -117,7 +117,7 @@ namespace ChocolArm64.Memory
while ((ulong)Size < (ulong)HeapSize)
{
Allocator.Free(GetPhys(Position, AMemoryPerm.None));
Allocator.Free(Position);
Position += PageSize;
}
@ -254,38 +254,6 @@ namespace ChocolArm64.Memory
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)]
private bool HasPTEntry(long Position)
{

View file

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

View file

@ -9,15 +9,13 @@ namespace Ryujinx.OsHle.Handles
public long Position { 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.Perm = Perm;
this.Position = Position;
this.Size = Size;
this.PhysPos = PhysPos;
}
}
}

View file

@ -159,5 +159,12 @@ namespace Ryujinx.OsHle
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);
Context.Ns.Gpu.Renderer.FrameBufferPtr =
Context.Memory.Manager.GetPhys(NvMap.Address, AMemoryPerm.Read);
Context.Ns.Gpu.Renderer.FrameBufferPtr = NvMap.Address;
}
return MakeReplyParcel(Context, 0);

View file

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