Skip to content

Commit

Permalink
Add missing lock on texture cache UpdateMapping method (#6657)
Browse files Browse the repository at this point in the history
  • Loading branch information
gdkchan committed May 14, 2024
1 parent a3dc295 commit cd78adf
Showing 1 changed file with 84 additions and 11 deletions.
95 changes: 84 additions & 11 deletions src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Ryujinx.Memory.Range;
using System;
using System.Collections.Generic;
using System.Threading;

namespace Ryujinx.Graphics.Gpu.Image
{
Expand Down Expand Up @@ -39,6 +40,8 @@ public OverlapInfo(TextureViewCompatibility compatibility, int firstLayer, int f
private readonly MultiRangeList<Texture> _textures;
private readonly HashSet<Texture> _partiallyMappedTextures;

private readonly ReaderWriterLockSlim _texturesLock;

private Texture[] _textureOverlaps;
private OverlapInfo[] _overlapInfo;

Expand All @@ -57,6 +60,8 @@ public TextureCache(GpuContext context, PhysicalMemory physicalMemory)
_textures = new MultiRangeList<Texture>();
_partiallyMappedTextures = new HashSet<Texture>();

_texturesLock = new ReaderWriterLockSlim();

_textureOverlaps = new Texture[OverlapsBufferInitialCapacity];
_overlapInfo = new OverlapInfo[OverlapsBufferInitialCapacity];

Expand All @@ -75,10 +80,16 @@ public void MemoryUnmappedHandler(object sender, UnmapEventArgs e)

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)
{
Expand Down Expand Up @@ -217,7 +228,18 @@ public void Lift(Texture texture)
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++)
{
Expand All @@ -231,11 +253,20 @@ public bool UpdateMapping(Texture texture, MultiRange range)
}
}

_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;
}
Expand Down Expand Up @@ -611,11 +642,17 @@ private static void DiscardIfNeeded(bool discard, Texture texture, Size? sizeHin

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;

Expand Down Expand Up @@ -698,10 +735,16 @@ private static void DiscardIfNeeded(bool discard, Texture texture, Size? sizeHin

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)
Expand Down Expand Up @@ -1025,10 +1068,16 @@ private static void DiscardIfNeeded(bool discard, Texture texture, Size? sizeHin
_cache.Add(texture);
}

lock (_textures)
_texturesLock.EnterWriteLock();

try
{
_textures.Add(texture);
}
finally
{
_texturesLock.ExitWriteLock();
}

if (partiallyMapped)
{
Expand Down Expand Up @@ -1091,7 +1140,19 @@ public Texture FindShortCache(in TextureDescriptor descriptor)
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++)
Expand Down Expand Up @@ -1232,10 +1293,16 @@ public static TextureCreateInfo GetCreateInfo(TextureInfo info, Capabilities cap
/// <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)
{
Expand Down Expand Up @@ -1324,13 +1391,19 @@ public void Tick()
/// </summary>
public void Dispose()
{
lock (_textures)
_texturesLock.EnterReadLock();

try
{
foreach (Texture texture in _textures)
{
texture.Dispose();
}
}
finally
{
_texturesLock.ExitReadLock();
}
}
}
}

0 comments on commit cd78adf

Please sign in to comment.