kenji-nx/src/Ryujinx.Audio/Renderer/Server/MemoryPool/AddressInfo.cs
LotP c0b7452cb5 SDK20 and REV15 support
* Fixed an issue where games would boot loop because of an incorrect HID state.

  * Turns out the SamplingNumber of the atomic input storage doesn't match the SamplingNumber of the input state held by the atomic storage, instead it is exactly double the value in the input state.

* Added new Condition struct to the HID Shared memory and populate it with dummy data to fix the no-controller crash (already merged).

* The audio renderer has been mostly updated to rev15, allowing rev15 games to launch.

  * Biquad filters now use floats.

  * Several structures have been renamed to match the SDK names, making it easier to compare functionality. A few names are still missing and will be changed at a later date.

  * The new commands from rev15 have been added to the CommandType enum, but they are still missing from the code itself.

    * Due to changes in the SDK layout, the time estimation functions are either missing or very well hidden (or Ghidra search functionality is useless). We can't fully implement the new commands until the timing data has been located.

  * A few minor tweaks to the code have been made to more accurately match the SDK.
2025-10-11 10:39:50 -05:00

133 lines
4.3 KiB
C#

using System;
using System.Runtime.InteropServices;
using CpuAddress = System.UInt64;
using DspAddress = System.UInt64;
namespace Ryujinx.Audio.Renderer.Server.MemoryPool
{
/// <summary>
/// Represents the information of a region shared between the CPU and DSP.
/// </summary>
public struct AddressInfo
{
/// <summary>
/// The target CPU address of the region.
/// </summary>
public CpuAddress CpuAddress;
/// <summary>
/// The size of the region.
/// </summary>
public ulong Size;
private unsafe MemoryPoolInfo* _memoryPools;
/// <summary>
/// The forced DSP address of the region.
/// </summary>
public DspAddress ForceMappedDspAddress;
private readonly unsafe ref MemoryPoolInfo MemoryPoolInfo => ref *_memoryPools;
public readonly unsafe bool HasMemoryPoolState => (IntPtr)_memoryPools != IntPtr.Zero;
/// <summary>
/// Create an new empty <see cref="AddressInfo"/>.
/// </summary>
/// <returns>A new empty <see cref="AddressInfo"/>.</returns>
public static AddressInfo Create()
{
return Create(0, 0);
}
/// <summary>
/// Create a new <see cref="AddressInfo"/>.
/// </summary>
/// <param name="cpuAddress">The target <see cref="CpuAddress"/> of the region.</param>
/// <param name="size">The target size of the region.</param>
/// <returns>A new <see cref="AddressInfo"/>.</returns>
public static AddressInfo Create(CpuAddress cpuAddress, ulong size)
{
unsafe
{
return new AddressInfo
{
CpuAddress = cpuAddress,
_memoryPools = MemoryPoolInfo.Null,
Size = size,
ForceMappedDspAddress = 0,
};
}
}
/// <summary>
/// Setup the CPU address and size of the <see cref="AddressInfo"/>.
/// </summary>
/// <param name="cpuAddress">The target <see cref="CpuAddress"/> of the region.</param>
/// <param name="size">The size of the region.</param>
public void Setup(CpuAddress cpuAddress, ulong size)
{
CpuAddress = cpuAddress;
Size = size;
ForceMappedDspAddress = 0;
unsafe
{
_memoryPools = MemoryPoolInfo.Null;
}
}
/// <summary>
/// Set the <see cref="MemoryPoolInfo"/> associated.
/// </summary>
/// <param name="memoryPoolState">The <see cref="MemoryPoolInfo"/> associated.</param>
public void SetupMemoryPool(Span<MemoryPoolInfo> memoryPoolState)
{
unsafe
{
fixed (MemoryPoolInfo* ptr = &MemoryMarshal.GetReference(memoryPoolState))
{
SetupMemoryPool(ptr);
}
}
}
/// <summary>
/// Set the <see cref="MemoryPoolInfo"/> associated.
/// </summary>
/// <param name="memoryPoolState">The <see cref="MemoryPoolInfo"/> associated.</param>
public unsafe void SetupMemoryPool(MemoryPoolInfo* memoryPoolState)
{
_memoryPools = memoryPoolState;
}
/// <summary>
/// Check if the <see cref="MemoryPoolInfo"/> is mapped.
/// </summary>
/// <returns>Returns true if the <see cref="MemoryPoolInfo"/> is mapped.</returns>
public readonly bool HasMappedMemoryPool()
{
return HasMemoryPoolState && MemoryPoolInfo.IsMapped();
}
/// <summary>
/// Get the DSP address associated to the <see cref="AddressInfo"/>.
/// </summary>
/// <param name="markUsed">If true, mark the <see cref="MemoryPoolInfo"/> as used.</param>
/// <returns>Returns the DSP address associated to the <see cref="AddressInfo"/>.</returns>
public readonly DspAddress GetReference(bool markUsed)
{
if (!HasMappedMemoryPool())
{
return ForceMappedDspAddress;
}
if (markUsed)
{
MemoryPoolInfo.IsUsed = true;
}
return MemoryPoolInfo.Translate(CpuAddress, Size);
}
}
}