From cf0f0fc4e740c774eadaa328dc543ee9a03fbd09 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 25 Oct 2020 17:09:45 -0300 Subject: [PATCH] Improve the speed of redundant ASTC texture data updates (#1636) --- Ryujinx.Graphics.Gpu/Image/Texture.cs | 31 ++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/Ryujinx.Graphics.Gpu/Image/Texture.cs b/Ryujinx.Graphics.Gpu/Image/Texture.cs index 6778567c5..2b1aaa0ad 100644 --- a/Ryujinx.Graphics.Gpu/Image/Texture.cs +++ b/Ryujinx.Graphics.Gpu/Image/Texture.cs @@ -16,6 +16,11 @@ namespace Ryujinx.Graphics.Gpu.Image /// 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 } /// - /// 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. /// /// @@ -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 /// private void DisposeTextures() { + _currentData = null; HostTexture.Release(); _arrayViewTexture?.Release();