private NvInternalResult UnmapCommandBuffer(Span <byte> arguments) { 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) { NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, commandBufferEntry.MapHandle); if (map == null) { Logger.PrintWarning(LogClass.ServiceNv, $"Invalid handle 0x{commandBufferEntry.MapHandle:x8}!"); return(NvInternalResult.InvalidInput); } lock (map) { if (map.DmaMapAddress != 0) { gmm.Free((ulong)map.DmaMapAddress, (uint)map.Size); map.DmaMapAddress = 0; } } } return(NvInternalResult.Success); }
private NvInternalResult UnmapCommandBuffer(Span <byte> arguments) { 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) { NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, commandBufferEntry.MapHandle); if (map == null) { Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid handle 0x{commandBufferEntry.MapHandle:x8}!"); return(NvInternalResult.InvalidInput); } lock (map) { if (map.DmaMapAddress != 0) { // 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; } } } return(NvInternalResult.Success); }
protected NvInternalResult SubmitGpfifo(ref SubmitGpfifoArguments header, Span <long> entries) { NvGpuVmm vmm = NvHostAsGpuDeviceFile.GetAddressSpaceContext(Owner).Vmm; foreach (long entry in entries) { _gpu.Pusher.Push(vmm, entry); } header.Fence.Id = 0; header.Fence.Value = 0; return(NvInternalResult.Success); }
private NvInternalResult MapCommandBuffer(Span <byte> arguments) { 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) { NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, commandBufferEntry.MapHandle); if (map == null) { Logger.Warning?.Print(LogClass.ServiceNv, $"Invalid handle 0x{commandBufferEntry.MapHandle:x8}!"); return(NvInternalResult.InvalidInput); } lock (map) { if (map.DmaMapAddress == 0) { ulong va = _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); map.DmaMapAddress = va; } else { map.DmaMapAddress = NvMemoryAllocator.PteUnmapped; } } commandBufferEntry.MapAddress = (int)map.DmaMapAddress; } } return(NvInternalResult.Success); }
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) { NvMapHandle map = NvMapDeviceFile.GetMapFromHandle(Owner, commandBufferEntry.MemoryId); int[] commandBufferData = new int[commandBufferEntry.WordsCount]; for (int offset = 0; offset < commandBufferData.Length; offset++) { commandBufferData[offset] = _memory.ReadInt32(map.Address + commandBufferEntry.Offset + offset * 4); } // TODO: Submit command to engines. } return(NvInternalResult.Success); }