forked from Mirror/Ryujinx
Add missing lock on texture cache UpdateMapping method (#6657)
This commit is contained in:
parent
a3dc295c5f
commit
cd78adf07f
1 changed files with 84 additions and 11 deletions
|
@ -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
|
|||
}
|
||||
}
|
||||
|
||||
_texturesLock.EnterWriteLock();
|
||||
|
||||
try
|
||||
{
|
||||
_textures.Remove(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 a new issue