IPC refactor part 2: Use ReplyAndReceive on HLE services and remove special handling from kernel (#1458)

* IPC refactor part 2: Use ReplyAndReceive on HLE services and remove special handling from kernel

* Fix for applet transfer memory + some nits

* Keep handles if possible to avoid server handle table exhaustion

* Fix IPC ZeroFill bug

* am: Correctly implement CreateManagedDisplayLayer and implement CreateManagedDisplaySeparableLayer

CreateManagedDisplaySeparableLayer is requires since 10.x+ when appletResourceUserId != 0

* Make it exit properly

* Make ServiceNotImplementedException show the full message again

* Allow yielding execution to avoid starving other threads

* Only wait if active

* Merge IVirtualMemoryManager and IAddressSpaceManager

* Fix Ro loading data from the wrong process

Co-authored-by: Thog <me@thog.eu>
This commit is contained in:
gdkchan
2020-12-01 20:23:43 -03:00
committed by GitHub
parent 461c24092a
commit cf6cd71488
115 changed files with 2356 additions and 1088 deletions

View File

@ -16,7 +16,7 @@
//
using Ryujinx.Audio.Renderer.Common;
using Ryujinx.Cpu;
using Ryujinx.Memory;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -65,7 +65,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
IsEffectEnabled = isEnabled;
}
private uint Read(MemoryManager memoryManager, ulong bufferAddress, uint countMax, Span<int> outBuffer, uint count, uint readOffset, uint updateCount)
private uint Read(IVirtualMemoryManager memoryManager, ulong bufferAddress, uint countMax, Span<int> outBuffer, uint count, uint readOffset, uint updateCount)
{
if (countMax == 0 || bufferAddress == 0)
{
@ -104,7 +104,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
return count;
}
private uint Write(MemoryManager memoryManager, ulong outBufferAddress, uint countMax, ReadOnlySpan<int> buffer, uint count, uint writeOffset, uint updateCount)
private uint Write(IVirtualMemoryManager memoryManager, ulong outBufferAddress, uint countMax, ReadOnlySpan<int> buffer, uint count, uint writeOffset, uint updateCount)
{
if (countMax == 0 || outBufferAddress == 0)
{
@ -175,8 +175,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
}
else
{
MemoryHelper.FillWithZeros(context.MemoryManager, (long)BufferInfo.SendBufferInfo, Unsafe.SizeOf<AuxiliaryBufferInfo>());
MemoryHelper.FillWithZeros(context.MemoryManager, (long)BufferInfo.ReturnBufferInfo, Unsafe.SizeOf<AuxiliaryBufferInfo>());
ZeroFill(context.MemoryManager, BufferInfo.SendBufferInfo, Unsafe.SizeOf<AuxiliaryBufferInfo>());
ZeroFill(context.MemoryManager, BufferInfo.ReturnBufferInfo, Unsafe.SizeOf<AuxiliaryBufferInfo>());
if (InputBufferIndex != OutputBufferIndex)
{
@ -184,5 +184,22 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
}
}
}
private static void ZeroFill(IVirtualMemoryManager memoryManager, ulong address, int size)
{
ulong endAddress = address + (ulong)size;
while (address + 7UL < endAddress)
{
memoryManager.Write(address, 0UL);
address += 8;
}
while (address < endAddress)
{
memoryManager.Write(address, (byte)0);
address++;
}
}
}
}

View File

