Improve the speed of redundant ASTC texture data updates (#1636)

This commit is contained in:
gdkchan 2020-10-25 17:09:45 -03:00 committed by GitHub
parent 49f970d5bd
commit cf0f0fc4e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -16,6 +16,11 @@ namespace Ryujinx.Graphics.Gpu.Image
/// </summary>
class Texture : IRange, IDisposable
{
// How many updates we need before switching to the byte-by-byte comparison
// modification check method.
// This method uses much more memory so we want to avoid it if possible.
private const int ByteComparisonSwitchThreshold = 4;
private GpuContext _context;
private SizeInfo _sizeInfo;
@ -51,6 +56,8 @@ namespace Ryujinx.Graphics.Gpu.Image
private int _firstLevel;
private bool _hasData;
private int _updateCount;
private byte[] _currentData;
private ITexture _arrayViewTexture;
private Target _arrayViewTarget;
@ -545,7 +552,7 @@ namespace Ryujinx.Graphics.Gpu.Image
}
/// <summary>
/// Checks if the memory for this texture was modified, and returns true if it was.
/// Checks if the memory for this texture was modified, and returns true if it was.
/// The modified flags are consumed as a result.
/// </summary>
/// <remarks>
@ -591,6 +598,27 @@ namespace Ryujinx.Graphics.Gpu.Image
IsModified = false;
// If the host does not support ASTC compression, we need to do the decompression.
// The decompression is slow, so we want to avoid it as much as possible.
// This does a byte-by-byte check and skips the update if the data is equal in this case.
// This improves the speed on applications that overwrites ASTC data without changing anything.
if (Info.FormatInfo.Format.IsAstc() && !_context.Capabilities.SupportsAstcCompression)
{
if (_updateCount < ByteComparisonSwitchThreshold)
{
_updateCount++;
}
else
{
bool dataMatches = _currentData != null && data.SequenceEqual(_currentData);
_currentData = data.ToArray();
if (dataMatches)
{
return;
}
}
}
data = ConvertToHostCompatibleFormat(data);
HostTexture.SetData(data);
@ -1132,6 +1160,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// </summary>
private void DisposeTextures()
{
_currentData = null;
HostTexture.Release();
_arrayViewTexture?.Release();