aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2020-07-12 00:07:01 -0300
committerGitHub <noreply@github.com>2020-07-12 05:07:01 +0200
commit4d02a2d2c0451b4de1f6de3bbce54c457cacebe2 (patch)
tree120fe4fb8cfa1ac1c6ef4c97d92be47e955e8c0f /Ryujinx.HLE
parent38b26cf4242999fa7d8c550993ac0940cd03d55f (diff)
New NVDEC and VIC implementation (#1384)
* Initial NVDEC and VIC implementation * Update FFmpeg.AutoGen to 4.3.0 * Add nvdec dependencies for Windows * Unify some VP9 structures * Rename VP9 structure fields * Improvements to Video API * XML docs for Common.Memory * Remove now unused or redundant overloads from MemoryAccessor * NVDEC UV surface read/write scalar paths * Add FIXME comments about hacky things/stuff that will need to be fixed in the future * Cleaned up VP9 memory allocation * Remove some debug logs * Rename some VP9 structs * Remove unused struct * No need to compile Ryujinx.Graphics.Host1x with unsafe anymore * Name AsyncWorkQueue threads to make debugging easier * Make Vp9PictureInfo a ref struct * LayoutConverter no longer needs the depth argument (broken by rebase) * Pooling of VP9 buffers, plus fix a memory leak on VP9 * Really wish VS could rename projects properly... * Address feedback * Remove using * Catch OperationCanceledException * Add licensing informations * Add THIRDPARTY.md to release too Co-authored-by: Thog <me@thog.eu>
Diffstat (limited to 'Ryujinx.HLE')
-rw-r--r--Ryujinx.HLE/HOS/Horizon.cs2
-rw-r--r--Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs2
-rw-r--r--Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvDeviceFile.cs2
-rw-r--r--Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs62
-rw-r--r--Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitArguments.cs29
-rw-r--r--Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostSyncPt.cs6
-rw-r--r--Ryujinx.HLE/Ryujinx.HLE.csproj3
-rw-r--r--Ryujinx.HLE/Switch.cs37
8 files changed, 114 insertions, 29 deletions
diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs
index b3af3290..f302e98a 100644
--- a/Ryujinx.HLE/HOS/Horizon.cs
+++ b/Ryujinx.HLE/HOS/Horizon.cs
@@ -293,8 +293,6 @@ namespace Ryujinx.HLE.HOS
KernelContext.ThreadCounter.Wait();
KernelContext.Dispose();
-
- Device.Unload();
}
}
}
diff --git a/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs b/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs
index ce7314f4..d6cc85e9 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs
@@ -60,6 +60,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv
NvDeviceFile deviceFile = (NvDeviceFile)constructor.Invoke(new object[] { context });
+ deviceFile.Path = path;
+
return _deviceFileIdRegistry.Add(deviceFile);
}
else
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvDeviceFile.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvDeviceFile.cs
index fe3ae652..e426945d 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvDeviceFile.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvDeviceFile.cs
@@ -14,6 +14,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices
public readonly ServiceCtx Context;
public readonly KProcess Owner;
+ public string Path;
+
public NvDeviceFile(ServiceCtx context)
{
Context = context;
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs
index 208bec3b..70c9a47b 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs
@@ -1,10 +1,10 @@
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu.Memory;
-using Ryujinx.HLE.HOS.Services.Nv.Types;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap;
+using Ryujinx.HLE.HOS.Services.Nv.Types;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -130,28 +130,56 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
private NvInternalResult Submit(Span<byte> arguments)
{
- int headerSize = Unsafe.SizeOf<SubmitArguments>();
- SubmitArguments submitHeader = MemoryMarshal.Cast<byte, SubmitArguments>(arguments)[0];
- Span<CommandBuffer> commandBufferEntries = MemoryMarshal.Cast<byte, CommandBuffer>(arguments.Slice(headerSize)).Slice(0, submitHeader.CmdBufsCount);
- MemoryManager gmm = NvHostAsGpuDeviceFile.GetAddressSpaceContext(Context).Gmm;
-
- foreach (CommandBuffer commandBufferEntry in commandBufferEntries)
+ SubmitArguments submitHeader = GetSpanAndSkip<SubmitArguments>(ref arguments, 1)[0];
+ Span<CommandBuffer> commandBuffers = GetSpanAndSkip<CommandBuffer>(ref arguments, submitHeader.CmdBufsCount);
+ Span<Reloc> relocs = GetSpanAndSkip<Reloc>(ref arguments, submitHeader.RelocsCount);
+ Span<uint> relocShifts = GetSpanAndSkip<uint>(ref arguments, submitHeader.RelocsCount);
+ Span<SyncptIncr> syncptIncrs = GetSpanAndSkip<SyncptIncr>(ref arguments, submitHeader.SyncptIncrsCount);
+ Span<SyncptIncr> waitChecks = GetSpanAndSkip<SyncptIncr>(ref arguments, submitHeader.SyncptIncrsCount); // ?
+ Span<Fence> fences = GetSpanAndSkip<Fence>(ref arguments, submitHeader.FencesCount);
+
+ lock (_device)
{
- NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, commandBufferEntry.MemoryId);
+ for (int i = 0; i < syncptIncrs.Length; i++)
+ {
+ SyncptIncr syncptIncr = syncptIncrs[i];
- int[] commandBufferData = new int[commandBufferEntry.WordsCount];
+ uint id = syncptIncr.Id;
- for (int offset = 0; offset < commandBufferData.Length; offset++)
- {
- commandBufferData[offset] = _memory.Read<int>((ulong)(map.Address + commandBufferEntry.Offset + offset * 4));
+ fences[i].Id = id;
+ fences[i].Thresh = Context.Device.System.HostSyncpoint.IncrementSyncpointMax(id, syncptIncr.Incrs);
}
- // TODO: Submit command to engines.
+ foreach (CommandBuffer commandBuffer in commandBuffers)
+ {
+ NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, commandBuffer.Mem);
+
+ var data = _memory.GetSpan((ulong)map.Address + commandBuffer.Offset, commandBuffer.WordsCount * 4);
+
+ _device.Host1x.Submit(MemoryMarshal.Cast<byte, int>(data));
+ }
}
+ fences[0].Thresh = Context.Device.System.HostSyncpoint.IncrementSyncpointMax(fences[0].Id, 1);
+
+ Span<int> tmpCmdBuff = stackalloc int[1];
+
+ tmpCmdBuff[0] = (4 << 28) | (int)fences[0].Id;
+
+ _device.Host1x.Submit(tmpCmdBuff);
+
return NvInternalResult.Success;
}
+ private Span<T> GetSpanAndSkip<T>(ref Span<byte> arguments, int count) where T : unmanaged
+ {
+ Span<T> output = MemoryMarshal.Cast<byte, T>(arguments).Slice(0, count);
+
+ arguments = arguments.Slice(Unsafe.SizeOf<T>() * count);
+
+ return output;
+ }
+
private NvInternalResult GetSyncpoint(ref GetParameterArguments arguments)
{
if (arguments.Parameter >= MaxModuleSyncpoint)
@@ -248,9 +276,13 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
{
if (map.DmaMapAddress != 0)
{
- gmm.Free((ulong)map.DmaMapAddress, (uint)map.Size);
+ // FIXME:
+ // To make unmapping work, we need separate address space per channel.
+ // Right now NVDEC and VIC share the GPU address space which is not correct at all.
+
+ // gmm.Free((ulong)map.DmaMapAddress, (uint)map.Size);
- map.DmaMapAddress = 0;
+ // map.DmaMapAddress = 0;
}
}
}
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitArguments.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitArguments.cs
index bb2fd1cc..7ef7e39e 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitArguments.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/Types/SubmitArguments.cs
@@ -5,17 +5,40 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.Types
[StructLayout(LayoutKind.Sequential)]
struct CommandBuffer
{
- public int MemoryId;
- public int Offset;
+ public int Mem;
+ public uint Offset;
public int WordsCount;
}
[StructLayout(LayoutKind.Sequential)]
+ struct Reloc
+ {
+ public int CmdbufMem;
+ public int CmdbufOffset;
+ public int Target;
+ public int TargetOffset;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct SyncptIncr
+ {
+ public uint Id;
+ public uint Incrs;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct Fence
+ {
+ public uint Id;
+ public uint Thresh;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
struct SubmitArguments
{
public int CmdBufsCount;
public int RelocsCount;
public int SyncptIncrsCount;
- public int WaitchecksCount;
+ public int FencesCount;
}
}
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostSyncPt.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostSyncPt.cs
index ff56fbf5..aa730b57 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostSyncPt.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostCtrl/Types/NvHostSyncPt.cs
@@ -1,6 +1,5 @@
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu.Synchronization;
-using Ryujinx.HLE.HOS.Kernel.Threading;
using System;
using System.Threading;
@@ -172,6 +171,11 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl
return (uint)Interlocked.Increment(ref _counterMax[id]);
}
+ public uint IncrementSyncpointMax(uint id, uint incrs)
+ {
+ return (uint)Interlocked.Add(ref _counterMax[id], (int)incrs);
+ }
+
public bool IsSyncpointExpired(uint id, uint threshold)
{
return MinCompare(id, _counterMin[id], _counterMax[id], (int)threshold);
diff --git a/Ryujinx.HLE/Ryujinx.HLE.csproj b/Ryujinx.HLE/Ryujinx.HLE.csproj
index b05a9087..01e20792 100644
--- a/Ryujinx.HLE/Ryujinx.HLE.csproj
+++ b/Ryujinx.HLE/Ryujinx.HLE.csproj
@@ -47,6 +47,9 @@
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
<ProjectReference Include="..\Ryujinx.Cpu\Ryujinx.Cpu.csproj" />
<ProjectReference Include="..\Ryujinx.Debugger\Ryujinx.Debugger.csproj" />
+ <ProjectReference Include="..\Ryujinx.Graphics.Host1x\Ryujinx.Graphics.Host1x.csproj" />
+ <ProjectReference Include="..\Ryujinx.Graphics.Nvdec\Ryujinx.Graphics.Nvdec.csproj" />
+ <ProjectReference Include="..\Ryujinx.Graphics.Vic\Ryujinx.Graphics.Vic.csproj" />
<ProjectReference Include="..\Ryujinx.Memory\Ryujinx.Memory.csproj" />
<ProjectReference Include="..\ARMeilleure\ARMeilleure.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />
diff --git a/Ryujinx.HLE/Switch.cs b/Ryujinx.HLE/Switch.cs
index 5713bd9e..9defe25d 100644
--- a/Ryujinx.HLE/Switch.cs
+++ b/Ryujinx.HLE/Switch.cs
@@ -3,6 +3,9 @@ using Ryujinx.Audio;
using Ryujinx.Configuration;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu;
+using Ryujinx.Graphics.Host1x;
+using Ryujinx.Graphics.Nvdec;
+using Ryujinx.Graphics.Vic;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.HOS;
@@ -11,7 +14,6 @@ using Ryujinx.HLE.HOS.Services.Hid;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.Memory;
using System;
-using System.Threading;
namespace Ryujinx.HLE
{
@@ -23,6 +25,8 @@ namespace Ryujinx.HLE
public GpuContext Gpu { get; private set; }
+ internal Host1xDevice Host1x { get; }
+
public VirtualFileSystem FileSystem { get; private set; }
public Horizon System { get; private set; }
@@ -53,6 +57,27 @@ namespace Ryujinx.HLE
Gpu = new GpuContext(renderer);
+ Host1x = new Host1xDevice(Gpu.Synchronization);
+ var nvdec = new NvdecDevice(Gpu.MemoryManager);
+ var vic = new VicDevice(Gpu.MemoryManager);
+ Host1x.RegisterDevice(ClassId.Nvdec, nvdec);
+ Host1x.RegisterDevice(ClassId.Vic, vic);
+
+ nvdec.FrameDecoded += (FrameDecodedEventArgs e) =>
+ {
+ // FIXME:
+ // Figure out what is causing frame ordering issues on H264.
+ // For now this is needed as workaround.
+ if (e.CodecId == CodecId.H264)
+ {
+ vic.SetSurfaceOverride(e.LumaOffset, e.ChromaOffset, 0);
+ }
+ else
+ {
+ vic.DisableSurfaceOverride();
+ }
+ };
+
FileSystem = fileSystem;
System = new Horizon(this, contentManager);
@@ -136,13 +161,6 @@ namespace Ryujinx.HLE
Gpu.Window.Present(swapBuffersCallback);
}
- internal void Unload()
- {
- FileSystem.Unload();
-
- Memory.Dispose();
- }
-
public void DisposeGpu()
{
Gpu.Dispose();
@@ -158,7 +176,10 @@ namespace Ryujinx.HLE
if (disposing)
{
System.Dispose();
+ Host1x.Dispose();
AudioOut.Dispose();
+ FileSystem.Unload();
+ Memory.Dispose();
}
}
}