- add support to HipcGenerator for buffers of type Memory<byte>

- change `AudioRenderer` `RequestUpdate()` and `RequestUpdateAuto()` to use Memory<byte> for output buffers, removing another memory block allocation/copy
This commit is contained in:
jhorv 2024-04-05 19:44:17 -04:00
parent 697ac394cb
commit b57d0e14fa
3 changed files with 27 additions and 22 deletions

View file

@ -18,6 +18,7 @@ namespace Ryujinx.Horizon.Generators.Hipc
private const string OutRawDataVariableName = "outRawData";
private const string TypeSystemBuffersReadOnlySequence = "System.Buffers.ReadOnlySequence";
private const string TypeSystemMemory = "System.Memory";
private const string TypeSystemReadOnlySpan = "System.ReadOnlySpan";
private const string TypeSystemSpan = "System.Span";
private const string TypeStructLayoutAttribute = "System.Runtime.InteropServices.StructLayoutAttribute";
@ -330,7 +331,11 @@ namespace Ryujinx.Horizon.Generators.Hipc
value = $"{InObjectsVariableName}[{inObjectIndex++}]";
break;
case CommandArgType.Buffer:
if (IsReadOnlySequence(compilation, parameter))
if (IsMemory(compilation, parameter))
{
value = $"CommandSerialization.GetWritableRegion(processor.GetBufferRange({index}))";
}
else if (IsReadOnlySequence(compilation, parameter))
{
value = $"CommandSerialization.GetReadOnlySequence(processor.GetBufferRange({index}))";
}
@ -351,7 +356,13 @@ namespace Ryujinx.Horizon.Generators.Hipc
break;
}
if (IsSpan(compilation, parameter))
if (IsMemory(compilation, parameter))
{
generator.AppendLine($"using var {argName} = {value};");
argName = $"{argName}.Memory";
}
else if (IsSpan(compilation, parameter))
{
generator.AppendLine($"using var {argName} = {value};");
@ -642,7 +653,8 @@ namespace Ryujinx.Horizon.Generators.Hipc
private static bool IsValidTypeForBuffer(Compilation compilation, ParameterSyntax parameter)
{
return IsReadOnlySequence(compilation, parameter) ||
return IsMemory(compilation, parameter) ||
IsReadOnlySequence(compilation, parameter) ||
IsReadOnlySpan(compilation, parameter) ||
IsSpan(compilation, parameter) ||
IsUnmanagedType(compilation, parameter.Type);
@ -655,6 +667,11 @@ namespace Ryujinx.Horizon.Generators.Hipc
return typeInfo.Type.IsUnmanagedType;
}
private static bool IsMemory(Compilation compilation, ParameterSyntax parameter)
{
return GetCanonicalTypeName(compilation, parameter.Type) == TypeSystemMemory;
}
private static bool IsReadOnlySequence(Compilation compilation, ParameterSyntax parameter)
{
return GetCanonicalTypeName(compilation, parameter.Type) == TypeSystemBuffersReadOnlySequence;

View file

@ -57,23 +57,11 @@ namespace Ryujinx.Horizon.Sdk.Audio.Detail
[CmifCommand(4)]
public Result RequestUpdate(
[Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span<byte> output,
[Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span<byte> performanceOutput,
[Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Memory<byte> output,
[Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Memory<byte> performanceOutput,
[Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySequence<byte> input)
{
using IMemoryOwner<byte> outputOwner = ByteMemoryPool.Rent(output.Length);
using IMemoryOwner<byte> performanceOutputOwner = ByteMemoryPool.Rent(performanceOutput.Length);
Memory<byte> outputMemory = outputOwner.Memory;
Memory<byte> performanceOutputMemory = performanceOutputOwner.Memory;
using MemoryHandle outputHandle = outputMemory.Pin();
using MemoryHandle performanceOutputHandle = performanceOutputMemory.Pin();
Result result = new Result((int)_renderSystem.Update(outputMemory, performanceOutputMemory, input));
outputMemory.Span.CopyTo(output);
performanceOutputMemory.Span.CopyTo(performanceOutput);
Result result = new Result((int)_renderSystem.Update(output, performanceOutput, input));
return result;
}
@ -127,8 +115,8 @@ namespace Ryujinx.Horizon.Sdk.Audio.Detail
[CmifCommand(10)] // 3.0.0+
public Result RequestUpdateAuto(
[Buffer(HipcBufferFlags.Out | HipcBufferFlags.AutoSelect)] Span<byte> output,
[Buffer(HipcBufferFlags.Out | HipcBufferFlags.AutoSelect)] Span<byte> performanceOutput,
[Buffer(HipcBufferFlags.Out | HipcBufferFlags.AutoSelect)] Memory<byte> output,
[Buffer(HipcBufferFlags.Out | HipcBufferFlags.AutoSelect)] Memory<byte> performanceOutput,
[Buffer(HipcBufferFlags.In | HipcBufferFlags.AutoSelect)] ReadOnlySequence<byte> input)
{
return RequestUpdate(output, performanceOutput, input);

View file

@ -11,13 +11,13 @@ namespace Ryujinx.Horizon.Sdk.Audio.Detail
Result GetSampleCount(out int sampleCount);
Result GetMixBufferCount(out int mixBufferCount);
Result GetState(out int state);
Result RequestUpdate(Span<byte> output, Span<byte> performanceOutput, ReadOnlySequence<byte> input);
Result RequestUpdate(Memory<byte> output, Memory<byte> performanceOutput, ReadOnlySequence<byte> input);
Result Start();
Result Stop();
Result QuerySystemEvent(out int eventHandle);
Result SetRenderingTimeLimit(int percent);
Result GetRenderingTimeLimit(out int percent);
Result RequestUpdateAuto(Span<byte> output, Span<byte> performanceOutput, ReadOnlySequence<byte> input);
Result RequestUpdateAuto(Memory<byte> output, Memory<byte> performanceOutput, ReadOnlySequence<byte> input);
Result ExecuteAudioRendererRendering();
Result SetVoiceDropParameter(float voiceDropParameter);
Result GetVoiceDropParameter(out float voiceDropParameter);