SDK20 and REV15 support (ryubing/ryujinx!50)

See merge request ryubing/ryujinx!50
This commit is contained in:
LotP
2025-10-11 02:11:39 -05:00
committed by GreemDev
parent 4444ecae41
commit e2143d43bc
83 changed files with 2343 additions and 1195 deletions

View File

@@ -55,22 +55,27 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// If set to true, the previous mix volume is explicitly resetted using the input parameter, instead of implicitly on first use.
/// </summary>
public bool IsSplitterPrevVolumeResetSupported { get; private set; }
/// <summary>
/// If set to true, the previous mix volume is explicitly resetted using the input parameter, instead of implicitly on first use.
/// </summary>
public bool IsBiquadFilterParameterFloatSupported { get; private set; }
/// <summary>
/// Initialize <see cref="SplitterContext"/>.
/// </summary>
/// <param name="behaviourContext">The behaviour context.</param>
/// <param name="behaviourInfo">The behaviour context.</param>
/// <param name="parameter">The audio renderer configuration.</param>
/// <param name="workBufferAllocator">The <see cref="WorkBufferAllocator"/>.</param>
/// <param name="splitterBqfStates">Memory to store the biquad filtering state for splitters during processing.</param>
/// <returns>Return true if the initialization was successful.</returns>
public bool Initialize(
ref BehaviourContext behaviourContext,
ref BehaviourInfo behaviourInfo,
ref AudioRendererConfiguration parameter,
WorkBufferAllocator workBufferAllocator,
Memory<BiquadFilterState> splitterBqfStates)
{
if (!behaviourContext.IsSplitterSupported() || parameter.SplitterCount <= 0 || parameter.SplitterDestinationCount <= 0)
if (!behaviourInfo.IsSplitterSupported() || parameter.SplitterCount <= 0 || parameter.SplitterDestinationCount <= 0)
{
Setup(Memory<SplitterState>.Empty, Memory<SplitterDestinationVersion1>.Empty, Memory<SplitterDestinationVersion2>.Empty, false);
@@ -94,7 +99,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
Memory<SplitterDestinationVersion1> splitterDestinationsV1 = Memory<SplitterDestinationVersion1>.Empty;
Memory<SplitterDestinationVersion2> splitterDestinationsV2 = Memory<SplitterDestinationVersion2>.Empty;
if (!behaviourContext.IsBiquadFilterParameterForSplitterEnabled())
if (!behaviourInfo.IsBiquadFilterParameterForSplitterEnabled())
{
Version = 1;
@@ -144,11 +149,12 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
}
}
IsSplitterPrevVolumeResetSupported = behaviourContext.IsSplitterPrevVolumeResetSupported();
IsSplitterPrevVolumeResetSupported = behaviourInfo.IsSplitterPrevVolumeResetSupported();
IsBiquadFilterParameterFloatSupported = behaviourInfo.IsBiquadFilterParameterFloatSupported();
SplitterState.InitializeSplitters(splitters.Span);
Setup(splitters, splitterDestinationsV1, splitterDestinationsV2, behaviourContext.IsSplitterBugFixed());
Setup(splitters, splitterDestinationsV1, splitterDestinationsV2, behaviourInfo.IsSplitterBugFixed());
return true;
}
@@ -157,16 +163,16 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// Get the work buffer size while adding the size needed for splitter to operate.
/// </summary>
/// <param name="size">The current size.</param>
/// <param name="behaviourContext">The behaviour context.</param>
/// <param name="behaviourInfo">The behaviour context.</param>
/// <param name="parameter">The renderer configuration.</param>
/// <returns>Return the new size taking splitter into account.</returns>
public static ulong GetWorkBufferSize(ulong size, ref BehaviourContext behaviourContext, ref AudioRendererConfiguration parameter)
public static ulong GetWorkBufferSize(ulong size, ref BehaviourInfo behaviourInfo, ref AudioRendererConfiguration parameter)
{
if (behaviourContext.IsSplitterSupported())
if (behaviourInfo.IsSplitterSupported())
{
size = WorkBufferAllocator.GetTargetSize<SplitterState>(size, parameter.SplitterCount, SplitterState.Alignment);
if (behaviourContext.IsBiquadFilterParameterForSplitterEnabled())
if (behaviourInfo.IsBiquadFilterParameterForSplitterEnabled())
{
size = WorkBufferAllocator.GetTargetSize<SplitterDestinationVersion2>(size, parameter.SplitterDestinationCount, SplitterDestinationVersion2.Alignment);
}
@@ -175,12 +181,10 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
size = WorkBufferAllocator.GetTargetSize<SplitterDestinationVersion1>(size, parameter.SplitterDestinationCount, SplitterDestinationVersion1.Alignment);
}
if (behaviourContext.IsSplitterBugFixed())
if (behaviourInfo.IsSplitterBugFixed())
{
size = WorkBufferAllocator.GetTargetSize<int>(size, parameter.SplitterDestinationCount, 0x10);
}
return size;
}
return size;
@@ -227,7 +231,16 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
return 0;
}
int length = _splitterDestinationsV2.IsEmpty ? _splitterDestinationsV1.Length : _splitterDestinationsV2.Length;
int length;
if (_splitterDestinationsV2.IsEmpty)
{
length = _splitterDestinationsV1.Length;
}
else
{
length = _splitterDestinationsV2.Length;
}
return length / _splitters.Length;
}
@@ -278,8 +291,17 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
if (parameter.IsMagicValid())
{
int length = _splitterDestinationsV2.IsEmpty ? _splitterDestinationsV1.Length : _splitterDestinationsV2.Length;
int length;
if (_splitterDestinationsV2.IsEmpty)
{
length = _splitterDestinationsV1.Length;
}
else
{
length = _splitterDestinationsV2.Length;
}
if (parameter.Id >= 0 && parameter.Id < length)
{
SplitterDestination destination = GetDestination(parameter.Id);
@@ -315,9 +337,19 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
}
else if (Version == 2)
{
if (!UpdateData<SplitterDestinationInParameterVersion2>(ref input))
if (IsBiquadFilterParameterFloatSupported)
{
break;
if (!UpdateData<SplitterDestinationInParameterVersion2b>(ref input))
{
break;
}
}
else
{
if (!UpdateData<SplitterDestinationInParameterVersion2a>(ref input))
{
break;
}
}
}
else
@@ -381,10 +413,8 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return new SplitterDestination(ref SpanIOHelper.GetFromMemory(_splitterDestinationsV1, id, (uint)_splitterDestinationsV1.Length));
}
else
{
return new SplitterDestination(ref SpanIOHelper.GetFromMemory(_splitterDestinationsV2, id, (uint)_splitterDestinationsV2.Length));
}
return new SplitterDestination(ref SpanIOHelper.GetFromMemory(_splitterDestinationsV2, id, (uint)_splitterDestinationsV2.Length));
}
/// <summary>

