Skip some invalid texture flushes (#5755)

This commit is contained in:
gdkchan 2023-10-30 19:18:28 -03:00 committed by GitHub
parent c14ce4d2a5
commit 9ef0be477b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 3 deletions

View file

@ -101,6 +101,11 @@ namespace Ryujinx.Graphics.Gpu.Image
/// </summary> /// </summary>
public bool AlwaysFlushOnOverlap { get; private set; } public bool AlwaysFlushOnOverlap { get; private set; }
/// <summary>
/// Indicates that the texture was fully unmapped since the modified flag was set, and flushes should be ignored until it is modified again.
/// </summary>
public bool FlushStale { get; private set; }
/// <summary> /// <summary>
/// Increments when the host texture is swapped, or when the texture is removed from all pools. /// Increments when the host texture is swapped, or when the texture is removed from all pools.
/// </summary> /// </summary>
@ -149,6 +154,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// </summary> /// </summary>
public bool HadPoolOwner { get; private set; } public bool HadPoolOwner { get; private set; }
/// <summary>
/// Physical memory ranges where the texture data is located. /// Physical memory ranges where the texture data is located.
/// </summary> /// </summary>
public MultiRange Range { get; private set; } public MultiRange Range { get; private set; }
@ -1411,6 +1417,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// </summary> /// </summary>
public void SignalModified() public void SignalModified()
{ {
FlushStale = false;
_scaledSetScore = Math.Max(0, _scaledSetScore - 1); _scaledSetScore = Math.Max(0, _scaledSetScore - 1);
if (_modifiedStale || Group.HasCopyDependencies) if (_modifiedStale || Group.HasCopyDependencies)
@ -1431,6 +1438,7 @@ namespace Ryujinx.Graphics.Gpu.Image
{ {
if (bound) if (bound)
{ {
FlushStale = false;
_scaledSetScore = Math.Max(0, _scaledSetScore - 1); _scaledSetScore = Math.Max(0, _scaledSetScore - 1);
} }
@ -1695,12 +1703,17 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <param name="unmapRange">The range of memory being unmapped</param> /// <param name="unmapRange">The range of memory being unmapped</param>
public void Unmapped(MultiRange unmapRange) public void Unmapped(MultiRange unmapRange)
{ {
if (unmapRange.Contains(Range))
{
// If this is a full unmap, prevent flushes until the texture is mapped again.
FlushStale = true;
}
ChangedMapping = true; ChangedMapping = true;
if (Group.Storage == this) if (Group.Storage == this)
{ {
Group.Unmapped(); Group.Unmapped();
Group.ClearModified(unmapRange); Group.ClearModified(unmapRange);
} }
} }

View file

@ -107,8 +107,6 @@ namespace Ryujinx.Graphics.Gpu.Image
// Any texture that has been unmapped at any point or is partially unmapped // Any texture that has been unmapped at any point or is partially unmapped
// should update their pool references after the remap completes. // should update their pool references after the remap completes.
MultiRange unmapped = ((MemoryManager)sender).GetPhysicalRegions(e.Address, e.Size);
foreach (var texture in _partiallyMappedTextures) foreach (var texture in _partiallyMappedTextures)
{ {
texture.UpdatePoolMappings(); texture.UpdatePoolMappings();

View file

@ -1659,6 +1659,14 @@ namespace Ryujinx.Graphics.Gpu.Image
return; return;
} }
// If size is zero, we have nothing to flush.
// If the flush is stale, we should ignore it because the texture was unmapped since the modified
// flag was set, and flushing it is not safe anymore as the GPU might no longer own the memory.
if (size == 0 || Storage.FlushStale)
{
return;
}
// There is a small gap here where the action is removed but _actionRegistered is still 1. // There is a small gap here where the action is removed but _actionRegistered is still 1.
// In this case it will skip registering the action, but here we are already handling it, // In this case it will skip registering the action, but here we are already handling it,
// so there shouldn't be any issue as it's the same handler for all actions. // so there shouldn't be any issue as it's the same handler for all actions.