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

View file

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

View file

@ -11,13 +11,13 @@ namespace Ryujinx.Horizon.Sdk.Audio.Detail
Result GetSampleCount(out int sampleCount); Result GetSampleCount(out int sampleCount);
Result GetMixBufferCount(out int mixBufferCount); Result GetMixBufferCount(out int mixBufferCount);
Result GetState(out int state); 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 Start();
Result Stop(); Result Stop();
Result QuerySystemEvent(out int eventHandle); Result QuerySystemEvent(out int eventHandle);
Result SetRenderingTimeLimit(int percent); Result SetRenderingTimeLimit(int percent);
Result GetRenderingTimeLimit(out 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 ExecuteAudioRendererRendering();
Result SetVoiceDropParameter(float voiceDropParameter); Result SetVoiceDropParameter(float voiceDropParameter);
Result GetVoiceDropParameter(out float voiceDropParameter); Result GetVoiceDropParameter(out float voiceDropParameter);