aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs')
-rw-r--r--Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs62
1 files changed, 47 insertions, 15 deletions
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;
}
}
}