Implement SubmitGpfifoEx and fix nvdec
This commit is contained in:
parent
9b6bafb742
commit
72db77fbe6
6 changed files with 116 additions and 27 deletions
|
@ -32,7 +32,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv
|
|||
{ "/dev/nvhost-ctrl", typeof(NvHostCtrlFileDevice) },
|
||||
{ "/dev/nvhost-ctrl-gpu", typeof(NvHostCtrlGpuFileDevice) },
|
||||
{ "/dev/nvhost-as-gpu", typeof(NvHostAsGpuFileDevice) },
|
||||
{ "/dev/nvhost-gpu", typeof(NvHostChannelFileDevice) },
|
||||
{ "/dev/nvhost-gpu", typeof(NvHostGpuFileDevice) },
|
||||
//{ "/dev/nvhost-msenc", typeof(NvHostChannelFileDevice) },
|
||||
{ "/dev/nvhost-nvdec", typeof(NvHostChannelFileDevice) },
|
||||
//{ "/dev/nvhost-nvjpg", typeof(NvHostChannelFileDevice) },
|
||||
|
@ -67,13 +67,10 @@ namespace Ryujinx.HLE.HOS.Services.Nv
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
Logger.PrintWarning(LogClass.ServiceNv, $"Cannot find file device \"{path}\"!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Logger.PrintWarning(LogClass.ServiceNv, $"Cannot find file device \"{path}\"!");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -85,8 +82,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv
|
|||
NvIoctl.Direction ioctlDirection = ioctlCommand.GetDirectionValue();
|
||||
uint ioctlSize = ioctlCommand.GetSizeValue();
|
||||
|
||||
bool isRead = (ioctlDirection & NvIoctl.Direction.Read) == NvIoctl.Direction.Read;
|
||||
bool isWrite = (ioctlDirection & NvIoctl.Direction.Write) == NvIoctl.Direction.Write;
|
||||
bool isRead = (ioctlDirection & NvIoctl.Direction.Read) != 0;
|
||||
bool isWrite = (ioctlDirection & NvIoctl.Direction.Write) != 0;
|
||||
|
||||
if ((isWrite && ioctlSize > outputDataSize) || (isRead && ioctlSize > inputDataSize))
|
||||
{
|
||||
|
@ -403,7 +400,9 @@ namespace Ryujinx.HLE.HOS.Services.Nv
|
|||
// DumpGraphicsMemoryInfo()
|
||||
public ResultCode DumpGraphicsMemoryInfo(ServiceCtx context)
|
||||
{
|
||||
throw new ServiceNotImplementedException(context);
|
||||
Logger.PrintStub(LogClass.ServiceNv);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[Command(10)] // 3.0.0+
|
||||
|
@ -414,10 +413,48 @@ namespace Ryujinx.HLE.HOS.Services.Nv
|
|||
}
|
||||
|
||||
[Command(11)] // 3.0.0+
|
||||
// Ioctl2(s32 fd, u32 ioctl_cmd, buffer<bytes, 0x21> in_args, buffer<bytes, 0x21> in_additional_buffer) -> (u32 error_code, buffer<bytes, 0x22> out_args)
|
||||
// Ioctl2(s32 fd, u32 ioctl_cmd, buffer<bytes, 0x21> in_args, buffer<bytes, 0x21> inline_in_buffer) -> (u32 error_code, buffer<bytes, 0x22> out_args)
|
||||
public ResultCode Ioctl2(ServiceCtx context)
|
||||
{
|
||||
throw new ServiceNotImplementedException(context);
|
||||
NvResult errorCode = EnsureInitialized();
|
||||
|
||||
if (errorCode == NvResult.Success)
|
||||
{
|
||||
int fd = context.RequestData.ReadInt32();
|
||||
NvIoctl ioctlCommand = context.RequestData.ReadStruct<NvIoctl>();
|
||||
|
||||
(long inlineInBufferPosition, long inlineInBufferSize) = context.Request.GetBufferType0x21(1);
|
||||
|
||||
errorCode = GetIoctlArgument(context, ioctlCommand, out Span<byte> arguments);
|
||||
|
||||
Span<byte> inlineInBuffer = new Span<byte>(context.Memory.ReadBytes(inlineInBufferPosition, inlineInBufferSize));
|
||||
|
||||
if (errorCode == NvResult.Success)
|
||||
{
|
||||
errorCode = GetFileDeviceFromFd(fd, out NvFileDevice fileDevice);
|
||||
|
||||
if (errorCode == NvResult.Success)
|
||||
{
|
||||
NvInternalResult internalResult = fileDevice.Ioctl2(ioctlCommand, arguments, inlineInBuffer);
|
||||
|
||||
if (internalResult == NvInternalResult.NotImplemented)
|
||||
{
|
||||
throw new NvIoctlNotImplementedException(context, fileDevice, ioctlCommand);
|
||||
}
|
||||
|
||||
errorCode = ConvertInternalErrorCode(internalResult);
|
||||
|
||||
if (errorCode == NvResult.Success && (ioctlCommand.GetDirectionValue() & NvIoctl.Direction.Write) != 0)
|
||||
{
|
||||
context.Memory.WriteBytes(context.Request.GetBufferType0x22(0).Position, arguments.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.ResponseData.Write((uint)errorCode);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[Command(12)] // 3.0.0+
|
||||
|
@ -431,7 +468,9 @@ namespace Ryujinx.HLE.HOS.Services.Nv
|
|||
// FinishInitialize(unknown<8>)
|
||||
public ResultCode FinishInitialize(ServiceCtx context)
|
||||
{
|
||||
throw new ServiceNotImplementedException(context);
|
||||
Logger.PrintStub(LogClass.ServiceNv);
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
using Ryujinx.HLE.HOS.Kernel.Process;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices
|
||||
|
@ -37,25 +38,32 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices
|
|||
return NvInternalResult.NotImplemented;
|
||||
}
|
||||
|
||||
public virtual NvInternalResult Ioctl2(NvIoctl command, Span<byte> arguments, Span<byte> inBuffer)
|
||||
public virtual NvInternalResult Ioctl2(NvIoctl command, Span<byte> arguments, Span<byte> inlineInBuffer)
|
||||
{
|
||||
return NvInternalResult.NotImplemented;
|
||||
}
|
||||
|
||||
public virtual NvInternalResult Ioctl3(NvIoctl command, Span<byte> arguments, Span<byte> outBuffer)
|
||||
public virtual NvInternalResult Ioctl3(NvIoctl command, Span<byte> arguments, Span<byte> inlineOutBuffer)
|
||||
{
|
||||
return NvInternalResult.NotImplemented;
|
||||
}
|
||||
|
||||
protected delegate NvInternalResult IoctlProcessor<T>(ref T arguments);
|
||||
protected delegate NvInternalResult IoctlProcessorSpan<T>(Span<T> arguments);
|
||||
protected delegate NvInternalResult IoctlProcessorInline<T, Y>(ref T arguments, Span<Y> inlineData);
|
||||
|
||||
protected static NvInternalResult CallIoctlMethod<T>(IoctlProcessor<T> callback, Span<byte> arguments) where T : struct
|
||||
{
|
||||
Debug.Assert(arguments.Length == Marshal.SizeOf<T>());
|
||||
Debug.Assert(arguments.Length == Unsafe.SizeOf<T>());
|
||||
return callback(ref MemoryMarshal.Cast<byte, T>(arguments)[0]);
|
||||
}
|
||||
|
||||
protected static NvInternalResult CallIoctlMethod<T, Y>(IoctlProcessorInline<T, Y> callback, Span<byte> arguments, Span<byte> inlineInBuffer) where T : struct where Y : struct
|
||||
{
|
||||
Debug.Assert(arguments.Length == Unsafe.SizeOf<T>());
|
||||
return callback(ref MemoryMarshal.Cast<byte, T>(arguments)[0], MemoryMarshal.Cast<byte, Y>(inlineInBuffer));
|
||||
}
|
||||
|
||||
protected static NvInternalResult CallIoctlMethod<T>(IoctlProcessorSpan<T> callback, Span<byte> arguments) where T : struct
|
||||
{
|
||||
return callback(MemoryMarshal.Cast<byte, T>(arguments));
|
||||
|
|
|
@ -243,17 +243,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
|
|||
SubmitGpfifoArguments gpfifoSubmissionHeader = MemoryMarshal.Cast<byte, SubmitGpfifoArguments>(arguments)[0];
|
||||
Span<long> gpfifoEntries = MemoryMarshal.Cast<byte, long>(arguments.Slice(headerSize)).Slice(0, gpfifoSubmissionHeader.NumEntries);
|
||||
|
||||
NvGpuVmm vmm = NvHostAsGpuFileDevice.GetAddressSpaceContext(_owner).Vmm;
|
||||
|
||||
foreach (long entry in gpfifoEntries)
|
||||
{
|
||||
_gpu.Pusher.Push(vmm, entry);
|
||||
}
|
||||
|
||||
gpfifoSubmissionHeader.Fence.Id = 0;
|
||||
gpfifoSubmissionHeader.Fence.Value = 0;
|
||||
|
||||
return NvInternalResult.Success;
|
||||
return SubmitGpfifo(ref gpfifoSubmissionHeader, gpfifoEntries);
|
||||
}
|
||||
|
||||
private NvInternalResult AllocObjCtx(ref AllocObjCtxArguments arguments)
|
||||
|
@ -338,6 +328,21 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
|
|||
return NvInternalResult.Success;
|
||||
}
|
||||
|
||||
protected NvInternalResult SubmitGpfifo(ref SubmitGpfifoArguments header, Span<long> entries)
|
||||
{
|
||||
NvGpuVmm vmm = NvHostAsGpuFileDevice.GetAddressSpaceContext(_owner).Vmm;
|
||||
|
||||
foreach (long entry in entries)
|
||||
{
|
||||
_gpu.Pusher.Push(vmm, entry);
|
||||
}
|
||||
|
||||
header.Fence.Id = 0;
|
||||
header.Fence.Value = 0;
|
||||
|
||||
return NvInternalResult.Success;
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
// TODO
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
|
||||
{
|
||||
internal class NvHostGpuFileDevice : NvHostChannelFileDevice
|
||||
{
|
||||
public NvHostGpuFileDevice(ServiceCtx context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public override NvInternalResult Ioctl2(NvIoctl command, Span<byte> arguments, Span<byte> inlineInBuffer)
|
||||
{
|
||||
NvInternalResult result = NvInternalResult.NotImplemented;
|
||||
|
||||
if (command.GetTypeValue() == NvIoctl.NvHostMagic)
|
||||
{
|
||||
switch (command.GetNumberValue())
|
||||
{
|
||||
case 0x1b:
|
||||
result = CallIoctlMethod<SubmitGpfifoArguments, long>(SubmitGpfifoEx, arguments, inlineInBuffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private NvInternalResult SubmitGpfifoEx(ref SubmitGpfifoArguments arguments, Span<long> inlineData)
|
||||
{
|
||||
return SubmitGpfifo(ref arguments, inlineData);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,12 +9,13 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types
|
|||
public int MapAddress;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct MapCommandBufferArguments
|
||||
{
|
||||
public int NumEntries;
|
||||
public int DataAddress; // Ignored by the driver.
|
||||
public bool AttachHostChDas;
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool AttachHostChDas;
|
||||
public byte Padding1;
|
||||
public short Padding2;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,9 @@ namespace Ryujinx.HLE.HOS.Services.Nv.Types
|
|||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.AppendLine($"Device File: {FileDevice.GetType().Name}");
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendLine($"Ioctl (0x{Command.RawValue:x8})");
|
||||
sb.AppendLine($"\tNumber: 0x{Command.GetNumberValue():x8}");
|
||||
sb.AppendLine($"\tType: 0x{Command.GetTypeValue():x8}");
|
||||
|
|
Loading…
Add table
Reference in a new issue