diff options
| author | gdk <gab.dark.100@gmail.com> | 2019-10-13 03:02:07 -0300 |
|---|---|---|
| committer | Thog <thog@protonmail.com> | 2020-01-09 02:13:00 +0100 |
| commit | 1876b346fea647e8284a66bb6d62c38801035cff (patch) | |
| tree | 6eeff094298cda84d1613dc5ec0691e51d7b35f1 /Ryujinx.HLE/HOS/Services/Nv | |
| parent | f617fb542a0e3d36012d77a4b5acbde7b08902f2 (diff) | |
Initial work
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Nv')
7 files changed, 87 insertions, 54 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs b/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs index 2b9f09fa..a227d892 100644 --- a/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs +++ b/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs @@ -102,7 +102,9 @@ namespace Ryujinx.HLE.HOS.Services.Nv byte[] outputData = new byte[outputDataSize]; - context.Memory.ReadBytes(inputDataPosition, outputData, 0, (int)inputDataSize); + byte[] temp = context.Memory.ReadBytes(inputDataPosition, inputDataSize); + + Buffer.BlockCopy(temp, 0, outputData, 0, temp.Length); arguments = new Span<byte>(outputData); } diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvDeviceFile.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvDeviceFile.cs index 73007c91..de6c9ba9 100644 --- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvDeviceFile.cs +++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvDeviceFile.cs @@ -9,11 +9,13 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices { abstract class NvDeviceFile { + public readonly ServiceCtx Context; public readonly KProcess Owner; public NvDeviceFile(ServiceCtx context) { - Owner = context.Process; + Context = context; + Owner = context.Process; } public virtual NvInternalResult QueryEvent(out int eventHandle, uint eventId) diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs index b48377a4..84a9d3d5 100644 --- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs +++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs @@ -1,5 +1,5 @@ using Ryujinx.Common.Logging; -using Ryujinx.Graphics.Memory; +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.NvMap; @@ -79,7 +79,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu private NvInternalResult AllocSpace(ref AllocSpaceArguments arguments) { - AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Owner); + AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Context); ulong size = (ulong)arguments.Pages * (ulong)arguments.PageSize; @@ -91,11 +91,11 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu // the Offset field holds the alignment size instead. if ((arguments.Flags & AddressSpaceFlags.FixedOffset) != 0) { - arguments.Offset = addressSpaceContext.Vmm.ReserveFixed(arguments.Offset, (long)size); + arguments.Offset = (long)addressSpaceContext.Gmm.ReserveFixed((ulong)arguments.Offset, size); } else { - arguments.Offset = addressSpaceContext.Vmm.Reserve((long)size, arguments.Offset); + arguments.Offset = (long)addressSpaceContext.Gmm.Reserve((ulong)size, (ulong)arguments.Offset); } if (arguments.Offset < 0) @@ -117,7 +117,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu private NvInternalResult FreeSpace(ref FreeSpaceArguments arguments) { - AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Owner); + AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Context); NvInternalResult result = NvInternalResult.Success; @@ -127,7 +127,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu if (addressSpaceContext.RemoveReservation(arguments.Offset)) { - addressSpaceContext.Vmm.Free(arguments.Offset, (long)size); + addressSpaceContext.Gmm.Free((ulong)arguments.Offset, size); } else { @@ -143,7 +143,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu private NvInternalResult UnmapBuffer(ref UnmapBufferArguments arguments) { - AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Owner); + AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Context); lock (addressSpaceContext) { @@ -151,7 +151,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu { if (size != 0) { - addressSpaceContext.Vmm.Free(arguments.Offset, size); + addressSpaceContext.Gmm.Free((ulong)arguments.Offset, (ulong)size); } } else @@ -167,7 +167,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu { const string mapErrorMsg = "Failed to map fixed buffer with offset 0x{0:x16} and size 0x{1:x16}!"; - AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Owner); + AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Context); NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, arguments.NvMapHandle, true); @@ -190,7 +190,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu physicalAddress += arguments.BufferOffset; - if (addressSpaceContext.Vmm.Map(physicalAddress, virtualAddress, arguments.MappingSize) < 0) + if ((long)addressSpaceContext.Gmm.Map((ulong)physicalAddress, (ulong)virtualAddress, (ulong)arguments.MappingSize) < 0) { string message = string.Format(mapErrorMsg, virtualAddress, arguments.MappingSize); @@ -231,7 +231,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu { if (addressSpaceContext.ValidateFixedBuffer(arguments.Offset, size)) { - arguments.Offset = addressSpaceContext.Vmm.Map(physicalAddress, arguments.Offset, size); + arguments.Offset = (long)addressSpaceContext.Gmm.Map((ulong)physicalAddress, (ulong)arguments.Offset, (ulong)size); } else { @@ -244,7 +244,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu } else { - arguments.Offset = addressSpaceContext.Vmm.Map(physicalAddress, size); + arguments.Offset = (long)addressSpaceContext.Gmm.Map((ulong)physicalAddress, (ulong)size); } if (arguments.Offset < 0) @@ -282,7 +282,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu { for (int index = 0; index < arguments.Length; index++) { - NvGpuVmm vmm = GetAddressSpaceContext(Owner).Vmm; + MemoryManager gmm = GetAddressSpaceContext(Context).Gmm; NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, arguments[index].NvMapHandle, true); @@ -293,10 +293,10 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu return NvInternalResult.InvalidInput; } - long result = vmm.Map( - ((long)arguments[index].MapOffset << 16) + map.Address, - (long)arguments[index].GpuOffset << 16, - (long)arguments[index].Pages << 16); + long result = (long)gmm.Map( + ((ulong)arguments[index].MapOffset << 16) + (ulong)map.Address, + (ulong)arguments[index].GpuOffset << 16, + (ulong)arguments[index].Pages << 16); if (result < 0) { @@ -312,9 +312,9 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu public override void Close() { } - public static AddressSpaceContext GetAddressSpaceContext(KProcess process) + public static AddressSpaceContext GetAddressSpaceContext(ServiceCtx context) { - return _addressSpaceContextRegistry.GetOrAdd(process, (key) => new AddressSpaceContext(process)); + 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 5c283000..5238645e 100644 --- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs +++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs @@ -1,16 +1,12 @@ -using ARMeilleure.Memory; -using Ryujinx.Graphics.Memory; +using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.HLE.HOS.Kernel.Process; using System; using System.Collections.Generic; -using System.Text; namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types { class AddressSpaceContext { - public NvGpuVmm Vmm { get; private set; } - private class Range { public ulong Start { get; private set; } @@ -42,9 +38,45 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types private SortedList<long, Range> _maps; private SortedList<long, Range> _reservations; - public AddressSpaceContext(KProcess process) + public MemoryManager Gmm { get; } + + private class MemoryProxy : IPhysicalMemory + { + private ARMeilleure.Memory.MemoryManager _cpuMemory; + + public MemoryProxy(ARMeilleure.Memory.MemoryManager cpuMemory) + { + _cpuMemory = cpuMemory; + } + + public Span<byte> Read(ulong address, ulong size) + { + return _cpuMemory.ReadBytes((long)address, (long)size); + } + + public void Write(ulong address, Span<byte> data) + { + _cpuMemory.WriteBytes((long)address, data.ToArray()); + } + + public (ulong, ulong)[] GetModifiedRanges(ulong address, ulong size) + { + return _cpuMemory.GetModifiedRanges(address, size); + } + + public int GetPageSize() + { + return 4096; + } + } + + public AddressSpaceContext(ServiceCtx context) { - Vmm = new NvGpuVmm(process.CpuMemory); + Gmm = context.Device.Gpu.MemoryManager; + + var memoryProxy = new MemoryProxy(context.Process.CpuMemory); + + context.Device.Gpu.SetVmm(memoryProxy); _maps = new SortedList<long, Range>(); _reservations = new SortedList<long, Range>(); @@ -61,7 +93,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types } // Check if address is page aligned. - if ((position & NvGpuVmm.PageMask) != 0) + if ((position & (long)MemoryManager.PageMask) != 0) { return false; } diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs index 80a7ce80..72235427 100644 --- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs +++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostChannelDeviceFile.cs @@ -1,7 +1,6 @@ -using ARMeilleure.Memory; -using Ryujinx.Common.Logging; -using Ryujinx.Graphics; -using Ryujinx.Graphics.Memory; +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.NvMap; @@ -16,8 +15,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel private uint _timeout; private uint _submitTimeout; private uint _timeslice; - private NvGpu _gpu; - private MemoryManager _memory; + private GpuContext _gpu; + private ARMeilleure.Memory.MemoryManager _memory; public NvHostChannelDeviceFile(ServiceCtx context) : base(context) { @@ -110,7 +109,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel 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); - NvGpuVmm vmm = NvHostAsGpuDeviceFile.GetAddressSpaceContext(Owner).Vmm; + MemoryManager gmm = NvHostAsGpuDeviceFile.GetAddressSpaceContext(Context).Gmm; foreach (CommandBuffer commandBufferEntry in commandBufferEntries) { @@ -123,7 +122,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel commandBufferData[offset] = _memory.ReadInt32(map.Address + commandBufferEntry.Offset + offset * 4); } - _gpu.PushCommandBuffer(vmm, commandBufferData); + // TODO: Submit command to engines. } return NvInternalResult.Success; @@ -161,7 +160,7 @@ 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); - NvGpuVmm vmm = NvHostAsGpuDeviceFile.GetAddressSpaceContext(Owner).Vmm; + MemoryManager gmm = NvHostAsGpuDeviceFile.GetAddressSpaceContext(Context).Gmm; foreach (ref CommandBufferHandle commandBufferEntry in commandBufferEntries) { @@ -178,7 +177,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel { if (map.DmaMapAddress == 0) { - map.DmaMapAddress = vmm.MapLow(map.Address, map.Size); + map.DmaMapAddress = (long)gmm.MapLow((ulong)map.Address, (uint)map.Size); } commandBufferEntry.MapAddress = (int)map.DmaMapAddress; @@ -193,7 +192,7 @@ 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); - NvGpuVmm vmm = NvHostAsGpuDeviceFile.GetAddressSpaceContext(Owner).Vmm; + MemoryManager gmm = NvHostAsGpuDeviceFile.GetAddressSpaceContext(Context).Gmm; foreach (ref CommandBufferHandle commandBufferEntry in commandBufferEntries) { @@ -210,7 +209,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel { if (map.DmaMapAddress != 0) { - vmm.Free(map.DmaMapAddress, map.Size); + gmm.Free((ulong)map.DmaMapAddress, (uint)map.Size); map.DmaMapAddress = 0; } @@ -240,7 +239,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel { int headerSize = Unsafe.SizeOf<SubmitGpfifoArguments>(); SubmitGpfifoArguments gpfifoSubmissionHeader = MemoryMarshal.Cast<byte, SubmitGpfifoArguments>(arguments)[0]; - Span<long> gpfifoEntries = MemoryMarshal.Cast<byte, long>(arguments.Slice(headerSize)).Slice(0, gpfifoSubmissionHeader.NumEntries); + Span<ulong> gpfifoEntries = MemoryMarshal.Cast<byte, ulong>(arguments.Slice(headerSize)).Slice(0, gpfifoSubmissionHeader.NumEntries); return SubmitGpfifo(ref gpfifoSubmissionHeader, gpfifoEntries); } @@ -327,13 +326,11 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel return NvInternalResult.Success; } - protected NvInternalResult SubmitGpfifo(ref SubmitGpfifoArguments header, Span<long> entries) + protected NvInternalResult SubmitGpfifo(ref SubmitGpfifoArguments header, Span<ulong> entries) { - NvGpuVmm vmm = NvHostAsGpuDeviceFile.GetAddressSpaceContext(Owner).Vmm; - - foreach (long entry in entries) + foreach (ulong entry in entries) { - _gpu.Pusher.Push(vmm, entry); + _gpu.DmaPusher.Push(entry); } header.Fence.Id = 0; diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostGpuDeviceFile.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostGpuDeviceFile.cs index 582ba50e..7eaa5cc5 100644 --- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostGpuDeviceFile.cs +++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostChannel/NvHostGpuDeviceFile.cs @@ -27,7 +27,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel switch (command.Number) { case 0x1b: - result = CallIoctlMethod<SubmitGpfifoArguments, long>(SubmitGpfifoEx, arguments, inlineInBuffer); + result = CallIoctlMethod<SubmitGpfifoArguments, ulong>(SubmitGpfifoEx, arguments, inlineInBuffer); break; } } @@ -70,7 +70,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel return NvInternalResult.Success; } - private NvInternalResult SubmitGpfifoEx(ref SubmitGpfifoArguments arguments, Span<long> inlineData) + private NvInternalResult SubmitGpfifoEx(ref SubmitGpfifoArguments arguments, Span<ulong> inlineData) { return SubmitGpfifo(ref arguments, inlineData); } diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/NvMapDeviceFile.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/NvMapDeviceFile.cs index 2ca847a3..d03ede94 100644 --- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/NvMapDeviceFile.cs +++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/NvMapDeviceFile.cs @@ -1,6 +1,6 @@ using Ryujinx.Common; using Ryujinx.Common.Logging; -using Ryujinx.Graphics.Memory; +using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.HLE.HOS.Kernel.Process; using System; using System.Collections.Concurrent; @@ -73,7 +73,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap return NvInternalResult.InvalidInput; } - int size = BitUtils.AlignUp(arguments.Size, NvGpuVmm.PageSize); + int size = BitUtils.AlignUp(arguments.Size, (int)MemoryManager.PageSize); arguments.Handle = CreateHandleFromMap(new NvMapHandle(size)); @@ -118,9 +118,9 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap return NvInternalResult.InvalidInput; } - if ((uint)arguments.Align < NvGpuVmm.PageSize) + if ((uint)arguments.Align < MemoryManager.PageSize) { - arguments.Align = NvGpuVmm.PageSize; + arguments.Align = (int)MemoryManager.PageSize; } NvInternalResult result = NvInternalResult.Success; @@ -132,7 +132,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap map.Align = arguments.Align; map.Kind = (byte)arguments.Kind; - int size = BitUtils.AlignUp(map.Size, NvGpuVmm.PageSize); + int size = BitUtils.AlignUp(map.Size, (int)MemoryManager.PageSize); long address = arguments.Address; |
