From 81f1a4dc3161882b0385c9d4752fbba84b9eca96 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Fri, 9 Sep 2022 22:16:24 -0300 Subject: 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 --- Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs | 19 ++++++++++------ .../Renderer/Server/AudioRendererManager.cs | 25 ++++++++++++++++++++-- 2 files changed, 35 insertions(+), 9 deletions(-) (limited to 'Ryujinx.Audio/Renderer/Server') diff --git a/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs b/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs index 904b56f6..af163ae0 100644 --- a/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs +++ b/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs @@ -55,7 +55,6 @@ namespace Ryujinx.Audio.Renderer.Server private uint _processHandle; private ulong _appletResourceId; - private WritableRegion _workBufferRegion; private MemoryHandle _workBufferMemoryPin; private Memory _mixBuffer; @@ -98,7 +97,15 @@ namespace Ryujinx.Audio.Renderer.Server _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 workBufferMemory, + CpuAddress workBuffer, + ulong workBufferSize, + int sessionId, + ulong appletResourceId, + IVirtualMemoryManager memoryManager) { if (!BehaviourContext.CheckValidRevision(parameter.Revision)) { @@ -134,11 +141,10 @@ namespace Ryujinx.Audio.Renderer.Server WorkBufferAllocator workBufferAllocator; - _workBufferRegion = MemoryManager.GetWritableRegion(workBuffer, (int)workBufferSize); - _workBufferRegion.Memory.Span.Fill(0); - _workBufferMemoryPin = _workBufferRegion.Memory.Pin(); + workBufferMemory.Span.Fill(0); + _workBufferMemoryPin = workBufferMemory.Pin(); - workBufferAllocator = new WorkBufferAllocator(_workBufferRegion.Memory); + workBufferAllocator = new WorkBufferAllocator(workBufferMemory); PoolMapper poolMapper = new PoolMapper(processHandle, false); poolMapper.InitializeSystemPool(ref _dspMemoryPoolState, workBuffer, workBufferSize); @@ -841,7 +847,6 @@ namespace Ryujinx.Audio.Renderer.Server _manager.Unregister(this); _terminationEvent.Dispose(); _workBufferMemoryPin.Dispose(); - _workBufferRegion.Dispose(); if (MemoryManager is IRefCounted rc) { diff --git a/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs b/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs index 3fbdc58d..4de0ad16 100644 --- a/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs +++ b/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs @@ -305,13 +305,34 @@ namespace Ryujinx.Audio.Renderer.Server /// The guest work buffer size. /// The process handle of the application. /// A reporting an error or a success. - 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(); 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 workBufferMemory = GC.AllocateArray((int)workBufferSize, pinned: true); + + ResultCode result = audioRenderer.Initialize( + ref parameter, + processHandle, + workBufferMemory, + workBufferAddress, + workBufferSize, + sessionId, + appletResourceUserId, + memoryManager); if (result == ResultCode.Success) { -- cgit v1.2.3