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 Ryujinx.Memory.Range;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Image
|
namespace Ryujinx.Graphics.Gpu.Image
|
||||||
{
|
{
|
||||||
|
@ -39,6 +40,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
private readonly MultiRangeList<Texture> _textures;
|
private readonly MultiRangeList<Texture> _textures;
|
||||||
private readonly HashSet<Texture> _partiallyMappedTextures;
|
private readonly HashSet<Texture> _partiallyMappedTextures;
|
||||||
|
|
||||||
|
private readonly ReaderWriterLockSlim _texturesLock;
|
||||||
|
|
||||||
private Texture[] _textureOverlaps;
|
private Texture[] _textureOverlaps;
|
||||||
private OverlapInfo[] _overlapInfo;
|
private OverlapInfo[] _overlapInfo;
|
||||||
|
|
||||||
|
@ -57,6 +60,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
_textures = new MultiRangeList<Texture>();
|
_textures = new MultiRangeList<Texture>();
|
||||||
_partiallyMappedTextures = new HashSet<Texture>();
|
_partiallyMappedTextures = new HashSet<Texture>();
|
||||||
|
|
||||||
|
_texturesLock = new ReaderWriterLockSlim();
|
||||||
|
|
||||||
_textureOverlaps = new Texture[OverlapsBufferInitialCapacity];
|
_textureOverlaps = new Texture[OverlapsBufferInitialCapacity];
|
||||||
_overlapInfo = new OverlapInfo[OverlapsBufferInitialCapacity];
|
_overlapInfo = new OverlapInfo[OverlapsBufferInitialCapacity];
|
||||||
|
|
||||||
|
@ -75,10 +80,16 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
MultiRange unmapped = ((MemoryManager)sender).GetPhysicalRegions(e.Address, e.Size);
|
MultiRange unmapped = ((MemoryManager)sender).GetPhysicalRegions(e.Address, e.Size);
|
||||||
|
|
||||||
lock (_textures)
|
_texturesLock.EnterReadLock();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
overlapCount = _textures.FindOverlaps(unmapped, ref overlaps);
|
overlapCount = _textures.FindOverlaps(unmapped, ref overlaps);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_texturesLock.ExitReadLock();
|
||||||
|
}
|
||||||
|
|
||||||
if (overlapCount > 0)
|
if (overlapCount > 0)
|
||||||
{
|
{
|
||||||
|
@ -217,7 +228,18 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
public bool UpdateMapping(Texture texture, MultiRange range)
|
public bool UpdateMapping(Texture texture, MultiRange range)
|
||||||
{
|
{
|
||||||
// There cannot be an existing texture compatible with this mapping in the texture cache already.
|
// 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++)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -611,11 +642,17 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
int sameAddressOverlapsCount;
|
int sameAddressOverlapsCount;
|
||||||
|
|
||||||
lock (_textures)
|
_texturesLock.EnterReadLock();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// Try to find a perfect texture match, with the same address and parameters.
|
// Try to find a perfect texture match, with the same address and parameters.
|
||||||
sameAddressOverlapsCount = _textures.FindOverlaps(address, ref _textureOverlaps);
|
sameAddressOverlapsCount = _textures.FindOverlaps(address, ref _textureOverlaps);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_texturesLock.ExitReadLock();
|
||||||
|
}
|
||||||
|
|
||||||
Texture texture = null;
|
Texture texture = null;
|
||||||
|
|
||||||
|
@ -698,10 +735,16 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
if (info.Target != Target.TextureBuffer)
|
if (info.Target != Target.TextureBuffer)
|
||||||
{
|
{
|
||||||
lock (_textures)
|
_texturesLock.EnterReadLock();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
overlapsCount = _textures.FindOverlaps(range.Value, ref _textureOverlaps);
|
overlapsCount = _textures.FindOverlaps(range.Value, ref _textureOverlaps);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_texturesLock.ExitReadLock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_overlapInfo.Length != _textureOverlaps.Length)
|
if (_overlapInfo.Length != _textureOverlaps.Length)
|
||||||
|
@ -1025,10 +1068,16 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
_cache.Add(texture);
|
_cache.Add(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (_textures)
|
_texturesLock.EnterWriteLock();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_textures.Add(texture);
|
_textures.Add(texture);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_texturesLock.ExitWriteLock();
|
||||||
|
}
|
||||||
|
|
||||||
if (partiallyMapped)
|
if (partiallyMapped)
|
||||||
{
|
{
|
||||||
|
@ -1091,7 +1140,19 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
return null;
|
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;
|
Texture textureMatch = null;
|
||||||
|
|
||||||
for (int i = 0; i < addressMatches; i++)
|
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>
|
/// <param name="texture">The texture to be removed</param>
|
||||||
public void RemoveTextureFromCache(Texture texture)
|
public void RemoveTextureFromCache(Texture texture)
|
||||||
{
|
{
|
||||||
lock (_textures)
|
_texturesLock.EnterWriteLock();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_textures.Remove(texture);
|
_textures.Remove(texture);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_texturesLock.ExitWriteLock();
|
||||||
|
}
|
||||||
|
|
||||||
lock (_partiallyMappedTextures)
|
lock (_partiallyMappedTextures)
|
||||||
{
|
{
|
||||||
|
@ -1324,13 +1391,19 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
lock (_textures)
|
_texturesLock.EnterReadLock();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
foreach (Texture texture in _textures)
|
foreach (Texture texture in _textures)
|
||||||
{
|
{
|
||||||
texture.Dispose();
|
texture.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_texturesLock.ExitReadLock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue