diff options
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Image/Pool.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Image/Pool.cs | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/Pool.cs b/Ryujinx.Graphics.Gpu/Image/Pool.cs index f54ce1d7..8e210513 100644 --- a/Ryujinx.Graphics.Gpu/Image/Pool.cs +++ b/Ryujinx.Graphics.Gpu/Image/Pool.cs @@ -1,6 +1,7 @@ using Ryujinx.Cpu.Tracking; using Ryujinx.Graphics.Gpu.Memory; using System; +using System.Runtime.InteropServices; namespace Ryujinx.Graphics.Gpu.Image { @@ -16,6 +17,7 @@ namespace Ryujinx.Graphics.Gpu.Image protected GpuContext Context; protected PhysicalMemory PhysicalMemory; protected int SequenceNumber; + protected int ModifiedSequenceNumber; protected T1[] Items; protected T2[] DescriptorCache; @@ -41,6 +43,9 @@ namespace Ryujinx.Graphics.Gpu.Image private readonly CpuMultiRegionHandle _memoryTracking; private readonly Action<ulong, ulong> _modifiedDelegate; + private int _modifiedSequenceOffset; + private bool _modified; + /// <summary> /// Creates a new instance of the GPU resource pool. /// </summary> @@ -80,6 +85,16 @@ namespace Ryujinx.Graphics.Gpu.Image } /// <summary> + /// Gets a reference to the descriptor for a given ID. + /// </summary> + /// <param name="id">ID of the descriptor. This is effectively a zero-based index</param> + /// <returns>A reference to the descriptor</returns> + public ref readonly T2 GetDescriptorRef(int id) + { + return ref MemoryMarshal.Cast<byte, T2>(PhysicalMemory.GetSpan(Address + (ulong)id * DescriptorSize, DescriptorSize))[0]; + } + + /// <summary> /// Gets the GPU resource with the given ID. /// </summary> /// <param name="id">ID of the resource. This is effectively a zero-based index</param> @@ -93,7 +108,13 @@ namespace Ryujinx.Graphics.Gpu.Image /// </summary> public void SynchronizeMemory() { + _modified = false; _memoryTracking.QueryModified(_modifiedDelegate); + + if (_modified) + { + UpdateModifiedSequence(); + } } /// <summary> @@ -103,6 +124,8 @@ namespace Ryujinx.Graphics.Gpu.Image /// <param name="mSize">Size of the modified region</param> private void RegionModified(ulong mAddress, ulong mSize) { + _modified = true; + if (mAddress < Address) { mAddress = Address; @@ -119,6 +142,15 @@ namespace Ryujinx.Graphics.Gpu.Image } /// <summary> + /// Updates the modified sequence number using the current sequence number and offset, + /// indicating that it has been modified. + /// </summary> + protected void UpdateModifiedSequence() + { + ModifiedSequenceNumber = SequenceNumber + _modifiedSequenceOffset; + } + + /// <summary> /// An action to be performed when a precise memory access occurs to this resource. /// Makes sure that the dirty flags are checked. /// </summary> @@ -129,6 +161,16 @@ namespace Ryujinx.Graphics.Gpu.Image { if (write && Context.SequenceNumber == SequenceNumber) { + if (ModifiedSequenceNumber == SequenceNumber + _modifiedSequenceOffset) + { + // The modified sequence number is offset when PreciseActions occur so that + // users checking it will see an increment and know the pool has changed since + // their last look, even though the main SequenceNumber has not been changed. + + _modifiedSequenceOffset++; + } + + // Force the pool to be checked again the next time it is used. SequenceNumber--; } |