forked from Mirror/Ryujinx
Allocate work buffer for audio renderer instead of using guest supplied memory (#3276)
* Allocate work buffer for audio renderer instead of using guest supplied memory * Typo * Use GC.AllocateArray to allocate pinned array
This commit is contained in:
parent
c64524a240
commit
81f1a4dc31
4 changed files with 60 additions and 12 deletions
|
@ -55,7 +55,6 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||||
private uint _processHandle;
|
private uint _processHandle;
|
||||||
private ulong _appletResourceId;
|
private ulong _appletResourceId;
|
||||||
|
|
||||||
private WritableRegion _workBufferRegion;
|
|
||||||
private MemoryHandle _workBufferMemoryPin;
|
private MemoryHandle _workBufferMemoryPin;
|
||||||
|
|
||||||
private Memory<float> _mixBuffer;
|
private Memory<float> _mixBuffer;
|
||||||
|
@ -98,7 +97,15 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||||
_sessionId = 0;
|
_sessionId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultCode Initialize(ref AudioRendererConfiguration parameter, uint processHandle, CpuAddress workBuffer, ulong workBufferSize, int sessionId, ulong appletResourceId, IVirtualMemoryManager memoryManager)
|
public ResultCode Initialize(
|
||||||
|
ref AudioRendererConfiguration parameter,
|
||||||
|
uint processHandle,
|
||||||
|
Memory<byte> workBufferMemory,
|
||||||
|
CpuAddress workBuffer,
|
||||||
|
ulong workBufferSize,
|
||||||
|
int sessionId,
|
||||||
|
ulong appletResourceId,
|
||||||
|
IVirtualMemoryManager memoryManager)
|
||||||
{
|
{
|
||||||
if (!BehaviourContext.CheckValidRevision(parameter.Revision))
|
if (!BehaviourContext.CheckValidRevision(parameter.Revision))
|
||||||
{
|
{
|
||||||
|
@ -134,11 +141,10 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||||
|
|
||||||
WorkBufferAllocator workBufferAllocator;
|
WorkBufferAllocator workBufferAllocator;
|
||||||
|
|
||||||
_workBufferRegion = MemoryManager.GetWritableRegion(workBuffer, (int)workBufferSize);
|
workBufferMemory.Span.Fill(0);
|
||||||
_workBufferRegion.Memory.Span.Fill(0);
|
_workBufferMemoryPin = workBufferMemory.Pin();
|
||||||
_workBufferMemoryPin = _workBufferRegion.Memory.Pin();
|
|
||||||
|
|
||||||
workBufferAllocator = new WorkBufferAllocator(_workBufferRegion.Memory);
|
workBufferAllocator = new WorkBufferAllocator(workBufferMemory);
|
||||||
|
|
||||||
PoolMapper poolMapper = new PoolMapper(processHandle, false);
|
PoolMapper poolMapper = new PoolMapper(processHandle, false);
|
||||||
poolMapper.InitializeSystemPool(ref _dspMemoryPoolState, workBuffer, workBufferSize);
|
poolMapper.InitializeSystemPool(ref _dspMemoryPoolState, workBuffer, workBufferSize);
|
||||||
|
@ -841,7 +847,6 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||||
_manager.Unregister(this);
|
_manager.Unregister(this);
|
||||||
_terminationEvent.Dispose();
|
_terminationEvent.Dispose();
|
||||||
_workBufferMemoryPin.Dispose();
|
_workBufferMemoryPin.Dispose();
|
||||||
_workBufferRegion.Dispose();
|
|
||||||
|
|
||||||
if (MemoryManager is IRefCounted rc)
|
if (MemoryManager is IRefCounted rc)
|
||||||
{
|
{
|
||||||
|
|
|
@ -305,13 +305,34 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||||
/// <param name="workBufferSize">The guest work buffer size.</param>
|
/// <param name="workBufferSize">The guest work buffer size.</param>
|
||||||
/// <param name="processHandle">The process handle of the application.</param>
|
/// <param name="processHandle">The process handle of the application.</param>
|
||||||
/// <returns>A <see cref="ResultCode"/> reporting an error or a success.</returns>
|
/// <returns>A <see cref="ResultCode"/> reporting an error or a success.</returns>
|
||||||
public ResultCode OpenAudioRenderer(out AudioRenderSystem renderer, IVirtualMemoryManager memoryManager, ref AudioRendererConfiguration parameter, ulong appletResourceUserId, ulong workBufferAddress, ulong workBufferSize, uint processHandle, float volume)
|
public ResultCode OpenAudioRenderer(
|
||||||
|
out AudioRenderSystem renderer,
|
||||||
|
IVirtualMemoryManager memoryManager,
|
||||||
|
ref AudioRendererConfiguration parameter,
|
||||||
|
ulong appletResourceUserId,
|
||||||
|
ulong workBufferAddress,
|
||||||
|
ulong workBufferSize,
|
||||||
|
uint processHandle,
|
||||||
|
float volume)
|
||||||
{
|
{
|
||||||
int sessionId = AcquireSessionId();
|
int sessionId = AcquireSessionId();
|
||||||
|
|
||||||
AudioRenderSystem audioRenderer = new AudioRenderSystem(this, _sessionsSystemEvent[sessionId]);
|
AudioRenderSystem audioRenderer = new AudioRenderSystem(this, _sessionsSystemEvent[sessionId]);
|
||||||
|
|
||||||
ResultCode result = audioRenderer.Initialize(ref parameter, processHandle, workBufferAddress, workBufferSize, sessionId, appletResourceUserId, memoryManager);
|
// TODO: Eventually, we should try to use the guest supplied work buffer instead of allocating
|
||||||
|
// our own. However, it was causing problems on some applications that would unmap the memory
|
||||||
|
// before the audio renderer was fully disposed.
|
||||||
|
Memory<byte> workBufferMemory = GC.AllocateArray<byte>((int)workBufferSize, pinned: true);
|
||||||
|
|
||||||
|
ResultCode result = audioRenderer.Initialize(
|
||||||
|
ref parameter,
|
||||||
|
processHandle,
|
||||||
|
workBufferMemory,
|
||||||
|
workBufferAddress,
|
||||||
|
workBufferSize,
|
||||||
|
sessionId,
|
||||||
|
appletResourceUserId,
|
||||||
|
memoryManager);
|
||||||
|
|
||||||
if (result == ResultCode.Success)
|
if (result == ResultCode.Success)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,11 +31,26 @@ namespace Ryujinx.HLE.HOS.Services.Audio
|
||||||
return AudioRendererManagerImpl.GetWorkBufferSize(ref parameter);
|
return AudioRendererManagerImpl.GetWorkBufferSize(ref parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultCode OpenAudioRenderer(ServiceCtx context, out IAudioRenderer obj, ref AudioRendererConfiguration parameter, ulong workBufferSize, ulong appletResourceUserId, KTransferMemory workBufferTransferMemory, uint processHandle)
|
public ResultCode OpenAudioRenderer(
|
||||||
|
ServiceCtx context,
|
||||||
|
out IAudioRenderer obj,
|
||||||
|
ref AudioRendererConfiguration parameter,
|
||||||
|
ulong workBufferSize,
|
||||||
|
ulong appletResourceUserId,
|
||||||
|
KTransferMemory workBufferTransferMemory,
|
||||||
|
uint processHandle)
|
||||||
{
|
{
|
||||||
var memoryManager = context.Process.HandleTable.GetKProcess((int)processHandle).CpuMemory;
|
var memoryManager = context.Process.HandleTable.GetKProcess((int)processHandle).CpuMemory;
|
||||||
|
|
||||||
ResultCode result = (ResultCode)_impl.OpenAudioRenderer(out AudioRenderSystem renderer, memoryManager, ref parameter, appletResourceUserId, workBufferTransferMemory.Address, workBufferTransferMemory.Size, processHandle, context.Device.Configuration.AudioVolume);
|
ResultCode result = (ResultCode)_impl.OpenAudioRenderer(
|
||||||
|
out AudioRenderSystem renderer,
|
||||||
|
memoryManager,
|
||||||
|
ref parameter,
|
||||||
|
appletResourceUserId,
|
||||||
|
workBufferTransferMemory.Address,
|
||||||
|
workBufferTransferMemory.Size,
|
||||||
|
processHandle,
|
||||||
|
context.Device.Configuration.AudioVolume);
|
||||||
|
|
||||||
if (result == ResultCode.Success)
|
if (result == ResultCode.Success)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,14 @@ namespace Ryujinx.HLE.HOS.Services.Audio
|
||||||
KTransferMemory workBufferTransferMemory = context.Process.HandleTable.GetObject<KTransferMemory>(transferMemoryHandle);
|
KTransferMemory workBufferTransferMemory = context.Process.HandleTable.GetObject<KTransferMemory>(transferMemoryHandle);
|
||||||
uint processHandle = (uint)context.Request.HandleDesc.ToCopy[1];
|
uint processHandle = (uint)context.Request.HandleDesc.ToCopy[1];
|
||||||
|
|
||||||
ResultCode result = _impl.OpenAudioRenderer(context, out IAudioRenderer renderer, ref parameter, workBufferSize, appletResourceUserId, workBufferTransferMemory, processHandle);
|
ResultCode result = _impl.OpenAudioRenderer(
|
||||||
|
context,
|
||||||
|
out IAudioRenderer renderer,
|
||||||
|
ref parameter,
|
||||||
|
workBufferSize,
|
||||||
|
appletResourceUserId,
|
||||||
|
workBufferTransferMemory,
|
||||||
|
processHandle);
|
||||||
|
|
||||||
if (result == ResultCode.Success)
|
if (result == ResultCode.Success)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue