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>
This commit is contained in:
parent
38b26cf424
commit
4d02a2d2c0
202 changed files with 20563 additions and 2567 deletions
|
@ -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;
|
||||
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);
|
||||
|
||||
foreach (CommandBuffer commandBufferEntry in commandBufferEntries)
|
||||
lock (_device)
|
||||
{
|
||||
NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, commandBufferEntry.MemoryId);
|
||||
|
||||
int[] commandBufferData = new int[commandBufferEntry.WordsCount];
|
||||
|
||||
for (int offset = 0; offset < commandBufferData.Length; offset++)
|
||||
for (int i = 0; i < syncptIncrs.Length; i++)
|
||||
{
|
||||
commandBufferData[offset] = _memory.Read<int>((ulong)(map.Address + commandBufferEntry.Offset + offset * 4));
|
||||
SyncptIncr syncptIncr = syncptIncrs[i];
|
||||
|
||||
uint id = syncptIncr.Id;
|
||||
|
||||
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.
|
||||
|
||||
map.DmaMapAddress = 0;
|
||||
// gmm.Free((ulong)map.DmaMapAddress, (uint)map.Size);
|
||||
|
||||
// map.DmaMapAddress = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue