mirror of
				https://github.com/ryujinx-mirror/ryujinx.git
				synced 2025-11-04 08:18:58 -06:00 
			
		
		
		
	Add missing lock on texture cache UpdateMapping method (#6657)
This commit is contained in:
		@@ -8,6 +8,7 @@ using Ryujinx.Graphics.Texture;
 | 
			
		||||
using Ryujinx.Memory.Range;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
 | 
			
		||||
namespace Ryujinx.Graphics.Gpu.Image
 | 
			
		||||
{
 | 
			
		||||
@@ -39,6 +40,8 @@ namespace Ryujinx.Graphics.Gpu.Image
 | 
			
		||||
        private readonly MultiRangeList<Texture> _textures;
 | 
			
		||||
        private readonly HashSet<Texture> _partiallyMappedTextures;
 | 
			
		||||
 | 
			
		||||
        private readonly ReaderWriterLockSlim _texturesLock;
 | 
			
		||||
 | 
			
		||||
        private Texture[] _textureOverlaps;
 | 
			
		||||
        private OverlapInfo[] _overlapInfo;
 | 
			
		||||
 | 
			
		||||
@@ -57,6 +60,8 @@ namespace Ryujinx.Graphics.Gpu.Image
 | 
			
		||||
            _textures = new MultiRangeList<Texture>();
 | 
			
		||||
            _partiallyMappedTextures = new HashSet<Texture>();
 | 
			
		||||
 | 
			
		||||
            _texturesLock = new ReaderWriterLockSlim();
 | 
			
		||||
 | 
			
		||||
            _textureOverlaps = new Texture[OverlapsBufferInitialCapacity];
 | 
			
		||||
            _overlapInfo = new OverlapInfo[OverlapsBufferInitialCapacity];
 | 
			
		||||
 | 
			
		||||
@@ -75,10 +80,16 @@ namespace Ryujinx.Graphics.Gpu.Image
 | 
			
		||||
 | 
			
		||||
            MultiRange unmapped = ((MemoryManager)sender).GetPhysicalRegions(e.Address, e.Size);
 | 
			
		||||
 | 
			
		||||
            lock (_textures)
 | 
			
		||||
            _texturesLock.EnterReadLock();
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                overlapCount = _textures.FindOverlaps(unmapped, ref overlaps);
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                _texturesLock.ExitReadLock();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (overlapCount > 0)
 | 
			
		||||
            {
 | 
			
		||||
@@ -217,7 +228,18 @@ namespace Ryujinx.Graphics.Gpu.Image
 | 
			
		||||
        public bool UpdateMapping(Texture texture, MultiRange range)
 | 
			
		||||
        {
 | 
			
		||||
            // There cannot be an existing texture compatible with this mapping in the texture cache already.
 | 
			
		||||
            int overlapCount = _textures.FindOverlaps(range, ref _textureOverlaps);
 | 
			
		||||
            int overlapCount;
 | 
			
		||||
 | 
			
		||||
            _texturesLock.EnterReadLock();
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                overlapCount = _textures.FindOverlaps(range, ref _textureOverlaps);
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                _texturesLock.ExitReadLock();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < overlapCount; i++)
 | 
			
		||||
            {
 | 
			
		||||
@@ -231,11 +253,20 @@ namespace Ryujinx.Graphics.Gpu.Image
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _textures.Remove(texture);
 | 
			
		||||
            _texturesLock.EnterWriteLock();
 | 
			
		||||
 | 
			
		||||
            texture.ReplaceRange(range);
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                _textures.Remove(texture);
 | 
			
		||||
 | 
			
		||||
            _textures.Add(texture);
 | 
			
		||||
                texture.ReplaceRange(range);
 | 
			
		||||
 | 
			
		||||
                _textures.Add(texture);
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                _texturesLock.ExitWriteLock();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
@@ -611,11 +642,17 @@ namespace Ryujinx.Graphics.Gpu.Image
 | 
			
		||||
 | 
			
		||||
            int sameAddressOverlapsCount;
 | 
			
		||||
 | 
			
		||||
            lock (_textures)
 | 
			
		||||
            _texturesLock.EnterReadLock();
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                // Try to find a perfect texture match, with the same address and parameters.
 | 
			
		||||
                sameAddressOverlapsCount = _textures.FindOverlaps(address, ref _textureOverlaps);
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                _texturesLock.ExitReadLock();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Texture texture = null;
 | 
			
		||||
 | 
			
		||||
@@ -698,10 +735,16 @@ namespace Ryujinx.Graphics.Gpu.Image
 | 
			
		||||
 | 
			
		||||
            if (info.Target != Target.TextureBuffer)
 | 
			
		||||
            {
 | 
			
		||||
                lock (_textures)
 | 
			
		||||
                _texturesLock.EnterReadLock();
 | 
			
		||||
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    overlapsCount = _textures.FindOverlaps(range.Value, ref _textureOverlaps);
 | 
			
		||||
                }
 | 
			
		||||
                finally
 | 
			
		||||
                {
 | 
			
		||||
                    _texturesLock.ExitReadLock();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (_overlapInfo.Length != _textureOverlaps.Length)
 | 
			
		||||
@@ -1025,10 +1068,16 @@ namespace Ryujinx.Graphics.Gpu.Image
 | 
			
		||||
                _cache.Add(texture);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            lock (_textures)
 | 
			
		||||
            _texturesLock.EnterWriteLock();
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                _textures.Add(texture);
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                _texturesLock.ExitWriteLock();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (partiallyMapped)
 | 
			
		||||
            {
 | 
			
		||||
@@ -1091,7 +1140,19 @@ namespace Ryujinx.Graphics.Gpu.Image
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            int addressMatches = _textures.FindOverlaps(address, ref _textureOverlaps);
 | 
			
		||||
            int addressMatches;
 | 
			
		||||
 | 
			
		||||
            _texturesLock.EnterReadLock();
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                addressMatches = _textures.FindOverlaps(address, ref _textureOverlaps);
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                _texturesLock.ExitReadLock();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Texture textureMatch = null;
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < addressMatches; i++)
 | 
			
		||||
@@ -1232,10 +1293,16 @@ namespace Ryujinx.Graphics.Gpu.Image
 | 
			
		||||
        /// <param name="texture">The texture to be removed</param>
 | 
			
		||||
        public void RemoveTextureFromCache(Texture texture)
 | 
			
		||||
        {
 | 
			
		||||
            lock (_textures)
 | 
			
		||||
            _texturesLock.EnterWriteLock();
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                _textures.Remove(texture);
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                _texturesLock.ExitWriteLock();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            lock (_partiallyMappedTextures)
 | 
			
		||||
            {
 | 
			
		||||
@@ -1324,13 +1391,19 @@ namespace Ryujinx.Graphics.Gpu.Image
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void Dispose()
 | 
			
		||||
        {
 | 
			
		||||
            lock (_textures)
 | 
			
		||||
            _texturesLock.EnterReadLock();
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                foreach (Texture texture in _textures)
 | 
			
		||||
                {
 | 
			
		||||
                    texture.Dispose();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                _texturesLock.ExitReadLock();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user