View File

@@ -31,15 +31,11 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return 0;
}
else
{
return _v1.Id;
}
}
else
{
return _v2.Id;
return _v1.Id;
}
return _v2.Id;
}
}
@@ -56,15 +52,11 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return 0;
}
else
{
return _v1.DestinationId;
}
}
else
{
return _v2.DestinationId;
return _v1.DestinationId;
}
return _v2.DestinationId;
}
}
@@ -82,15 +74,11 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return Span<float>.Empty;
}
else
{
return _v1.MixBufferVolume;
}
}
else
{
return _v2.MixBufferVolume;
return _v1.MixBufferVolume;
}
return _v2.MixBufferVolume;
}
}
@@ -108,15 +96,11 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return Span<float>.Empty;
}
else
{
return _v1.PreviousMixBufferVolume;
}
}
else
{
return _v2.PreviousMixBufferVolume;
return _v1.PreviousMixBufferVolume;
}
return _v2.PreviousMixBufferVolume;
}
}
@@ -135,15 +119,11 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return new SplitterDestination();
}
else
{
return new SplitterDestination(ref _v1.Next);
}
}
else
{
return new SplitterDestination(ref _v2.Next);
return new SplitterDestination(ref _v1.Next);
}
return new SplitterDestination(ref _v2.Next);
}
}
}
@@ -169,6 +149,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
_v2 = ref v2;
}
/// <summary>
/// Creates a new splitter destination wrapper for the splitter destination data.
/// </summary>
@@ -233,7 +214,12 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// <returns>True if the splitter destination is used and has a destination.</returns>
public readonly bool IsConfigured()
{
return Unsafe.IsNullRef(ref _v2) ? _v1.IsConfigured() : _v2.IsConfigured();
if (Unsafe.IsNullRef(ref _v2))
{
return _v1.IsConfigured();
}
return _v2.IsConfigured();
}
/// <summary>
@@ -243,7 +229,12 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// <returns>The volume for the given destination.</returns>
public float GetMixVolume(int destinationIndex)
{
return Unsafe.IsNullRef(ref _v2) ? _v1.GetMixVolume(destinationIndex) : _v2.GetMixVolume(destinationIndex);
if (Unsafe.IsNullRef(ref _v2))
{
return _v1.GetMixVolume(destinationIndex);
}
return _v2.GetMixVolume(destinationIndex);
}
/// <summary>
@@ -253,7 +244,12 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// <returns>The volume for the given destination.</returns>
public float GetMixVolumePrev(int destinationIndex)
{
return Unsafe.IsNullRef(ref _v2) ? _v1.GetMixVolumePrev(destinationIndex) : _v2.GetMixVolumePrev(destinationIndex);
if (Unsafe.IsNullRef(ref _v2))
{
return _v1.GetMixVolumePrev(destinationIndex);
}
return _v2.GetMixVolumePrev(destinationIndex);
}
/// <summary>
@@ -280,13 +276,13 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
if (Unsafe.IsNullRef(ref _v2))
{
Debug.Assert(!Unsafe.IsNullRef(ref next._v1));
_v1.Link(ref next._v1);
}
else
{
Debug.Assert(!Unsafe.IsNullRef(ref next._v2));
_v2.Link(ref next._v2);
}
}
@@ -308,6 +304,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// <summary>
/// Checks if any biquad filter is enabled.
/// Virtual function at function table + 0x8.
/// </summary>
/// <returns>True if any biquad filter is enabled.</returns>
public bool IsBiquadFilterEnabled()
@@ -326,13 +323,14 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// <summary>
/// Gets the biquad filter parameters.
/// /// Virtual function at function table + 0x10.
/// </summary>
/// <param name="index">Biquad filter index (0 or 1).</param>
/// <returns>Biquad filter parameters.</returns>
public ref BiquadFilterParameter GetBiquadFilterParameter(int index)
public ref BiquadFilterParameter2 GetBiquadFilterParameter(int index)
{
Debug.Assert(!Unsafe.IsNullRef(ref _v2));
return ref _v2.GetBiquadFilterParameter(index);
}

