diff options
| author | gdk <gab.dark.100@gmail.com> | 2019-11-24 21:29:37 -0300 |
|---|---|---|
| committer | Thog <thog@protonmail.com> | 2020-01-09 02:13:00 +0100 |
| commit | d0c7732fe21bc5c234ac611759e51926d2c8947e (patch) | |
| tree | ebc47b31dff5c03a1f0125ba4809e373968f08ec /Ryujinx.Graphics.Gpu/Image | |
| parent | e0c95b18eb225d62301b8e3c3fe9d4f689381100 (diff) | |
Optimize RangeList by not doing an allocation on every call to the Find methods
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Image')
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Image/TextureManager.cs | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs index 413ba327..5e5b1c97 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs @@ -11,6 +11,9 @@ namespace Ryujinx.Graphics.Gpu.Image { class TextureManager { + private const int OverlapsBufferInitialCapacity = 10; + private const int OverlapsBufferMaxCapacity = 10000; + private GpuContext _context; private TextureBindingsManager _cpBindingsManager; @@ -24,6 +27,8 @@ namespace Ryujinx.Graphics.Gpu.Image private RangeList<Texture> _textures; + private Texture[] _textureOverlaps; + private AutoDeleteCache _cache; public TextureManager(GpuContext context) @@ -41,6 +46,8 @@ namespace Ryujinx.Graphics.Gpu.Image _textures = new RangeList<Texture>(); + _textureOverlaps = new Texture[OverlapsBufferInitialCapacity]; + _cache = new AutoDeleteCache(); } @@ -321,10 +328,12 @@ namespace Ryujinx.Graphics.Gpu.Image bool isSamplerTexture = (flags & TextureSearchFlags.Sampler) != 0; // Try to find a perfect texture match, with the same address and parameters. - Texture[] sameAddressOverlaps = _textures.FindOverlaps(info.Address); + int sameAddressOverlapsCount = _textures.FindOverlaps(info.Address, ref _textureOverlaps); - foreach (Texture overlap in sameAddressOverlaps) + for (int index = 0; index < sameAddressOverlapsCount; index++) { + Texture overlap = _textureOverlaps[index]; + if (overlap.IsPerfectMatch(info, flags)) { if (!isSamplerTexture) @@ -376,12 +385,14 @@ namespace Ryujinx.Graphics.Gpu.Image // Find view compatible matches. ulong size = (ulong)sizeInfo.TotalSize; - Texture[] overlaps = _textures.FindOverlaps(info.Address, size); + int overlapsCount = _textures.FindOverlaps(info.Address, size, ref _textureOverlaps); Texture texture = null; - foreach (Texture overlap in overlaps) + for (int index = 0; index < overlapsCount; index++) { + Texture overlap = _textureOverlaps[index]; + if (overlap.IsViewCompatible(info, size, out int firstLayer, out int firstLevel)) { if (!isSamplerTexture) @@ -412,8 +423,10 @@ namespace Ryujinx.Graphics.Gpu.Image // otherwise the copied data would be overwritten by a future synchronization. texture.SynchronizeMemory(); - foreach (Texture overlap in overlaps) + for (int index = 0; index < overlapsCount; index++) { + Texture overlap = _textureOverlaps[index]; + if (texture.IsViewCompatible(overlap.Info, overlap.Size, out int firstLayer, out int firstLevel)) { TextureInfo overlapInfo = AdjustSizes(texture, overlap.Info, firstLevel); @@ -432,8 +445,10 @@ namespace Ryujinx.Graphics.Gpu.Image // of the 3D texture to the newly created 3D texture. if (info.Target == Target.Texture3D) { - foreach (Texture overlap in overlaps) + for (int index = 0; index < overlapsCount; index++) { + Texture overlap = _textureOverlaps[index]; + if (texture.IsViewCompatible( overlap.Info, overlap.Size, @@ -456,9 +471,19 @@ namespace Ryujinx.Graphics.Gpu.Image _textures.Add(texture); + ShrinkOverlapsBufferIfNeeded(); + return texture; } + private void ShrinkOverlapsBufferIfNeeded() + { + if (_textureOverlaps.Length > OverlapsBufferMaxCapacity) + { + Array.Resize(ref _textureOverlaps, OverlapsBufferMaxCapacity); + } + } + private static TextureInfo AdjustSizes(Texture parent, TextureInfo info, int firstLevel) { // When the texture is used as view of another texture, we must |
