forked from Mirror/Ryujinx
Merge pull request #2 from gdkchan/direct_memory
Removed parts of the MMU functionality to use memory directly (faster…
This commit is contained in:
commit
ae91da5b60
10 changed files with 89 additions and 188 deletions
16
GLScreen.cs
16
GLScreen.cs
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -159,5 +159,12 @@ namespace Ryujinx.OsHle
|
|||
|
||||
Handles.Delete(Handle);
|
||||
}
|
||||
|
||||
public long GetVirtHidOffset()
|
||||
{
|
||||
HSharedMem HidSharedMem = Handles.GetData<HSharedMem>(HidHandle);
|
||||
|
||||
return HidSharedMem.VirtPos;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Reference in a new issue