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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }