// // Copyright (c) 2019-2021 Ryujinx // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . // using System; using System.Runtime.InteropServices; using DspAddress = System.UInt64; using CpuAddress = System.UInt64; namespace Ryujinx.Audio.Renderer.Server.MemoryPool { /// /// Server state for a memory pool. /// [StructLayout(LayoutKind.Sequential, Size = 0x20, Pack = Alignment)] public struct MemoryPoolState { public const int Alignment = 0x10; /// /// The location of the . /// public enum LocationType : uint { /// /// located on the CPU side for user use. /// Cpu, /// /// located on the DSP side for system use. /// Dsp } /// /// The CPU address associated to the . /// public CpuAddress CpuAddress; /// /// The DSP address associated to the . /// public DspAddress DspAddress; /// /// The size associated to the . /// public ulong Size; /// /// The associated to the . /// public LocationType Location; /// /// Set to true if the is used. /// [MarshalAs(UnmanagedType.I1)] public bool IsUsed; public static unsafe MemoryPoolState* Null => (MemoryPoolState*)IntPtr.Zero.ToPointer(); /// /// Create a new with the given . /// /// The location type to use. /// A new with the given . public static MemoryPoolState Create(LocationType location) { return new MemoryPoolState { CpuAddress = 0, DspAddress = 0, Size = 0, Location = location }; } /// /// Set the and size of the . /// /// The . /// The size. public void SetCpuAddress(CpuAddress cpuAddress, ulong size) { CpuAddress = cpuAddress; Size = size; } /// /// Check if the given and size is contains in the . /// /// The . /// The size. /// True if the is contained inside the . public bool Contains(CpuAddress targetCpuAddress, ulong size) { if (CpuAddress <= targetCpuAddress && size + targetCpuAddress <= Size + CpuAddress) { return true; } return false; } /// /// Translate the given CPU address to a DSP address. /// /// The . /// The size. /// the target DSP address. public DspAddress Translate(CpuAddress targetCpuAddress, ulong size) { if (Contains(targetCpuAddress, size) && IsMapped()) { ulong offset = targetCpuAddress - CpuAddress; return DspAddress + offset; } return 0; } /// /// Is the mapped on the DSP? /// /// Returns true if the is mapped on the DSP. public bool IsMapped() { return DspAddress != 0; } } }