From b530f0e1104723b894695b2860cf0f568f24cc9a Mon Sep 17 00:00:00 2001 From: riperiperi Date: Tue, 2 Mar 2021 22:30:54 +0000 Subject: 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. --- Ryujinx.Memory/Tracking/IRegionHandle.cs | 2 +- Ryujinx.Memory/Tracking/RegionHandle.cs | 30 ++++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) (limited to 'Ryujinx.Memory/Tracking') 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 _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 /// /// Consume the dirty flag for this handle, and reprotect so it can be set on the next write. /// - public void Reprotect() + public void Reprotect(bool asDirty = false) { - Dirty = false; + Dirty = asDirty; lock (_tracking.TrackingLock) { foreach (VirtualRegion region in _regions) @@ -100,6 +109,16 @@ namespace Ryujinx.Memory.Tracking } } + /// + /// 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. + /// + /// Action to call on dirty + public void RegisterDirtyEvent(Action action) + { + _onDirty += action; + } + /// /// Add a child virtual region to this handle. /// @@ -125,6 +144,13 @@ namespace Ryujinx.Memory.Tracking /// public void Dispose() { + if (_disposed) + { + throw new ObjectDisposedException(GetType().FullName); + } + + _disposed = true; + lock (_tracking.TrackingLock) { foreach (VirtualRegion region in _regions) -- cgit v1.2.3