aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Memory/Tracking
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2021-03-02 22:30:54 +0000
committerGitHub <noreply@github.com>2021-03-02 19:30:54 -0300
commitb530f0e1104723b894695b2860cf0f568f24cc9a (patch)
tree04f6b7d76d334ddc5c0378f6aa00b98739bc793e /Ryujinx.Memory/Tracking
parent7a90abc03555f41ba7589bc8e1f714839f9e2fed (diff)
Texture Cache: "Texture Groups" and "Texture Dependencies" (#2001)
* Initial implementation (3d tex mips broken) This works rather well for most games, just need to fix 3d texture mips. * Cleanup * Address feedback * Copy Dependencies and various other fixes * Fix layer/level offset for copy from view<->view. * Remove dirty flag from dependency The dirty flag behaviour is not needed - DeferredCopy is all we need. * Fix tracking mip slices. * Propagate granularity (fix astral chain) * Address Feedback pt 1 * Save slice sizes as part of SizeInfo * Fix nits * Fix disposing multiple dependencies causing a crash This list is obviously modified when removing dependencies, so create a copy of it.
Diffstat (limited to 'Ryujinx.Memory/Tracking')
-rw-r--r--Ryujinx.Memory/Tracking/IRegionHandle.cs2
-rw-r--r--Ryujinx.Memory/Tracking/RegionHandle.cs30
2 files changed, 29 insertions, 3 deletions
diff --git a/Ryujinx.Memory/Tracking/IRegionHandle.cs b/Ryujinx.Memory/Tracking/IRegionHandle.cs
index 33628da6..cd33e5c8 100644
--- a/Ryujinx.Memory/Tracking/IRegionHandle.cs
+++ b/Ryujinx.Memory/Tracking/IRegionHandle.cs
@@ -10,7 +10,7 @@ namespace Ryujinx.Memory.Tracking
ulong Size { get; }
ulong EndAddress { get; }
- void Reprotect();
+ void Reprotect(bool asDirty = false);
void RegisterAction(RegionSignal action);
}
}
diff --git a/Ryujinx.Memory/Tracking/RegionHandle.cs b/Ryujinx.Memory/Tracking/RegionHandle.cs
index 3ddcb6db..4da184dd 100644
--- a/Ryujinx.Memory/Tracking/RegionHandle.cs
+++ b/Ryujinx.Memory/Tracking/RegionHandle.cs
@@ -1,4 +1,5 @@
using Ryujinx.Memory.Range;
+using System;
using System.Collections.Generic;
using System.Threading;
@@ -19,9 +20,12 @@ namespace Ryujinx.Memory.Tracking
internal IMultiRegionHandle Parent { get; set; }
internal int SequenceNumber { get; set; }
+ private event Action _onDirty;
+
private RegionSignal _preAction; // Action to perform before a read or write. This will block the memory access.
private readonly List<VirtualRegion> _regions;
private readonly MemoryTracking _tracking;
+ private bool _disposed;
internal MemoryPermission RequiredPermission => _preAction != null ? MemoryPermission.None : (Dirty ? MemoryPermission.ReadAndWrite : MemoryPermission.Read);
internal RegionSignal PreAction => _preAction;
@@ -60,7 +64,12 @@ namespace Ryujinx.Memory.Tracking
if (write)
{
+ bool oldDirty = Dirty;
Dirty = true;
+ if (!oldDirty)
+ {
+ _onDirty?.Invoke();
+ }
Parent?.SignalWrite();
}
}
@@ -68,9 +77,9 @@ namespace Ryujinx.Memory.Tracking
/// <summary>
/// Consume the dirty flag for this handle, and reprotect so it can be set on the next write.
/// </summary>
- public void Reprotect()
+ public void Reprotect(bool asDirty = false)
{
- Dirty = false;
+ Dirty = asDirty;
lock (_tracking.TrackingLock)
{
foreach (VirtualRegion region in _regions)
@@ -101,6 +110,16 @@ namespace Ryujinx.Memory.Tracking
}
/// <summary>
+ /// Register an action to perform when the region is written to.
+ /// This action will not be removed when it is called - it is called each time the dirty flag is set.
+ /// </summary>
+ /// <param name="action">Action to call on dirty</param>
+ public void RegisterDirtyEvent(Action action)
+ {
+ _onDirty += action;
+ }
+
+ /// <summary>
/// Add a child virtual region to this handle.
/// </summary>
/// <param name="region">Virtual region to add as a child</param>
@@ -125,6 +144,13 @@ namespace Ryujinx.Memory.Tracking
/// </summary>
public void Dispose()
{
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(GetType().FullName);
+ }
+
+ _disposed = true;
+
lock (_tracking.TrackingLock)
{
foreach (VirtualRegion region in _regions)