Return valid event handles with QueryEvent
Also add an exception for unimplemented event ids. This commit doesn't implement accurately the events, this only define different events for different event ids.
This commit is contained in:
parent
c94b2da01b
commit
16669d576d
5 changed files with 171 additions and 6 deletions
|
@ -24,7 +24,6 @@ namespace Ryujinx.HLE.HOS.Services.Nv
|
|||
[Service("nvdrv:t")]
|
||||
class INvDrvServices : IpcService
|
||||
{
|
||||
// TODO: everything
|
||||
private static Dictionary<string, Type> _fileDeviceRegistry =
|
||||
new Dictionary<string, Type>()
|
||||
{
|
||||
|
@ -329,7 +328,14 @@ namespace Ryujinx.HLE.HOS.Services.Nv
|
|||
|
||||
if (errorCode == NvResult.Success)
|
||||
{
|
||||
errorCode = ConvertInternalErrorCode(fileDevice.QueryEvent(out int eventHandle, eventId));
|
||||
NvInternalResult internalResult = fileDevice.QueryEvent(out int eventHandle, eventId);
|
||||
|
||||
if (internalResult == NvInternalResult.NotImplemented)
|
||||
{
|
||||
throw new NvQueryEventlNotImplementedException(context, fileDevice, eventId);
|
||||
}
|
||||
|
||||
errorCode = ConvertInternalErrorCode(internalResult);
|
||||
|
||||
if (errorCode == NvResult.Success)
|
||||
{
|
||||
|
|
|
@ -1,12 +1,21 @@
|
|||
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types;
|
||||
using Ryujinx.HLE.HOS.Kernel.Common;
|
||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
|
||||
{
|
||||
internal class NvHostGpuFileDevice : NvHostChannelFileDevice
|
||||
{
|
||||
private KEvent _smExceptionBptIntReportEvent;
|
||||
private KEvent _smExceptionBptPauseReportEvent;
|
||||
private KEvent _errorNotifierEvent;
|
||||
|
||||
public NvHostGpuFileDevice(ServiceCtx context) : base(context)
|
||||
{
|
||||
_smExceptionBptIntReportEvent = new KEvent(context.Device.System);
|
||||
_smExceptionBptPauseReportEvent = new KEvent(context.Device.System);
|
||||
_errorNotifierEvent = new KEvent(context.Device.System);
|
||||
}
|
||||
|
||||
public override NvInternalResult Ioctl2(NvIoctl command, Span<byte> arguments, Span<byte> inlineInBuffer)
|
||||
|
@ -25,6 +34,41 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
|
|||
return result;
|
||||
}
|
||||
|
||||
public override NvInternalResult QueryEvent(out int eventHandle, uint eventId)
|
||||
{
|
||||
// TODO: accurately represent and implement those events.
|
||||
KEvent targetEvent = null;
|
||||
|
||||
switch (eventId)
|
||||
{
|
||||
case 0x1:
|
||||
targetEvent = _smExceptionBptIntReportEvent;
|
||||
break;
|
||||
case 0x2:
|
||||
targetEvent = _smExceptionBptPauseReportEvent;
|
||||
break;
|
||||
case 0x3:
|
||||
targetEvent = _errorNotifierEvent;
|
||||
break;
|
||||
}
|
||||
|
||||
if (targetEvent != null)
|
||||
{
|
||||
if (_owner.HandleTable.GenerateHandle(targetEvent.ReadableEvent, out eventHandle) != KernelResult.Success)
|
||||
{
|
||||
throw new InvalidOperationException("Out of handles!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eventHandle = 0;
|
||||
|
||||
return NvInternalResult.InvalidInput;
|
||||
}
|
||||
|
||||
return NvInternalResult.Success;
|
||||
}
|
||||
|
||||
private NvInternalResult SubmitGpfifoEx(ref SubmitGpfifoArguments arguments, Span<long> inlineData)
|
||||
{
|
||||
return SubmitGpfifo(ref arguments, inlineData);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Kernel.Common;
|
||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl.Types;
|
||||
using Ryujinx.HLE.HOS.Services.Nv.Types;
|
||||
using Ryujinx.HLE.HOS.Services.Settings;
|
||||
|
@ -16,6 +18,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl
|
|||
private bool _isProductionMode;
|
||||
private NvHostSyncpt _syncpt;
|
||||
private NvHostEvent[] _events;
|
||||
private KEvent _dummyEvent;
|
||||
|
||||
public NvHostCtrlFileDevice(ServiceCtx context) : base(context)
|
||||
{
|
||||
|
@ -28,8 +31,9 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl
|
|||
_isProductionMode = true;
|
||||
}
|
||||
|
||||
_syncpt = new NvHostSyncpt();
|
||||
_events = new NvHostEvent[EventsCount];
|
||||
_syncpt = new NvHostSyncpt();
|
||||
_events = new NvHostEvent[EventsCount];
|
||||
_dummyEvent = new KEvent(context.Device.System);
|
||||
}
|
||||
|
||||
public override NvInternalResult Ioctl(NvIoctl command, Span<byte> arguments)
|
||||
|
@ -82,6 +86,28 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl
|
|||
return result;
|
||||
}
|
||||
|
||||
public override NvInternalResult QueryEvent(out int eventHandle, uint eventId)
|
||||
{
|
||||
// TODO: implement SyncPts <=> KEvent logic accurately. For now we return a dummy event.
|
||||
KEvent targetEvent = _dummyEvent;
|
||||
|
||||
if (targetEvent != null)
|
||||
{
|
||||
if (_owner.HandleTable.GenerateHandle(targetEvent.ReadableEvent, out eventHandle) != KernelResult.Success)
|
||||
{
|
||||
throw new InvalidOperationException("Out of handles!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eventHandle = 0;
|
||||
|
||||
return NvInternalResult.InvalidInput;
|
||||
}
|
||||
|
||||
return NvInternalResult.Success;
|
||||
}
|
||||
|
||||
private NvInternalResult SyncptRead(ref NvFence arguments)
|
||||
{
|
||||
return SyncptReadMinOrMax(ref arguments, max: false);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Kernel.Common;
|
||||
using Ryujinx.HLE.HOS.Kernel.Process;
|
||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu.Types;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
@ -11,9 +13,13 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu
|
|||
private static Stopwatch _pTimer = new Stopwatch();
|
||||
private static double _ticksToNs = (1.0 / Stopwatch.Frequency) * 1_000_000_000;
|
||||
|
||||
private KEvent _errorEvent;
|
||||
private KEvent _unknownEvent;
|
||||
|
||||
public NvHostCtrlGpuFileDevice(ServiceCtx context) : base(context)
|
||||
{
|
||||
|
||||
_errorEvent = new KEvent(context.Device.System);
|
||||
_unknownEvent = new KEvent(context.Device.System);
|
||||
}
|
||||
|
||||
static NvHostCtrlGpuFileDevice()
|
||||
|
@ -76,6 +82,38 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu
|
|||
return result;
|
||||
}
|
||||
|
||||
public override NvInternalResult QueryEvent(out int eventHandle, uint eventId)
|
||||
{
|
||||
// TODO: accurately represent and implement those events.
|
||||
KEvent targetEvent = null;
|
||||
|
||||
switch (eventId)
|
||||
{
|
||||
case 0x1:
|
||||
targetEvent = _errorEvent;
|
||||
break;
|
||||
case 0x2:
|
||||
targetEvent = _unknownEvent;
|
||||
break;
|
||||
}
|
||||
|
||||
if (targetEvent != null)
|
||||
{
|
||||
if (_owner.HandleTable.GenerateHandle(targetEvent.ReadableEvent, out eventHandle) != KernelResult.Success)
|
||||
{
|
||||
throw new InvalidOperationException("Out of handles!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eventHandle = 0;
|
||||
|
||||
return NvInternalResult.InvalidInput;
|
||||
}
|
||||
|
||||
return NvInternalResult.Success;
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices;
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Nv.Types
|
||||
{
|
||||
class NvQueryEventlNotImplementedException : Exception
|
||||
{
|
||||
public ServiceCtx Context { get; }
|
||||
public NvFileDevice FileDevice { get; }
|
||||
public uint EventId { get; }
|
||||
|
||||
public NvQueryEventlNotImplementedException(ServiceCtx context, NvFileDevice fileDevice, uint eventId)
|
||||
: this(context, fileDevice, eventId, "The ioctl is not implemented.")
|
||||
{ }
|
||||
|
||||
public NvQueryEventlNotImplementedException(ServiceCtx context, NvFileDevice fileDevice, uint eventId, string message)
|
||||
: base(message)
|
||||
{
|
||||
Context = context;
|
||||
FileDevice = fileDevice;
|
||||
EventId = eventId;
|
||||
}
|
||||
|
||||
public override string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.Message +
|
||||
Environment.NewLine +
|
||||
Environment.NewLine +
|
||||
BuildMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private string BuildMessage()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.AppendLine($"Device File: {FileDevice.GetType().Name}");
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendLine($"Event ID: (0x{EventId:x8})");
|
||||
|
||||
sb.AppendLine("Guest Stack Trace:");
|
||||
sb.AppendLine(Context.Thread.GetGuestStackTrace());
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue