mirror of
https://git.743378673.xyz/MeloNX/MeloNX.git
synced 2025-08-03 08:57:10 +02:00
Allow more than one process, free resources on process dispose, implement SvcExitThread
This commit is contained in:
parent
3aaa4717b6
commit
7a27990faa
46 changed files with 926 additions and 598 deletions
|
@ -139,7 +139,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud
|
|||
|
||||
public long RegisterBufferEvent(ServiceCtx Context)
|
||||
{
|
||||
int Handle = Context.Ns.Os.Handles.GenerateId(new HEvent());
|
||||
int Handle = Context.Process.HandleTable.OpenHandle(new HEvent());
|
||||
|
||||
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud
|
|||
|
||||
public long QuerySystemEvent(ServiceCtx Context)
|
||||
{
|
||||
int Handle = Context.Ns.Os.Handles.GenerateId(new HEvent());
|
||||
int Handle = Context.Process.HandleTable.OpenHandle(new HEvent());
|
||||
|
||||
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
|
||||
|
||||
|
|
|
@ -10,21 +10,23 @@ namespace Ryujinx.Core.OsHle.IpcServices.Hid
|
|||
|
||||
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
|
||||
|
||||
private HSharedMem Handle;
|
||||
private HSharedMem HidSharedMem;
|
||||
|
||||
public IAppletResource(HSharedMem Handle)
|
||||
public IAppletResource(HSharedMem HidSharedMem)
|
||||
{
|
||||
m_Commands = new Dictionary<int, ServiceProcessRequest>()
|
||||
{
|
||||
{ 0, GetSharedMemoryHandle }
|
||||
};
|
||||
|
||||
this.Handle = Handle;
|
||||
this.HidSharedMem = HidSharedMem;
|
||||
}
|
||||
|
||||
public static long GetSharedMemoryHandle(ServiceCtx Context)
|
||||
public long GetSharedMemoryHandle(ServiceCtx Context)
|
||||
{
|
||||
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Context.Ns.Os.HidHandle);
|
||||
int Handle = Context.Process.HandleTable.OpenHandle(HidSharedMem);
|
||||
|
||||
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
using Ryujinx.Core.OsHle.Handles;
|
||||
using Ryujinx.Core.OsHle.Ipc;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
@ -32,9 +31,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Hid
|
|||
|
||||
public long CreateAppletResource(ServiceCtx Context)
|
||||
{
|
||||
HSharedMem HidHndData = Context.Ns.Os.Handles.GetData<HSharedMem>(Context.Ns.Os.HidHandle);
|
||||
|
||||
MakeObject(Context, new IAppletResource(HidHndData));
|
||||
MakeObject(Context, new IAppletResource(Context.Ns.Os.HidSharedMem));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
12
Ryujinx.Core/OsHle/Services/Nv/NvFd.cs
Normal file
12
Ryujinx.Core/OsHle/Services/Nv/NvFd.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
{
|
||||
class NvFd
|
||||
{
|
||||
public string Name { get; private set; }
|
||||
|
||||
public NvFd(string Name)
|
||||
{
|
||||
this.Name = Name;
|
||||
}
|
||||
}
|
||||
}
|
12
Ryujinx.Core/OsHle/Services/Nv/NvMap.cs
Normal file
12
Ryujinx.Core/OsHle/Services/Nv/NvMap.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
{
|
||||
class NvMap
|
||||
{
|
||||
public int Handle;
|
||||
public int Id;
|
||||
public int Size;
|
||||
public int Align;
|
||||
public int Kind;
|
||||
public long Address;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using ChocolArm64.Memory;
|
||||
using Ryujinx.Core.OsHle.Handles;
|
||||
using Ryujinx.Core.OsHle.Ipc;
|
||||
using Ryujinx.Core.OsHle.Utilities;
|
||||
using Ryujinx.Graphics.Gpu;
|
||||
|
@ -12,41 +11,17 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
{
|
||||
private delegate long ServiceProcessIoctl(ServiceCtx Context);
|
||||
|
||||
private static Dictionary<(string, int), ServiceProcessIoctl> IoctlCmds =
|
||||
new Dictionary<(string, int), ServiceProcessIoctl>()
|
||||
{
|
||||
{ ("/dev/nvhost-as-gpu", 0x4101), NvGpuAsIoctlBindChannel },
|
||||
{ ("/dev/nvhost-as-gpu", 0x4102), NvGpuAsIoctlAllocSpace },
|
||||
{ ("/dev/nvhost-as-gpu", 0x4106), NvGpuAsIoctlMapBufferEx },
|
||||
{ ("/dev/nvhost-as-gpu", 0x4108), NvGpuAsIoctlGetVaRegions },
|
||||
{ ("/dev/nvhost-as-gpu", 0x4109), NvGpuAsIoctlInitializeEx },
|
||||
{ ("/dev/nvhost-ctrl", 0x001b), NvHostIoctlCtrlGetConfig },
|
||||
{ ("/dev/nvhost-ctrl", 0x001d), NvHostIoctlCtrlEventWait },
|
||||
{ ("/dev/nvhost-ctrl-gpu", 0x4701), NvGpuIoctlZcullGetCtxSize },
|
||||
{ ("/dev/nvhost-ctrl-gpu", 0x4702), NvGpuIoctlZcullGetInfo },
|
||||
{ ("/dev/nvhost-ctrl-gpu", 0x4705), NvGpuIoctlGetCharacteristics },
|
||||
{ ("/dev/nvhost-ctrl-gpu", 0x4706), NvGpuIoctlGetTpcMasks },
|
||||
{ ("/dev/nvhost-ctrl-gpu", 0x4714), NvGpuIoctlZbcGetActiveSlotMask },
|
||||
{ ("/dev/nvhost-gpu", 0x4714), NvMapIoctlChannelSetUserData },
|
||||
{ ("/dev/nvhost-gpu", 0x4801), NvMapIoctlChannelSetNvMap },
|
||||
{ ("/dev/nvhost-gpu", 0x4808), NvMapIoctlChannelSubmitGpFifo },
|
||||
{ ("/dev/nvhost-gpu", 0x4809), NvMapIoctlChannelAllocObjCtx },
|
||||
{ ("/dev/nvhost-gpu", 0x480b), NvMapIoctlChannelZcullBind },
|
||||
{ ("/dev/nvhost-gpu", 0x480c), NvMapIoctlChannelSetErrorNotifier },
|
||||
{ ("/dev/nvhost-gpu", 0x480d), NvMapIoctlChannelSetPriority },
|
||||
{ ("/dev/nvhost-gpu", 0x481a), NvMapIoctlChannelAllocGpFifoEx2 },
|
||||
{ ("/dev/nvmap", 0x0101), NvMapIocCreate },
|
||||
{ ("/dev/nvmap", 0x0103), NvMapIocFromId },
|
||||
{ ("/dev/nvmap", 0x0104), NvMapIocAlloc },
|
||||
{ ("/dev/nvmap", 0x0105), NvMapIocFree },
|
||||
{ ("/dev/nvmap", 0x0109), NvMapIocParam },
|
||||
{ ("/dev/nvmap", 0x010e), NvMapIocGetId },
|
||||
};
|
||||
|
||||
private Dictionary<int, ServiceProcessRequest> m_Commands;
|
||||
|
||||
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
|
||||
|
||||
private Dictionary<(string, int), ServiceProcessIoctl> IoctlCmds;
|
||||
|
||||
private IdDictionary Fds;
|
||||
|
||||
private IdDictionary NvMaps;
|
||||
private IdDictionary NvMapsById;
|
||||
|
||||
public ServiceNvDrv()
|
||||
{
|
||||
m_Commands = new Dictionary<int, ServiceProcessRequest>()
|
||||
|
@ -58,15 +33,50 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
{ 4, QueryEvent },
|
||||
{ 8, SetClientPid },
|
||||
};
|
||||
|
||||
IoctlCmds = new Dictionary<(string, int), ServiceProcessIoctl>()
|
||||
{
|
||||
{ ("/dev/nvhost-as-gpu", 0x4101), NvGpuAsIoctlBindChannel },
|
||||
{ ("/dev/nvhost-as-gpu", 0x4102), NvGpuAsIoctlAllocSpace },
|
||||
{ ("/dev/nvhost-as-gpu", 0x4106), NvGpuAsIoctlMapBufferEx },
|
||||
{ ("/dev/nvhost-as-gpu", 0x4108), NvGpuAsIoctlGetVaRegions },
|
||||
{ ("/dev/nvhost-as-gpu", 0x4109), NvGpuAsIoctlInitializeEx },
|
||||
{ ("/dev/nvhost-ctrl", 0x001b), NvHostIoctlCtrlGetConfig },
|
||||
{ ("/dev/nvhost-ctrl", 0x001d), NvHostIoctlCtrlEventWait },
|
||||
{ ("/dev/nvhost-ctrl-gpu", 0x4701), NvGpuIoctlZcullGetCtxSize },
|
||||
{ ("/dev/nvhost-ctrl-gpu", 0x4702), NvGpuIoctlZcullGetInfo },
|
||||
{ ("/dev/nvhost-ctrl-gpu", 0x4705), NvGpuIoctlGetCharacteristics },
|
||||
{ ("/dev/nvhost-ctrl-gpu", 0x4706), NvGpuIoctlGetTpcMasks },
|
||||
{ ("/dev/nvhost-ctrl-gpu", 0x4714), NvGpuIoctlZbcGetActiveSlotMask },
|
||||
{ ("/dev/nvhost-gpu", 0x4714), NvMapIoctlChannelSetUserData },
|
||||
{ ("/dev/nvhost-gpu", 0x4801), NvMapIoctlChannelSetNvMap },
|
||||
{ ("/dev/nvhost-gpu", 0x4808), NvMapIoctlChannelSubmitGpFifo },
|
||||
{ ("/dev/nvhost-gpu", 0x4809), NvMapIoctlChannelAllocObjCtx },
|
||||
{ ("/dev/nvhost-gpu", 0x480b), NvMapIoctlChannelZcullBind },
|
||||
{ ("/dev/nvhost-gpu", 0x480c), NvMapIoctlChannelSetErrorNotifier },
|
||||
{ ("/dev/nvhost-gpu", 0x480d), NvMapIoctlChannelSetPriority },
|
||||
{ ("/dev/nvhost-gpu", 0x481a), NvMapIoctlChannelAllocGpFifoEx2 },
|
||||
{ ("/dev/nvmap", 0x0101), NvMapIocCreate },
|
||||
{ ("/dev/nvmap", 0x0103), NvMapIocFromId },
|
||||
{ ("/dev/nvmap", 0x0104), NvMapIocAlloc },
|
||||
{ ("/dev/nvmap", 0x0105), NvMapIocFree },
|
||||
{ ("/dev/nvmap", 0x0109), NvMapIocParam },
|
||||
{ ("/dev/nvmap", 0x010e), NvMapIocGetId },
|
||||
};
|
||||
|
||||
Fds = new IdDictionary();
|
||||
|
||||
NvMaps = new IdDictionary();
|
||||
NvMapsById = new IdDictionary();
|
||||
}
|
||||
|
||||
public static long Open(ServiceCtx Context)
|
||||
public long Open(ServiceCtx Context)
|
||||
{
|
||||
long NamePtr = Context.Request.SendBuff[0].Position;
|
||||
|
||||
string Name = AMemoryHelper.ReadAsciiString(Context.Memory, NamePtr);
|
||||
|
||||
int Fd = Context.Ns.Os.Fds.GenerateId(new FileDesc(Name));
|
||||
int Fd = Fds.Add(new NvFd(Name));
|
||||
|
||||
Context.ResponseData.Write(Fd);
|
||||
Context.ResponseData.Write(0);
|
||||
|
@ -74,12 +84,12 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
public static long Ioctl(ServiceCtx Context)
|
||||
public long Ioctl(ServiceCtx Context)
|
||||
{
|
||||
int Fd = Context.RequestData.ReadInt32();
|
||||
int Cmd = Context.RequestData.ReadInt32() & 0xffff;
|
||||
|
||||
FileDesc FdData = Context.Ns.Os.Fds.GetData<FileDesc>(Fd);
|
||||
NvFd FdData = Fds.GetData<NvFd>(Fd);
|
||||
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -95,18 +105,18 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
}
|
||||
}
|
||||
|
||||
public static long Close(ServiceCtx Context)
|
||||
public long Close(ServiceCtx Context)
|
||||
{
|
||||
int Fd = Context.RequestData.ReadInt32();
|
||||
|
||||
Context.Ns.Os.Fds.Delete(Fd);
|
||||
Fds.Delete(Fd);
|
||||
|
||||
Context.ResponseData.Write(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static long Initialize(ServiceCtx Context)
|
||||
public long Initialize(ServiceCtx Context)
|
||||
{
|
||||
long TransferMemSize = Context.RequestData.ReadInt64();
|
||||
int TransferMemHandle = Context.Request.HandleDesc.ToCopy[0];
|
||||
|
@ -116,7 +126,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
public static long QueryEvent(ServiceCtx Context)
|
||||
public long QueryEvent(ServiceCtx Context)
|
||||
{
|
||||
int Fd = Context.RequestData.ReadInt32();
|
||||
int EventId = Context.RequestData.ReadInt32();
|
||||
|
@ -128,7 +138,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
public static long SetClientPid(ServiceCtx Context)
|
||||
public long SetClientPid(ServiceCtx Context)
|
||||
{
|
||||
long Pid = Context.RequestData.ReadInt64();
|
||||
|
||||
|
@ -137,7 +147,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvGpuAsIoctlBindChannel(ServiceCtx Context)
|
||||
private long NvGpuAsIoctlBindChannel(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -146,7 +156,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvGpuAsIoctlAllocSpace(ServiceCtx Context)
|
||||
private long NvGpuAsIoctlAllocSpace(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -172,7 +182,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvGpuAsIoctlMapBufferEx(ServiceCtx Context)
|
||||
private long NvGpuAsIoctlMapBufferEx(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -186,18 +196,29 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
long MapSize = Reader.ReadInt64();
|
||||
long Offset = Reader.ReadInt64();
|
||||
|
||||
HNvMap NvMap = Context.Ns.Os.Handles.GetData<HNvMap>(Handle);
|
||||
|
||||
if (NvMap != null)
|
||||
if (Handle == 0)
|
||||
{
|
||||
if ((Flags & 1) != 0)
|
||||
{
|
||||
Offset = Context.Ns.Gpu.MapMemory(NvMap.Address, Offset, NvMap.Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
Offset = Context.Ns.Gpu.MapMemory(NvMap.Address, NvMap.Size);
|
||||
}
|
||||
//Handle 0 is valid here, but it refers to something else.
|
||||
//TODO: Figure out what, for now just return success.
|
||||
return 0;
|
||||
}
|
||||
|
||||
NvMap Map = NvMaps.GetData<NvMap>(Handle);
|
||||
|
||||
if (Map == null)
|
||||
{
|
||||
Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!");
|
||||
|
||||
return -1; //TODO: Corrent error code.
|
||||
}
|
||||
|
||||
if ((Flags & 1) != 0)
|
||||
{
|
||||
Offset = Context.Ns.Gpu.MapMemory(Map.Address, Offset, Map.Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
Offset = Context.Ns.Gpu.MapMemory(Map.Address, Map.Size);
|
||||
}
|
||||
|
||||
Context.Memory.WriteInt64(Position + 0x20, Offset);
|
||||
|
@ -205,7 +226,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvGpuAsIoctlGetVaRegions(ServiceCtx Context)
|
||||
private long NvGpuAsIoctlGetVaRegions(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -235,7 +256,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvGpuAsIoctlInitializeEx(ServiceCtx Context)
|
||||
private long NvGpuAsIoctlInitializeEx(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -252,7 +273,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvHostIoctlCtrlGetConfig(ServiceCtx Context)
|
||||
private long NvHostIoctlCtrlGetConfig(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -267,7 +288,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvHostIoctlCtrlEventWait(ServiceCtx Context)
|
||||
private long NvHostIoctlCtrlEventWait(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -283,7 +304,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvGpuIoctlZcullGetCtxSize(ServiceCtx Context)
|
||||
private long NvGpuIoctlZcullGetCtxSize(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -292,7 +313,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvGpuIoctlZcullGetInfo(ServiceCtx Context)
|
||||
private long NvGpuIoctlZcullGetInfo(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -312,7 +333,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvGpuIoctlGetCharacteristics(ServiceCtx Context)
|
||||
private long NvGpuIoctlGetCharacteristics(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -374,7 +395,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvGpuIoctlGetTpcMasks(ServiceCtx Context)
|
||||
private long NvGpuIoctlGetTpcMasks(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -388,7 +409,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvGpuIoctlZbcGetActiveSlotMask(ServiceCtx Context)
|
||||
private long NvGpuIoctlZbcGetActiveSlotMask(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -398,14 +419,14 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvMapIoctlChannelSetUserData(ServiceCtx Context)
|
||||
private long NvMapIoctlChannelSetUserData(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static long NvMapIoctlChannelSetNvMap(ServiceCtx Context)
|
||||
private long NvMapIoctlChannelSetNvMap(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -414,7 +435,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvMapIoctlChannelSubmitGpFifo(ServiceCtx Context)
|
||||
private long NvMapIoctlChannelSubmitGpFifo(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -453,7 +474,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvMapIoctlChannelAllocObjCtx(ServiceCtx Context)
|
||||
private long NvMapIoctlChannelAllocObjCtx(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -465,7 +486,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvMapIoctlChannelZcullBind(ServiceCtx Context)
|
||||
private long NvMapIoctlChannelZcullBind(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -478,7 +499,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvMapIoctlChannelSetErrorNotifier(ServiceCtx Context)
|
||||
private long NvMapIoctlChannelSetErrorNotifier(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -492,7 +513,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvMapIoctlChannelSetPriority(ServiceCtx Context)
|
||||
private long NvMapIoctlChannelSetPriority(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -501,7 +522,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvMapIoctlChannelAllocGpFifoEx2(ServiceCtx Context)
|
||||
private long NvMapIoctlChannelAllocGpFifoEx2(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -521,47 +542,46 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvMapIocCreate(ServiceCtx Context)
|
||||
private long NvMapIocCreate(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
int Size = Context.Memory.ReadInt32(Position);
|
||||
|
||||
int Id = Context.Ns.Os.NvMapIds.GenerateId();
|
||||
NvMap Map = new NvMap() { Size = Size };
|
||||
|
||||
int Handle = Context.Ns.Os.Handles.GenerateId(new HNvMap(Id, Size));
|
||||
Map.Handle = NvMaps.Add(Map);
|
||||
|
||||
Context.Memory.WriteInt32(Position + 4, Handle);
|
||||
Map.Id = NvMapsById.Add(Map);
|
||||
|
||||
Logging.Info($"NvMap {Id} created with size {Size:x8}!");
|
||||
Context.Memory.WriteInt32(Position + 4, Map.Handle);
|
||||
|
||||
Logging.Info($"NvMap {Map.Id} created with size {Size:x8}!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static long NvMapIocFromId(ServiceCtx Context)
|
||||
private long NvMapIocFromId(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
int Id = Context.Memory.ReadInt32(Position);
|
||||
|
||||
int Handle = -1;
|
||||
NvMap Map = NvMapsById.GetData<NvMap>(Id);
|
||||
|
||||
foreach (KeyValuePair<int, object> KV in Context.Ns.Os.Handles)
|
||||
if (Map == null)
|
||||
{
|
||||
if (KV.Value is HNvMap NvMap && NvMap.Id == Id)
|
||||
{
|
||||
Handle = KV.Key;
|
||||
|
||||
break;
|
||||
}
|
||||
Logging.Warn($"Trying to use invalid NvMap Id {Id}!");
|
||||
|
||||
return -1; //TODO: Corrent error code.
|
||||
}
|
||||
|
||||
Context.Memory.WriteInt32(Position + 4, Handle);
|
||||
Context.Memory.WriteInt32(Position + 4, Map.Handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static long NvMapIocAlloc(ServiceCtx Context)
|
||||
private long NvMapIocAlloc(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -574,38 +594,49 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
byte Kind = (byte)Reader.ReadInt64();
|
||||
long Addr = Reader.ReadInt64();
|
||||
|
||||
HNvMap NvMap = Context.Ns.Os.Handles.GetData<HNvMap>(Handle);
|
||||
NvMap Map = NvMaps.GetData<NvMap>(Handle);
|
||||
|
||||
if (NvMap != null)
|
||||
if (Map == null)
|
||||
{
|
||||
NvMap.Address = Addr;
|
||||
NvMap.Align = Align;
|
||||
NvMap.Kind = Kind;
|
||||
Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!");
|
||||
|
||||
return -1; //TODO: Corrent error code.
|
||||
}
|
||||
|
||||
Map.Address = Addr;
|
||||
Map.Align = Align;
|
||||
Map.Kind = Kind;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static long NvMapIocFree(ServiceCtx Context)
|
||||
private long NvMapIocFree(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
MemReader Reader = new MemReader(Context.Memory, Position);
|
||||
MemWriter Writer = new MemWriter(Context.Memory, Position + 8);
|
||||
|
||||
int Handle = Reader.ReadInt32();
|
||||
int Padding = Reader.ReadInt32();
|
||||
int Handle = Reader.ReadInt32();
|
||||
int Padding = Reader.ReadInt32();
|
||||
|
||||
HNvMap NvMap = Context.Ns.Os.Handles.GetData<HNvMap>(Handle);
|
||||
NvMap Map = NvMaps.GetData<NvMap>(Handle);
|
||||
|
||||
if (Map == null)
|
||||
{
|
||||
Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!");
|
||||
|
||||
return -1; //TODO: Corrent error code.
|
||||
}
|
||||
|
||||
Writer.WriteInt64(0);
|
||||
Writer.WriteInt32(NvMap.Size);
|
||||
Writer.WriteInt32(Map.Size);
|
||||
Writer.WriteInt32(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static long NvMapIocParam(ServiceCtx Context)
|
||||
private long NvMapIocParam(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
|
@ -614,16 +645,23 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
int Handle = Reader.ReadInt32();
|
||||
int Param = Reader.ReadInt32();
|
||||
|
||||
HNvMap NvMap = Context.Ns.Os.Handles.GetData<HNvMap>(Handle);
|
||||
NvMap Map = NvMaps.GetData<NvMap>(Handle);
|
||||
|
||||
if (Map == null)
|
||||
{
|
||||
Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!");
|
||||
|
||||
return -1; //TODO: Corrent error code.
|
||||
}
|
||||
|
||||
int Response = 0;
|
||||
|
||||
|
||||
switch (Param)
|
||||
{
|
||||
case 1: Response = NvMap.Size; break;
|
||||
case 2: Response = NvMap.Align; break;
|
||||
case 4: Response = 0x40000000; break;
|
||||
case 5: Response = NvMap.Kind; break;
|
||||
case 1: Response = Map.Size; break;
|
||||
case 2: Response = Map.Align; break;
|
||||
case 4: Response = 0x40000000; break;
|
||||
case 5: Response = Map.Kind; break;
|
||||
}
|
||||
|
||||
Context.Memory.WriteInt32(Position + 8, Response);
|
||||
|
@ -631,17 +669,29 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static long NvMapIocGetId(ServiceCtx Context)
|
||||
private long NvMapIocGetId(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
int Handle = Context.Memory.ReadInt32(Position + 4);
|
||||
|
||||
HNvMap NvMap = Context.Ns.Os.Handles.GetData<HNvMap>(Handle);
|
||||
NvMap Map = NvMaps.GetData<NvMap>(Handle);
|
||||
|
||||
Context.Memory.WriteInt32(Position, NvMap.Id);
|
||||
if (Map == null)
|
||||
{
|
||||
Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!");
|
||||
|
||||
return -1; //TODO: Corrent error code.
|
||||
}
|
||||
|
||||
Context.Memory.WriteInt32(Position, Map.Id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public NvMap GetNvMap(int Handle)
|
||||
{
|
||||
return NvMaps.GetData<NvMap>(Handle);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,13 +9,13 @@ namespace Ryujinx.Core.OsHle.IpcServices
|
|||
{
|
||||
if (Context.Session is HDomain Dom)
|
||||
{
|
||||
Context.Response.ResponseObjIds.Add(Dom.GenerateObjectId(Obj));
|
||||
Context.Response.ResponseObjIds.Add(Dom.Add(Obj));
|
||||
}
|
||||
else
|
||||
{
|
||||
HSessionObj HndData = new HSessionObj(Context.Session, Obj);
|
||||
|
||||
int VHandle = Context.Ns.Os.Handles.GenerateId(HndData);
|
||||
int VHandle = Context.Process.HandleTable.OpenHandle(HndData);
|
||||
|
||||
Context.Response.HandleDesc = IpcHandleDesc.MakeMove(VHandle);
|
||||
}
|
||||
|
|
|
@ -20,30 +20,32 @@ namespace Ryujinx.Core.OsHle.IpcServices.Pl
|
|||
};
|
||||
}
|
||||
|
||||
public static long GetLoadState(ServiceCtx Context)
|
||||
public long GetLoadState(ServiceCtx Context)
|
||||
{
|
||||
Context.ResponseData.Write(1); //Loaded
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static long GetFontSize(ServiceCtx Context)
|
||||
public long GetFontSize(ServiceCtx Context)
|
||||
{
|
||||
Context.ResponseData.Write(Horizon.FontSize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static long GetSharedMemoryAddressOffset(ServiceCtx Context)
|
||||
public long GetSharedMemoryAddressOffset(ServiceCtx Context)
|
||||
{
|
||||
Context.ResponseData.Write(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static long GetSharedMemoryNativeHandle(ServiceCtx Context)
|
||||
public long GetSharedMemoryNativeHandle(ServiceCtx Context)
|
||||
{
|
||||
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Context.Ns.Os.FontHandle);
|
||||
int Handle = Context.Process.HandleTable.OpenHandle(Context.Ns.Os.FontSharedMem);
|
||||
|
||||
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
using Ryujinx.Core.OsHle.IpcServices.Acc;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Am;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Apm;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Aud;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Bsd;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Friend;
|
||||
using Ryujinx.Core.OsHle.IpcServices.FspSrv;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Hid;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Lm;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Nifm;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Ns;
|
||||
using Ryujinx.Core.OsHle.IpcServices.NvServices;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Pctl;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Pl;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Set;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Sfdnsres;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Sm;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Ssl;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Time;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Vi;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Core.OsHle.IpcServices
|
||||
{
|
||||
static class ServiceFactory
|
||||
{
|
||||
public static IIpcService MakeService(string Name)
|
||||
{
|
||||
switch (Name)
|
||||
{
|
||||
case "acc:u0": return new ServiceAcc();
|
||||
case "aoc:u": return new ServiceNs();
|
||||
case "apm": return new ServiceApm();
|
||||
case "apm:p": return new ServiceApm();
|
||||
case "appletOE": return new ServiceAppletOE();
|
||||
case "audout:u": return new ServiceAudOut();
|
||||
case "audren:u": return new ServiceAudRen();
|
||||
case "bsd:s": return new ServiceBsd();
|
||||
case "bsd:u": return new ServiceBsd();
|
||||
case "friend:a": return new ServiceFriend();
|
||||
case "fsp-srv": return new ServiceFspSrv();
|
||||
case "hid": return new ServiceHid();
|
||||
case "lm": return new ServiceLm();
|
||||
case "nifm:u": return new ServiceNifm();
|
||||
case "nvdrv": return new ServiceNvDrv();
|
||||
case "nvdrv:a": return new ServiceNvDrv();
|
||||
case "pctl:a": return new ServicePctl();
|
||||
case "pl:u": return new ServicePl();
|
||||
case "set": return new ServiceSet();
|
||||
case "set:sys": return new ServiceSetSys();
|
||||
case "sfdnsres": return new ServiceSfdnsres();
|
||||
case "sm:": return new ServiceSm();
|
||||
case "ssl": return new ServiceSsl();
|
||||
case "time:s": return new ServiceTime();
|
||||
case "time:u": return new ServiceTime();
|
||||
case "vi:m": return new ServiceVi();
|
||||
case "vi:s": return new ServiceVi();
|
||||
case "vi:u": return new ServiceVi();
|
||||
}
|
||||
|
||||
throw new NotImplementedException(Name);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -55,9 +55,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Sm
|
|||
return 0;
|
||||
}
|
||||
|
||||
HSession Session = new HSession(ServiceFactory.MakeService(Name));
|
||||
HSession Session = new HSession(Context.Process.Services.GetService(Name));
|
||||
|
||||
int Handle = Context.Ns.Os.Handles.GenerateId(Session);
|
||||
int Handle = Context.Process.HandleTable.OpenHandle(Session);
|
||||
|
||||
Context.Response.HandleDesc = IpcHandleDesc.MakeMove(Handle);
|
||||
|
||||
|
|
12
Ryujinx.Core/OsHle/Services/Vi/Display.cs
Normal file
12
Ryujinx.Core/OsHle/Services/Vi/Display.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Core.OsHle.IpcServices.Vi
|
||||
{
|
||||
class Display
|
||||
{
|
||||
public string Name { get; private set; }
|
||||
|
||||
public Display(string Name)
|
||||
{
|
||||
this.Name = Name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,6 +15,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
|
|||
|
||||
public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
|
||||
|
||||
private IdDictionary Displays;
|
||||
|
||||
public IApplicationDisplayService()
|
||||
{
|
||||
m_Commands = new Dictionary<int, ServiceProcessRequest>()
|
||||
|
@ -28,14 +30,17 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
|
|||
{ 2020, OpenLayer },
|
||||
{ 2021, CloseLayer },
|
||||
{ 2030, CreateStrayLayer },
|
||||
{ 2031, DestroyStrayLayer },
|
||||
{ 2101, SetLayerScalingMode },
|
||||
{ 5202, GetDisplayVSyncEvent }
|
||||
};
|
||||
|
||||
Displays = new IdDictionary();
|
||||
}
|
||||
|
||||
public long GetRelayService(ServiceCtx Context)
|
||||
{
|
||||
MakeObject(Context, new IHOSBinderDriver());
|
||||
MakeObject(Context, new IHOSBinderDriver(Context.Ns.Gpu.Renderer));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -56,7 +61,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
|
|||
|
||||
public long GetIndirectDisplayTransactionService(ServiceCtx Context)
|
||||
{
|
||||
MakeObject(Context, new IHOSBinderDriver());
|
||||
MakeObject(Context, new IHOSBinderDriver(Context.Ns.Gpu.Renderer));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -65,7 +70,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
|
|||
{
|
||||
string Name = GetDisplayName(Context);
|
||||
|
||||
long DisplayId = Context.Ns.Os.Displays.GenerateId(new Display(Name));
|
||||
long DisplayId = Displays.Add(new Display(Name));
|
||||
|
||||
Context.ResponseData.Write(DisplayId);
|
||||
|
||||
|
@ -76,7 +81,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
|
|||
{
|
||||
int DisplayId = Context.RequestData.ReadInt32();
|
||||
|
||||
Context.Ns.Os.Displays.Delete(DisplayId);
|
||||
Displays.Delete(DisplayId);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -99,6 +104,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
|
|||
|
||||
public long CloseLayer(ServiceCtx Context)
|
||||
{
|
||||
long LayerId = Context.RequestData.ReadInt64();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -109,7 +116,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
|
|||
|
||||
long ParcelPtr = Context.Request.ReceiveBuff[0].Position;
|
||||
|
||||
Display Disp = Context.Ns.Os.Displays.GetData<Display>((int)DisplayId);
|
||||
Display Disp = Displays.GetData<Display>((int)DisplayId);
|
||||
|
||||
byte[] Parcel = MakeIGraphicsBufferProducer(ParcelPtr);
|
||||
|
||||
|
@ -121,6 +128,11 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
|
|||
return 0;
|
||||
}
|
||||
|
||||
public long DestroyStrayLayer(ServiceCtx Context)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long SetLayerScalingMode(ServiceCtx Context)
|
||||
{
|
||||
int ScalingMode = Context.RequestData.ReadInt32();
|
||||
|
@ -133,7 +145,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
|
|||
{
|
||||
string Name = GetDisplayName(Context);
|
||||
|
||||
int Handle = Context.Ns.Os.Handles.GenerateId(new HEvent());
|
||||
int Handle = Context.Process.HandleTable.OpenHandle(new HEvent());
|
||||
|
||||
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using ChocolArm64.Memory;
|
||||
using Ryujinx.Core.OsHle.Ipc;
|
||||
using Ryujinx.Core.OsHle.IpcServices.Android;
|
||||
using Ryujinx.Graphics.Gal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
@ -14,7 +15,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
|
|||
|
||||
private NvFlinger Flinger;
|
||||
|
||||
public IHOSBinderDriver()
|
||||
public IHOSBinderDriver(IGalRenderer Renderer)
|
||||
{
|
||||
m_Commands = new Dictionary<int, ServiceProcessRequest>()
|
||||
{
|
||||
|
@ -23,7 +24,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi
|
|||
{ 2, GetNativeHandle }
|
||||
};
|
||||
|
||||
Flinger = new NvFlinger();
|
||||
Flinger = new NvFlinger(Renderer);
|
||||
}
|
||||
|
||||
public long TransactParcel(ServiceCtx Context)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using ChocolArm64.Memory;
|
||||
using Ryujinx.Core.OsHle.Handles;
|
||||
using Ryujinx.Core.OsHle.IpcServices.NvServices;
|
||||
using Ryujinx.Graphics.Gal;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
|
@ -54,18 +55,27 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
public GbpBuffer Data;
|
||||
}
|
||||
|
||||
private IGalRenderer Renderer;
|
||||
|
||||
private BufferEntry[] BufferQueue;
|
||||
|
||||
private ManualResetEvent WaitBufferFree;
|
||||
|
||||
private object RenderQueueLock;
|
||||
|
||||
private int RenderQueueCount;
|
||||
|
||||
private bool NvFlingerDisposed;
|
||||
|
||||
private bool KeepRunning;
|
||||
|
||||
public NvFlinger()
|
||||
public NvFlinger(IGalRenderer Renderer)
|
||||
{
|
||||
Commands = new Dictionary<(string, int), ServiceProcessParcel>()
|
||||
{
|
||||
{ ("android.gui.IGraphicBufferProducer", 0x1), GbpRequestBuffer },
|
||||
{ ("android.gui.IGraphicBufferProducer", 0x3), GbpDequeueBuffer },
|
||||
{ ("android.gui.IGraphicBufferProducer", 0x4), GbpDetachBuffer },
|
||||
{ ("android.gui.IGraphicBufferProducer", 0x7), GbpQueueBuffer },
|
||||
{ ("android.gui.IGraphicBufferProducer", 0x8), GbpCancelBuffer },
|
||||
{ ("android.gui.IGraphicBufferProducer", 0x9), GbpQuery },
|
||||
|
@ -74,10 +84,14 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
{ ("android.gui.IGraphicBufferProducer", 0xe), GbpPreallocBuffer }
|
||||
};
|
||||
|
||||
this.Renderer = Renderer;
|
||||
|
||||
BufferQueue = new BufferEntry[0x40];
|
||||
|
||||
WaitBufferFree = new ManualResetEvent(false);
|
||||
|
||||
RenderQueueLock = new object();
|
||||
|
||||
KeepRunning = true;
|
||||
}
|
||||
|
||||
|
@ -193,6 +207,11 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
return MakeReplyParcel(Context, 1280, 720, 0, 0, 0);
|
||||
}
|
||||
|
||||
private long GbpDetachBuffer(ServiceCtx Context, BinaryReader ParcelReader)
|
||||
{
|
||||
return MakeReplyParcel(Context, 0);
|
||||
}
|
||||
|
||||
private long GbpCancelBuffer(ServiceCtx Context, BinaryReader ParcelReader)
|
||||
{
|
||||
//TODO: Errors.
|
||||
|
@ -266,7 +285,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
|
||||
long FbSize = (uint)FbWidth * FbHeight * 4;
|
||||
|
||||
HNvMap NvMap = GetNvMap(Context, Slot);
|
||||
NvMap NvMap = GetNvMap(Context, Slot);
|
||||
|
||||
if ((ulong)(NvMap.Address + FbSize) > AMemoryMgr.AddrSize)
|
||||
{
|
||||
|
@ -330,7 +349,17 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
Rotate = -MathF.PI * 0.5f;
|
||||
}
|
||||
|
||||
byte* Fb = (byte*)Context.Ns.Memory.Ram + NvMap.Address;
|
||||
lock (RenderQueueLock)
|
||||
{
|
||||
if (NvFlingerDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Interlocked.Increment(ref RenderQueueCount);
|
||||
}
|
||||
|
||||
byte* Fb = (byte*)Context.Memory.Ram + NvMap.Address;
|
||||
|
||||
Context.Ns.Gpu.Renderer.QueueAction(delegate()
|
||||
{
|
||||
|
@ -346,6 +375,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
|
||||
BufferQueue[Slot].State = BufferState.Free;
|
||||
|
||||
Interlocked.Decrement(ref RenderQueueCount);
|
||||
|
||||
lock (WaitBufferFree)
|
||||
{
|
||||
WaitBufferFree.Set();
|
||||
|
@ -353,7 +384,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
});
|
||||
}
|
||||
|
||||
private HNvMap GetNvMap(ServiceCtx Context, int Slot)
|
||||
private NvMap GetNvMap(ServiceCtx Context, int Slot)
|
||||
{
|
||||
int NvMapHandle = BitConverter.ToInt32(BufferQueue[Slot].Data.RawData, 0x4c);
|
||||
|
||||
|
@ -366,7 +397,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
NvMapHandle = BitConverter.ToInt32(RawValue, 0);
|
||||
}
|
||||
|
||||
return Context.Ns.Os.Handles.GetData<HNvMap>(NvMapHandle);
|
||||
ServiceNvDrv NvDrv = (ServiceNvDrv)Context.Process.Services.GetService("nvdrv");
|
||||
|
||||
return NvDrv.GetNvMap(NvMapHandle);
|
||||
}
|
||||
|
||||
private int GetFreeSlotBlocking(int Width, int Height)
|
||||
|
@ -432,10 +465,24 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
Dispose(true);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
protected virtual void Dispose(bool Disposing)
|
||||
{
|
||||
if (disposing)
|
||||
if (Disposing && !NvFlingerDisposed)
|
||||
{
|
||||
lock (RenderQueueLock)
|
||||
{
|
||||
NvFlingerDisposed = true;
|
||||
}
|
||||
|
||||
//Ensure that all pending actions was sent before
|
||||
//we can safely assume that the class was disposed.
|
||||
while (RenderQueueCount > 0)
|
||||
{
|
||||
Thread.Yield();
|
||||
}
|
||||
|
||||
Renderer.ResetFrameBuffer();
|
||||
|
||||
lock (WaitBufferFree)
|
||||
{
|
||||
KeepRunning = false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue