Inherit buffer tracking handles rather than recreating on resize (#2330)

This greatly speeds up games that constantly resize buffers, and removes stuttering on games that resize large buffers occasionally:

- Large improvement on Super Mario 3D All-Stars (#1663 needed for best performance)
- Improvement to Hyrule Warriors: AoC, and UE4 games. These games can still stutter due to texture creation/loading.
- Small improvement to other games, potential 1-frame stutters avoided.

`ForceSynchronizeMemory`, which was added with POWER, is no longer needed. Some tests have been added for the MultiRegionHandle.
This commit is contained in:
riperiperi
2021-06-24 00:31:26 +01:00
committed by GitHub
parent e053663f27
commit 12a7a2ead8
11 changed files with 255 additions and 58 deletions

View File

@ -1,6 +1,8 @@
using Ryujinx.Cpu.Tracking;
using Ryujinx.Memory;
using Ryujinx.Memory.Tracking;
using System;
using System.Collections.Generic;
namespace Ryujinx.Cpu
{
@ -26,9 +28,10 @@ namespace Ryujinx.Cpu
/// </summary>
/// <param name="address">CPU virtual address of the region</param>
/// <param name="size">Size of the region</param>
/// <param name="handles">Handles to inherit state from or reuse. When none are present, provide null</param>
/// <param name="granularity">Desired granularity of write tracking</param>
/// <returns>The memory tracking handle</returns>
CpuMultiRegionHandle BeginGranularTracking(ulong address, ulong size, ulong granularity);
CpuMultiRegionHandle BeginGranularTracking(ulong address, ulong size, IEnumerable<IRegionHandle> handles, ulong granularity);
/// <summary>
/// Obtains a smart memory tracking handle for the given virtual region, with a specified granularity. This should be disposed when finished with.

View File

@ -550,9 +550,9 @@ namespace Ryujinx.Cpu
}
/// <inheritdoc/>
public CpuMultiRegionHandle BeginGranularTracking(ulong address, ulong size, ulong granularity)
public CpuMultiRegionHandle BeginGranularTracking(ulong address, ulong size, IEnumerable<IRegionHandle> handles, ulong granularity)
{
return new CpuMultiRegionHandle(Tracking.BeginGranularTracking(address, size, granularity));
return new CpuMultiRegionHandle(Tracking.BeginGranularTracking(address, size, handles, granularity));
}
/// <inheritdoc/>

View File

@ -586,9 +586,9 @@ namespace Ryujinx.Cpu
}
/// <inheritdoc/>
public CpuMultiRegionHandle BeginGranularTracking(ulong address, ulong size, ulong granularity)
public CpuMultiRegionHandle BeginGranularTracking(ulong address, ulong size, IEnumerable<IRegionHandle> handles, ulong granularity)
{
return new CpuMultiRegionHandle(Tracking.BeginGranularTracking(address, size, granularity));
return new CpuMultiRegionHandle(Tracking.BeginGranularTracking(address, size, handles, granularity));
}
/// <inheritdoc/>

View File

@ -1,5 +1,6 @@
using Ryujinx.Memory.Tracking;
using System;
using System.Collections.Generic;
namespace Ryujinx.Cpu.Tracking
{
@ -16,6 +17,7 @@ namespace Ryujinx.Cpu.Tracking
public void Dispose() => _impl.Dispose();
public void ForceDirty(ulong address, ulong size) => _impl.ForceDirty(address, size);
public IEnumerable<IRegionHandle> GetHandles() => _impl.GetHandles();
public void QueryModified(Action<ulong, ulong> modifiedAction) => _impl.QueryModified(modifiedAction);
public void QueryModified(ulong address, ulong size, Action<ulong, ulong> modifiedAction) => _impl.QueryModified(address, size, modifiedAction);
public void QueryModified(ulong address, ulong size, Action<ulong, ulong> modifiedAction, int sequenceNumber) => _impl.QueryModified(address, size, modifiedAction, sequenceNumber);

View File

@ -21,6 +21,7 @@ namespace Ryujinx.Cpu.Tracking
public void Dispose() => _impl.Dispose();
public bool DirtyOrVolatile() => _impl.DirtyOrVolatile();
public void ForceDirty() => _impl.ForceDirty();
public IRegionHandle GetHandle() => _impl;
public void RegisterAction(RegionSignal action) => _impl.RegisterAction(action);
public void RegisterDirtyEvent(Action action) => _impl.RegisterDirtyEvent(action);
public void Reprotect(bool asDirty = false) => _impl.Reprotect(asDirty);