aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.HLE/HOS')
-rw-r--r--Ryujinx.HLE/HOS/ArmProcessContext.cs14
-rw-r--r--Ryujinx.HLE/HOS/ArmProcessContextFactory.cs14
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/IProcessContextFactory.cs2
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs37
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/ProcessContextFactory.cs2
-rw-r--r--Ryujinx.HLE/HOS/ProgramLoader.cs4
-rw-r--r--Ryujinx.HLE/HOS/Services/Nv/Host1xContext.cs47
-rw-r--r--Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs18
-rw-r--r--Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs73
-rw-r--r--Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs8
-rw-r--r--Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs60
-rw-r--r--Ryujinx.HLE/HOS/Services/Nv/NvMemoryAllocator.cs2
-rw-r--r--Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs5
13 files changed, 175 insertions, 111 deletions
diff --git a/Ryujinx.HLE/HOS/ArmProcessContext.cs b/Ryujinx.HLE/HOS/ArmProcessContext.cs
index 457d1218..89ce0eb3 100644
--- a/Ryujinx.HLE/HOS/ArmProcessContext.cs
+++ b/Ryujinx.HLE/HOS/ArmProcessContext.cs
@@ -1,27 +1,34 @@
using ARMeilleure.Memory;
using ARMeilleure.State;
using Ryujinx.Cpu;
+using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.HOS.Kernel.Process;
using Ryujinx.Memory;
namespace Ryujinx.HLE.HOS
{
- class ArmProcessContext<T> : IProcessContext where T : class, IVirtualMemoryManager, IMemoryManager
+ class ArmProcessContext<T> : IProcessContext where T : class, IVirtualMemoryManagerTracked, IMemoryManager
{
+ private readonly long _pid;
+ private readonly GpuContext _gpuContext;
private readonly CpuContext _cpuContext;
private T _memoryManager;
public IVirtualMemoryManager AddressSpace => _memoryManager;
- public ArmProcessContext(T memoryManager, bool for64Bit)
+ public ArmProcessContext(long pid, GpuContext gpuContext, T memoryManager, bool for64Bit)
{
if (memoryManager is IRefCounted rc)
{
rc.IncrementReferenceCount();
}
- _memoryManager = memoryManager;
+ gpuContext.RegisterProcess(pid, memoryManager);
+
+ _pid = pid;
+ _gpuContext = gpuContext;
_cpuContext = new CpuContext(memoryManager, for64Bit);
+ _memoryManager = memoryManager;
}
public void Execute(ExecutionContext context, ulong codeAddress)
@@ -36,6 +43,7 @@ namespace Ryujinx.HLE.HOS
rc.DecrementReferenceCount();
_memoryManager = null;
+ _gpuContext.UnregisterProcess(_pid);
}
}
}
diff --git a/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs b/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs
index 04d06e1f..50dbd843 100644
--- a/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs
+++ b/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs
@@ -1,5 +1,6 @@
using Ryujinx.Common.Configuration;
using Ryujinx.Cpu;
+using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.HOS.Kernel;
using Ryujinx.HLE.HOS.Kernel.Process;
using Ryujinx.Memory;
@@ -9,19 +10,26 @@ namespace Ryujinx.HLE.HOS
{
class ArmProcessContextFactory : IProcessContextFactory
{
- public IProcessContext Create(KernelContext context, ulong addressSpaceSize, InvalidAccessHandler invalidAccessHandler, bool for64Bit)
+ private readonly GpuContext _gpu;
+
+ public ArmProcessContextFactory(GpuContext gpu)
+ {
+ _gpu = gpu;
+ }
+
+ public IProcessContext Create(KernelContext context, long pid, ulong addressSpaceSize, InvalidAccessHandler invalidAccessHandler, bool for64Bit)
{
MemoryManagerMode mode = context.Device.Configuration.MemoryManagerMode;
switch (mode)
{
case MemoryManagerMode.SoftwarePageTable:
- return new ArmProcessContext<MemoryManager>(new MemoryManager(addressSpaceSize, invalidAccessHandler), for64Bit);
+ return new ArmProcessContext<MemoryManager>(pid, _gpu, new MemoryManager(addressSpaceSize, invalidAccessHandler), for64Bit);
case MemoryManagerMode.HostMapped:
case MemoryManagerMode.HostMappedUnsafe:
bool unsafeMode = mode == MemoryManagerMode.HostMappedUnsafe;
- return new ArmProcessContext<MemoryManagerHostMapped>(new MemoryManagerHostMapped(addressSpaceSize, unsafeMode, invalidAccessHandler), for64Bit);
+ return new ArmProcessContext<MemoryManagerHostMapped>(pid, _gpu, new MemoryManagerHostMapped(addressSpaceSize, unsafeMode, invalidAccessHandler), for64Bit);
default:
throw new ArgumentOutOfRangeException();
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/IProcessContextFactory.cs b/Ryujinx.HLE/HOS/Kernel/Process/IProcessContextFactory.cs
index fbd6c139..10df43a8 100644
--- a/Ryujinx.HLE/HOS/Kernel/Process/IProcessContextFactory.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/IProcessContextFactory.cs
@@ -4,6 +4,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
{
interface IProcessContextFactory
{
- IProcessContext Create(KernelContext context, ulong addressSpaceSize, InvalidAccessHandler invalidAccessHandler, bool for64Bit);
+ IProcessContext Create(KernelContext context, long pid, ulong addressSpaceSize, InvalidAccessHandler invalidAccessHandler, bool for64Bit);
}
}
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs b/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
index 90cd01f0..fbdd812e 100644
--- a/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
@@ -126,6 +126,13 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
AddressSpaceType addrSpaceType = (AddressSpaceType)((int)(creationInfo.Flags & ProcessCreationFlags.AddressSpaceMask) >> (int)ProcessCreationFlags.AddressSpaceShift);
+ Pid = KernelContext.NewKipId();
+
+ if (Pid == 0 || (ulong)Pid >= KernelConstants.InitialProcessId)
+ {
+ throw new InvalidOperationException($"Invalid KIP Id {Pid}.");
+ }
+
InitializeMemoryManager(creationInfo.Flags);
bool aslrEnabled = creationInfo.Flags.HasFlag(ProcessCreationFlags.EnableAslr);
@@ -171,13 +178,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
return result;
}
- Pid = KernelContext.NewKipId();
-
- if (Pid == 0 || (ulong)Pid >= KernelConstants.InitialProcessId)
- {
- throw new InvalidOperationException($"Invalid KIP Id {Pid}.");
- }
-
return ParseProcessInfo(creationInfo);
}
@@ -233,6 +233,13 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
AddressSpaceType addrSpaceType = (AddressSpaceType)((int)(creationInfo.Flags & ProcessCreationFlags.AddressSpaceMask) >> (int)ProcessCreationFlags.AddressSpaceShift);
+ Pid = KernelContext.NewProcessId();
+
+ if (Pid == -1 || (ulong)Pid < KernelConstants.InitialProcessId)
+ {
+ throw new InvalidOperationException($"Invalid Process Id {Pid}.");
+ }
+
InitializeMemoryManager(creationInfo.Flags);
bool aslrEnabled = creationInfo.Flags.HasFlag(ProcessCreationFlags.EnableAslr);
@@ -286,13 +293,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
return result;
}
- Pid = KernelContext.NewProcessId();
-
- if (Pid == -1 || (ulong)Pid < KernelConstants.InitialProcessId)
- {
- throw new InvalidOperationException($"Invalid Process Id {Pid}.");
- }
-
result = ParseProcessInfo(creationInfo);
if (result != KernelResult.Success)
@@ -1051,14 +1051,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
bool for64Bit = flags.HasFlag(ProcessCreationFlags.Is64Bit);
- Context = _contextFactory.Create(KernelContext, 1UL << addrSpaceBits, InvalidAccessHandler, for64Bit);
-
- // TODO: This should eventually be removed.
- // The GPU shouldn't depend on the CPU memory manager at all.
- if (flags.HasFlag(ProcessCreationFlags.IsApplication))
- {
- KernelContext.Device.Gpu.SetVmm((IVirtualMemoryManagerTracked)CpuMemory);
- }
+ Context = _contextFactory.Create(KernelContext, Pid, 1UL << addrSpaceBits, InvalidAccessHandler, for64Bit);
if (Context.AddressSpace is MemoryManagerHostMapped)
{
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/ProcessContextFactory.cs b/Ryujinx.HLE/HOS/Kernel/Process/ProcessContextFactory.cs
index 5920fe44..ff250e88 100644
--- a/Ryujinx.HLE/HOS/Kernel/Process/ProcessContextFactory.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/ProcessContextFactory.cs
@@ -4,7 +4,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
{
class ProcessContextFactory : IProcessContextFactory
{
- public IProcessContext Create(KernelContext context, ulong addressSpaceSize, InvalidAccessHandler invalidAccessHandler, bool for64Bit)
+ public IProcessContext Create(KernelContext context, long pid, ulong addressSpaceSize, InvalidAccessHandler invalidAccessHandler, bool for64Bit)
{
return new ProcessContext(new AddressSpaceManager(addressSpaceSize));
}
diff --git a/Ryujinx.HLE/HOS/ProgramLoader.cs b/Ryujinx.HLE/HOS/ProgramLoader.cs
index cc1c76c2..93ddd7ee 100644
--- a/Ryujinx.HLE/HOS/ProgramLoader.cs
+++ b/Ryujinx.HLE/HOS/ProgramLoader.cs
@@ -83,7 +83,7 @@ namespace Ryujinx.HLE.HOS
KProcess process = new KProcess(context);
- var processContextFactory = new ArmProcessContextFactory();
+ var processContextFactory = new ArmProcessContextFactory(context.Device.Gpu);
result = process.InitializeKip(
creationInfo,
@@ -228,7 +228,7 @@ namespace Ryujinx.HLE.HOS
return false;
}
- var processContextFactory = new ArmProcessContextFactory();
+ var processContextFactory = new ArmProcessContextFactory(context.Device.Gpu);
result = process.Initialize(
creationInfo,
diff --git a/Ryujinx.HLE/HOS/Services/Nv/Host1xContext.cs b/Ryujinx.HLE/HOS/Services/Nv/Host1xContext.cs
new file mode 100644
index 00000000..1fcc12b5
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Nv/Host1xContext.cs
@@ -0,0 +1,47 @@
+using Ryujinx.Graphics.Gpu;
+using Ryujinx.Graphics.Gpu.Memory;
+using Ryujinx.Graphics.Host1x;
+using Ryujinx.Graphics.Nvdec;
+using Ryujinx.Graphics.Vic;
+using System;
+
+namespace Ryujinx.HLE.HOS.Services.Nv
+{
+ class Host1xContext : IDisposable
+ {
+ public MemoryManager Smmu { get; }
+ public NvMemoryAllocator MemoryAllocator { get; }
+ public Host1xDevice Host1x { get;}
+
+ public Host1xContext(GpuContext gpu, long pid)
+ {
+ MemoryAllocator = new NvMemoryAllocator();
+ Host1x = new Host1xDevice(gpu.Synchronization);
+ Smmu = gpu.CreateMemoryManager(pid);
+ var nvdec = new NvdecDevice(Smmu);
+ var vic = new VicDevice(Smmu);
+ 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();
+ }
+ };
+ }
+
+ public void Dispose()
+ {
+ Host1x.Dispose();
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs b/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs
index 25279af3..24c784c3 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs
@@ -3,7 +3,6 @@ using Ryujinx.Common.Logging;
using Ryujinx.Cpu;
using Ryujinx.HLE.Exceptions;
using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.HOS.Kernel.Memory;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel;
@@ -24,8 +23,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv
[Service("nvdrv:t")]
class INvDrvServices : IpcService
{
- private static Dictionary<string, Type> _deviceFileRegistry =
- new Dictionary<string, Type>()
+ private static Dictionary<string, Type> _deviceFileRegistry = new Dictionary<string, Type>()
{
{ "/dev/nvmap", typeof(NvMapDeviceFile) },
{ "/dev/nvhost-ctrl", typeof(NvHostCtrlDeviceFile) },
@@ -39,7 +37,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv
//{ "/dev/nvhost-display", typeof(NvHostChannelDeviceFile) },
};
- private static IdDictionary _deviceFileIdRegistry = new IdDictionary();
+ public static IdDictionary DeviceFileIdRegistry = new IdDictionary();
private IVirtualMemoryManager _clientMemory;
private long _owner;
@@ -61,7 +59,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv
deviceFile.Path = path;
- return _deviceFileIdRegistry.Add(deviceFile);
+ return DeviceFileIdRegistry.Add(deviceFile);
}
else
{
@@ -139,7 +137,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv
return NvResult.InvalidParameter;
}
- deviceFile = _deviceFileIdRegistry.GetData<NvDeviceFile>(fd);
+ deviceFile = DeviceFileIdRegistry.GetData<NvDeviceFile>(fd);
if (deviceFile == null)
{
@@ -302,7 +300,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv
{
deviceFile.Close();
- _deviceFileIdRegistry.Delete(fd);
+ DeviceFileIdRegistry.Delete(fd);
}
}
@@ -569,14 +567,16 @@ namespace Ryujinx.HLE.HOS.Services.Nv
public static void Destroy()
{
- foreach (object entry in _deviceFileIdRegistry.Values)
+ NvHostChannelDeviceFile.Destroy();
+
+ foreach (object entry in DeviceFileIdRegistry.Values)
{
NvDeviceFile deviceFile = (NvDeviceFile)entry;
deviceFile.Close();
}
- _deviceFileIdRegistry.Clear();
+ DeviceFileIdRegistry.Clear();
}
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs
index ac0c4ab1..b3be6fba 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs
@@ -1,22 +1,22 @@
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu.Memory;
-using Ryujinx.HLE.HOS.Kernel.Process;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types;
+using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap;
using Ryujinx.Memory;
using System;
-using System.Collections.Concurrent;
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
{
class NvHostAsGpuDeviceFile : NvDeviceFile
{
- private static ConcurrentDictionary<KProcess, AddressSpaceContext> _addressSpaceContextRegistry = new ConcurrentDictionary<KProcess, AddressSpaceContext>();
- private NvMemoryAllocator _memoryAllocator;
+ private readonly AddressSpaceContext _asContext;
+ private readonly NvMemoryAllocator _memoryAllocator;
public NvHostAsGpuDeviceFile(ServiceCtx context, IVirtualMemoryManager memory, long owner) : base(context, owner)
{
- _memoryAllocator = context.Device.MemoryAllocator;
+ _asContext = new AddressSpaceContext(context.Device.Gpu.CreateMemoryManager(owner));
+ _memoryAllocator = new NvMemoryAllocator();
}
public override NvInternalResult Ioctl(NvIoctl command, Span<byte> arguments)
@@ -77,20 +77,24 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
private NvInternalResult BindChannel(ref BindChannelArguments arguments)
{
- Logger.Stub?.PrintStub(LogClass.ServiceNv);
+ var channelDeviceFile = INvDrvServices.DeviceFileIdRegistry.GetData<NvHostChannelDeviceFile>(arguments.Fd);
+ if (channelDeviceFile == null)
+ {
+ // TODO: Return invalid Fd error.
+ }
+
+ channelDeviceFile.Channel.BindMemory(_asContext.Gmm);
return NvInternalResult.Success;
}
private NvInternalResult AllocSpace(ref AllocSpaceArguments arguments)
{
- AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Context);
-
ulong size = (ulong)arguments.Pages * (ulong)arguments.PageSize;
NvInternalResult result = NvInternalResult.Success;
- lock (addressSpaceContext)
+ lock (_asContext)
{
// Note: When the fixed offset flag is not set,
// the Offset field holds the alignment size instead.
@@ -132,7 +136,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
}
else
{
- addressSpaceContext.AddReservation(arguments.Offset, size);
+ _asContext.AddReservation(arguments.Offset, size);
}
}
@@ -141,18 +145,16 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
private NvInternalResult FreeSpace(ref FreeSpaceArguments arguments)
{
- AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Context);
+ ulong size = (ulong)arguments.Pages * (ulong)arguments.PageSize;
NvInternalResult result = NvInternalResult.Success;
- lock (addressSpaceContext)
+ lock (_asContext)
{
- ulong size = (ulong)arguments.Pages * (ulong)arguments.PageSize;
-
- if (addressSpaceContext.RemoveReservation(arguments.Offset))
+ if (_asContext.RemoveReservation(arguments.Offset))
{
_memoryAllocator.DeallocateRange(arguments.Offset, size);
- addressSpaceContext.Gmm.Unmap(arguments.Offset, size);
+ _asContext.Gmm.Unmap(arguments.Offset, size);
}
else
{
@@ -168,16 +170,14 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
private NvInternalResult UnmapBuffer(ref UnmapBufferArguments arguments)
{
- AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Context);
-
- lock (addressSpaceContext)
+ lock (_asContext)
{
- if (addressSpaceContext.RemoveMap(arguments.Offset, out ulong size))
+ if (_asContext.RemoveMap(arguments.Offset, out ulong size))
{
if (size != 0)
{
_memoryAllocator.DeallocateRange(arguments.Offset, size);
- addressSpaceContext.Gmm.Unmap(arguments.Offset, size);
+ _asContext.Gmm.Unmap(arguments.Offset, size);
}
}
else
@@ -191,22 +191,20 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
private NvInternalResult MapBufferEx(ref MapBufferExArguments arguments)
{
- const string mapErrorMsg = "Failed to map fixed buffer with offset 0x{0:x16}, size 0x{1:x16} and alignment 0x{2:x16}!";
-
- AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Context);
+ const string MapErrorMsg = "Failed to map fixed buffer with offset 0x{0:x16}, size 0x{1:x16} and alignment 0x{2:x16}!";
ulong physicalAddress;
if ((arguments.Flags & AddressSpaceFlags.RemapSubRange) != 0)
{
- lock (addressSpaceContext)
+ lock (_asContext)
{
- if (addressSpaceContext.TryGetMapPhysicalAddress(arguments.Offset, out physicalAddress))
+ if (_asContext.TryGetMapPhysicalAddress(arguments.Offset, out physicalAddress))
{
ulong virtualAddress = arguments.Offset + arguments.BufferOffset;
physicalAddress += arguments.BufferOffset;
- addressSpaceContext.Gmm.Map(physicalAddress, virtualAddress, arguments.MappingSize);
+ _asContext.Gmm.Map(physicalAddress, virtualAddress, arguments.MappingSize);
return NvInternalResult.Success;
}
@@ -246,7 +244,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
NvInternalResult result = NvInternalResult.Success;
- lock (addressSpaceContext)
+ lock (_asContext)
{
// Note: When the fixed offset flag is not set,
// the Offset field holds the alignment size instead.
@@ -254,13 +252,13 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
if (!virtualAddressAllocated)
{
- if (addressSpaceContext.ValidateFixedBuffer(arguments.Offset, size, pageSize))
+ if (_asContext.ValidateFixedBuffer(arguments.Offset, size, pageSize))
{
- addressSpaceContext.Gmm.Map(physicalAddress, arguments.Offset, size);
+ _asContext.Gmm.Map(physicalAddress, arguments.Offset, size);
}
else
{
- string message = string.Format(mapErrorMsg, arguments.Offset, size, pageSize);
+ string message = string.Format(MapErrorMsg, arguments.Offset, size, pageSize);
Logger.Warning?.Print(LogClass.ServiceNv, message);
@@ -275,7 +273,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
_memoryAllocator.AllocateRange(va, size, freeAddressStartPosition);
}
- addressSpaceContext.Gmm.Map(physicalAddress, va, size);
+ _asContext.Gmm.Map(physicalAddress, va, size);
arguments.Offset = va;
}
@@ -289,7 +287,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
}
else
{
- addressSpaceContext.AddMap(arguments.Offset, size, physicalAddress, virtualAddressAllocated);
+ _asContext.AddMap(arguments.Offset, size, physicalAddress, virtualAddressAllocated);
}
}
@@ -312,12 +310,10 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
private NvInternalResult Remap(Span<RemapArguments> arguments)
{
- AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Context);
+ MemoryManager gmm = _asContext.Gmm;
for (int index = 0; index < arguments.Length; index++)
{
- MemoryManager gmm = GetAddressSpaceContext(Context).Gmm;
-
ulong mapOffs = (ulong)arguments[index].MapOffset << 16;
ulong gpuVa = (ulong)arguments[index].GpuOffset << 16;
ulong size = (ulong)arguments[index].Pages << 16;
@@ -345,10 +341,5 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
}
public override void Close() { }
-
- public static AddressSpaceContext GetAddressSpaceContext(ServiceCtx context)
- {
- return _addressSpaceContextRegistry.GetOrAdd(context.Process, (key) => new AddressSpaceContext(context));
- }
}
}
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs
index 4e7f82ef..ab9d798e 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs
@@ -34,9 +34,9 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types
private readonly SortedList<ulong, Range> _maps;
private readonly SortedList<ulong, Range> _reservations;
- public AddressSpaceContext(ServiceCtx context)
+ public AddressSpaceContext(MemoryManager gmm)
{
- Gmm = context.Device.Gpu.MemoryManager;
+ Gmm = gmm;
_maps = new SortedList<ulong, Range>();
_reservations = new SortedList<ulong, Range>();
@@ -123,7 +123,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types
return _reservations.Remove(gpuVa);
}
- private Range BinarySearch(SortedList<ulong, Range> list, ulong address)
+ private static Range BinarySearch(SortedList<ulong, Range> list, ulong address)
{
int left = 0;
int right = list.Count - 1;
@@ -154,7 +154,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types
return null;
}
- private Range BinarySearchLt(SortedList<ulong, Range> list, ulong address)
+ private static Range BinarySearchLt(SortedList<ulong, Range> list, ulong address)
{
Range ltRg = null;
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs
index 644fc835..ebaab0c9 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs
@@ -1,13 +1,13 @@
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu;
using Ryujinx.Graphics.Gpu.Memory;
-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 Ryujinx.Memory;
using System;
+using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -15,6 +15,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
{
class NvHostChannelDeviceFile : NvDeviceFile
{
+ private static readonly ConcurrentDictionary<long, Host1xContext> _host1xContextRegistry = new();
+
private const uint MaxModuleSyncpoint = 16;
private uint _timeout;
@@ -24,8 +26,9 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
private readonly Switch _device;
private readonly IVirtualMemoryManager _memory;
- private readonly NvMemoryAllocator _memoryAllocator;
- private readonly GpuChannel _channel;
+ private readonly Host1xContext _host1xContext;
+
+ public GpuChannel Channel { get; }
public enum ResourcePolicy
{
@@ -43,13 +46,13 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
public NvHostChannelDeviceFile(ServiceCtx context, IVirtualMemoryManager memory, long owner) : base(context, owner)
{
- _device = context.Device;
- _memory = memory;
- _timeout = 3000;
- _submitTimeout = 0;
- _timeslice = 0;
- _memoryAllocator = _device.MemoryAllocator;
- _channel = _device.Gpu.CreateChannel();
+ _device = context.Device;
+ _memory = memory;
+ _timeout = 3000;
+ _submitTimeout = 0;
+ _timeslice = 0;
+ _host1xContext = GetHost1XContext(context.Device.Gpu, owner);
+ Channel = _device.Gpu.CreateChannel();
ChannelSyncpoints = new uint[MaxModuleSyncpoint];
@@ -162,7 +165,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
var data = _memory.GetSpan(map.Address + commandBuffer.Offset, commandBuffer.WordsCount * 4);
- _device.Host1x.Submit(MemoryMarshal.Cast<byte, int>(data));
+ _host1xContext.Host1x.Submit(MemoryMarshal.Cast<byte, int>(data));
}
}
@@ -172,7 +175,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
tmpCmdBuff[0] = (4 << 28) | (int)fences[0].Id;
- _device.Host1x.Submit(tmpCmdBuff);
+ _host1xContext.Host1x.Submit(tmpCmdBuff);
return NvInternalResult.Success;
}
@@ -233,7 +236,6 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
int headerSize = Unsafe.SizeOf<MapCommandBufferArguments>();
MapCommandBufferArguments commandBufferHeader = MemoryMarshal.Cast<byte, MapCommandBufferArguments>(arguments)[0];
Span<CommandBufferHandle> commandBufferEntries = MemoryMarshal.Cast<byte, CommandBufferHandle>(arguments.Slice(headerSize)).Slice(0, commandBufferHeader.NumEntries);
- MemoryManager gmm = NvHostAsGpuDeviceFile.GetAddressSpaceContext(Context).Gmm;
foreach (ref CommandBufferHandle commandBufferEntry in commandBufferEntries)
{
@@ -250,12 +252,12 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
{
if (map.DmaMapAddress == 0)
{
- ulong va = _memoryAllocator.GetFreeAddress((ulong) map.Size, out ulong freeAddressStartPosition, 1, MemoryManager.PageSize);
+ ulong va = _host1xContext.MemoryAllocator.GetFreeAddress((ulong)map.Size, out ulong freeAddressStartPosition, 1, MemoryManager.PageSize);
if (va != NvMemoryAllocator.PteUnmapped && va <= uint.MaxValue && (va + (uint)map.Size) <= uint.MaxValue)
{
- _memoryAllocator.AllocateRange(va, (uint)map.Size, freeAddressStartPosition);
- gmm.Map(map.Address, va, (uint)map.Size);
+ _host1xContext.MemoryAllocator.AllocateRange(va, (uint)map.Size, freeAddressStartPosition);
+ _host1xContext.Smmu.Map(map.Address, va, (uint)map.Size);
map.DmaMapAddress = va;
}
else
@@ -276,7 +278,6 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
int headerSize = Unsafe.SizeOf<MapCommandBufferArguments>();
MapCommandBufferArguments commandBufferHeader = MemoryMarshal.Cast<byte, MapCommandBufferArguments>(arguments)[0];
Span<CommandBufferHandle> commandBufferEntries = MemoryMarshal.Cast<byte, CommandBufferHandle>(arguments.Slice(headerSize)).Slice(0, commandBufferHeader.NumEntries);
- MemoryManager gmm = NvHostAsGpuDeviceFile.GetAddressSpaceContext(Context).Gmm;
foreach (ref CommandBufferHandle commandBufferEntry in commandBufferEntries)
{
@@ -297,7 +298,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
// 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);
+ // _host1xContext.MemoryAllocator.Free((ulong)map.DmaMapAddress, (uint)map.Size);
// map.DmaMapAddress = 0;
}
@@ -431,10 +432,10 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
if (header.Flags.HasFlag(SubmitGpfifoFlags.FenceWait) && !_device.System.HostSyncpoint.IsSyncpointExpired(header.Fence.Id, header.Fence.Value))
{
- _channel.PushHostCommandBuffer(CreateWaitCommandBuffer(header.Fence));
+ Channel.PushHostCommandBuffer(CreateWaitCommandBuffer(header.Fence));
}
- _channel.PushEntries(entries);
+ Channel.PushEntries(entries);
header.Fence.Id = _channelSyncpoint.Id;
@@ -456,7 +457,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
if (header.Flags.HasFlag(SubmitGpfifoFlags.FenceIncrement))
{
- _channel.PushHostCommandBuffer(CreateIncrementCommandBuffer(ref header.Fence, header.Flags));
+ Channel.PushHostCommandBuffer(CreateIncrementCommandBuffer(ref header.Fence, header.Flags));
}
header.Flags = SubmitGpfifoFlags.None;
@@ -545,7 +546,22 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel
public override void Close()
{
- _channel.Dispose();
+ Channel.Dispose();
+ }
+
+ private static Host1xContext GetHost1XContext(GpuContext gpu, long pid)
+ {
+ return _host1xContextRegistry.GetOrAdd(pid, (long key) => new Host1xContext(gpu, key));
+ }
+
+ public static void Destroy()
+ {
+ foreach (Host1xContext host1xContext in _host1xContextRegistry.Values)
+ {
+ host1xContext.Dispose();
+ }
+
+ _host1xContextRegistry.Clear();
}
}
}
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvMemoryAllocator.cs b/Ryujinx.HLE/HOS/Services/Nv/NvMemoryAllocator.cs
index 44746db6..7369bee5 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvMemoryAllocator.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvMemoryAllocator.cs
@@ -4,7 +4,7 @@ using System;
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Common.Logging;
-namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices
+namespace Ryujinx.HLE.HOS.Services.Nv
{
class NvMemoryAllocator
{
diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
index 9d8e526f..6e56aefa 100644
--- a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
+++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
@@ -49,8 +49,8 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
private class TextureCallbackInformation
{
- public Layer Layer;
- public BufferItem Item;
+ public Layer Layer;
+ public BufferItem Item;
}
public SurfaceFlinger(Switch device)
@@ -385,6 +385,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
}
_device.Gpu.Window.EnqueueFrameThreadSafe(
+ layer.Owner,
frameBufferAddress,
frameBufferWidth,
frameBufferHeight,