mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-07-23 13:07:10 +02:00
mm: Migrate service in Horizon project (#5580)
* mm: Migrate service in Horizon project This PR migrate the `mm:u` service to the Horizon project, things were checked by some RE aswell, that's why some vars are renamed, the logic should be the same as before. Tests are welcome. * Lock _sessionList instead * Fix comment * Fix Session fields order
This commit is contained in:
parent
6ed613a6e6
commit
b0b7843d5c
10 changed files with 280 additions and 230 deletions
|
@ -1,196 +0,0 @@
|
|||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Services.Mm.Types;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Mm
|
||||
{
|
||||
[Service("mm:u")]
|
||||
class IRequest : IpcService
|
||||
{
|
||||
private readonly object _sessionListLock = new();
|
||||
private readonly List<MultiMediaSession> _sessionList = new();
|
||||
|
||||
private uint _uniqueId = 1;
|
||||
|
||||
public IRequest(ServiceCtx context) { }
|
||||
|
||||
[CommandCmif(0)]
|
||||
// InitializeOld(u32, u32, u32)
|
||||
public ResultCode InitializeOld(ServiceCtx context)
|
||||
{
|
||||
MultiMediaOperationType operationType = (MultiMediaOperationType)context.RequestData.ReadUInt32();
|
||||
int fgmId = context.RequestData.ReadInt32();
|
||||
bool isAutoClearEvent = context.RequestData.ReadInt32() != 0;
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceMm, new { operationType, fgmId, isAutoClearEvent });
|
||||
|
||||
Register(operationType, fgmId, isAutoClearEvent);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(1)]
|
||||
// FinalizeOld(u32)
|
||||
public ResultCode FinalizeOld(ServiceCtx context)
|
||||
{
|
||||
MultiMediaOperationType operationType = (MultiMediaOperationType)context.RequestData.ReadUInt32();
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceMm, new { operationType });
|
||||
|
||||
lock (_sessionListLock)
|
||||
{
|
||||
_sessionList.Remove(GetSessionByType(operationType));
|
||||
}
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(2)]
|
||||
// SetAndWaitOld(u32, u32, u32)
|
||||
public ResultCode SetAndWaitOld(ServiceCtx context)
|
||||
{
|
||||
MultiMediaOperationType operationType = (MultiMediaOperationType)context.RequestData.ReadUInt32();
|
||||
uint frequenceHz = context.RequestData.ReadUInt32();
|
||||
int timeout = context.RequestData.ReadInt32();
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceMm, new { operationType, frequenceHz, timeout });
|
||||
|
||||
lock (_sessionListLock)
|
||||
{
|
||||
GetSessionByType(operationType)?.SetAndWait(frequenceHz, timeout);
|
||||
}
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(3)]
|
||||
// GetOld(u32) -> u32
|
||||
public ResultCode GetOld(ServiceCtx context)
|
||||
{
|
||||
MultiMediaOperationType operationType = (MultiMediaOperationType)context.RequestData.ReadUInt32();
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceMm, new { operationType });
|
||||
|
||||
lock (_sessionListLock)
|
||||
{
|
||||
MultiMediaSession session = GetSessionByType(operationType);
|
||||
|
||||
uint currentValue = session == null ? 0 : session.CurrentValue;
|
||||
|
||||
context.ResponseData.Write(currentValue);
|
||||
}
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(4)]
|
||||
// Initialize(u32, u32, u32) -> u32
|
||||
public ResultCode Initialize(ServiceCtx context)
|
||||
{
|
||||
MultiMediaOperationType operationType = (MultiMediaOperationType)context.RequestData.ReadUInt32();
|
||||
int fgmId = context.RequestData.ReadInt32();
|
||||
bool isAutoClearEvent = context.RequestData.ReadInt32() != 0;
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceMm, new { operationType, fgmId, isAutoClearEvent });
|
||||
|
||||
uint id = Register(operationType, fgmId, isAutoClearEvent);
|
||||
|
||||
context.ResponseData.Write(id);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(5)]
|
||||
// Finalize(u32)
|
||||
public ResultCode Finalize(ServiceCtx context)
|
||||
{
|
||||
uint id = context.RequestData.ReadUInt32();
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceMm, new { id });
|
||||
|
||||
lock (_sessionListLock)
|
||||
{
|
||||
_sessionList.Remove(GetSessionById(id));
|
||||
}
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(6)]
|
||||
// SetAndWait(u32, u32, u32)
|
||||
public ResultCode SetAndWait(ServiceCtx context)
|
||||
{
|
||||
uint id = context.RequestData.ReadUInt32();
|
||||
uint frequenceHz = context.RequestData.ReadUInt32();
|
||||
int timeout = context.RequestData.ReadInt32();
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceMm, new { id, frequenceHz, timeout });
|
||||
|
||||
lock (_sessionListLock)
|
||||
{
|
||||
GetSessionById(id)?.SetAndWait(frequenceHz, timeout);
|
||||
}
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(7)]
|
||||
// Get(u32) -> u32
|
||||
public ResultCode Get(ServiceCtx context)
|
||||
{
|
||||
uint id = context.RequestData.ReadUInt32();
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceMm, new { id });
|
||||
|
||||
lock (_sessionListLock)
|
||||
{
|
||||
MultiMediaSession session = GetSessionById(id);
|
||||
|
||||
uint currentValue = session == null ? 0 : session.CurrentValue;
|
||||
|
||||
context.ResponseData.Write(currentValue);
|
||||
}
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
private MultiMediaSession GetSessionById(uint id)
|
||||
{
|
||||
foreach (MultiMediaSession session in _sessionList)
|
||||
{
|
||||
if (session.Id == id)
|
||||
{
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private MultiMediaSession GetSessionByType(MultiMediaOperationType type)
|
||||
{
|
||||
foreach (MultiMediaSession session in _sessionList)
|
||||
{
|
||||
if (session.Type == type)
|
||||
{
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private uint Register(MultiMediaOperationType type, int fgmId, bool isAutoClearEvent)
|
||||
{
|
||||
lock (_sessionListLock)
|
||||
{
|
||||
// Nintendo ignore the fgm id as the other interfaces were deprecated.
|
||||
MultiMediaSession session = new(_uniqueId++, type, isAutoClearEvent);
|
||||
|
||||
_sessionList.Add(session);
|
||||
|
||||
return session.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
namespace Ryujinx.HLE.HOS.Services.Mm.Types
|
||||
{
|
||||
enum MultiMediaOperationType : uint
|
||||
{
|
||||
Ram = 2,
|
||||
NvEnc = 5,
|
||||
NvDec = 6,
|
||||
NvJpg = 7,
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
namespace Ryujinx.HLE.HOS.Services.Mm.Types
|
||||
{
|
||||
class MultiMediaSession
|
||||
{
|
||||
public MultiMediaOperationType Type { get; }
|
||||
|
||||
public bool IsAutoClearEvent { get; }
|
||||
public uint Id { get; }
|
||||
public uint CurrentValue { get; private set; }
|
||||
|
||||
public MultiMediaSession(uint id, MultiMediaOperationType type, bool isAutoClearEvent)
|
||||
{
|
||||
Type = type;
|
||||
Id = id;
|
||||
IsAutoClearEvent = isAutoClearEvent;
|
||||
CurrentValue = 0;
|
||||
}
|
||||
|
||||
public void SetAndWait(uint value, int timeout)
|
||||
{
|
||||
CurrentValue = value;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue