GPU: Track buffer migrations and flush source on incomplete copy (#3952)

* Track buffer migrations and flush source on incomplete copy

Makes sure that the modified range list is always from the latest iteration of the buffer, and flushes earlier iterations of a buffer if the data has not been migrated yet.

* Cleanup 1

* Reduce cost for redundant signal checks on Vulkan

* Only inherit the range list if there are pending ranges.

* Fix OpenGL

* Address Feedback

* Whoops
This commit is contained in:
riperiperi 2022-12-01 15:30:13 +00:00 committed by GitHub
parent 817b89767a
commit 458452279c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 451 additions and 87 deletions

View file

@ -65,6 +65,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
private bool _useGranular;
private bool _syncActionRegistered;
private int _referenceCount = 1;
/// <summary>
/// Creates a new instance of the buffer.
/// </summary>
@ -229,7 +231,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
{
if (_modifiedRanges == null)
{
_modifiedRanges = new BufferModifiedRangeList(_context);
_modifiedRanges = new BufferModifiedRangeList(_context, this, Flush);
}
}
@ -290,7 +292,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
/// <param name="from">The buffer to inherit from</param>
public void InheritModifiedRanges(Buffer from)
{
if (from._modifiedRanges != null)
if (from._modifiedRanges != null && from._modifiedRanges.HasRanges)
{
if (from._syncActionRegistered && !_syncActionRegistered)
{
@ -310,17 +312,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
}
};
if (_modifiedRanges == null)
{
_modifiedRanges = from._modifiedRanges;
_modifiedRanges.ReregisterRanges(registerRangeAction);
EnsureRangeList();
from._modifiedRanges = null;
}
else
{
_modifiedRanges.InheritRanges(from._modifiedRanges, registerRangeAction);
}
_modifiedRanges.InheritRanges(from._modifiedRanges, registerRangeAction);
}
}
@ -456,7 +450,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
if (ranges != null)
{
(address, size) = PageAlign(address, size);
ranges.WaitForAndGetRanges(address, size, Flush);
ranges.WaitForAndFlushRanges(address, size);
}
}, true);
}
@ -508,6 +502,25 @@ namespace Ryujinx.Graphics.Gpu.Memory
UnmappedSequence++;
}
/// <summary>
/// Increments the buffer reference count.
/// </summary>
public void IncrementReferenceCount()
{
_referenceCount++;
}
/// <summary>
/// Decrements the buffer reference count.
/// </summary>
public void DecrementReferenceCount()
{
if (--_referenceCount == 0)
{
DisposeData();
}
}
/// <summary>
/// Disposes the host buffer's data, not its tracking handles.
/// </summary>
@ -528,7 +541,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
_memoryTrackingGranular?.Dispose();
_memoryTracking?.Dispose();
DisposeData();
DecrementReferenceCount();
}
}
}