View File

@@ -1,3 +1,4 @@
using Ryujinx.Audio.Renderer.Dsp;
using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Common.Memory;
using Ryujinx.Common.Utilities;
@@ -11,7 +12,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// <summary>
/// Server state for a splitter destination (version 2).
/// </summary>
[StructLayout(LayoutKind.Sequential, Size = 0x110, Pack = Alignment)]
[StructLayout(LayoutKind.Sequential, Size = 0x128, Pack = Alignment)]
public struct SplitterDestinationVersion2
{
public const int Alignment = 0x10;
@@ -78,7 +79,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
}
}
private Array2<BiquadFilterParameter> _biquadFilters;
private Array2<BiquadFilterParameter2> _biquadFilters;
private Array2<bool> _isPreviousBiquadFilterEnabled;
@@ -109,7 +110,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
parameter.MixBufferVolume.CopyTo(MixBufferVolume);
_biquadFilters = parameter.BiquadFilters;
_biquadFilters = parameter.BiquadFilters2;
bool resetPrevVolume = isPrevVolumeResetSupported ? parameter.ResetPrevVolume : !IsUsed && parameter.IsUsed;
if (resetPrevVolume)
@@ -218,7 +219,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// <returns>True if any biquad filter is enabled.</returns>
public bool IsBiquadFilterEnabled()
{
Span<BiquadFilterParameter> biquadFiltersSpan = _biquadFilters.AsSpan();
Span<BiquadFilterParameter2> biquadFiltersSpan = _biquadFilters.AsSpan();
return biquadFiltersSpan[0].Enable || biquadFiltersSpan[1].Enable;
}
@@ -236,7 +237,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// </summary>
/// <param name="index">Biquad filter index (0 or 1).</param>
/// <returns>Biquad filter parameters.</returns>
public ref BiquadFilterParameter GetBiquadFilterParameter(int index)
public ref BiquadFilterParameter2 GetBiquadFilterParameter(int index)
{
return ref _biquadFilters[index];
}