@ -19,7 +19,7 @@ using Ryujinx.Audio.Renderer.Integration;
using Ryujinx.Audio.Renderer.Server;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.Cpu;
using Ryujinx.Memory;
using System;
using System.Collections.Generic;
@ -37,7 +37,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public List<ICommand> Commands { get; }
public MemoryManager MemoryManager { get; }
public IVirtualMemoryManager MemoryManager { get; }
public HardwareDevice OutputDevice { get; private set; }
@ -50,7 +50,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
{
}
public CommandList(MemoryManager memoryManager, Memory<float> mixBuffer, uint sampleCount, uint sampleRate, uint mixBufferCount, uint voiceChannelCountMax)
public CommandList(IVirtualMemoryManager memoryManager, Memory<float> mixBuffer, uint sampleCount, uint sampleRate, uint mixBufferCount, uint voiceChannelCountMax)
{
SampleCount = sampleCount;
SampleRate = sampleRate;

View File

@ -18,7 +18,7 @@
using Ryujinx.Audio.Renderer.Common;
using Ryujinx.Audio.Renderer.Dsp.State;
using Ryujinx.Common.Logging;
using Ryujinx.Cpu;
using Ryujinx.Memory;
using System;
using System.Buffers;
using System.Diagnostics;
@ -63,7 +63,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
}
}
public static void ProcessWaveBuffers(MemoryManager memoryManager, Span<float> outputBuffer, WaveBufferInformation info, uint targetSampleRate, int sampleCount)
public static void ProcessWaveBuffers(IVirtualMemoryManager memoryManager, Span<float> outputBuffer, WaveBufferInformation info, uint targetSampleRate, int sampleCount)
{
const int tempBufferSize = 0x3F00;

View File

@ -15,7 +15,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
using Ryujinx.Cpu;
using Ryujinx.Memory;
using System.Runtime.InteropServices;
namespace Ryujinx.Audio.Renderer.Dsp.State
@ -33,22 +33,22 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
public uint WriteOffset;
private uint _reserved;
public static uint GetReadOffset(MemoryManager manager, ulong bufferAddress)
public static uint GetReadOffset(IVirtualMemoryManager manager, ulong bufferAddress)
{
return manager.Read<uint>(bufferAddress + ReadOffsetPosition);
}
public static uint GetWriteOffset(MemoryManager manager, ulong bufferAddress)
public static uint GetWriteOffset(IVirtualMemoryManager manager, ulong bufferAddress)
{
return manager.Read<uint>(bufferAddress + WriteOffsetPosition);
}
public static void SetReadOffset(MemoryManager manager, ulong bufferAddress, uint value)
public static void SetReadOffset(IVirtualMemoryManager manager, ulong bufferAddress, uint value)
{
manager.Write(bufferAddress + ReadOffsetPosition, value);
}
public static void SetWriteOffset(MemoryManager manager, ulong bufferAddress, uint value)
public static void SetWriteOffset(IVirtualMemoryManager manager, ulong bufferAddress, uint value)
{
manager.Write(bufferAddress + WriteOffsetPosition, value);
}

View File

@ -8,6 +8,7 @@
<ItemGroup>
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
<ProjectReference Include="..\Ryujinx.Cpu\Ryujinx.Cpu.csproj" />
<ProjectReference Include="..\Ryujinx.Memory\Ryujinx.Memory.csproj" />
</ItemGroup>
</Project>

View File

@ -31,7 +31,7 @@ using Ryujinx.Audio.Renderer.Server.Voice;
using Ryujinx.Audio.Renderer.Utils;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.Cpu;
using Ryujinx.Memory;
using System;
using System.Buffers;
using System.Diagnostics;
@ -87,7 +87,7 @@ namespace Ryujinx.Audio.Renderer.Server
private Memory<byte> _performanceBuffer;
public MemoryManager MemoryManager { get; private set; }
public IVirtualMemoryManager MemoryManager { get; private set; }
private ulong _elapsedFrameCount;
private ulong _renderingStartTick;
@ -96,14 +96,14 @@ namespace Ryujinx.Audio.Renderer.Server
public AudioRenderSystem(AudioRendererManager manager, IWritableEvent systemEvent)
{
_manager = manager;
_terminationEvent = new ManualResetEvent(false);
_manager = manager;
_terminationEvent = new ManualResetEvent(false);
_dspMemoryPoolState = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp);
_voiceContext = new VoiceContext();
_mixContext = new MixContext();
_sinkContext = new SinkContext();
_splitterContext = new SplitterContext();
_effectContext = new EffectContext();
_voiceContext = new VoiceContext();
_mixContext = new MixContext();
_sinkContext = new SinkContext();
_splitterContext = new SplitterContext();
_effectContext = new EffectContext();
_commandProcessingTimeEstimator = null;
_systemEvent = systemEvent;
@ -113,7 +113,7 @@ namespace Ryujinx.Audio.Renderer.Server
_sessionId = 0;
}
public ResultCode Initialize(ref AudioRendererConfiguration parameter, uint processHandle, CpuAddress workBuffer, ulong workBufferSize, int sessionId, ulong appletResourceId, MemoryManager memoryManager)
public ResultCode Initialize(ref AudioRendererConfiguration parameter, uint processHandle, CpuAddress workBuffer, ulong workBufferSize, int sessionId, ulong appletResourceId, IVirtualMemoryManager memoryManager)
{
if (!BehaviourContext.CheckValidRevision(parameter.Revision))
{

View File

@ -19,7 +19,7 @@ using Ryujinx.Audio.Renderer.Dsp;
using Ryujinx.Audio.Renderer.Integration;
using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Common.Logging;
using Ryujinx.Cpu;
using Ryujinx.Memory;
using System;
using System.Diagnostics;
using System.Threading;
@ -288,7 +288,7 @@ namespace Ryujinx.Audio.Renderer.Server
/// <param name="workBufferSize">The guest work buffer size.</param>
/// <param name="processHandle">The process handle of the application.</param>
/// <returns>A <see cref="ResultCode"/> reporting an error or a success.</returns>
public ResultCode OpenAudioRenderer(out AudioRenderSystem renderer, MemoryManager memoryManager, ref AudioRendererConfiguration parameter, ulong appletResourceUserId, ulong workBufferAddress, ulong workBufferSize, uint processHandle)
public ResultCode OpenAudioRenderer(out AudioRenderSystem renderer, IVirtualMemoryManager memoryManager, ref AudioRendererConfiguration parameter, ulong appletResourceUserId, ulong workBufferAddress, ulong workBufferSize, uint processHandle)
{
int sessionId = AcquireSessionId();
@ -321,6 +321,14 @@ namespace Ryujinx.Audio.Renderer.Server
{
if (disposing)
{
lock (_audioProcessorLock)
{
if (_isRunning)
{
StopLocked();
}
}
Processor.Dispose();
foreach (HardwareDevice device in OutputDevices)